package GenRGenS.IU;

/**
 * Title:        GenRGenS GUI<p>
 * Description:  Random generation of genomic sequences<p>
 * Company:    U.P.S.  <p>
 * @author  Yann Ponty
 * @version 1.0
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import GenRGenS.utility.*;
import GenRGenS.*;
import java.io.FileFilter;
import java.io.*;

public class MainFrame extends JFrame
{

  JPanel contentPane;
  JMenuBar menuBar1 = new JMenuBar();
  JMenu menuFile = new JMenu();
  JMenuItem menuFileExit = new JMenuItem();
  JMenu menuHelp = new JMenu();
  JMenu menuBuffers = new JMenu();
  JMenuItem menuOptionsFlushBuffers = new JMenuItem();
  JToolBar toolBar = new JToolBar();
  JButton jButton1 = new JButton();
  JButton jButton2 = new JButton();
  JButton jButton3 = new JButton();
  ImageIcon image1;
  ImageIcon image2;
  ImageIcon image3;
  Label statusBar = new Label();
  BorderLayout borderLayout1 = new BorderLayout();
  JPanel jPanel1 = new JPanel();
  JPanel jPanel2 = new JPanel();
  JButton jButton4 = new JButton();
  BorderLayout borderLayout2 = new BorderLayout();
  JPanel jPanel8 = new JPanel();
  JTextArea jTextArea2 = new JTextArea();
  JTextArea jTextArea1 = new JTextArea();
  JLabel jLabel2 = new JLabel();
  GridLayout gridLayout4 = new GridLayout();
  BorderLayout borderLayout3 = new BorderLayout();
  JMenuItem jMenuItem1 = new JMenuItem();
  JMenuItem jMenuItem4 = new JMenuItem();
  int generated = 0;
  JPanel jPanel7 = new JPanel();
  FileWriter directOut = null;
  JSplitPane jSplitPane1 = new JSplitPane();
  JMenu menuUtilities = new JMenu();
  JMenuItem jMenuItem5 = new JMenuItem();
  JMenuItem jMenuItem3 = new JMenuItem();
  JMenu recent = new JMenu();
  JLabel jLabel1 = new JLabel();
  JMenuItem jMenuItem2 = new JMenuItem();
  GenRGenSDialog generationConfig = null;
  JScrollPane jScrollPane1 = new JScrollPane();
  JScrollPane jScrollPane2 = new JScrollPane();
  JMenuItem jMenuItem7 = new JMenuItem();
  ComptageDialog counter = null;
  BorderLayout borderLayout5 = new BorderLayout();
  BorderLayout borderLayout4 = new BorderLayout();
  JMenuItem jMenuItem6 = new JMenuItem();
  JMenuItem jMenuItem8 = new JMenuItem();
  HelpDialog _help = new HelpDialog();
  ProgressDialog progress = new ProgressDialog(this,"Generation",true);


  //Construct the frame
  public MainFrame()
  {
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    GenRGenS.setSize(10);
    GenRGenS.setHowMany(1);
    try
    {
      jbInit();
      GenRGenS.out =new MainFramePrintStream(this);
      GenRGenS.err = new TextAreaPrintStream(jTextArea2);
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }

  }

  public void addResult(String s)
  {
    if (generationConfig.outToBuffer())
    {
      jTextArea1.append(s);
    }
    if (generationConfig.outToFile())
    {
        try
        { directOut.write(s); }
        catch(IOException e)
        { GenRGenS.err.println(e.toString()); }
    }
    generated++ ;
    progress.setProgress(generated);
    if (generated < GenRGenS.getHowMany())
    {
      statusBar.setText("  Generating ... "+generated +"/" + GenRGenS.getHowMany() );
    }
    else
    {
      statusBar.setText("  Generation complete ! "+generated +" sequences generated .");
    }
  }


  //Component initialization
  private void jbInit() throws Exception
  {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension helpsize = new Dimension(screenSize.width/2,screenSize.height/2);
    _help.setSize(helpsize);
    jMenuItem2.setText("GenRGenS ...");
    jMenuItem2.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        jMenuItem2_actionPerformed(e);
      }
    });
    menuBar1.setDoubleBuffered(true);
    jLabel1.setPreferredSize(new Dimension(96, 50));
    jScrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    jScrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    jScrollPane2.setMinimumSize(new Dimension(24, 70));
    jScrollPane2.setPreferredSize(new Dimension(24, 70));
    jMenuItem4.setToolTipText("");
    jMenuItem7.setText("Save Error Buffer Content ...");
    jMenuItem5.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        jMenuItem5_actionPerformed(e);
      }
    });
    this.addWindowListener(new java.awt.event.WindowAdapter()
    {

      public void windowOpened(WindowEvent e)
      {
        this_windowOpened(e);
      }
    });
    jMenuItem3.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        jMenuItem3_actionPerformed(e);
      }
    });
    jMenuItem6.setText("About ...");
    jMenuItem6.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        jMenuItem6_actionPerformed(e);
      }
    });
    jMenuItem8.setText("Content ...");
    jMenuItem8.addActionListener(new MainFrame_jMenuItem8_actionAdapter(this));
    menuUtilities.add(jMenuItem2);
    menuUtilities.addSeparator();
    image1 = new ImageIcon(MainFrame.class.getResource("bin/openFile.gif"));
    image2 = new ImageIcon(MainFrame.class.getResource("bin/closeFile.gif"));
    image3 = new ImageIcon(MainFrame.class.getResource("bin/help.gif"));
    contentPane = (JPanel) this.getContentPane();
    contentPane.setLayout(borderLayout1);
    this.setSize(new Dimension(400, 300));
    this.setTitle("GenRGenS");
    statusBar.setText("   Welcome to GenRGenS !");
    menuFile.setText("File");
    menuFileExit.setText("Exit");
    menuFileExit.addActionListener(new MainFrame_menuFileExit_ActionAdapter(this));

    menuBuffers.setText("Buffers");
    menuOptionsFlushBuffers.setText("Flush buffers");
    menuOptionsFlushBuffers.addActionListener(new MainFrame_menuOptionsFlushBuffers_actionAdapter(this));
    menuHelp.setText("Help");
    jButton1.setIcon(image1);
    jButton1.addActionListener(new MainFrame_jButton1_actionAdapter(this));
    jButton1.setToolTipText("Open File");
    jButton2.setIcon(image2);
    jButton2.addActionListener(new MainFrame_jButton2_actionAdapter(this));
    jButton2.setToolTipText("Close File");
    jButton3.setIcon(image3);
    jButton3.addActionListener(new MainFrame_jButton3_actionAdapter(this));
    jButton3.setToolTipText("Help");
    jPanel2.setLayout(borderLayout2);
    jPanel1.setLayout(borderLayout3);
    jButton4.setText("GenRGenS");
    jButton4.addActionListener(new MainFrame_jButton4_actionAdapter(this));
    jTextArea1.setFont(new java.awt.Font("Monospaced", 0, 12));
    jTextArea1.setEditable(false);
    jPanel8.setLayout(borderLayout5);
    jPanel8.setMinimumSize(new Dimension(10, 10));
    jPanel8.setPreferredSize(new Dimension(10, 10));
    jLabel2.setHorizontalAlignment(SwingConstants.LEFT);
    jLabel2.setHorizontalTextPosition(SwingConstants.CENTER);
    jLabel2.setText("How many ?");
    gridLayout4.setRows(2);
    jTextArea2.setEditable(false);
    jMenuItem4.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        jMenuItem4_actionPerformed(e);
      }
    });
    jPanel7.setMinimumSize(new Dimension(27, 24));
    jPanel7.setPreferredSize(new Dimension(27, 24));
    jPanel7.setLayout(borderLayout4);
    jSplitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT);
    jSplitPane1.setBorder(BorderFactory.createLineBorder(Color.black));
    jSplitPane1.setContinuousLayout(true);
    jSplitPane1.setDividerSize(6);
    jSplitPane1.setOneTouchExpandable(true);
    menuUtilities.setText("Utilities");
    jMenuItem5.setText("Build Markovian GGD From File ...");
    jMenuItem4.setText("Save Output Buffer Content ...");
    jMenuItem3.setText("Open Description File ...");
    recent.setText("ReOpen ...");
    jLabel1.setText("No File Loaded ...");
    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel1.setHorizontalTextPosition(SwingConstants.CENTER);
    menuFile.add(jMenuItem3);
    menuFile.add(recent);
    menuFile.add(menuFileExit);
    menuUtilities.add(jMenuItem5);
    menuBuffers.add(jMenuItem4);
    menuBuffers.add(jMenuItem7);
    menuBuffers.addSeparator();
    menuBuffers.add(menuOptionsFlushBuffers);
    menuBar1.add(menuFile);
    menuBar1.add(menuBuffers);
    menuBar1.add(menuUtilities);
    menuBar1.add(menuHelp);
    this.setJMenuBar(menuBar1);
    contentPane.add(jPanel2, BorderLayout.CENTER);
    jPanel2.add(jPanel1, BorderLayout.NORTH);
    jPanel1.add(jLabel1, BorderLayout.NORTH);
    jPanel2.add(jPanel8, BorderLayout.CENTER);
    jTextArea2.setSize(jTextArea2.getWidth(), 30  );
    //jSplitPane1.add(jTextArea1,JSplitPane.TOP);
    //jSplitPane1.add(jTextArea2,JSplitPane.BOTTOM);
    //jPanel8.add(jSplitPane1, null);
    jScrollPane1.getViewport().add(jTextArea1, null);
    jScrollPane2.getViewport().add(jTextArea2, null);
    jPanel8.add(jScrollPane1, BorderLayout.CENTER);
    jPanel8.add(jScrollPane2, BorderLayout.SOUTH);
    jPanel7.add(statusBar, BorderLayout.CENTER);
    contentPane.add(jPanel7, BorderLayout.SOUTH);
    contentPane.add(toolBar, BorderLayout.NORTH);
    toolBar.add(jButton1);
    toolBar.add(jButton2);
    toolBar.add(jButton4);
    toolBar.add(jButton3);
    menuHelp.add(jMenuItem8);
    menuHelp.add(jMenuItem6);
    GenRGenS.progress = new WorkProgress()
    {
      private long _amount=1;
      private long _progress=0;
      private int CHARS_PER_LINE = 75;

      public void setWorkName(String name)
      {
        progress.setTitle(name);
      }
      public void setAmount(long amount)
      {
        progress.setMax((int)amount);
      }
      public void setProgress(long value)
      {
        progress.setProgress((int)value);
      }
    };
  }



  private void addRecent(String file)
  {
    int count = recent.getItemCount();
    if (count >= 10)
    {
      recent.remove(9);
    }

    boolean fini = false;
    for(int i = 0 ; (i < recent.getItemCount()) && (!fini);i++)
    {
      JMenuItem c = recent.getItem(i);
      if (file.equals(c.getText()))
      {
        recent.remove(c);
      }
    }
    Action item = new MenuAction(file,this);
    recent.insert(item,0);

  }


  public void loadFile(String file)
  {
        File SelectedFile = new File(file) ;
        if (SelectedFile.exists())
        {
          String s = SelectedFile.getAbsolutePath();
          setTitle("GenRGenS - "+s);
          jLabel1.setText(SelectedFile.getName());
          GenRGenS.setFileName(s);
        }
        else
        {JOptionPane.showMessageDialog(null, "File \""+file+"\" is no longer available !", "Error", JOptionPane.ERROR_MESSAGE);}
  }

  //File | Exit action performed
  public void fileExit_actionPerformed(ActionEvent e)
  {
    try
    {
      FileWriter out = new FileWriter("GenRGenS.ini");
      out.write("[recent]\n");
      boolean fini = false;
      if (recent.getItemCount() > 0 )
      {
        for(int i = recent.getItemCount()-1 ; (i >= 0) && (!fini);i--)
        {
          JMenuItem c = recent.getItem(i);
          out.write(c.getText()+"\n");
        }
      }
      out.close();
    }
    catch(Exception e3)
    {}
    System.exit(0);
  }

  //Help | About action performed
  public void helpAbout_actionPerformed(ActionEvent e)
  {
    MainFrame_AboutBox dlg = new MainFrame_AboutBox(this);
    Dimension dlgSize = dlg.getPreferredSize();
    Dimension frmSize = getSize();
    Point loc = getLocation();
    dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, (frmSize.height - dlgSize.height) / 2 + loc.y);
    dlg.setModal(true);
    dlg.show();
  }

  //Overridden so we can exit when window is closed
  protected void processWindowEvent(WindowEvent e)
  {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING)
    {
      fileExit_actionPerformed(null);
    }
  }

  void jButton1_actionPerformed(ActionEvent e)
  {
    String s;
    FileDialog d = new FileDialog(this, "Choose a GenRGenS description file.", FileDialog.LOAD);
    //d.setFile("*.ggd");
    d.show();
    if ((d.getFile() != null)&&(d.getDirectory() != null))
    {
      this.addRecent(d.getDirectory() +  d.getFile());
      File SelectedFile = new File(d.getDirectory() +  d.getFile()) ;
      //j.setMultiSelectionEnabled(false);
      s = SelectedFile.getAbsolutePath();
      setTitle("GenRGenS - "+s);
      jLabel1.setText(SelectedFile.getName());
      GenRGenS.setFileName(s);
    }
  }


  private void startGeneration()
  {
    this.generated = 0;
    if (generationConfig == null)
    {
      generationConfig = new GenRGenSDialog(this, "Generation Configuration",true);
    }
    Dimension dlgSize = generationConfig.getSize();
    Dimension frmSize = getSize();
    Point loc = getLocation();
    generationConfig.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, (frmSize.height - dlgSize.height) / 2 + loc.y);

    if (GenRGenS.getFileName().equals(""))
    {
      String s;
      FileDialog d = new FileDialog(this, "Choose a GenRGenS description file.", FileDialog.LOAD);
      //d.setFile("*.ggd");
      //d.pack();
      d.show();
      if ((d.getFile() != null)&&(d.getDirectory() != null))
      {
        this.addRecent(d.getDirectory() +  d.getFile());
        File SelectedFile = new File(d.getDirectory() +  d.getFile()) ;
        //j.setMultiSelectionEnabled(false);
        s = SelectedFile.getAbsolutePath();
        setTitle("GenRGenS - "+s);
        jLabel1.setText(SelectedFile.getName());
        GenRGenS.setFileName(s);
      }
    }
    if (!GenRGenS.getFileName().equals(""))
    {
      generationConfig.setDescriptionFileName(GenRGenS.getFileName());
      generationConfig.show();
      if (generationConfig.getReturnValue() == GenRGenSDialog.DLG_OK )
      {
        GenerationThread r = new GenerationThread();
        int how = generationConfig.getHowMany();
        GenRGenS.setHowMany(how);
        GenRGenS.setSize(generationConfig.getSequenceSize());
        //progress = new ProgressDialog(this,"Generation",true);
        dlgSize = progress.getSize();
        frmSize = getSize();
        loc = getLocation();
        progress.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, (frmSize.height - dlgSize.height) / 2 + loc.y);
        progress.setMax(how);
        progress.setProgress(0);
        if (generationConfig.outToFile())
        {
          try
          {
            directOut = new FileWriter(generationConfig.outputFilename());
            progress.setThread(r);
            r.setPriority(Thread.MAX_PRIORITY);
            r.setDialog(progress);

            progress.show();
            directOut.close();
          }
          catch( IOException e2)
          {}
        }
        else
        {
            progress.setThread(r);
            r.setDialog(progress);
            r.setPriority(Thread.MAX_PRIORITY);
            progress.show();
         //GenRGenS.startGeneration();
        }
        if (generated != GenRGenS.getHowMany())
        {
          statusBar.setText("Generation aborted !");
          progress.hide();
        }
      }
    }
  }




  void jButton4_actionPerformed(ActionEvent e)
  {
    startGeneration();
  }

  void menuOptionsFlushBuffers_actionPerformed(ActionEvent e)
  {
    this.jTextArea1.setText("");
    this.jTextArea2.setText("");
  }


  void jButton3_actionPerformed(ActionEvent e)
  {
    this.helpAbout_actionPerformed(e);
  }

  void jButton2_actionPerformed(ActionEvent e)
  {
    String s;
    FileDialog d = new FileDialog(this, "Save Output Buffer content as ...", FileDialog.SAVE);
    d.show();
    if ((d.getFile() != null)&&(d.getDirectory() != null))
    {
      File SelectedFile = new File(d.getDirectory() +  d.getFile()) ;
      s = SelectedFile.getAbsolutePath();
      try
      {
        FileWriter f = new FileWriter(s);
        f.write(this.jTextArea1.getText());
        f.close();
      }
      catch(IOException e2)
      {
        JOptionPane.showMessageDialog(null, "Couldn't create or write over \"" + s +"\".", "I/O Error", JOptionPane.ERROR_MESSAGE);
      }
    }
  }

  void jMenuItem3_actionPerformed(ActionEvent e)
  {
     this.jButton1_actionPerformed(e);
     this.repaint();
  }
  void jMenuItem7_actionPerformed(ActionEvent e)
  {
    String s;
    FileDialog d = new FileDialog(this, "Save Error Buffer content as ...", FileDialog.SAVE);
    d.show();
    if ((d.getFile() != null)&&(d.getDirectory() != null))
    {
      File SelectedFile = new File(d.getDirectory() +  d.getFile()) ;
      s = SelectedFile.getAbsolutePath();
      try
      {
        FileWriter f = new FileWriter(s);
        f.write(this.jTextArea2.getText());
        f.close();
      }
      catch(IOException e2)
      {
        JOptionPane.showMessageDialog(null, "Couldn't create or write over \"" + s +"\".", "I/O Error", JOptionPane.ERROR_MESSAGE);
      }
    }
  }

  void jMenuItem4_actionPerformed(ActionEvent e)
  {
     this.jButton2_actionPerformed(e);
     this.repaint();
  }

  void jMenuItem5_actionPerformed(ActionEvent e)
  {
    if (this.counter==null)
    {
      counter = new ComptageDialog(this,"Building a markovian description file from a file",true);
    }
    Dimension dlgSize = counter.getSize();
    Dimension frmSize = getSize();
    Point loc = getLocation();
    counter.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, (frmSize.height - dlgSize.height) / 2 + loc.y);

    counter.show();
  }

  void this_windowOpened(WindowEvent e)
  {
    // Etats du parsing simplifie ...
    final int HEADER = 0;
    final int BODY = 1;
    int state = BODY;

    // Constantes "de clause" ...
    final int RECENT_FILES = 0;
    int clause = -1;
    try
    {
      Reader r = new FileReader("GenRGenS.ini");
      StreamTokenizer s = new StreamTokenizer(r);
      s.resetSyntax();
      s.eolIsSignificant(false);
      s.wordChars('\u0000','\u00FF');
      s.whitespaceChars('\u0000','\u000F');
      s.ordinaryChar('[');s.ordinaryChar(']');
      int token = s.nextToken();
      while(token != StreamTokenizer.TT_EOF)
      {
        switch(token)
        {
          case('[') :
          {
            state = HEADER;
          }
          break;
          case(']') :
          {
            state = BODY;
          }
          break;
          case(StreamTokenizer.TT_WORD) :
          {
            String word = s.sval;
            switch(state)
            {
              case(HEADER) :
              {
                if (word.equals("recent"))
                { clause = RECENT_FILES; }
              }
              break;
              case(BODY) :
              {
                switch(clause)
                {
                  case(RECENT_FILES) :
                  {
                    this.addRecent(word);
                  }
                }
              }
              break;
            }
          }
          break;
        }
        token = s.nextToken();
      }
    }
    catch(Exception exc1)
    {}
  }

  void jMenuItem2_actionPerformed(ActionEvent e)
  {
    startGeneration();
  }

  void jMenuItem8_actionPerformed(ActionEvent e)
  {
    Dimension dlgSize = _help.getSize();
    Dimension frmSize = getSize();
    Point loc = getLocation();
    _help.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, (frmSize.height - dlgSize.height) / 2 + loc.y);
    _help.setVisible(true);
  }

  void jMenuItem6_actionPerformed(ActionEvent e)
  {
    this.helpAbout_actionPerformed(e);
  }
}

class MainFrame_menuFileExit_ActionAdapter implements ActionListener
{
  MainFrame adaptee;

  MainFrame_menuFileExit_ActionAdapter(MainFrame adaptee)
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e)
  {
    adaptee.fileExit_actionPerformed(e);
  }
}

class MainFrame_jButton1_actionAdapter implements java.awt.event.ActionListener
{
  MainFrame adaptee;

  MainFrame_jButton1_actionAdapter(MainFrame adaptee)
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e)
  {
    adaptee.jButton1_actionPerformed(e);
  }
}

class MainFrame_jButton4_actionAdapter implements java.awt.event.ActionListener
{
  MainFrame adaptee;

  MainFrame_jButton4_actionAdapter(MainFrame adaptee)
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e)
  {
    adaptee.jButton4_actionPerformed(e);
  }
}

class MainFrame_menuOptionsFlushBuffers_actionAdapter implements java.awt.event.ActionListener
{
  MainFrame adaptee;

  MainFrame_menuOptionsFlushBuffers_actionAdapter(MainFrame adaptee)
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e)
  {
    adaptee.menuOptionsFlushBuffers_actionPerformed(e);
  }
}

class MainFrame_jButton3_actionAdapter implements java.awt.event.ActionListener
{
  MainFrame adaptee;

  MainFrame_jButton3_actionAdapter(MainFrame adaptee)
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e)
  {
    adaptee.jButton3_actionPerformed(e);
  }
}

class MainFrame_jButton2_actionAdapter implements java.awt.event.ActionListener
{
  MainFrame adaptee;

  MainFrame_jButton2_actionAdapter(MainFrame adaptee)
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e)
  {
    adaptee.jButton2_actionPerformed(e);
  }
}

class MainFrame_jMenuItem8_actionAdapter implements java.awt.event.ActionListener
{
  MainFrame adaptee;

  MainFrame_jMenuItem8_actionAdapter(MainFrame adaptee)
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e)
  {
    adaptee.jMenuItem8_actionPerformed(e);
  }
}

class GenerationThread extends Thread
{
  private ProgressDialog p = null;

  public void setDialog(ProgressDialog d)
  {
    p = d;
  }

  public void run()
  {
    GenRGenS.startGeneration();
    p.hide();
  }
}
