package client.control.benchmark;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import reseau.DataNotFoundException;
import reseau.IMathematicsOperationsProxyFacade;
import reseau.MathematicsException;
import reseau.OptimEISTIServerProxyFacade;
import reseau.UnauthorizedOperationException;
import reseau.XMLBuilder;
import client.Application;
import client.model.benchmark.Benchmarks;
import client.model.problem.Methode;
import client.model.problem.Parameters;
import client.view.member.PanelMembre;
import client.view.respoGroup.PanelRespoGroupe;

/**
 * <u><b>Explication générale de la classe :</b></u>
 * <P>
 * Cette classe permet de gérer l'évènement lié au bouton exécuter un benchmark
 * 
 * @author Dream Team - ING2
 */
public class EcouteurExecBenchmarks implements ActionListener {

	// Variables permettant de définir les ActionCommand
	public static final String VALIDER = "VALIDER";
	public static final String ANNULER = "ANNULER";

	// Variables permettant de définir les noms des paramètres
	public static final String INITIALVECTOR = "Initial-Vector";
	public static final String EPSILON = "Epsilon";
	public static final String ITERATION = "Iteration";
	public static final String STEP = "Step";
	public static final String TEMPERATURE = "Temperature";
	public static final String EXPLORATIONSTEP = "Exploration-Step";
	public static final String SIZEOFINITIALPOPULATION = "Size-Of-Initial-Population";
	public static final String CROSSPROBABILITY = "Cross-Probability";
	public static final String MUTATIONPROBABILITY = "Mutation-Probability";
	public static final String INFLIMIT = "Inferior-Limit";
	public static final String SUPLIMIT = "Superior-Limit";

	public EcouteurExecBenchmarks() {}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de gérer les évènements liés à la souris
	 * 
	 * @param e
	 *            Evènement souris
	 * 
	 */
	public void actionPerformed(ActionEvent e) {
		Component c = (Component) e.getSource();

		PanelRespoGroupe prg = null;
		PanelMembre pm = null;

		while (c != null) {
			if (c instanceof PanelRespoGroupe) {
				prg = (PanelRespoGroupe) c;
			} else if (c instanceof PanelMembre) {
				pm = (PanelMembre) c;
			}
			c = c.getParent();
		}

		if (e.getActionCommand().equals(VALIDER)) {

			// Si on a un panel des responsables
			if (prg != null) {

				// id du groupe et problème
				int idGroup = Application.getInstance().getIdGroupe(
						prg.getAccueil().getNomGroupe());
				int idProblem = Application.getInstance().getIdProbleme(
						prg.getBenchmark().getPanBenchmarkPb().getProblemeBox()
								.getSelectedItem().toString());

				// On affiche le résultat du benchmark et on cache celui des
				// conditions initiales
				prg.getBenchmark().getPanBenchmarkRes().setVisible(true);
				prg.getBenchmark().getPanCondiInitial().setVisible(false);

				// On ajoute les méthodes sélectionnées dans le panel résultat
				prg.getBenchmark().getPanBenchmarkRes().getMethodesBox()
						.removeAllItems();
				Object[] tabMethode = prg.getBenchmark().getPanBenchmarkPb()
						.getListOfResultat().getSelectedValues();

				// On ajoute les méthodes
				for (int i = 0; i < tabMethode.length; i++)
					prg.getBenchmark().getPanBenchmarkRes().getMethodesBox()
							.addItem(tabMethode[i]);

				try {
					// On récupère le reseau
					IMathematicsOperationsProxyFacade dao = OptimEISTIServerProxyFacade
							.getInstance();

					// On recupere les conditions initiales du benchmark !
					ArrayList<Parameters> arrayCondiInit = new ArrayList<Parameters>();

					// TODO Vecteur Initial du type (1, 2, 3, 4)
					if (prg.getBenchmark().getPanCondiInitial()
							.getInitialVector().isVisible())
						arrayCondiInit.add(new Parameters(INITIALVECTOR, prg
								.getProbleme().getPanExecPb()
								.getInitialVector().getText()));
					if (prg.getBenchmark().getPanCondiInitial().getEpsilon()
							.isVisible())
						arrayCondiInit.add(new Parameters(EPSILON, prg
								.getProbleme().getPanExecPb().getEpsilon()
								.getText()));
					if (prg.getBenchmark().getPanCondiInitial().getIteration()
							.isVisible())
						arrayCondiInit.add(new Parameters(ITERATION, prg
								.getProbleme().getPanExecPb().getIteration()
								.getText()));
					if (prg.getBenchmark().getPanCondiInitial().getStep()
							.isVisible())
						arrayCondiInit.add(new Parameters(STEP, prg
								.getProbleme().getPanExecPb().getStep()
								.getText()));
					if (prg.getBenchmark().getPanCondiInitial()
							.getTemperature().isVisible())
						arrayCondiInit.add(new Parameters(TEMPERATURE, prg
								.getProbleme().getPanExecPb().getTemperature()
								.getText()));
					if (prg.getBenchmark().getPanCondiInitial()
							.getExplorationStep().isVisible())
						arrayCondiInit.add(new Parameters(EXPLORATIONSTEP, prg
								.getProbleme().getPanExecPb()
								.getExplorationStep().getText()));
					if (prg.getBenchmark().getPanCondiInitial()
							.getSizeOfInitialPop().isVisible())
						arrayCondiInit.add(new Parameters(
								SIZEOFINITIALPOPULATION, prg.getProbleme()
										.getPanExecPb().getSizeOfInitialPop()
										.getText()));
					if (prg.getBenchmark().getPanCondiInitial().getCrossProba()
							.isVisible())
						arrayCondiInit.add(new Parameters(CROSSPROBABILITY, prg
								.getProbleme().getPanExecPb().getCrossProba()
								.getText()));
					if (prg.getBenchmark().getPanCondiInitial()
							.getMutationProba().isVisible())
						arrayCondiInit.add(new Parameters(MUTATIONPROBABILITY,
								prg.getProbleme().getPanExecPb()
										.getMutationProba().getText()));
					if (prg.getBenchmark().getPanCondiInitial().getInf()
							.isVisible())
						arrayCondiInit.add(new Parameters(INFLIMIT, prg
								.getProbleme().getPanExecPb().getInf()
								.getText()));
					if (prg.getBenchmark().getPanCondiInitial().getSup()
							.isVisible())
						arrayCondiInit.add(new Parameters(SUPLIMIT, prg
								.getProbleme().getPanExecPb().getSup()
								.getText()));

					// On recupere les id des methodes selectionnes du benchmark
					// !
					int numberOfMethodsSelected = prg.getBenchmark()
							.getPanBenchmarkRes().getMethodesBox()
							.getItemCount();
					int[] arrayIdMethods = new int[numberOfMethodsSelected];

					for (int i = 0; i < numberOfMethodsSelected; i++)
						arrayIdMethods[i] = Methode.getIdMethode(prg
								.getBenchmark().getPanBenchmarkRes()
								.getMethodesBox().getItemAt(i).toString());

					// On resoud le benchmark
					Benchmarks b = dao.resolve(Application.idSelect, idGroup,
							idProblem, arrayCondiInit, arrayIdMethods);

					// On ajoute le resultat dans l'arrayResultat
					Application.getInstance().addBenchmark(b.getIdBenchmark(),
							b);

					// On crée le benchmark imprimable au cas où on demande
					// l'impression de ce dernier
					XMLBuilder.BuildBenchmarkPrintMessage(b);

					EcouteurImprimer.idBenchmark = b.getIdBenchmark();

				} catch (UnauthorizedOperationException ex) {
					JOptionPane
							.showMessageDialog(
									null,
									ex.getLocalizedMessage(),
									"Impossible d'exécuter ce problème : interdit pour vous !",
									JOptionPane.ERROR_MESSAGE);
				} catch (DataNotFoundException ed) {
					JOptionPane
							.showMessageDialog(
									null,
									ed.getLocalizedMessage(),
									"Impossible d'exécuter ce problème : problème non trouvé !",
									JOptionPane.ERROR_MESSAGE);
				} catch (MathematicsException em) {
					JOptionPane
							.showMessageDialog(
									null,
									em.getLocalizedMessage(),
									"Impossible d'exécuter ce problème : erreur mathématique !",
									JOptionPane.ERROR_MESSAGE);
				}

				// Si on a un panel des membres
			} else if (pm != null) {

				// id du groupe et problème
				int idGroup = Application.getInstance().getIdGroupe(
						pm.getAccueil().getNomGroupe());
				int idProblem = Application.getInstance().getIdProbleme(
						pm.getBenchmark().getPanBenchmarkPb().getProblemeBox()
								.getSelectedItem().toString());

				// On affiche le résultat des benchmarks et on cache celui des
				// conditions initiales
				pm.getBenchmark().getPanBenchmarkRes().setVisible(true);
				pm.getBenchmark().getPanCondiInitial().setVisible(false);

				// On ajoute les méthodes sélectionnées dans le panel résultat
				pm.getBenchmark().getPanBenchmarkRes().getMethodesBox()
						.removeAllItems();
				Object[] tabMethode = pm.getBenchmark().getPanBenchmarkPb()
						.getListOfResultat().getSelectedValues();

				// On ajoute les méthodes
				for (int i = 0; i < tabMethode.length; i++)
					pm.getBenchmark().getPanBenchmarkRes().getMethodesBox()
							.addItem(tabMethode[i]);

				try {
					// On recupère le reseau
					IMathematicsOperationsProxyFacade dao = OptimEISTIServerProxyFacade
							.getInstance();

					// On recupere les conditions initiales du benchmark !
					ArrayList<Parameters> arrayCondiInit = new ArrayList<Parameters>();

					if (pm.getBenchmark().getPanCondiInitial()
							.getInitialVector().isVisible())
						arrayCondiInit.add(new Parameters(INITIALVECTOR, pm
								.getProbleme().getPanExecPb()
								.getInitialVector().getText()));
					if (pm.getBenchmark().getPanCondiInitial().getEpsilon()
							.isVisible())
						arrayCondiInit.add(new Parameters(EPSILON, pm
								.getProbleme().getPanExecPb().getEpsilon()
								.getText()));
					if (pm.getBenchmark().getPanCondiInitial().getIteration()
							.isVisible())
						arrayCondiInit.add(new Parameters(ITERATION, pm
								.getProbleme().getPanExecPb().getIteration()
								.getText()));
					if (pm.getBenchmark().getPanCondiInitial().getStep()
							.isVisible())
						arrayCondiInit.add(new Parameters(STEP, pm
								.getProbleme().getPanExecPb().getStep()
								.getText()));
					if (pm.getBenchmark().getPanCondiInitial().getTemperature()
							.isVisible())
						arrayCondiInit.add(new Parameters(TEMPERATURE, pm
								.getProbleme().getPanExecPb().getTemperature()
								.getText()));
					if (pm.getBenchmark().getPanCondiInitial()
							.getExplorationStep().isVisible())
						arrayCondiInit.add(new Parameters(EXPLORATIONSTEP, pm
								.getProbleme().getPanExecPb()
								.getExplorationStep().getText()));
					if (pm.getBenchmark().getPanCondiInitial()
							.getSizeOfInitialPop().isVisible())
						arrayCondiInit.add(new Parameters(
								SIZEOFINITIALPOPULATION, pm.getProbleme()
										.getPanExecPb().getSizeOfInitialPop()
										.getText()));
					if (pm.getBenchmark().getPanCondiInitial().getCrossProba()
							.isVisible())
						arrayCondiInit.add(new Parameters(CROSSPROBABILITY, pm
								.getProbleme().getPanExecPb().getCrossProba()
								.getText()));
					if (pm.getBenchmark().getPanCondiInitial()
							.getMutationProba().isVisible())
						arrayCondiInit.add(new Parameters(MUTATIONPROBABILITY,
								pm.getProbleme().getPanExecPb()
										.getMutationProba().getText()));
					if (pm.getBenchmark().getPanCondiInitial().getInf()
							.isVisible())
						arrayCondiInit.add(new Parameters(INFLIMIT, pm
								.getProbleme().getPanExecPb().getInf()
								.getText()));
					if (pm.getBenchmark().getPanCondiInitial().getSup()
							.isVisible())
						arrayCondiInit.add(new Parameters(SUPLIMIT, pm
								.getProbleme().getPanExecPb().getSup()
								.getText()));

					// On recupere les id des methodes selectionnes du benchmark
					// !
					int numberOfMethodsSelected = pm.getBenchmark()
							.getPanBenchmarkRes().getMethodesBox()
							.getItemCount();
					int[] arrayIdMethods = new int[numberOfMethodsSelected];

					for (int i = 0; i < numberOfMethodsSelected; i++)
						arrayIdMethods[i] = Methode.getIdMethode(pm
								.getBenchmark().getPanBenchmarkRes()
								.getMethodesBox().getItemAt(i).toString());

					// On resoud le benchmark
					Benchmarks b = dao.resolve(Application.idSelect, idGroup,
							idProblem, arrayCondiInit, arrayIdMethods);

					// On ajoute le resultat dans l'arrayResultat
					Application.getInstance().addBenchmark(b.getIdBenchmark(),
							b);

					// On cree le benchmark imprimable au cas ou on demande
					// l'impression de ce dernier
					XMLBuilder.BuildBenchmarkPrintMessage(b);

					EcouteurImprimer.idBenchmark = b.getIdBenchmark();

				} catch (UnauthorizedOperationException ex) {
					JOptionPane
							.showMessageDialog(
									null,
									ex.getLocalizedMessage(),
									"Impossible d'ex�cuter ce probl�me : interdit pour vous !",
									JOptionPane.ERROR_MESSAGE);
				} catch (DataNotFoundException ed) {
					JOptionPane
							.showMessageDialog(
									null,
									ed.getLocalizedMessage(),
									"Impossible d'ex�cuter ce probl�me : probl�me non trouv� !",
									JOptionPane.ERROR_MESSAGE);
				} catch (MathematicsException em) {
					JOptionPane
							.showMessageDialog(
									null,
									em.getLocalizedMessage(),
									"Impossible d'ex�cuter ce probl�me : erreur math�matique !",
									JOptionPane.ERROR_MESSAGE);
				}

			}
		} else if (e.getActionCommand().equals(ANNULER)) {
			if (prg != null) {
				prg.getBenchmark().getPanCondiInitial().setVisible(false);

			} else if (pm != null) {
				pm.getBenchmark().getPanCondiInitial().setVisible(false);
			}
		}
	}

}
