/**
 * 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.JButton;
import javax.swing.JRadioButton;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JScrollBar;
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;
import java.io.IOException;

public class SampleAlignments extends JFrame {

    JTextArea textOutput;
    JTextField textNumber;
    JCheckBox boxResult;
    JCheckBox boxFolder;
    JCheckBox boxNexus;
    JCheckBox boxFasta;
    JScrollPane sp;
    JScrollBar sb;

    String resultPath = new String("sample_result.csv");
    String folderPath = new String("");
    String nexusPath = new String("");
    String fastaPath = new String("");
    int numRun;

    boolean writeResults = true;
    boolean writeAlignments = false;
    boolean writeNexus = false;
    boolean writeFasta = false;
    boolean isRunning = true;

    OutFile resultOut;

    int height = 300;
    int width = 600;

    ProAlign pa;
    ResultWindow rw;
    SampleAlignments sa;

    SampleAlignments(ResultWindow rw) {

	setTitle("Sample alignments");   
	this.rw = rw;
	this.pa = rw.pa;
	sa = this;

	Font font = new Font(ProAlign.paFontName, Font.PLAIN, ProAlign.paFontSize);
	try {
	    resultOut = new OutFile(resultPath);
	} catch(IOException ioe) { }

	JButton buttonResult = new JButton("Select");
	buttonResult.setFont(font);
	buttonResult.setActionCommand("result");
	buttonResult.addActionListener(new ButtonL());
	JButton buttonFolder = new JButton("Select");
	buttonFolder.setFont(font);
	buttonFolder.setActionCommand("folder");
	buttonFolder.addActionListener(new ButtonL());
	JButton buttonNexus = new JButton("Select");
	buttonNexus.setFont(font);
	buttonNexus.setActionCommand("nexus");
	buttonNexus.addActionListener(new ButtonL());
	JButton buttonFasta = new JButton("Select");
	buttonFasta.setFont(font);
	buttonFasta.setActionCommand("fasta");
	buttonFasta.addActionListener(new ButtonL());
	JButton buttonStart = new JButton("Start");
	buttonStart.setFont(font);
	buttonStart.setActionCommand("start");
	buttonStart.addActionListener(new ButtonL());
	JButton buttonStop = new JButton("Stop");
	buttonStop.setFont(font);
	buttonStop.setActionCommand("stop");
	buttonStop.addActionListener(new ButtonL());
	JButton buttonClose = new JButton("Close");
	buttonClose.setFont(font);
	buttonClose.setActionCommand("close");
	buttonClose.addActionListener(new ButtonL());

	JLabel labelHeader = new JLabel("   Sampling parameters");
	labelHeader.setFont(font);
	JLabel labelResult = new JLabel("Change file");
	labelResult.setFont(font);
	JLabel labelFolder = new JLabel("Change folder");
	labelFolder.setFont(font);
	JLabel labelNexus = new JLabel("Change folder");
	labelNexus.setFont(font);
	JLabel labelFasta = new JLabel("Change folder");
	labelFasta.setFont(font);
	JLabel labelNumber = new JLabel("Permutations");
	labelNumber.setFont(font);
	JLabel labelSample = new JLabel("Traceback route");
	labelSample.setFont(font);

	textNumber = new JTextField("100");
	textNumber.setFont(font);

	boxResult = new JCheckBox("Write results");
	boxResult.setActionCommand("result");
	boxResult.setFont(font);
	if(writeResults) {
	    boxResult.setSelected(true);
	} else {
	    boxResult.setSelected(false);
	}

	boxFolder = new JCheckBox("Save ."+ProAlign.fileExt);
	boxFolder.setActionCommand("folder");
	boxFolder.setFont(font);
	boxFolder.setSelected(false);

	boxNexus = new JCheckBox("Save .nex");
	boxNexus.setActionCommand("nexus");
	boxNexus.setFont(font);
	boxNexus.setSelected(false);

	boxFasta = new JCheckBox("Save .pir");
	boxFasta.setActionCommand("fasta");
	boxFasta.setFont(font);
	boxFasta.setSelected(false);

	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);
	}

	CheckBoxListener chboxL = new CheckBoxListener();
	boxResult.addItemListener(chboxL);
	boxFolder.addItemListener(chboxL);
	boxNexus.addItemListener(chboxL);
	boxFasta.addItemListener(chboxL);

	JPanel fullPanel = new JPanel();
	fullPanel.setLayout(new GridLayout(1,2,15,15));
	JPanel halfPanel = new JPanel();
	halfPanel.setLayout(new GridLayout(10,1,5,5));

	halfPanel.add(labelHeader);

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

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(boxResult);
	pnl.add(labelResult);
	pnl.add(buttonResult);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(boxFolder);
	pnl.add(labelFolder);
	pnl.add(buttonFolder);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(boxNexus);
	pnl.add(labelNexus);
	pnl.add(buttonNexus);
	halfPanel.add(pnl);

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(boxFasta);
	pnl.add(labelFasta);
	pnl.add(buttonFasta);
	halfPanel.add(pnl);

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

	RadioListener radioL = new RadioListener();
        traceBest.addActionListener(radioL);
        traceSample.addActionListener(radioL);

	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 JPanel());

	pnl = new JPanel();
	pnl.setLayout(new GridLayout(1,3,5,5));
	pnl.add(buttonStart);
	pnl.add(buttonStop);
	pnl.add(buttonClose);
	halfPanel.add(pnl);

	fullPanel.add(halfPanel);


	textOutput = new JTextArea();
	textOutput.setFont(font);

	sp = new JScrollPane(textOutput,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
			      JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
	sb = sp.getVerticalScrollBar();

	fullPanel.add(sp);

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

	addWindowListener(new WindowAdapter() {
		public void windowClosing(WindowEvent e) {
		    dispose();
		}
	    });
    }
     
    public void write(String str) {
	if (str != "") {
	    textOutput.append("  " + str + "  \n");
	    sb.setValue(sb.getMaximum());
	}
    }

    class ButtonL implements ActionListener {
	public void actionPerformed(ActionEvent e) {
	    
	    JButton target = (JButton)e.getSource();
	    String actionCommand = target.getActionCommand();
	    
	    if(actionCommand.equals("result")) {
		
		OpenFileChooser opf = 
		    new OpenFileChooser(SampleAlignments.this,"Save",false);
		String filepath = opf.openFile();
	 	if(!filepath.equals("")) {
		    resultOut.close();
		    try {
			resultOut = new OutFile(filepath);
		    } catch(IOException ioe) { }
		    sa.write("result file is: "+filepath);
		    resultPath = filepath;
		    UserSettings user = new UserSettings(); 
		    String[] userdata = user.readSettings();
		    userdata[0] = new File(filepath).getParent();
                    user.writeSettings(userdata);
		}
		
	    } else if(actionCommand.equals("folder")) {

		OpenFolderChooser opf = 
		    new OpenFolderChooser(SampleAlignments.this,"Select");
		String filepath = opf.openFile();
	 	if(!filepath.equals("")) {
		    folderPath = filepath;
		    sa.write("alignment folder is: "+new File(folderPath).getAbsolutePath());
		    UserSettings user = new UserSettings(); 
		    String[] userdata = user.readSettings();
		    userdata[0] = new File(filepath).getParent();
                    user.writeSettings(userdata);
		}
		
	    } else if(actionCommand.equals("nexus")) {

		OpenFolderChooser opf = 
		    new OpenFolderChooser(SampleAlignments.this,"Select");
		String filepath = opf.openFile();
	 	if(!filepath.equals("")) {
		    nexusPath = filepath;
		    sa.write("nexus folder is: "+new File(nexusPath).getAbsolutePath());
		    UserSettings user = new UserSettings(); 
		    String[] userdata = user.readSettings();
		    userdata[0] = new File(filepath).getParent();
                    user.writeSettings(userdata);
		}

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

		OpenFolderChooser opf = 
		    new OpenFolderChooser(SampleAlignments.this,"Select");
		String filepath = opf.openFile();
	 	if(!filepath.equals("")) {
		    fastaPath = filepath;
		    sa.write("fasta folder is: "+new File(fastaPath).getAbsolutePath());
		    UserSettings user = new UserSettings(); 
		    String[] userdata = user.readSettings();
		    userdata[0] = new File(filepath).getParent();
                    user.writeSettings(userdata);
		}

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

		while(true) {
		    try{
			int maxRun = new Integer(textNumber.getText()).intValue();
			if(maxRun>0) {
			    numRun = maxRun;
			} else {
			    String text = new String("\n   Illegal value!  \n");
			    OpenDialog od = new OpenDialog(SampleAlignments.this);
			    od.showDialog("Error!", text); 
			    break;
			}
			if(ProAlign.DEBUG) {
			    ProAlign.log("SampleAlignments");
			    ProAlign.log("resultPath="+resultPath+","+writeResults);
			    ProAlign.log("folderPath="+folderPath+","+writeAlignments);
			    ProAlign.log("nexusPath="+nexusPath+","+writeNexus);
			    ProAlign.log("fastaPath="+fastaPath+","+writeFasta);
			    ProAlign.log("numRun="+numRun);
			    ProAlign.log("trackBest="+ProAlign.trackBest);
			    ProAlign.log.flush();
			}
		    } catch(NumberFormatException nfe) {
			String text = new String("\n   Illegal value!  \n");
			OpenDialog od = new OpenDialog(SampleAlignments.this);
			od.showDialog("Error!", text); 
			break;
		    }
		    
		    SampleLoop sl = new SampleLoop(SampleAlignments.this);
		    break;
		}

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

		isRunning = false;

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

		dispatchEvent(new WindowEvent(SampleAlignments.this,
					      WindowEvent.WINDOW_CLOSING));	    
	    }
	}
    }


    class CheckBoxListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
	    
	    JCheckBox target = (JCheckBox)e.getItem();
	    String actionCommand = target.getActionCommand();

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

		if (e.getStateChange() == ItemEvent.DESELECTED) {
		    writeResults = false;
		    sa.write("writing results stopped!");
		} else {
		    writeResults = true;
		    sa.write("writing results started.");
		}
		
	    } else if(actionCommand.equals("folder")) {

		if (e.getStateChange() == ItemEvent.DESELECTED) {
		    writeAlignments = false;
		    sa.write("sampled alignments are not saved!");
		} else {
		    writeAlignments = true;
		    sa.write("all sampled alignments are saved.");
		}

	    } else if(actionCommand.equals("nexus")) {
		
		if (e.getStateChange() == ItemEvent.DESELECTED) {
		    writeNexus = false;
		    sa.write("nexus files are not saved!");
		} else {
		    writeNexus = true;
		    sa.write("alignments are saved as nexus files.");
		}

	    } else if(actionCommand.equals("fasta")) {
		
		if (e.getStateChange() == ItemEvent.DESELECTED) {
		    writeFasta = false;
		    sa.write("fasta files are not saved!");
		} else {
		    writeFasta = true;
		    sa.write("alignments are saved as fasta files.");
		}
	    }
	}
    }

    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;
	    }
	}
    }
}
