/*******************************************************************************
 * GenRGenS v.1.0, Generation of Random Genomic Sequences                      *
 * Copyright (C) 2001  Alain Denise/Yann Ponty                                 *
 *                                                                             *
 * This program is free software; you can redistribute it and/or               *
 * modify it under the terms of the GNU General Public License                 *
 * as published by the Free Software Foundation; either version 2              *
 * of the License, or (at your option) any later version.                      *
 *                                                                             *
 * This program is distributed in the hope that it will be useful,             *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of              *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
 * GNU General Public License for more details.                                *
 *                                                                             *
 * You should have received a copy of the GNU General Public License           *
 * along with this program; if not, write to the Free Software                 *
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. *
 *******************************************************************************/

package GenRGenS.Applet;

import GenRGenS.*;
import GenRGenS.utility.*;
import GenRGenS.utility.holder.*;
import GenRGenS.IU.Option;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;


public class MainApplet extends Applet
{
  boolean isStandalone = false;
  BorderLayout borderLayout1 = new BorderLayout();
  Panel CardPane = new Panel();
  CardLayout cardLayout1 = new CardLayout();
  Panel SourcePanel = new Panel();
  Panel GenerationPanel = new Panel();
  Panel Tabs = new Panel();
  Button button1 = new Button();
  Button button2 = new Button();
  FlowLayout flowLayout1 = new FlowLayout();
  TextArea textArea1 = new TextArea();
  TextArea textArea2 = new TextArea();
  BorderLayout borderLayout2 = new BorderLayout();
  BorderLayout borderLayout3 = new BorderLayout();
  Panel panel1 = new Panel();
  Label label1 = new Label();
  Panel panel2 = new Panel();
  ScrollPane scrollPane3 = new ScrollPane();
  TextArea textArea3 = new TextArea();
  Label label2 = new Label();
  TextField textField1 = new TextField();
  Label label3 = new Label();
  TextField textField2 = new TextField();
  Button button4 = new Button();
  Label label4 = new Label();
  Panel panel3 = new Panel();
  BorderLayout borderLayout4 = new BorderLayout();
  Panel panel4 = new Panel();
  Checkbox checkbox1 = new Checkbox();
  Button button3 = new Button();
  Panel OptionsPanel = new Panel();
  Panel panel5 = new Panel();
  BorderLayout borderLayout5 = new BorderLayout();
  Label OptionsTitle = new Label();
  ScrollPane scrollPane1 = new ScrollPane();
  Panel OptionsContainer = new Panel();
  GridLayout gridLayout1 = new GridLayout();

  //Get a parameter value
  public String getParameter(String key, String def)
  {
    return isStandalone ? System.getProperty(key, def) :
      (getParameter(key) != null ? getParameter(key) : def);
  }

  //Construct the applet
  public MainApplet()
  {
  }

  //Initialize the applet
  public void init()
  {
    try
    {
      jbInit();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    GenRGenS.out = new EasyPrint(textArea2);
    GenRGenS.err = new EasyPrint(textArea3);
    Packages.installCommonPackages();
  }

  //Component initialization
  private void jbInit() throws Exception
  {
    this.setLayout(borderLayout1);
    CardPane.setLayout(cardLayout1);
    button1.setEnabled(false);
    button1.setLabel("Source");
    button1.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        button1_actionPerformed(e);
      }
    });
    button2.setLabel("Generation");
    button2.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        button2_actionPerformed(e);
      }
    });
    Tabs.setLayout(flowLayout1);
    flowLayout1.setAlignment(FlowLayout.LEFT);
    textArea1.setBackground(Color.white);
    textArea1.setBounds(new Rectangle(-7, 0, 440, 190));
    textArea2.setBackground(Color.white);
    textArea2.setBounds(new Rectangle(-6, 0, 440, 190));
    textArea2.setEditable(false);
    GenerationPanel.setLayout(borderLayout2);
    SourcePanel.setLayout(borderLayout3);
    label1.setText("Copy/Paste your source file to the Panel below");
    panel1.setFont(new java.awt.Font("Dialog", 0, 14));
    textArea3.setBackground(Color.white);
    textArea3.setBounds(new Rectangle(0, 0, 440, 190));
    label2.setText("Sequence Size :");
    textField1.setBackground(Color.white);
    textField1.setText("10");
    label3.setText("How many ?");
    textField2.setBackground(Color.white);
    textField2.setText("1");
    button4.setFont(new java.awt.Font("Dialog", 1, 14));
    button4.setLabel("GenRGenS");
    button4.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        button4_actionPerformed(e);
      }
    });
    panel2.setLayout(borderLayout4);
    checkbox1.setLabel("Verbose");
    button3.setLabel("Advanced Options ...");
    button3.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        button3_actionPerformed(e);
      }
    });
    OptionsPanel.setLayout(borderLayout5);
    OptionsTitle.setFont(new java.awt.Font("DialogInput", 1, 12));
    OptionsTitle.setText("options");
    OptionsContainer.setBounds(new Rectangle(311, 135, 10, 10));
    OptionsContainer.setLayout(gridLayout1);
    gridLayout1.setColumns(1);
    gridLayout1.setRows(0);
    textArea4.setEditable(false);
    panel6.setLayout(gridLayout2);
    gridLayout2.setColumns(1);
    gridLayout2.setRows(0);
    button5.setLabel("Markovian");
    button5.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        button5_actionPerformed(e);
      }
    });
    button6.setLabel("Grammar");
    button6.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        button6_actionPerformed(e);
      }
    });
    panel9.setLayout(gridLayout3);
    label5.setText(" or choose a demo GenRGenS\' file on the right");
    gridLayout3.setColumns(1);
    gridLayout3.setRows(0);
    this.add(CardPane, BorderLayout.CENTER);
    CardPane.add(SourcePanel, "Source");
    SourcePanel.add(panel1, BorderLayout.NORTH);
    panel1.add(panel9, null);
    panel9.add(label1, null);
    panel9.add(label5, null);
    SourcePanel.add(panel6, BorderLayout.EAST);
    panel6.add(panel8, null);
    panel8.add(button5, null);
    panel6.add(panel7, null);
    panel7.add(button6, null);
    SourcePanel.add(scrollPane3, BorderLayout.CENTER);
    scrollPane3.add(textArea1, null);
    CardPane.add(GenerationPanel, "Generation");
    GenerationPanel.add(panel2, BorderLayout.NORTH);
    GenerationPanel.add(textArea2, BorderLayout.CENTER);
    GenerationPanel.add(textArea3, BorderLayout.SOUTH);
    panel2.add(panel3, BorderLayout.NORTH);
    panel3.add(label2, null);
    panel3.add(textField1, null);
    panel3.add(label3, null);
    panel3.add(textField2, null);
    panel3.add(label4, null);
    panel3.add(checkbox1, null);
    panel2.add(panel4, BorderLayout.SOUTH);
    panel4.add(button4, null);
    CardPane.add(OptionsPanel, "Options");
    OptionsPanel.add(panel5, BorderLayout.NORTH);
    panel5.add(OptionsTitle, null);
    OptionsPanel.add(scrollPane1, BorderLayout.CENTER);
    OptionsPanel.add(textArea4, BorderLayout.SOUTH);
    scrollPane1.add(OptionsContainer, null);
    this.add(Tabs, BorderLayout.NORTH);
    Tabs.add(button1, null);
    Tabs.add(button2, null);
    Tabs.add(button3, null);
  }

  //Get Applet information
  public String getAppletInfo()
  {
    return "Applet Information";
  }

  //Get parameter info
  public String[][] getParameterInfo()
  {
    return null;
  }

  private Button[] button2OptionIndex;
  private String[] helpStrings;
  private Component[] component2Option;
  private Option[] optionsBackup;
  TextArea textArea4 = new TextArea();

  public void b_actionPerformed(ActionEvent e)
  {
    for(int i = 0; i<button2OptionIndex.length; i++)
    {
      Button b = button2OptionIndex[i];
      if ((Object)b ==e.getSource())
      {
        textArea4.setText(helpStrings[i]);
      }
    }
  }

  private void removeComponents(Panel p)
  {
    Component[] tab = new Component[p.getComponentCount()];
    for(int i=0; i<tab.length;i++)
    {
      tab[i] = p.getComponent(i);
    }
    for(int i=0; i<tab.length;i++)
    {
      p.remove(tab[i]);
    }
  }

  private void updateOptionsPanel()
  {
    try
    {
        String type = Linker.getDescriptionFileHeader(new StringReader(textArea1.getText()));
        GeneratorConfigFile f = Linker.getGeneratorConfigFileFromType(type);
        OptionsTitle.setText(f.getLitteralName()+" Options :");
        Option[] opts = f.getOptions();
        optionsBackup = opts;
        button2OptionIndex = new Button[opts.length];
        component2Option = new Component[opts.length];
        helpStrings =  new String[opts.length];
        removeComponents(OptionsContainer);

        for(int i =0;i<opts.length;i++)
        {
          Option o = opts[i];
          o.getOptionName();
          // On traitera dans les prochaines versions des parametrages plus riches (String, entiers etc ...)
          //if(o.getCallback().getTypename() == Callback.TYPE_BOOLEAN)
          {
            Panel p = new Panel();
            Checkbox c = new Checkbox(o.getOptionName());
            Button b = new Button("?");
            b.addActionListener(new java.awt.event.ActionListener()
            {
              public void actionPerformed(ActionEvent e)
              {
                b_actionPerformed(e);
              }
            });
            c.setState(((BooleanHolder)o.getHolder()).get());
            p.add(c);

            p.add(b);
            button2OptionIndex[i] = b;
            component2Option[i] = c;
            OptionsContainer.add(p,null);
            helpStrings[i] = o.getLongHelp();
          }
        }
      }
      catch(FileNotFoundException e)
      {}
      catch(IOException e)
      {}
      catch(GeneratorCreationException e)
      {
        removeComponents(OptionsContainer);
        OptionsTitle.setText("Unknown Description File Type !");
        GenRGenS.err.println(e);
      }
  }


  private void updateOptionsValues()
  {
    Option[] opts = optionsBackup;

    for(int i =0;i<opts.length;i++)
    {
      Holder o = opts[i].getHolder();
      Component c = component2Option[i];

      // On traitera dans les prochaines versions des parametrages plus riches (String, entiers etc ...)
      if(o.getTypename() == Holder.TYPE_BOOLEAN)
      {
        ((BooleanHolder)o).set(((Checkbox)c).getState());
      }
    }
  }

  Panel selectedPanel = SourcePanel;
  Panel panel6 = new Panel();
  GridLayout gridLayout2 = new GridLayout();
  Button button5 = new Button();
  Button button6 = new Button();
  Panel panel7 = new Panel();
  Panel panel8 = new Panel();
  Panel panel9 = new Panel();
  GridLayout gridLayout3 = new GridLayout();
  Label label5 = new Label();

  void button1_actionPerformed(ActionEvent e)
  {
    cardLayout1.show(CardPane,"Source");
    selectedPanel = SourcePanel;
    button1.setEnabled(false);
    button2.setEnabled(true);
    button3.setEnabled(true);
  }

  void button2_actionPerformed(ActionEvent e)
  {
    if (selectedPanel == OptionsPanel)
    { updateOptionsValues(); }

    cardLayout1.show(CardPane,"Generation");
    selectedPanel = GenerationPanel;
    button1.setEnabled(true);
    button2.setEnabled(false);
    button3.setEnabled(true);
  }

  void button3_actionPerformed(ActionEvent e3)
  {
    updateOptionsPanel();
    cardLayout1.show(CardPane,"Options");
    selectedPanel = OptionsPanel;
    button1.setEnabled(true);
    button2.setEnabled(true);
    button3.setEnabled(false);
  }

   public void startGeneration()
  {
		Generator gen=null;

    if ( textArea1.getText().equals(""))
		{
		  GenRGenS.err.println("Source content needed !");
		}
    else
    {
      if (GenRGenS.size == -1)
			{
			  GenRGenS.err.println("Size for the generated sequence is needed !");
			}
      else
      {
        try
				{
          Reader fr = new StringReader(textArea1.getText());

					String type = Linker.getDescriptionFileHeader(fr);

					Class GeneratorClass = Linker.getGeneratorClassFromType(type);
					Class[] argTypes = new Class[1];
				  Object[] args = new Object[1];
		      if (GenRGenS.verbose)
      		{
		        GenRGenS.err.println("Searching a generator for this file's type ...");
		      }
					try
					{
  					try
	  				{

			  	    argTypes[0] =textArea1.getText().getClass();
  			  	  Constructor c = GeneratorClass.getConstructor(argTypes) ;
    		      if (GenRGenS.verbose)
          		{
		            GenRGenS.err.println("Found a generator !");
		          }
	  			    args[0] = textArea1.getText();
		  		    gen = (Generator) c.newInstance(args);
   					}
		  			catch(NoSuchMethodException e1)
			  		{
	            GenRGenS.err.println("No constructor matching Reader found in package \""+type+"\" !");
			  		}
			  	}
  	  		catch(InvocationTargetException in)
  	  		{
	          GenRGenS.err.println(in. getTargetException() );
  	  		}
					if (gen != null)
					{

  	        if (GenRGenS.verbose)
       	  	{
	            GenRGenS.err.println("Generator built, starting sequence generation ...");
	          }
            for (int i=0; i<GenRGenS.howMany; i++)
			      {
						  GenRGenS.out.println(gen.generateRandomWord(GenRGenS.size));
				    };
  	        if (GenRGenS.verbose)
       	  	{
	            GenRGenS.err.println("Generation complete!");
	          }
          }
        }
		    catch (FileNotFoundException e)
		    {
		      GenRGenS.err.println("File not found :  \""+GenRGenS.nomFichier+"\"");
		    }
        catch (GenerationException e)
        {
          GenRGenS.err.println(e.toString());
          //System.exit(2);
        }
			  catch	(Exception e)
			  {
				  GenRGenS.err.println (e.toString());
				  //System.exit(2);
			  };
      }
    }
  }

  void button4_actionPerformed(ActionEvent e)
  {
    try
    {
      GenRGenS.howMany = Integer.parseInt(textField2.getText());
      try
      {
        GenRGenS.size = Integer.parseInt(textField1.getText());
        GenRGenS.verbose = checkbox1.getState();
        startGeneration();
      }
      catch(NumberFormatException e1)
      {
        textField1.setText(""+GenRGenS.size);
      }
    }
    catch(NumberFormatException e2)
    {
      textField2.setText(""+GenRGenS.howMany);
    }
  }

  void button5_actionPerformed(ActionEvent e)
  {
    textArea1.setText(
    "TYPE = MARKOV\n\n"+ 
    "ORDER = 2\n\n"+
    "SYMBOLS = LETTERS\n\n"+
    "FREQUENCIES =\n"+
    "  aaa	13	aac	15	aag	56	aat	30\n"+
    "  aca	20	acc	13	acg	15	act	23\n"+
    "  aga	11	agc	4 	agg	5 	agt	15\n"+
    "  ata	8 	atc	16	atg	7 	att	10\n\n"+
    "  caa	9 	cac	14	cag	16	cat	13\n"+
    "  cca	16	ccc	5 	ccg	12	cct	52\n"+
    "  cga	19	cgc	22	cgg	11	cgt	16\n"+
    "  cta	25	ctc	25	ctg	21	ctt	18\n\n"+
    "  gaa	14	gac	13	gag	23	gat	1\n"+
    "  gca	13	gcc	3 	gcg	1 	gct	16\n"+
    "  gga	2 	ggc	9 	ggg	5 	ggt	5\n"+
    "  gta	6 	gtc	29	gtg	36	gtt	14\n\n"+
    "  taa	19	tac	7 	tag	3 	tat	31\n"+
    "  tca	25	tcc	16	tcg	12	tct	6\n"+
    "  tga	34	tgc	9 	tgg	15	tgt	14\n"+
    "  tta	18	ttc	13	ttg	2 	ttt	31");
  }

  void button6_actionPerformed(ActionEvent e)
  {
    textArea1.setText(
      "TYPE=GRAMMAR\n\n"+
      "RULES =\n"+
      "  T -> a T t;\n"+
      "  T -> t T a;\n"+
      "  T -> c T g;\n"+
      "  T -> g T c;\n"+
      "  T -> a B1 t;\n"+
      "  T -> t B1 a;\n"+
      "  T -> c B1 g;\n"+
      "  T -> g B1 c;\n\n"+
      "  B1 -> a B0 a;\n"+
      "  B1 -> a B0 c;\n"+
      "  B1 -> a B0 g;\n"+
      "  B1 -> c B0 a;\n"+
      "  B1 -> c B0 c;\n"+
      "  B1 -> c B0 t;\n"+
      "  B1 -> g B0 a;\n"+
      "  B1 -> g B0 g;\n"+
      "  B1 -> g B0 t;\n"+
      "  B1 -> t B0 c;\n"+
      "  B1 -> t B0 g;\n"+
      "  B1 -> t B0 t;\n\n"+
      "  B0 -> a B0;\n"+
      "  B0 -> c B0;\n"+
      "  B0 -> g B0;\n"+
      "  B0 -> t B0;\n"+
      "  B0 -> a;\n"+
      "  B0 -> c;\n"+
      "  B0 -> g;\n"+
      "  B0 -> t;\n\n"+
      "WEIGHTS =\n"+
      "  a 3\n"+
      "  c 0,35\n"+
      "  g 6\n"+
      "  t 15");
  }
  
  


}
