/**
 * Title:        ProAlign<p>
 * Description:  <p>
 * Copyright:    Copyright (c) Ari Loytynoja<p>
 * License:      GNU GENERAL PUBLIC LICENSE<p>
 * @see          http://www.gnu.org/copyleft/gpl.html
 * Company:      ULB<p>
 * @author Ari Loytynoja
 * @version 1.0
 */
package proalign;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JComboBox;
import javax.swing.JButton;
import javax.swing.JRadioButton;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JTextField;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.io.File;

public class SetParameters extends JFrame {

    JTextField textDelta;
    JTextField textEpsil;
    JTextField textGapF;
    JTextField textGapP;
    JTextField[] textFreq;
    JTextField textPwOpen;
    JTextField textPwExt;
    JTextField textPwMat;
    JTextField textWidth;
    JTextField textClustalw;
    JTextField textTemp;
    JTextField textOffset;
    JTextField textScale;
    JCheckBox boxLog;
    JCheckBox boxTrail;
    JCheckBox boxMultiple;
    JCheckBox boxPenalize;
    JComboBox pwSubst;

    String[] pwMatrix = {"pam60","pam120","pam160","pam250"};

    int height = 300;
    int width = 600;

    ProAlign pa;
    ResultWindow rw;

    SetParameters(ResultWindow rw) {

	setTitle("Set parameters");   
	this.rw = rw;
	this.pa = rw.pa;

	Font font = new Font(ProAlign.paFontName, Font.PLAIN, ProAlign.paFontSize);

	ButtonListener but = new ButtonListener(); 
	JButton buttonEstFreq = new JButton("Estimate");
	buttonEstFreq.setFont(font);
	buttonEstFreq.setActionCommand("estimatefreq");
	buttonEstFreq.addActionListener(but);
	JButton buttonDefFreq = new JButton("Default");
	buttonDefFreq.setFont(font);
	buttonDefFreq.setActionCommand("defaultfreq");
	buttonDefFreq.addActionListener(but);
	JButton buttonSetFreq = new JButton("Set");
	buttonSetFreq.setFont(font);
	buttonSetFreq.setActionCommand("setfreq");
	buttonSetFreq.addActionListener(but);
	JButton buttonLock = new JButton();
	buttonLock.setFont(font);
	buttonLock.setActionCommand("lock");
	buttonLock.addActionListener(but);
	JButton buttonHmmE = new JButton("Default");
	buttonHmmE.setFont(font);
	buttonHmmE.setActionCommand("hmmE");
	buttonHmmE.addActionListener(but);
	JButton buttonHmmD = new JButton("Default");
	buttonHmmD.setFont(font);
	buttonHmmD.setActionCommand("hmmD");
	buttonHmmD.addActionListener(but);
	JButton buttonHmmEst = new JButton("Estimate");
	buttonHmmEst.setFont(font);
	buttonHmmEst.setActionCommand("hmmEst");
	buttonHmmEst.addActionListener(but);
	if(rw.hasTree) {
	    buttonHmmEst.setEnabled(true);
	} else {
	    buttonHmmEst.setEnabled(false);  
	}
	JButton buttonGapF = new JButton("Default");
	buttonGapF.setFont(font);
	buttonGapF.setActionCommand("gapF");
	buttonGapF.addActionListener(but);
	JButton buttonGapP = new JButton("Default");
	buttonGapP.setFont(font);
	buttonGapP.setActionCommand("gapP");
	buttonGapP.addActionListener(but);

	JButton buttonOffset = new JButton("Default");
	buttonOffset.setFont(font);
	buttonOffset.setActionCommand("offset");
	buttonOffset.addActionListener(but);
	JButton buttonLog = new JButton("Select");
	buttonLog.setFont(font);
	buttonLog.setActionCommand("log");
	buttonLog.addActionListener(but);
	JButton buttonWidth = new JButton("Default");
	buttonWidth.setFont(font);
	buttonWidth.setActionCommand("defwidth");
	buttonWidth.addActionListener(but);
	JButton buttonClustalw = new JButton("Change");
	buttonClustalw.setFont(font);
	buttonClustalw.setActionCommand("clustalw");
	buttonClustalw.addActionListener(but);
	JButton buttonTemp = new JButton("Change");
	buttonTemp.setFont(font);
	buttonTemp.setActionCommand("temp");
	buttonTemp.addActionListener(but);
	JButton buttonOK = new JButton("OK");
	buttonOK.setFont(font);
	buttonOK.setActionCommand("ok");
	buttonOK.addActionListener(but);
	JButton buttonCancel = new JButton("Cancel");
	buttonCancel.setFont(font);
	buttonCancel.setActionCommand("cancel");
	buttonCancel.addActionListener(but);

	JLabel labelHMM = new JLabel("   HMM model");
	labelHMM.setFont(font);
	JLabel labelVit = new JLabel("   Viterbi parameters");
	labelVit.setFont(font);
	JLabel labelSet = new JLabel("   Other parameters");
	labelSet.setFont(font);
	JLabel labelChar = new JLabel("   Character frequencies");
	labelChar.setFont(font);
	JLabel labelTrail = new JLabel(" Trailing sequences");
	labelTrail.setFont(font);
	JLabel labelPenalize = new JLabel(" Terminal gaps");
	labelPenalize.setFont(font);
	JLabel labelOffset = new JLabel("   Max allow");
	labelOffset.setFont(font);
	JLabel labelMultiple = new JLabel(" Distances");
	labelMultiple.setFont(font);
	JLabel labelScale = new JLabel(" scale");
	labelScale.setFont(font);
	
	JLabel labelSample = new JLabel(" Viterbi traceback");
	labelSample.setFont(font);
	JLabel labelClustalw = new JLabel(" ClustalW");
	labelClustalw.setFont(font);
	JLabel labelTemp = new JLabel(" Temp folder");
	labelTemp.setFont(font);
	JLabel labelLog = new JLabel(" Change file");
	labelLog.setFont(font);
	JLabel labelDelta = new JLabel(" Delta");
	labelDelta.setFont(font);
	JLabel labelEpsil = new JLabel(" Epsilon");
	labelEpsil.setFont(font);
	JLabel labelGapF = new JLabel(" Gap frequency");
	labelGapF.setFont(font);
	JLabel labelGapP = new JLabel(" Gap probability");
	labelGapP.setFont(font);
	JLabel labelPwPar = new JLabel("   Pairwise alignment");       
	labelPwPar.setFont(font);
	JLabel labelPwOpen = new JLabel(" Gap opening");       
	labelPwOpen.setFont(font);
	JLabel labelPwExt = new JLabel(" Gap extension");       
	labelPwExt.setFont(font);
	JLabel labelWidth = new JLabel(" Band width");
	labelWidth.setFont(font); 
	JLabel[] labelFreq = new JLabel[pa.sm.alphabet.length()];

	textDelta = new JTextField("     ");
	textDelta.setText(""+pa.sm.delta);
	textDelta.setFont(font);
	textEpsil = new JTextField("     ");
	textEpsil.setText(""+pa.sm.epsilon);
	textEpsil.setFont(font);

	textGapF = new JTextField("     ");
	textGapF.setText(""+pa.gapFreq);
	textGapF.setFont(font);
	textGapP = new JTextField("     ");
	textGapP.setText(""+pa.gapProb);
	textGapP.setFont(font);

	textPwOpen = new JTextField("     "); 
	textPwExt = new JTextField("     "); 
	textPwMat = new JTextField("     "); 
	textPwOpen.setFont(font);
	textPwExt.setFont(font);

	if(ProAlign.isDna) {
	    textPwOpen.setText(""+(float)pa.pwDnaOpen/100f);
	    textPwExt.setText(""+(float)pa.pwDnaExt/100f);
	    textPwMat.setText("  DNA");
	    textPwMat.setEditable(false);
	} else {
	    textPwOpen.setText(""+(float)pa.pwProtOpen/100f);
	    textPwExt.setText(""+(float)pa.pwProtExt/100f);
	    textPwMat.setText("  "+pa.pwProtMatrix);
	    textPwMat.setEditable(false);
	}

	// Pairwise protein score matrix 
	pwSubst = new JComboBox();
	pwSubst.setFont(font);
	pwSubst.addItemListener(new ComboBoxListener());

	for(int i=0; i<pwMatrix.length; i++) {
	    pwSubst.addItem(pwMatrix[i]);
	}
	pwSubst.setSelectedItem(pa.pwProtMatrix);

	if(ProAlign.isDna) {
	    textFreq = new JTextField[pa.sm.alphabet.length()];
	    for(int i=0; i<textFreq.length; i++) {
		labelFreq[i] = new JLabel();
		labelFreq[i].setFont(font);
		textFreq[i] = new JTextField();
		textFreq[i].setFont(font);
		labelFreq[i].setText("     "+pa.sm.alphabet.charAt(i));
		textFreq[i].setText((""+pa.sm.charFreqs[i]+"     ").substring(0,5));
	    }
	    buttonLock.setText(""+pa.sm.alphabet.charAt(pa.sm.alphabet.length()-1));
	    textFreq[pa.sm.alphabet.length()-1].setEditable(false);
	}

	textWidth = new JTextField("     ");
	textWidth.setText(""+pa.bandWidth);
	textWidth.setFont(font);
	textClustalw = new JTextField("     "); 
	textClustalw.setText(""+pa.clustalwPath);
	textClustalw.setFont(font);
	textClustalw.setEditable(false);
	textTemp = new JTextField("     "); 
	textTemp.setText(""+pa.tempFolder);
	textTemp.setFont(font);
	textTemp.setEditable(false);
 	textOffset = new JTextField("     "); 
	textOffset.setText(""+ProAlign.offset);
	textOffset.setFont(font);
 	textScale = new JTextField("     "); 
	textScale.setText(""+ProAlign.distScale);
	textScale.setFont(font);

	JRadioButton traceBest = new JRadioButton("select best");
	traceBest.setFont(font);
	traceBest.setActionCommand("best");
	JRadioButton traceSample = new JRadioButton("sample");
	traceSample.setFont(font);
	traceSample.setActionCommand("sample");

	if(ProAlign.trackBest) {
	    traceBest.setSelected(true);
	} else {
	   traceSample.setSelected(true);
	}

	boxLog = new JCheckBox("Write log");
	boxLog.setFont(font);
	boxLog.setActionCommand("log");
	boxLog.addActionListener(new CheckBoxListener());
	if(ProAlign.DEBUG) {
	    boxLog.setSelected(true);
	} else {
	    boxLog.setSelected(false);
	}

	boxTrail = new JCheckBox("correct");
	boxTrail.setFont(font);
	boxTrail.setActionCommand("trailing");
	boxTrail.addActionListener(new CheckBoxListener());
	if(ProAlign.removeTrailing) {
	    boxTrail.setSelected(true);
	    textOffset.setEditable(true);
	} else {
	    boxTrail.setSelected(false);
	    textOffset.setEditable(false);
	}

	boxMultiple = new JCheckBox("correct");
	boxMultiple.setFont(font);
	boxMultiple.setActionCommand("multiple");
	boxMultiple.addActionListener(new CheckBoxListener());
	if(ProAlign.correctMultiple) {
	    boxMultiple.setSelected(true);
	} else {
	    boxMultiple.setSelected(false);
	}

	boxPenalize = new JCheckBox("penalize");
	boxPenalize.setFont(font);
	boxPenalize.setActionCommand("terminal");
	boxPenalize.addActionListener(new CheckBoxListener());
	if(ProAlign.penalizeTerminal) {
	    boxPenalize.setSelected(true);
	} else {
	    boxPenalize.setSelected(false);
	}

	// Construct panels
	//
	JPanel fullPanel = new JPanel();
	fullPanel.setLayout(new GridLayout(1,2,15,15));
	JPanel halfPanel = new JPanel();
	halfPanel.setLayout(new GridLayout(11,1,5,5));

//
	halfPanel.add(labelChar);

	JPanel pnl = new JPanel(); 
	if(ProAlign.isDna) {
	    pnl = new JPanel();
	    pnl.setLayout(new GridLayout(1,textFreq.length,5,5));
	    for(int i=0; i<textFreq.length-1; i++) {
		pnl.add(labelFreq[i]);
	    }
	    pnl.add(buttonLock);
	    halfPanel.add(pnl);
	    
	    pnl = new JPanel();
	    pnl.setLayout(new GridLayout(1,textFreq.length,5,5));
	    for(int i=0; i<textFreq.length; i++) {
		pnl.add(textFreq[i]);
	    }
	    halfPanel.add(pnl);	

	    pnl = new JPanel();
	    pnl.setLayout(new GridLayout(1,3,5,5));
	    pnl.add(buttonSetFreq);
	    pnl.add(buttonDefFreq);
	    pnl.add(buttonEstFreq);
	    halfPanel.add(pnl);
	} else {
	    pnl = new JPanel();
	    pnl.setLayout(new GridLayout(1,3,5,5));
	    pnl.add(labelGapF);
	    pnl.add(textGapF);
	    pnl.add(buttonGapF);
	    halfPanel.add(pnl);

	    pnl = new JPanel();
	    pnl.setLayout(new GridLayout(1,3,5,5));
	    pnl.add(labelGapP);
	    pnl.add(textGapP);
	    pnl.add(buttonGapP);
	    halfPanel.add(pnl);

	    halfPanel.add(new JLabel());
	}

	halfPanel.add(labelPwPar);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	if(ProAlign.isDna) {
	    pnl.add(new JLabel());
	} else {
	    pnl.add(pwSubst);
	}
	pnl.add(labelPwOpen);
	pnl.add(labelPwExt);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(textPwMat);
	pnl.add(textPwOpen);
	pnl.add(textPwExt);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,2,5,5));
	pnl.add(labelPenalize);
	pnl.add(boxPenalize);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,2,5,5));
	pnl.add(labelTrail);
	pnl.add(boxTrail);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(labelOffset);
	pnl.add(textOffset);
	pnl.add(buttonOffset);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,4,5,5));
	pnl.add(labelMultiple);
	pnl.add(boxMultiple);
	pnl.add(labelScale);
	pnl.add(textScale);
	halfPanel.add(pnl);

	fullPanel.add(halfPanel);

	halfPanel = new JPanel();
	halfPanel.setLayout(new GridLayout(11,1,5,5));

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(labelHMM);
	pnl.add(new JLabel());
	pnl.add(buttonHmmEst);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(labelDelta);
	pnl.add(textDelta);
	pnl.add(buttonHmmD);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(labelEpsil);
	pnl.add(textEpsil);
	pnl.add(buttonHmmE);
	halfPanel.add(pnl);

	ButtonGroup traceBack = new ButtonGroup();
        traceBack.add(traceBest);
        traceBack.add(traceSample);
        traceBest.addActionListener(new RadioListener());
        traceSample.addActionListener(new RadioListener());

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,2,5,5));
	pnl.add(labelSample);
	pnl.add(traceBest);
	halfPanel.add(pnl);
	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,2,5,5));
	pnl.add(new JPanel());
	pnl.add(traceSample);
	halfPanel.add(pnl);

//	halfPanel.add(new JLabel());

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(boxLog);
	pnl.add(labelLog);
	pnl.add(buttonLog);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(labelWidth);
	pnl.add(textWidth);
	pnl.add(buttonWidth);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(labelClustalw);
	pnl.add(textClustalw);
	pnl.add(buttonClustalw);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(labelTemp);
	pnl.add(textTemp);
	pnl.add(buttonTemp);
	halfPanel.add(pnl);

	halfPanel.add(new JLabel());

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(new JLabel());
	pnl.add(buttonOK);
	pnl.add(buttonCancel);
	halfPanel.add(pnl);

	fullPanel.add(halfPanel);

	Container cp = getContentPane();
	cp.add(fullPanel);

	addWindowListener(new WindowAdapter() {
		public void windowClosing(WindowEvent e) {
		    dispose();
		}
	    });

    }
    
    class ButtonListener implements ActionListener {
	public void actionPerformed(ActionEvent e) {
	    
	    JButton target = (JButton)e.getSource();
	    String actionCommand = target.getActionCommand();

	    if(actionCommand.equals("estimatefreq")) {

		if(!rw.hasData) {

		    String text = new String("\n   Estimating frequencies needs some data! \n");
		    OpenDialog od = new OpenDialog(SetParameters.this);
		    od.showDialog("Error!", text);    

		} else {

		    EstimateFrequencies ef = new EstimateFrequencies(
			rw.seqcont.textArray,pa.sm.alphabet,pa.sm.equateAlphabet);
		    double[] freqs = ef.getCharacterFrequencies();

		    NicePrint nn = new NicePrint();
		    for(int i=0; i<textFreq.length; i++) {
			textFreq[i].setText(nn.rdbl(freqs[i],3));
		    }
		    
		    if(!rw.isAligned) {
			String text = new String("\n   Sequences are not aligned. Estimating \n"+
						 "  gap frequency does not make much sense!\n");
			OpenDialog od = new OpenDialog(SetParameters.this);
			od.showDialog("Warning!", text);
		    }
		}

	    } else if(actionCommand.equals("defaultfreq")) {

		for(int i=0; i<textFreq.length; i++) {
		    textFreq[i].setText(""+pa.sm.charFreqsDefault[i]);
		}
		
	    } else if(actionCommand.equals("setfreq")) {

		NicePrint nn = new NicePrint();
		if(textFreq[textFreq.length-1].isEditable()) {
		    double[] setFreqs = new double[textFreq.length];
		    double sum = 0d;
		    for(int i=0; i<textFreq.length; i++) {
			setFreqs[i] = new Double(textFreq[i].getText()).doubleValue();
			sum += setFreqs[i];
			System.out.println("read: "+setFreqs[i]+", sum: "+sum);
		    }
		    for(int i=0; i<textFreq.length; i++) {
			textFreq[i].setText(nn.rdbl(setFreqs[i]/sum,3));	
			System.out.println("write: "+setFreqs[i]/sum);
		    }
		} else {
		    double sum = 0d;
		    for(int i=0; i<textFreq.length-1; i++) {
			sum += new Double(textFreq[i].getText()).doubleValue();
		    }
		    if(sum < 1d) {
			textFreq[textFreq.length-1].setText(nn.rdbl(1d-sum,3));
		    }  
		}

	    } else if(actionCommand.equals("lock")) {

		if(textFreq[textFreq.length-1].isEditable()) {
		    textFreq[textFreq.length-1].setEditable(false);
		} else {
		    textFreq[textFreq.length-1].setEditable(true);
		}

	    } else if(actionCommand.equals("log")) {

		OpenFileChooser opf = 
		    new OpenFileChooser(SetParameters.this,"Start log",false);
		String filepath = opf.openFile();
	 	if(!filepath.equals("")) {
		    pa.log.close();
		    pa.startNewLog(filepath);
		    UserSettings user = new UserSettings(); 
		    String[] userdata = user.readSettings();
		    ProAlign.folderPath = new File(filepath).getParent();
		    userdata[0] = new File(filepath).getParent();
                    user.writeSettings(userdata);
		}
		
	    } else if(actionCommand.equals("hmmE")) {

		textEpsil.setText(""+pa.sm.epsilonDefault);

	    } else if(actionCommand.equals("hmmD")) {

		textDelta.setText(""+pa.sm.deltaDefault);

	    } else if(actionCommand.equals("hmmEst")) {

		ProAlign.estimateDelta = true;
		ProAlign.estimateEpsilon = true;
		ProAlign.estimateGapFreq = false;
		ProAlign.estimateGapProb = false;

		ParameterEstimates pe = new ParameterEstimates(rw,SetParameters.this);

	    } else if(actionCommand.equals("gapF")) {

		textGapF.setText(""+pa.sm.gapFreqDefault);

	    } else if(actionCommand.equals("gapP")) {

		textGapP.setText(""+pa.sm.gapProbDefault);

	    } else if(actionCommand.equals("defwidth")) {

		textWidth.setText(""+pa.defBandWidth);

	    } else if(actionCommand.equals("offset")) {
		
		textOffset.setText(""+pa.defOffset);
		textOffset.setEditable(true);
		boxTrail.setSelected(true);

	    } else if(actionCommand.equals("clustalw")) {

		OpenFileChooser opf = 
		    new OpenFileChooser(SetParameters.this,"Select",false);
		String filepath = opf.openFile();
	 	if(!filepath.equals("")) {
		    pa.clustalwPath = filepath;
		    textClustalw.setText(filepath);
		    UserSettings user = new UserSettings(); 
		    String[] userdata = user.readSettings();
		    userdata[1] = filepath;
                    user.writeSettings(userdata);

		}

	    } else if(actionCommand.equals("temp")) {

		OpenFolderChooser opf = 
		    new OpenFolderChooser(SetParameters.this,"Select");
		String filepath = opf.openFile();
	 	if(!filepath.equals("")) {
		    pa.tempFolder = filepath;
		    textTemp.setText(filepath);
		    UserSettings user = new UserSettings(); 
		    String[] userdata = user.readSettings();
		    userdata[2] = filepath;
                    user.writeSettings(userdata);
		}
		
	    } else if(actionCommand.equals("cancel")) {

		dispatchEvent(new WindowEvent(SetParameters.this,
					      WindowEvent.WINDOW_CLOSING));

	    } else if(actionCommand.equals("ok")) {

		while(true) {
		    try{

			if(ProAlign.isDna) {
			    // check that character freqs are reasonable and update them.
			    double[] setFreqs = new double[textFreq.length];
			    double sum = 0d;
			    for(int i=1; i<textFreq.length; i++) {
				setFreqs[i] = new Double(textFreq[i].getText()).doubleValue();
				sum += setFreqs[i];
			    }
			    if(sum < 1d) {
				setFreqs[0] = 1d-sum;
			    } 
			    pa.sm.charFreqs = setFreqs;
			    // or check that gap freq/prob are reasonable
			} else {
			    double gapF = new Double(textGapF.getText()).doubleValue();
			    double gapP = new Double(textGapP.getText()).doubleValue();
			    if(gapF>0d && gapF<0.5d && gapP>0d && gapP<0.5d) {
				pa.sm.gapFreq = gapF;
				pa.sm.gapProb = gapP;
			    } else {
				String text = new String("\n  Illegal value for gap frequency/"+
							 "probability!\n     Value not changed.\n");
				OpenDialog od = new OpenDialog(SetParameters.this);
				od.showDialog("Warning!", text); 
			    }   
			    
			}
			
			double delta = new Double(textDelta.getText()).doubleValue();
			if(delta>0d && delta<0.5d) {
			    pa.sm.delta = delta;
			} else {
			    String text = new String("\n  Illegal value for delta!\n"+
						     "     Value not changed.\n");
			    OpenDialog od = new OpenDialog(SetParameters.this);
			    od.showDialog("Warning!", text); 
			}
			
			double epsilon = new Double(textEpsil.getText()).doubleValue();
			if(epsilon>0d && epsilon<1.0d) {
			    pa.sm.epsilon = epsilon;
			} else {
			    String text = new String("\n  Illegal value for epsilon!\n"+
						     "     Value not changed.\n");
			    OpenDialog od = new OpenDialog(SetParameters.this);
			    od.showDialog("Warning!", text); 
			}
			
			int bandWidth = new Integer(textWidth.getText()).intValue();
			if(bandWidth>10) {
			    pa.bandWidth = bandWidth;
			} else {
			    String text = new String("\n  Band width too low!\n"+
						     "  Value not changed.\n");
			    OpenDialog od = new OpenDialog(SetParameters.this);
			    od.showDialog("Warning!", text); 
			}
			if(bandWidth>200) {
			    String text = new String("\n  Too great band width may run\n"+
						     "   your system out of memory!\n");
			    OpenDialog od = new OpenDialog(SetParameters.this);
			    od.showDialog("Warning!", text); 
			}
			int gapOpen = (int)(new Float(textPwOpen.getText()).floatValue()*100f);
			if(gapOpen>=0 && gapOpen<5100) {
			    if(ProAlign.isDna) {
				pa.pwDnaOpen = gapOpen;
			    } else {
				pa.pwProtOpen = gapOpen;
			    }
			} else {
			    String text = new String("\n  Illegal value for gap opening!\n"+
						     "     Value not changed.\n");
			    OpenDialog od = new OpenDialog(SetParameters.this);
			    od.showDialog("Warning!", text); 
			}

			int gapExt = (int)(new Float(textPwExt.getText()).floatValue()*100f);
			if(gapExt>=0 && gapExt<2100) {
			    if(ProAlign.isDna) {
				pa.pwDnaExt = gapExt;
			    } else {
				pa.pwProtExt = gapExt;
			    }
			} else {
			    String text = new String("\n  Illegal value for gap extension!\n"+
						     "     Value not changed.\n");
			    OpenDialog od = new OpenDialog(SetParameters.this);
			    od.showDialog("Warning!", text); 
			}
			
			int offset = new Integer(textOffset.getText()).intValue();
			if(offset>0 && offset<pa.bandWidth/2) {
			    pa.offset = offset;
			} else {
			    String text = new String("\n  Offset should be less than\n"+
						     "  a half of the band width!\n"+
						     "  Value not changed.\n");
			    OpenDialog od = new OpenDialog(SetParameters.this);
			    od.showDialog("Warning!", text); 
			}

			double scale = new Double(textScale.getText()).doubleValue();
			if(scale>0d && scale<2.0d) {
			    pa.distScale = scale;
			} else {
			    String text = new String("\n  Distance scale should be \n"+
						     "  between 0.0 and 2.0!\n"+
						     "  Value not changed.\n");
			    OpenDialog od = new OpenDialog(SetParameters.this);
			    od.showDialog("Warning!", text); 
			}

			if(!ProAlign.isDna) {
			    pa.pwProtMatrix = textPwMat.getText().trim();
			}

			if(ProAlign.DEBUG) {
			    ProAlign.log("SetParameters");
			    ProAlign.log(" trackBest="+ProAlign.trackBest);
			    ProAlign.log(" bandWidth="+ProAlign.bandWidth);
			    ProAlign.log(" clustalwPath="+ProAlign.clustalwPath);
			    ProAlign.log(" tempFolder="+ProAlign.tempFolder);
			    ProAlign.log(" offset="+ProAlign.offset);
			    ProAlign.log(" distScale="+ProAlign.distScale);
			    ProAlign.log(" removeTrailing="+ProAlign.removeTrailing);
			    ProAlign.log(" penalizeTerminal="+ProAlign.penalizeTerminal);
			    if(ProAlign.isDna) {
				ProAlign.log(" pwGapOpen="+pa.pwDnaOpen);
				ProAlign.log(" pwGapExt="+pa.pwDnaExt);
			    } else {
				ProAlign.log(" pwGapOpen="+pa.pwProtOpen);
				ProAlign.log(" pwGapExt="+pa.pwProtExt);
				ProAlign.log(" pwGapMatrix="+pa.pwProtMatrix);
			    }
			    ProAlign.log.flush();
			}

		    } catch(NumberFormatException nfe) {
			String text = new String("\n   Illegal value!\n");
			OpenDialog od = new OpenDialog(SetParameters.this);
			od.showDialog("Error!", text); 
			break;
		    }
		    
		    dispatchEvent(new WindowEvent(SetParameters.this,
						  WindowEvent.WINDOW_CLOSING));
		    break;
		}
	    }
	}
    }

     class RadioListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
	    String actionCommand = e.getActionCommand();

	    if(actionCommand.equals("sample")) {

		ProAlign.trackBest = false;

	    } else if(actionCommand.equals("best")) {

		ProAlign.trackBest = true;
	    }
	}
    }
    
    class ComboBoxListener implements ItemListener {
	public void itemStateChanged(ItemEvent e) {
	    if(!ProAlign.isDna) {
		String item = (String) e.getItem();
		textPwMat.setText("  "+item);
	    }
	}
    }

    class CheckBoxListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
	    String actionCommand = e.getActionCommand();
	    if(actionCommand.equals("log")) {
		if(boxLog.isSelected()) {
		    ProAlign.DEBUG = true;		
		} else {
		    ProAlign.DEBUG = false;
		}
	    } else if(actionCommand.equals("trailing")) {
		if(boxTrail.isSelected()) {
		    ProAlign.removeTrailing = true;
		    textOffset.setEditable(true);
		} else {
		    ProAlign.removeTrailing = false;
		    textOffset.setEditable(false);
		}
	    } else if(actionCommand.equals("multiple")) {
		if(boxMultiple.isSelected()) {
		    ProAlign.correctMultiple = true;		
		} else {
		    ProAlign.correctMultiple = false;
		}
	    } else if(actionCommand.equals("terminal")) {
		if(boxPenalize.isSelected()) {
		    ProAlign.penalizeTerminal = true;		
		} else {
		    ProAlign.penalizeTerminal = false;
		}
	    }
	}
    }
}
