package mosaiccreator;

import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JProgressBar;
import javax.swing.JCheckBox;
import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import java.io.File;
import java.awt.*;
import java.awt.event.*;

/**
 *
 * <p>Title: Main Window</p>
 * <p>Description: This is the main interface to the Mosaic Creator</p>
 * @author Lance Finfrock
 * @version 1.0
 */
public class MainWindow extends JFrame {

  private JMenuBar jMenuBar = new JMenuBar();
  private JMenu jMenuFile = new JMenu();
  private JMenu jMenuHelp = new JMenu();
  private JMenuItem jMenuFileExit = new JMenuItem();
  private JMenuItem jMenuFileOpen = new JMenuItem();
  private JMenuItem jMenuHelpAbout = new JMenuItem();
  private JMenuItem jMenuHelpManual = new JMenuItem();

  private MosaicAlgorithm Algorithm;
  private MosaicOpener mosaicOpener;
  private String PathToOriginalPicture;

  private JPanel contentPane;
  private JPanel jFindOriginalMosaicPicturePanel = new JPanel();
  private JPanel jMosaicPiecesPanel = new JPanel();
  private JPanel jStep1RightPanel = new JPanel();
  private JPanel jCreateMosaicPanel = new JPanel();
  private JPanel jStartStopPanel = new JPanel();
  private JPanel jProgressBarPanel = new JPanel();
  private JPanel jMosaicPiecesInsidePanel = new JPanel();

  private JLabel findMosaicPiecesLabel = new JLabel();
  private JLabel findMosaicPicture = new JLabel();
  private JLabel createMosaicLabel = new JLabel();
  private JLabel sliderLowLabel = new JLabel();
  private JLabel DivisionLabel = new JLabel();
  private JLabel ProgressBarLabel = new JLabel();
  private JLabel divisionWidthLabel = new JLabel();
  private JLabel divisionHeightLabel = new JLabel();
  private JLabel folderPathLabel = new JLabel();
  private JLabel numberOfPicturesLabel = new JLabel();
  private JLabel sliderBestPictureLabel = new JLabel();
  private JLabel sliderHighLabel = new JLabel();
  private JLabel NumberOfPictureNumberLable = new JLabel();
  private JLabel OriginalPictureFileNamelabel = new JLabel();

  private SampleView sampleView = new SampleView(6, 6);

  private JButton BrowsePictureButton = new JButton();
  private JButton StartButton = new JButton();
  private JButton BrowsePiecesButton = new JButton();
  private JButton ViewButton = new JButton();
  private JButton StopButton = new JButton();

  private GridBagLayout gridBagLayout = new GridBagLayout();

  private JSlider SliderPictureMatch = new JSlider();

  private JProgressBar progressBar = new JProgressBar();

  private File[] FilesOfPicturesReadIn;//     stores the picture files readin from the  FileFinder
  public static Mosaic currentMosaic;

  private JComboBox comboBoxDivisionsWidth;
  private JComboBox comboBoxDivisionsHeight;

  private JCheckBox isReplacementCheckBox = new JCheckBox();

  /**
   * Construct the frame
   */
  public MainWindow() {
    this.enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {
      this.jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Component initialization
   * @throws Exception
   */
  private void jbInit() throws Exception  {
    String[] divions = {60 + "", 55 + "", 50 + "", 45 + "", 40 + "", 35 + "", 30 + "", 25 + "", 20 + "", 15 + ""};
    this.comboBoxDivisionsWidth = new JComboBox(divions);
    this.comboBoxDivisionsHeight = new JComboBox(divions);
    this.setSize(new Dimension(440, 512));
    this.getContentPane().setBackground(new Color(245,245,245));
    this.setResizable(false);
    this.setTitle("Mosaic Creator");
    this.setIconImage(PictureTools.readImage("mosaicImage.gif", this));
    this.jMenuFile.setText("File");
    this.jMenuFileExit.setText("Exit");
    this.jMenuFileExit.addActionListener(new MainWindow_jMenuFileExit_ActionAdapter(this));
    this.jMenuFileOpen.setText("Open");
    this.jMenuFileOpen.addActionListener(new MainWindow_jMenuFileOpen_ActionAdapter(this));
    this.jMenuHelp.setText("Help");
    this.jMenuHelpAbout.setText("About");
    this.jMenuHelpManual.setText("Manual");
    this.jMenuHelpAbout.addActionListener(new MainWindow_jMenuHelpAbout_ActionAdapter(this));
    this.jMenuHelpManual.addActionListener(new MainWindow_jMenuHelpManual_ActionAdapter(this));

    this.contentPane = (JPanel) this.getContentPane();
    this.contentPane.setBackground(new Color(245, 245, 245));
    this.contentPane.setAlignmentX((float) 0.5);
    this.contentPane.setAlignmentY((float) 0.5);
    this.contentPane.setMinimumSize(new Dimension(30, 135));
    this.contentPane.setPreferredSize(new Dimension(90, 80));
    this.contentPane.setVerifyInputWhenFocusTarget(true);
    this.contentPane.setLayout(gridBagLayout);

    this.sampleView.setBackground(new Color(245, 245, 245));
    this.sampleView.setBorder(BorderFactory.createRaisedBevelBorder());
    this.sampleView.setDebugGraphicsOptions(0);
    this.sampleView.setDoubleBuffered(true);
    this.sampleView.setMinimumSize(new Dimension(250, 100));
    this.sampleView.setOpaque(true);
    this.sampleView.setPreferredSize(new Dimension(180, 65));

    this.jFindOriginalMosaicPicturePanel.setBackground(new Color(245, 245, 245));
    this.jFindOriginalMosaicPicturePanel.setMinimumSize(new Dimension(400, 100));
    this.jFindOriginalMosaicPicturePanel.setPreferredSize(new Dimension(440, 420));
    this.jFindOriginalMosaicPicturePanel.setLayout(gridBagLayout);
    this.jMosaicPiecesPanel.setBackground(new Color(245, 245, 245));
    this.jMosaicPiecesPanel.setMinimumSize(new Dimension(10, 100));
    this.jMosaicPiecesPanel.setPreferredSize(new Dimension(120, 100));
    this.jMosaicPiecesPanel.setLayout(gridBagLayout);
    this.jStep1RightPanel.setBackground(new Color(245, 245, 245));
    this.jStep1RightPanel.setMinimumSize(new Dimension(300, 107));
    this.jStep1RightPanel.setOpaque(true);
    this.jStep1RightPanel.setPreferredSize(new Dimension(300, 120));
    this.jStep1RightPanel.setToolTipText("");
    this.jStep1RightPanel.setLayout(gridBagLayout);

    this.findMosaicPicture.setFont(new java.awt.Font("Dialog", 1, 11));
    this.findMosaicPicture.setText("Step 1. Click to Find Mosaic Picture");
    this.findMosaicPicture.setVerticalAlignment(SwingConstants.TOP);

    this.BrowsePictureButton.setBackground(new Color(245, 245, 245));
    this.BrowsePictureButton.setEnabled(true);
    this.BrowsePictureButton.setForeground(Color.black);
    this.BrowsePictureButton.setOpaque(true);
    this.BrowsePictureButton.setPreferredSize(new Dimension(73, 25));
    this.BrowsePictureButton.setHorizontalAlignment(SwingConstants.LEFT);
    this.BrowsePictureButton.setMnemonic('0');
    this.BrowsePictureButton.setText("Browse");
    this.BrowsePictureButton.setVerticalAlignment(SwingConstants.CENTER);
    this.BrowsePictureButton.setVerticalTextPosition(SwingConstants.CENTER);
    this.BrowsePictureButton.addActionListener(new MainWindow_BrowsePictureButton_actionAdapter(this));

    this.OriginalPictureFileNamelabel.setPreferredSize(new Dimension(277, 21));
    this.OriginalPictureFileNamelabel.setText("No File Choosen");

    this.jCreateMosaicPanel.setBackground(new Color(245, 245, 245));
    this.jCreateMosaicPanel.setMinimumSize(new Dimension(10, 50));
    this.jCreateMosaicPanel.setOpaque(true);
    this.jCreateMosaicPanel.setPreferredSize(new Dimension(390, 80));
    this.jCreateMosaicPanel.setLayout(gridBagLayout);

    this.folderPathLabel.setBackground(new Color(245, 245, 245));
    this.folderPathLabel.setPreferredSize(new Dimension(170, 21));

    this.jMosaicPiecesInsidePanel.setLayout(gridBagLayout);
    this.jMosaicPiecesInsidePanel.setBackground(new Color(245, 245, 245));
    this.jMosaicPiecesInsidePanel.setPreferredSize(new Dimension(400, 100));

    this.findMosaicPiecesLabel.setBackground(new Color(245, 245, 245));
    this.findMosaicPiecesLabel.setFont(new java.awt.Font("Dialog", 1, 11));
    this.findMosaicPiecesLabel.setPreferredSize(new Dimension(120, 12));

    this.findMosaicPiecesLabel.setHorizontalAlignment(SwingConstants.LEFT);
    this.findMosaicPiecesLabel.setHorizontalTextPosition(SwingConstants.LEFT);
    this.findMosaicPiecesLabel.setIconTextGap(4);
    this.findMosaicPiecesLabel.setText("Step 2. Find Mosaic Pieces");
    this.findMosaicPiecesLabel.setVerticalAlignment(SwingConstants.CENTER);
    this.findMosaicPiecesLabel.setVerticalTextPosition(SwingConstants.CENTER);

    this.BrowsePiecesButton.setBackground(new Color(245, 245, 245));
    this.BrowsePiecesButton.setPreferredSize(new Dimension(73, 25));
    this.BrowsePiecesButton.setText("Browse");
    this.BrowsePiecesButton.addActionListener(new MainWindow_BrowsePiecesButton_actionAdapter(this));

    this.createMosaicLabel.setFont(new java.awt.Font("Dialog", 1, 11));
    this.createMosaicLabel.setText("Step 3. Create Mosaic");
    this.createMosaicLabel.setVerticalAlignment(SwingConstants.TOP);

    this.StartButton.setText("Start");
    this.StartButton.setBackground(new Color(245, 245, 245));
    this.StartButton.setVisible(false);
    this.StartButton.addActionListener(new MainWindow_StartButton_actionAdapter(this));

    this.jStartStopPanel.setLayout(gridBagLayout);
    this.jStartStopPanel.setBackground(new Color(245, 245, 245));
    this.jStartStopPanel.setMinimumSize(new Dimension(137, 47));
    this.jStartStopPanel.setPreferredSize(new Dimension(220, 75));


    this.jProgressBarPanel.setBackground(new Color(245, 245, 245));
    this.jProgressBarPanel.setMinimumSize(new Dimension(10, 10));
    this.jProgressBarPanel.setOpaque(true);
    this.jProgressBarPanel.setPreferredSize(new Dimension(190, 100));
    this.jProgressBarPanel.setRequestFocusEnabled(true);
    this.jProgressBarPanel.setToolTipText("");
    this.jProgressBarPanel.setLayout(gridBagLayout);

    this.SliderPictureMatch.setMaximum(2000);
    this.SliderPictureMatch.setMinimum(700);
    this.SliderPictureMatch.setBackground(UIManager.getColor("FormattedTextField.inactiveForeground"));
    this.SliderPictureMatch.setBorder(BorderFactory.createLoweredBevelBorder());
    this.SliderPictureMatch.setValue(1350);
    this.SliderPictureMatch.setPreferredSize(new Dimension(100, 24));

    this.progressBar.setVisible(false);

    this.sliderLowLabel.setOpaque(false);
    this.sliderLowLabel.setPreferredSize(new Dimension(447, 15));
    this.sliderLowLabel.setRequestFocusEnabled(true);
    this.sliderLowLabel.setToolTipText("");
    this.sliderLowLabel.setVerifyInputWhenFocusTarget(true);
    this.sliderLowLabel.setText("Low");

    this.DivisionLabel.setFont(new java.awt.Font("Dialog", 1, 11));
    this.DivisionLabel.setMaximumSize(new Dimension(50, 15));
    this.DivisionLabel.setMinimumSize(new Dimension(50, 15));
    this.DivisionLabel.setPreferredSize(new Dimension(50, 15));
    this.DivisionLabel.setText("Division");

    this.comboBoxDivisionsWidth.setActionCommand("comboBoxChanged");
    this.comboBoxDivisionsWidth.setSelectedIndex(5);
    this.comboBoxDivisionsWidth.addActionListener(new MainWindow_comboBoxDivisions_actionAdapter(this));
    this.comboBoxDivisionsHeight.setActionCommand("comboBoxChanged");
    this.comboBoxDivisionsHeight.setSelectedIndex(5);
    this.comboBoxDivisionsHeight.addActionListener(new MainWindow_comboBoxDivisions_actionAdapter(this));

    this.ViewButton.setText("View");
    this.ViewButton.setBackground(new Color(245, 245, 245));
    this.ViewButton.setVisible(false);
    this.ViewButton.setVerticalAlignment(SwingConstants.CENTER);
    this.ViewButton.addActionListener(new MainWindow_ViewButton_actionAdapter(this));

    this.ProgressBarLabel.setBackground(new Color(245, 245, 245));
    this.ProgressBarLabel.setText(" ");

    this.StopButton.setText("Stop");
    this.StopButton.setBackground(new Color(245, 245, 245));
    this.StopButton.setVisible(false);
    this.StopButton.addActionListener(new MainWindow_StopButton_actionAdapter(this));

    this.divisionWidthLabel.setText("Width");
    this.divisionHeightLabel.setText("Height");

    this.folderPathLabel.setText("No Folder Choosen");

    this.numberOfPicturesLabel.setHorizontalAlignment(SwingConstants.CENTER);
    this.numberOfPicturesLabel.setHorizontalTextPosition(SwingConstants.CENTER);
    this.numberOfPicturesLabel.setText("Number of Pictures Found");

    this.NumberOfPictureNumberLable.setBackground(new Color(245, 245, 245));
    NumberOfPictureNumberLable.setHorizontalAlignment(SwingConstants.CENTER);
    NumberOfPictureNumberLable.setHorizontalTextPosition(SwingConstants.CENTER);
    this.NumberOfPictureNumberLable.setText("0");


    this.isReplacementCheckBox.setSelected(true);
    this.isReplacementCheckBox.setText("Allow Duplicates of Pictures");
    this.isReplacementCheckBox.setBackground(new Color(245, 245, 245));
    this.isReplacementCheckBox.setVisible(false);

    this.sliderBestPictureLabel.setText("Best Picture Match");
    this.sliderHighLabel.setText("High");

    this.jMenuFile.add(jMenuFileOpen);
    this.jMenuFile.add(jMenuFileExit);
    this.jMenuHelp.add(jMenuHelpAbout);
    this.jMenuHelp.add(jMenuHelpManual);
    this.jMenuBar.add(jMenuFile);
    this.jMenuBar.add(jMenuHelp);

    jStep1RightPanel.add(comboBoxDivisionsWidth,       new GridBagConstraints(3, 1, 2, 1, 0.0, 0.0
            ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(1, 0, 0, 2), 6, -3));
    jStep1RightPanel.add(comboBoxDivisionsHeight,          new GridBagConstraints(4, 2, 1, 1, 0.0, 0.0
            ,GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 1), 6, -3));
    jStep1RightPanel.add(BrowsePictureButton,     new GridBagConstraints(0, 1, 1, 2, 0.0, 0.0
            ,GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(6, 32, 6, 19), 5, 0));
    jStep1RightPanel.add(divisionHeightLabel,       new GridBagConstraints(2, 2, 2, 1, 0.0, 0.0
            ,GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(0, 7, 0, 0), 7, 1));
    jStep1RightPanel.add(divisionWidthLabel,     new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 7, 0, 0), 9, 0));
    jStep1RightPanel.add(DivisionLabel, new GridBagConstraints(1, 0, 4, 1, 0.0, 0.0
            ,GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets(0, 3, 0, 8), 2, -2));
    jStep1RightPanel.add(OriginalPictureFileNamelabel,            new GridBagConstraints(0, 3, 3, 1, 1.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(3, 17, 5, 9), 103, 5));
    jFindOriginalMosaicPicturePanel.add(findMosaicPicture,      new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 6, 0, 18), 22, 0));
    contentPane.add(jCreateMosaicPanel,                           new GridBagConstraints(0, 4, 3, 1, 1.0, 1.0
            ,GridBagConstraints.SOUTHEAST, GridBagConstraints.HORIZONTAL, new Insets(4, 4, 1, 6), 0, 61));
    contentPane.add(sliderHighLabel,          new GridBagConstraints(2, 5, 1, 1, 0.0, 0.0
            ,GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 6), 4, 0));
    contentPane.add(sliderBestPictureLabel,   new GridBagConstraints(1, 5, 1, 1, 0.0, 0.0
            ,GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(0, 125, 0, 91), 6, 0));
    contentPane.add(sliderLowLabel,                new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0
            ,GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(0, 13, 0, 0), 8, 0));
    contentPane.add(SliderPictureMatch,                      new GridBagConstraints(0, 6, 3, 1, 0.0, 0.0
            ,GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(0, 2, 5, 2), 384, 0));
    jFindOriginalMosaicPicturePanel.add(sampleView,                          new GridBagConstraints(5, 0, 1, 2, 1.0, 1.0
            ,GridBagConstraints.EAST, GridBagConstraints.VERTICAL, new Insets(1, 18, 0, 4), 200, 55));
    jFindOriginalMosaicPicturePanel.add(jStep1RightPanel,                                     new GridBagConstraints(0, 1, 1, 2, 1.0, 1.0
            ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 188, 31));
    contentPane.add(findMosaicPiecesLabel,                     new GridBagConstraints(0, 1, 2, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 8, 0, 5), 43, 0));
    contentPane.add(jMosaicPiecesPanel,                                new GridBagConstraints(0, 2, 3, 1, 1.0, 1.0
            ,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 3, 5), 0, 4));
    jMosaicPiecesPanel.add(jMosaicPiecesInsidePanel,                   new GridBagConstraints(0, 0, 1, 2, 1.0, 1.0
            ,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(-1, 3, 2, 5), 26, 132));
    jMosaicPiecesInsidePanel.add(NumberOfPictureNumberLable,      new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(3, 84, 4, 0), 27, 12));
    jMosaicPiecesInsidePanel.add(numberOfPicturesLabel,    new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(16, 9, 8, 21), 12, 10));
    jMosaicPiecesInsidePanel.add(folderPathLabel, new GridBagConstraints(0, 3, 2, 4, 1.0, 0.0
            ,GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(4, 20, 17, 20), 420, 21));
    jMosaicPiecesInsidePanel.add(BrowsePiecesButton, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 31, 3, 96), 2, 0));
    contentPane.add(createMosaicLabel,                 new GridBagConstraints(0, 3, 3, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 8, 0, 5), 324, 0));
    jStartStopPanel.add(StopButton,          new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(11, 20, 16, 14), 11, 0));
    jStartStopPanel.add(isReplacementCheckBox,                new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0
            ,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(6, 21, 16, 7), 0, 0));
    jStartStopPanel.add(ViewButton,    new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(13, 13, 21, 27), 0, 0));
    jStartStopPanel.add(StartButton,             new GridBagConstraints(0, 1, 1, 2, 0.0, 0.0
            ,GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(13, 18, 14, 10), 3, 0));
    jProgressBarPanel.add(progressBar,         new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(-6, 0, 40, 0), 0, -2));
    jProgressBarPanel.add(ProgressBarLabel,      new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(9, 0, 10, 0), 0, 0));
    jCreateMosaicPanel.add(jStartStopPanel,  new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0
            ,GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(18, 21, 12, 4), 68, 100));
    jCreateMosaicPanel.add(jProgressBarPanel, new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0
            ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 1, 0, 8), 148, 81));
    contentPane.add(jFindOriginalMosaicPicturePanel,                                 new GridBagConstraints(0, 0, 3, 1, 1.0, 1.0
            ,GridBagConstraints.SOUTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 0, 0, 0), 43, 0));


    this.setJMenuBar(jMenuBar);
  }

  /**
   * File | Exit action performed used to close the program
   * @param e ActionEvent
   */
  public void jMenuFileExit_actionPerformed(ActionEvent e) {
    System.exit(0);
  }


  /**
   * Help | About action performed
   * @param e ActionEvent
   */
  public void jMenuHelpAbout_actionPerformed(ActionEvent e) {

    //creat the about window
    MainWindow_AboutBox dlg = new MainWindow_AboutBox(this);

    //get the preferred size
    Dimension dlgSize = dlg.getPreferredSize();
    Dimension frmSize = getSize();
    Point loc = getLocation();

    //center the window
    dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, (frmSize.height - dlgSize.height) / 2 + loc.y);
    dlg.setModal(true);
    dlg.pack();
    dlg.show();

  }

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

  /**
   * When the browse button to choose a folder to the mosaic pieces
   * @param e ActionEvent
   */
  public void BrowsePiecesButton_actionPerformed(ActionEvent e) {
    JFileChooser chooser = new JFileChooser();

    //only allows the user to choose a directory
    chooser.setFileSelectionMode(chooser.DIRECTORIES_ONLY);

    //opens the browse window
    int returnVal = chooser.showOpenDialog(this);

    //check if the user choose a directory
    if(returnVal == JFileChooser.APPROVE_OPTION){

      //get the folder choosen
      File file = chooser.getSelectedFile();

      //display the path to the folder
      this.folderPathLabel.setText(file.getPath());

      //set the number of images found to 0
      this.NumberOfPictureNumberLable.setText(0 + "");

      //start the file finder
      new FileFinder(file,this.NumberOfPictureNumberLable, this);

      //don't allow the user to choose a new folder while the file finder thread is running
      this.BrowsePiecesButton.setEnabled(false);

      //don't allow the user to start the creation of the mosaic while the image have not been found
      this.StartButton.setVisible(false);

    }
  }

  /**
   * This is the return method for the FileFinder class
   * @param PathToPieces File[] all the images found from the FileFinder
   */
  public void FileFinderReturn(File[] PathToPieces){
    //if no Pieces were found
    if(PathToPieces != null){

      //set the display labels
      this.FilesOfPicturesReadIn = PathToPieces;
      this.NumberOfPictureNumberLable.setText(this.FilesOfPicturesReadIn.length + "");

      //if the user has choosen the mosaic image
      if (!OriginalPictureFileNamelabel.getText().equals("No File Choosen")) {
        this.StartButton.setVisible(true);
      }

      int width = Integer.parseInt( (String) comboBoxDivisionsWidth.getSelectedItem());
      int height = Integer.parseInt( (String) comboBoxDivisionsHeight.getSelectedItem());

      //if there are enough images to allow no duplicates
      if (this.FilesOfPicturesReadIn != null &&
          width * height < FilesOfPicturesReadIn.length) {

        this.isReplacementCheckBox.setVisible(true);

      }
      else {
        this.isReplacementCheckBox.setSelected(true);
        this.isReplacementCheckBox.setVisible(false);
      }
    }

    //turn back on the Browse button to allow the user to rechoose the folder of mosaic pieces
    this.BrowsePiecesButton.setEnabled(true);
  }

  /**
   * The click of the Browse for the mosaic picture button this bring up the directory browers
   * @param e ActionEvent
   */
  public void BrowsePictureButton_actionPerformed(ActionEvent e) {

    JFileChooser fc = new JFileChooser();

    //Add a custom file filter and disable the default
    fc.addChoosableFileFilter(new ImageFilter());
    fc.setAcceptAllFileFilterUsed(false);

    //Add the preview pane.
    fc.setAccessory(new ImagePreview(fc));

    //Show the browser.
    int returnVal = fc.showDialog(this, "Choose");

    //if a image was choosen
    if (returnVal == JFileChooser.APPROVE_OPTION) {
      //get the file choosen
      File file = fc.getSelectedFile();

      //store the path to the file
      this.PathToOriginalPicture = file.getPath();

      //diplay the file name to the user
      this.OriginalPictureFileNamelabel.setText(file.getName());

      //put the image choosen in the sample viewer
      this.sampleView.setPicture(file.getPath());

      //if the user has already choosen mosaic pieces
      if (FilesOfPicturesReadIn != null) {

        //allow the user to start the mosaic creation
        this.StartButton.setVisible(true);
      }

    }

  }

  /**
   * grabs the open file click and starts the mosaicOpener class that allows the user to open a save .mosaic file
   * @param e ActionEvent
   */
  public void jMenuFileOpen_actionPerformed(ActionEvent e){

    //set the current mosaic to null to save memory
    this.currentMosaic = null;

    //start the mosaic opener
    mosaicOpener = new MosaicOpener(this.progressBar, this.ProgressBarLabel, this);

    //show the stop button to allow the user to stop the process of opening the .mosaic file
    this.StopButton.setVisible(true);

    //don't allow the user to change any of the setting on the main window
    this.StartButton.setVisible(false);
    this.ViewButton.setVisible(false);
    this.BrowsePiecesButton.setEnabled(false);
    this.BrowsePictureButton.setEnabled(false);
    this.isReplacementCheckBox.setEnabled(false);
    this.comboBoxDivisionsWidth.setEnabled(false);
    this.comboBoxDivisionsHeight.setEnabled(false);
    this.SliderPictureMatch.setEnabled(false);
    this.jMenuFileOpen.setVisible(false);

  }

  public void StartButton_actionPerformed(ActionEvent e) {

    //set the current mosaic to null to save memory
    this.currentMosaic = null;

    //start the mosaic creator algorithm
    this.Algorithm = new MosaicAlgorithm(PathToOriginalPicture,FilesOfPicturesReadIn,SliderPictureMatch.getValue(),Integer.parseInt((String)comboBoxDivisionsWidth.getSelectedItem()), Integer.parseInt((String)comboBoxDivisionsHeight.getSelectedItem()), isReplacementCheckBox.isSelected(),this,progressBar, ProgressBarLabel );

    //allow the user to stop the creation of the mosaic
    this.StopButton.setVisible(true);

    //don't allow the user to change any of the setting on the main window
    this.StartButton.setVisible(false);
    this.ViewButton.setVisible(false);
    this.BrowsePiecesButton.setEnabled(false);
    this.BrowsePictureButton.setEnabled(false);
    this.isReplacementCheckBox.setEnabled(false);
    this.comboBoxDivisionsWidth.setEnabled(false);
    this.comboBoxDivisionsHeight.setEnabled(false);
    this.SliderPictureMatch.setEnabled(false);
    this.jMenuFileOpen.setVisible(false);

  }

  /**
   * catches any change to the width of divisions of the mosaic
   * @param e ActionEvent
   */
  public void comboBoxDivisions_actionPerformed(ActionEvent e) {

    //change the sampleView image to show the amount of divions
    this.sampleView.setDivisions(11 - this.comboBoxDivisionsWidth.getSelectedIndex(), 11 - this.comboBoxDivisionsHeight.getSelectedIndex());

    int width = Integer.parseInt((String)this.comboBoxDivisionsWidth.getSelectedItem());
    int height = Integer.parseInt((String)this.comboBoxDivisionsHeight.getSelectedItem());

    //check if the user has choosen enough image to allow no duplicates
    if(this.FilesOfPicturesReadIn != null && width * height < this.FilesOfPicturesReadIn.length){

      //get the user the option of duplicates or no duplicates
      this.isReplacementCheckBox.setVisible(true);

    }
    else{

      //set the option of duplicate to no duplicates and do not give the option
      this.isReplacementCheckBox.setSelected(true);
      this.isReplacementCheckBox.setVisible(false);
    }
  }

  /**
   * catches the view button clicked and opens the interactive viewer
   * @param e ActionEvent
   */
  public void ViewButton_actionPerformed(ActionEvent e) {

    //if there is a mosaic stored in memory
    if(this.currentMosaic != null){

      //start the interactive viewer
      new InteractiveViewer(this);

    }
  }

  /**
   * starts the user manual viewer
   * @param e ActionEvent
   */
  public void jMenuHelpManual_actionPerformed(ActionEvent e){
    new UserManualFrame();
  }

  /**
   * A return from the two algorithms that created mosaics ( open mosaic and create mosiac )
   */
  public void StoreMosaic() {

    //if there is a mosaic in memory
    if(this.currentMosaic != null){

      //allow the user to start the interactive viewer
      this.ViewButton.setVisible(true);

    }

    //has the user choosen the mosaic pieces and the mosaic image allow them to create a new moaic
    if (FilesOfPicturesReadIn != null && !OriginalPictureFileNamelabel.getText().equals("No File Choosen")) {
      this.StartButton.setText("New Mosaic");
      this.StartButton.setVisible(true);
    }

    //turn off the stop button
    this.StopButton.setVisible(false);
    this.jMenuFileOpen.setVisible(true);
    this.BrowsePiecesButton.setEnabled(true);
    this.BrowsePictureButton.setEnabled(true);
    this.comboBoxDivisionsWidth.setEnabled(true);
    this.comboBoxDivisionsHeight.setEnabled(true);
    this.isReplacementCheckBox.setEnabled(true);
    this.SliderPictureMatch.setEnabled(true);

    //set the mosaic algorithm object to null to save memory
    this.Algorithm = null;
  }

  /**
   * catches the stop button clicked and stop the process of opening or creating a mosaic
   * @param e ActionEvent
   */
  public void StopButton_actionPerformed(ActionEvent e) {

    //check which thread is running and stops it
    if(this.Algorithm != null) this.Algorithm.isAlive = false;
    if(this.mosaicOpener != null)  this.mosaicOpener.isAlive = false;
  }

}

class MainWindow_jMenuFileExit_ActionAdapter implements ActionListener {
  MainWindow adaptee;

  MainWindow_jMenuFileExit_ActionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jMenuFileExit_actionPerformed(e);
  }
}
class MainWindow_jMenuFileOpen_ActionAdapter implements ActionListener {
  MainWindow adaptee;

  MainWindow_jMenuFileOpen_ActionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jMenuFileOpen_actionPerformed(e);
  }
}
class MainWindow_jMenuHelpManual_ActionAdapter implements ActionListener {
  MainWindow adaptee;

  MainWindow_jMenuHelpManual_ActionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jMenuHelpManual_actionPerformed(e);
  }

}
class MainWindow_jMenuHelpAbout_ActionAdapter implements ActionListener {
  MainWindow adaptee;

  MainWindow_jMenuHelpAbout_ActionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.jMenuHelpAbout_actionPerformed(e);
  }
}

class MainWindow_BrowsePiecesButton_actionAdapter implements java.awt.event.ActionListener {
  MainWindow adaptee;

  MainWindow_BrowsePiecesButton_actionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.BrowsePiecesButton_actionPerformed(e);
  }
}

class MainWindow_BrowsePictureButton_actionAdapter implements java.awt.event.ActionListener {
  MainWindow adaptee;

  MainWindow_BrowsePictureButton_actionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.BrowsePictureButton_actionPerformed(e);
  }
}

class MainWindow_StartButton_actionAdapter implements java.awt.event.ActionListener {
  MainWindow adaptee;

  MainWindow_StartButton_actionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.StartButton_actionPerformed(e);
  }
}

class MainWindow_comboBoxDivisions_actionAdapter implements java.awt.event.ActionListener {
  MainWindow adaptee;

  MainWindow_comboBoxDivisions_actionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.comboBoxDivisions_actionPerformed(e);
  }
}

class MainWindow_ViewButton_actionAdapter implements java.awt.event.ActionListener {
  MainWindow adaptee;

  MainWindow_ViewButton_actionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.ViewButton_actionPerformed(e);
  }
}

class MainWindow_StopButton_actionAdapter implements java.awt.event.ActionListener {
  MainWindow adaptee;

  MainWindow_StopButton_actionAdapter(MainWindow adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.StopButton_actionPerformed(e);
  }
}
