import java.awt.* ;
import java.awt.event.ComponentListener ;
import java.awt.event.ComponentEvent ;
import java.util.* ;
import javax.swing.*;
import javax.swing.event.* ;
import java.awt.event.*;
import java.awt.*;
import java.lang.*;
import java.io.*;
import java.awt.Graphics2D ;
import java.awt.geom.Rectangle2D ;
import java.awt.geom.Ellipse2D ;
import java.awt.geom.AffineTransform ;
import javax.swing.JSlider;

public class ControlPanel extends JPanel {

	 private int WIDTH = 650;
	 private int HEIGHT = 160;

	 private GeneticOperators geneticOperators;
	 private ArtPanel artPanel;

	 // 3 check boxes, one for each color
	 JLabel colorMaskLabel;
	 JCheckBox redMaskCheckBox;
	 JCheckBox greenMaskCheckBox;
	 JCheckBox blueMaskCheckBox;

	 //next generation button
	 JButton nextGeneration;

	 //Cross over and mutation radio buttons
	 ButtonGroup crossOverMutationGroup = new ButtonGroup();
	 JRadioButton mutationOnly;
	 JRadioButton crossoverOnly;
	 JRadioButton crossoverAndMutation;

	 //Function Set radio buttons
	 JLabel functionSetLabel;
	 ButtonGroup functionSetGroup = new ButtonGroup();
	 JRadioButton functionSetComplex;
	 JRadioButton FunctionSetBasic;

	 // slider and label for Mutation Chance
	 JSlider mutationChanceSlider;
	 JLabel mutationChanceLabel;
	 JLabel mutationChanceLabel1;

	 //slider and label for Number of Mutations
	 JSlider numberMutationsSlider;
	 JLabel numberMutationsLabel;
	 JLabel numberMutationsLabel1;

	 // check box for multiple point crossovers
	 JCheckBox multiplePointCrossover;

	 // slider + labels for chance of switching parents during multi point cross over
	 JSlider crossoverChanceSlider;
	 JLabel crossoverChanceLabel;
	 JLabel crossoverChanceLabel1;

	 public ControlPanel(GeneticOperators go, ArtPanel artPanel)
	 {
		 // set layout to null so i have full control over placement of buttons
		 this.setLayout(null);

		 geneticOperators = go;
		 this.artPanel = artPanel;

		 // create nextgeneration button
		 nextGeneration = new JButton("Next Generation");
		 nextGeneration.setBounds((int)(WIDTH/2) - 65, 0, 130, 15);
		 nextGeneration.addActionListener(new NextGenerationListener());


		 // create Cross over and Mutation radio buttons
		 mutationOnly = new JRadioButton("Only allow mutation", false);
		 mutationOnly.setBounds(5, 15, 200, 15);
		 mutationOnly.addActionListener(new CrossoverMutationListener());
		 crossOverMutationGroup.add(mutationOnly);

		 crossoverOnly = new JRadioButton("Only allow crossover", false);
		 crossoverOnly.setBounds(5, 30, 200, 15);
		 crossoverOnly.addActionListener(new CrossoverMutationListener());
		 crossOverMutationGroup.add(crossoverOnly);

		 crossoverAndMutation = new JRadioButton("Allow crossover and mutation", true);
		 crossoverAndMutation.setBounds(5, 45, 200, 15);
		 crossoverAndMutation.addActionListener(new CrossoverMutationListener());
		 crossOverMutationGroup.add(crossoverAndMutation);

		 //create multiplePointCrossover check box
		 multiplePointCrossover = new JCheckBox("Allow multiple point crossovers", false);
		 multiplePointCrossover.setBounds(5, 65, 220, 15);
		 multiplePointCrossover.addActionListener(new MultiplePointCrossoverListener());


		 //create slider + labels for chance of switching parents
		 //during multi point cross over
		 crossoverChanceLabel1 = new JLabel("-Chance of parent switching-");
		 crossoverChanceLabel1.setBounds(5, 85, 190, 15);

		 crossoverChanceLabel = new JLabel("40%");
		 crossoverChanceLabel.setBounds(105, 100, 30, 15);

		 crossoverChanceSlider = new JSlider(JSlider.HORIZONTAL , 0 , 100 , 40);
		 crossoverChanceSlider.setBounds(5, 100, 100, 15);
		 crossoverChanceSlider.addChangeListener(new CrossoverChanceListener());




		 //create mutation chance label and slider
		 mutationChanceLabel1 = new JLabel("-Mutation Chance-");
		 mutationChanceLabel1.setBounds(220, 15, 130, 15);

		 mutationChanceLabel = new JLabel("2%");
		 mutationChanceLabel.setBounds(220+100, 30, 30, 15);

		 mutationChanceSlider = new JSlider(JSlider.HORIZONTAL , 0 , 100 , 2);
		 mutationChanceSlider.setBounds(220, 30, 100, 15);
		 mutationChanceSlider.addChangeListener(new MutationChanceListener());


		 //create number of mutations label and slider
		 numberMutationsLabel1 = new JLabel("-Number of Mutations-");
		 numberMutationsLabel1.setBounds(220, 50, 150, 15);

		 numberMutationsLabel = new JLabel("1");
		 numberMutationsLabel.setBounds(220+100, 65, 30, 15);

		 numberMutationsSlider = new JSlider(JSlider.HORIZONTAL , 0 , 100 , 2);
		 numberMutationsSlider.setBounds(220, 65, 100, 15);
		 numberMutationsSlider.addChangeListener(new NumberMutationsListener());

		 // create function set buttons and label
		 functionSetLabel = new JLabel("-Function Sets-");
		 functionSetLabel.setBounds(220, 85, 130, 15);

		 functionSetComplex = new JRadioButton("Complex", true);
		 functionSetComplex.setBounds(220, 100, 80, 15);
		 functionSetComplex.addActionListener(new FunctionSetListener());
		 functionSetGroup.add(functionSetComplex);

		 FunctionSetBasic = new JRadioButton("Basic", false);
		 FunctionSetBasic.setBounds(220, 115, 80, 15);
		 FunctionSetBasic.addActionListener(new FunctionSetListener());
		 functionSetGroup.add(FunctionSetBasic);

		 // Mask check boxes and label
		 colorMaskLabel = new JLabel("-Color Masks-");
		 colorMaskLabel.setBounds(355, 15, 100, 15);

		 redMaskCheckBox = new JCheckBox("Red Mask", true);
		 redMaskCheckBox.setBounds(355, 30, 100, 15);
		 redMaskCheckBox.addActionListener(new RedMaskListener());

		 greenMaskCheckBox = new JCheckBox("Green Mask", true);
		 greenMaskCheckBox.setBounds(355, 45, 100, 15);
		 greenMaskCheckBox.addActionListener(new GreenMaskListener());

		 blueMaskCheckBox = new JCheckBox("Blue Mask", true);
		 blueMaskCheckBox.setBounds(355, 60, 100, 15);
		 blueMaskCheckBox.addActionListener(new BlueMaskListener());

		 // add everything to panel
		 this.add(colorMaskLabel, null);
		 this.add(redMaskCheckBox, null);
		 this.add(greenMaskCheckBox, null);
		 this.add(blueMaskCheckBox, null);
		 this.add(nextGeneration, null);
		 this.add(mutationOnly, null);
		 this.add(crossoverOnly, null);
		 this.add(crossoverAndMutation, null);
		 this.add(mutationChanceLabel, null);
		 this.add(mutationChanceLabel1, null);
		 this.add(mutationChanceSlider, null);
		 this.add(numberMutationsLabel, null);
		 this.add(numberMutationsLabel1, null);
		 this.add(numberMutationsSlider, null);
		 this.add(multiplePointCrossover, null);
		 this.add(crossoverChanceLabel1, null);
		 this.add(crossoverChanceLabel, null);
		 this.add(crossoverChanceSlider, null);
		 this.add(functionSetLabel, null);
		 this.add(functionSetComplex, null);
		 this.add(FunctionSetBasic, null);

	 }

	 public void setEnableAll(boolean t)
	 {
		 redMaskCheckBox.setEnabled(t);
		 greenMaskCheckBox.setEnabled(t);
		 blueMaskCheckBox.setEnabled(t);

		 nextGeneration.setEnabled(t);

		 mutationOnly.setEnabled(t);
		 crossoverOnly.setEnabled(t);
		 crossoverAndMutation.setEnabled(t);

		 mutationChanceSlider.setEnabled(t);

		 numberMutationsSlider.setEnabled(t);

		 multiplePointCrossover.setEnabled(t);

		 crossoverChanceSlider.setEnabled(t);

		 functionSetComplex.setEnabled(t);
		 FunctionSetBasic.setEnabled(t);
	 }

	 public void paintComponent( Graphics g )
	 {
		  Graphics2D g2 = ( Graphics2D ) g ;
		  super.paintComponent( g2 ) ;

		  int x = getWidth();
		  int y = getHeight();

		  int xPrint = x - 170;

		  g2.drawString("Current Node Size: "+artPanel.getNodeSize(), xPrint, 25);
		  g2.drawString("Generation: "+artPanel.getGeneration(), xPrint, 40);
	 }

// Listeners
	private class RedMaskListener implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			if(redMaskCheckBox.isSelected())
				artPanel.setRedMask(true);
			else
				artPanel.setRedMask(false);
		}
	}

	private class GreenMaskListener implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			if(greenMaskCheckBox.isSelected())
				artPanel.setGreenMask(true);
			else
				artPanel.setGreenMask(false);

		}
	}

	private class BlueMaskListener implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			if(blueMaskCheckBox.isSelected())
				artPanel.setBlueMask(true);
			else
				artPanel.setBlueMask(false);
		}
	}

	private class NextGenerationListener implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			artPanel.nextGeneration();
		}
	}

	private class CrossoverMutationListener implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			if(mutationOnly.isSelected())
			{
				artPanel.setMutationOnly(true);
				geneticOperators.setAllowCrossOverWithMutation(false);
			}
			else if(crossoverOnly.isSelected())
			{
				artPanel.setMutationOnly(false);
				geneticOperators.setAllowCrossOverWithMutation(false);
			}
			else // else crossover and mitation is selected
			{
				artPanel.setMutationOnly(false);
				geneticOperators.setAllowCrossOverWithMutation(true);
			}
		}
	}

	 public class MutationChanceListener implements ChangeListener {
		  public void stateChanged( ChangeEvent event )
		  {
			  mutationChanceLabel.setText(""+mutationChanceSlider.getValue()+"%");
			  geneticOperators.setMutationChance((double)mutationChanceSlider.getValue() / 100.0);
		  }
	 }

	 public class NumberMutationsListener implements ChangeListener {
		  public void stateChanged( ChangeEvent event )
		  {
			  numberMutationsLabel.setText(""+numberMutationsSlider.getValue());
			  geneticOperators.setNumberOfMutations(numberMutationsSlider.getValue());
		  }
	 }

	 public class MultiplePointCrossoverListener implements ActionListener {
		public void actionPerformed(ActionEvent event)
		{
			if(multiplePointCrossover.isSelected())
			{
				geneticOperators.setAllowMoreThenOneCrossOverPoint(true);
			}
			else
			{
				geneticOperators.setAllowMoreThenOneCrossOverPoint(false);
			}
		}
	 }

	 public class CrossoverChanceListener implements ChangeListener {
		public void stateChanged( ChangeEvent event )
		{
			  crossoverChanceLabel.setText(""+crossoverChanceSlider.getValue()+"%");
			  geneticOperators.setCrossOverChance((double)crossoverChanceSlider.getValue() / 100.0);
		}
	 }


	private class FunctionSetListener implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			if(functionSetComplex.isSelected())
			{
				geneticOperators.setFunctionSet(0);
				artPanel.calcFunctionChange();
			}
			else // else basic is selected
			{
				geneticOperators.setFunctionSet(1);
				artPanel.calcFunctionChange();
			}
		}
	}
}

