package view.gammeOperatoire;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.EventObject;
import java.util.Vector;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.UIManager;

import controller.BaseDonnees;
import controller.GestionPoste;


import model.article.Article;
import model.gammeOperatoire.Activite;
import model.gammeOperatoire.Attente;
import model.gammeOperatoire.GammeOperatoire;
import model.gammeOperatoire.Operation;
import model.gammeOperatoire.Stockage;
import model.gammeOperatoire.Transport;
import model.posteCharge.PosteCharge;

/**
 * Gestion de l'affichage des activites constituant une gamme operatoire
 * @author Magic Penguins
 * @see ViewGOP 
 *
 */
public class EventBouttons implements ActionListener{

	private GammeOperatoire g;
	private JList list;
	private JPanel panel;
	private JPanel container;
	private DefaultListModel modelList;
	private Activite a=null;
	private Vector<JLabel> listLabel = new Vector<JLabel>();
	private Vector<JTextField> listTxt = new Vector<JTextField>();
	private JRadioButton radioAssemble;
	private JRadioButton radioFabrique;
	private JComboBox choiceProd;
	private JComboBox choicePoste;


	/**
	 * Constructeur de EventBouttons
	 * @param GOP
	 * Gamme operatoire a afficher en IHM
	 * @param list
	 * Permet de determiner quel champ est selectionne
	 * @param panel
	 * JPanel sur lequel sera affiche les options
	 * @param container
	 * JPanel contenant tout l'onglet
	 * @param modelList
	 * Model associe a la {@link JList} list
	 */
	public EventBouttons(GammeOperatoire GOP, JList list, JPanel panel, JPanel container, DefaultListModel modelList) {
		this.g=GOP;
		this.list=list;
		this.panel=panel;
		this.container=container;
		this.modelList=modelList;

		radioFabrique = new JRadioButton("Fabrication");
		radioFabrique.setActionCommand("1");
		radioAssemble = new JRadioButton("Assemblage");
		radioAssemble.setActionCommand("2");
		choiceProd = new JComboBox(BaseDonnees.listeArticles);
		choicePoste= new JComboBox(BaseDonnees.listePostes);
		choiceProd.setPreferredSize(new Dimension(155,25));
		choicePoste.setPreferredSize(new Dimension(155,25));
	}


	/**
	 * Affichage des parametres sur le panel d'option en fonction de l'activitee selectionee ainsi que gestion des bouttons sur le JPanele central
	 * @param e
	 */
	public void action (EventObject e){
		if (e.getSource() instanceof JList) {
			a= (Activite)(list.getSelectedValue());
			setLists();
			setPanel();
		}
		else if (e.getSource() instanceof JButton) {
			JButton jb = (JButton)e.getSource();
			int pos=list.getSelectedIndex();

			if (jb.getText() == "Monter") {
				if (pos >0) {
					g.swapArticle(pos, pos-1);
					Activite a = (Activite)modelList.get(pos-1);
					modelList.set(pos-1, list.getSelectedValue());
					modelList.set(pos, a);
					list.setSelectedIndex(pos-1);
					list.updateUI();
				}
			}
			else if (jb.getText() == "Descendre") {
				if (pos>=0 && pos < g.getGamme().size()-1) {
					g.swapArticle(pos, pos+1);
					Activite a = (Activite)modelList.get(pos+1);
					modelList.set(pos+1, list.getSelectedValue());
					modelList.set(pos, a);
					list.setSelectedIndex(pos+1);
					list.updateUI();
				}
			}
			else if (jb.getText() == "Supprimer") {
				if (list.getSelectedIndex() == -1) JOptionPane.showMessageDialog(container, "Veuillez selectionner une activite", "Erreur",JOptionPane.ERROR_MESSAGE);
				else {
					int i = JOptionPane.showConfirmDialog(container, "Voulez vous vraiment supprimer de la base l'activite selectionnee ?", "Confirmer suppression", JOptionPane.YES_NO_OPTION);
					if (i == JOptionPane.OK_OPTION) {
						i=list.getSelectedIndex();
						Activite a = (Activite)list.getSelectedValue();
						((DefaultListModel)list.getModel()).removeElement(a);
						g.removeActivite(a);

						if (i<list.getComponentCount()) {list.setSelectedIndex(i);}
						else {list.setSelectedIndex(i-1);}
						if (((DefaultListModel)list.getModel()).getSize() == 0) {panel.removeAll();}
						list.updateUI();
						panel.updateUI();
					}
				}
			}
			else if (jb.getText() == "Nouveau...") {
				String [] str = {"Assemblage", "Attente", "Fabrication", "Stockage", "Transport"};
				String s = (String)JOptionPane.showInputDialog(container, "Selectionnez un type d'activite", "Nouvelle activite", JOptionPane.OK_CANCEL_OPTION, UIManager.getIcon("OptionPane.questionIcon"), str, str[0]);
				if (s != null) {
					if (s.equals("Assemblage")) {
						Operation o = newOperation(true);
						newActivite(o);
					}
					else if (s.equals("Attente")) {
						Attente a = newAttente();
						newActivite(a);
					}
					else if (s.equals("Fabrication")) {
						Operation o = newOperation(false);
						newActivite(o);
					}
					else if (s.equals("Stockage")) {
						Stockage st = newStockage();
						newActivite(st);
					}
					else if (s.equals("Transport")) {
						Transport t = newTransport();
						newActivite(t);
					}
				}
			}
			else System.out.println("Erreur. Bad button label : " + jb.getText());
		}
		else System.out.println("Erreur. Bad class : " + e.getSource().getClass());
	}

	//-----------------------------------------------------------------------------Gestion du panel d'option


	/**
	 * Generation de la liste de {@link JLabel} et de {@link JTextField} necessaires aux champs de l'objet selectione
	 */
	public void setLists() {
		String[] forbiden = {"Assemblage", "Produit", "Poste"};
		Vector<String> vForbiden = new Vector<String>(Arrays.asList(forbiden));

		if (a!= null) {
			listLabel.removeAllElements();
			listTxt.removeAllElements();
			for(String s : a.getParam()) {
				if (vForbiden.indexOf(s) == -1) {
					JLabel j = new JLabel(s);
					JTextField t = new JTextField(a.get(a.getParam().indexOf(s)).toString());
					if (s.equals("Quantite")) {
						//if (a instanceof Operation) if (g.isProduction()) t.setEnabled(false);
						j.setPreferredSize(new Dimension(72, 16));
					}
					else j.setPreferredSize(new Dimension(42, 16));
					listLabel.add(j);
					listTxt.add(t);
				}
			}
		}
	}


	/**
	 * Initialisation du panel d'options
	 */
	public void setPanel() {
		panel.setLayout(new BorderLayout());
		panel.removeAll();
		JPanel p1 = new JPanel();
		p1.setLayout(new BoxLayout(p1, BoxLayout.PAGE_AXIS));
		for (JLabel l : listLabel) {
			JPanel p = new JPanel();
			p.setLayout(new BoxLayout(p, BoxLayout.LINE_AXIS));
			p.add(l);
			p.add(listTxt.get(listLabel.indexOf(l)));
			p1.add(p);
		}
		if (a instanceof Operation) {
			setOperation(p1);
		}
		panel.add(p1,BorderLayout.NORTH);
		panel.add(Box.createVerticalGlue(), BorderLayout.CENTER);
		JButton ok = new JButton("Modifier");
		ok.addActionListener(this);
		panel.add(ok, BorderLayout.SOUTH);
		panel.updateUI();
	}


	/**
	 * Si l'activite selectionnee est une operation, il faut rajouter des champs et bouttons supplementaires
	 * @param p
	 * {@link JPanel} sur lequel on affiche les champs supplementaires
	 */
	public void setOperation(JPanel p) {
		radioAssemble.addActionListener(this);
		radioFabrique.addActionListener(this);
		if (((Operation)a).isAssemblage())	{
			radioAssemble.setSelected(true);
			radioFabrique.setSelected(false);
		}
		else {
			radioAssemble.setSelected(false);
			radioFabrique.setSelected(true);
		}
		p.add(radioAssemble);
		p.add(radioFabrique);

		JPanel panelProd = new JPanel();
		JLabel pc = new JLabel("Poste de Charge");
		JLabel produit = new JLabel("Produit");
		produit.setPreferredSize(pc.getPreferredSize());

		panelProd.add(produit);
		choiceProd.setSelectedIndex(BaseDonnees.listeArticles.indexOf(((Operation)a).getCible()));
		panelProd.add(choiceProd);
		p.add(panelProd);

		JPanel panelPoste = new JPanel();
		panelPoste.add(pc);
		choicePoste.setSelectedIndex(BaseDonnees.listePostes.indexOf(((Operation)a).getPoste()));
		panelPoste.add(choicePoste);
		p.add(panelPoste);

		JPanel posteButtonPanel = new JPanel();
		JButton editPoste = new JButton("Editer Poste");
		JButton newPoste = new JButton("Nouveau Poste...");

		editPoste.addActionListener(this);
		newPoste.addActionListener(this);
		posteButtonPanel.add(editPoste);
		posteButtonPanel.add(newPoste);
		p.add(posteButtonPanel);
	}




	/**
	 * Listener des bouttons contenus dans le panel d'option
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		//cas : c'est un JRadioButton (Assemblage - Fabrication)
		if (e.getSource() instanceof JRadioButton) {
			if (((JRadioButton)(e.getSource())).isSelected()) {
				if (e.getActionCommand().equals("1")) radioAssemble.setSelected(!radioFabrique.isSelected());
				else if (e.getActionCommand().equals("2")) radioFabrique.setSelected(!radioAssemble.isSelected());
			} else ((JRadioButton)(e.getSource())).setSelected(true);
		}

		//cas : c'est un JButton (associ� a l'objet Operation)
		else if (e.getSource() instanceof JButton){
			JButton jb = (JButton)e.getSource();
			//boutton Editer Poste
			if (jb.getText().equals("Editer Poste")) {
				PosteCharge pc = (PosteCharge)(choicePoste.getSelectedItem());
				ViewPC dialogPC=new ViewPC(pc);
				dialogPC.setVisible(true);
				if (BaseDonnees.listePostes.indexOf(pc) == -1) choicePoste.setSelectedIndex(0);
				choicePoste.updateUI();
			}
			//boutton nouveau poste
			else if (jb.getText().equals("Nouveau Poste...")) {
				String s = JOptionPane.showInputDialog(container, "Entrez le nom du nouveau poste de charge", "Nouveau poste de charge", JOptionPane.QUESTION_MESSAGE);
				if (s!=null) {
					if (s.isEmpty()) JOptionPane.showMessageDialog(container, "Vous devez entrer un nom valide", "Erreur",JOptionPane.ERROR_MESSAGE);
					else {
						GestionPoste.creerPoste(s);
						choicePoste.updateUI();
					}
				}
			}

			//boutton Modifier
			else if (jb.getText().equals("Modifier")) {

				Vector<Object> v = new Vector<Object>();
				boolean error = false;
				for (JTextField j : listTxt) {
					if (j.getText().trim().length() == 0) {
						error =true;
						break;
					}
					v.add(j.getText());
				}
				if (error) JOptionPane.showMessageDialog(container, "Veuillez remplir tout les champs", "Erreur",JOptionPane.ERROR_MESSAGE);
				else {
					if (a instanceof Operation) {
						v.add(radioAssemble.isSelected());
						v.add(choiceProd.getSelectedItem());
						v.add(choicePoste.getSelectedItem());
					}
					try {
						a.set(v);
						JOptionPane.showMessageDialog(container, "Les modifications ont bien ete enregistrees", "Activite Modifiee",JOptionPane.INFORMATION_MESSAGE);
						list.updateUI();
						panel.updateUI();
					} catch (NumberFormatException e1) {
						JOptionPane.showMessageDialog(container, "Erreur dans le format d'entree", "Erreur",JOptionPane.ERROR_MESSAGE);
						//e1.printStackTrace();
					}
					catch (Exception e1) {
						JOptionPane.showMessageDialog(container, "Unexpected Error.", "Erreur",JOptionPane.ERROR_MESSAGE);
						e1.printStackTrace();
					}
				}
			}
			else System.out.println("Erreur. Bad button label : " + jb.getText());
		}
	}

	//---------------------------------------------------------------IHM de creation de nouvelles activites

	/**
	 * IHM de creation d'une nouvelle operation
	 * @param assemblage
	 * indique s'il s'agit d'un assemblage ou d'une fabrication
	 * @return La nouvelle operation
	 */
	public Operation newOperation(boolean assemblage) {
		Operation o=null;

		JTextField duree = new JTextField();
		JComboBox produit = new JComboBox(BaseDonnees.listeArticles);
		JComboBox poste = new JComboBox(BaseDonnees.listePostes);

		JPanel pane = new JPanel();
		pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
		pane.add(new JLabel("Duree :"));
		pane.add(duree);
		pane.add(new JLabel("Produit :"));
		pane.add(produit);
		pane.add(new JLabel("Poste de charge :"));
		pane.add(poste);

		int i = JOptionPane.showConfirmDialog(container, pane, "Nouvelle operation : "+(assemblage? "Assemblage":"Fabrication"), JOptionPane.OK_CANCEL_OPTION);
		if (i == JOptionPane.OK_OPTION) {
			if (duree.getText().trim().length()==0) {
				JOptionPane.showMessageDialog(container, "Veuillez remplir tout les champs", "Erreur",JOptionPane.ERROR_MESSAGE);
				return newOperation(assemblage);
			}
			try {
				o = new Operation(Integer.parseInt(duree.getText()), (Article)produit.getSelectedItem(), (PosteCharge)poste.getSelectedItem(), 1, assemblage);
			}catch (NumberFormatException e) {
				JOptionPane.showMessageDialog(container, "Erreur de format", "Erreur",JOptionPane.ERROR_MESSAGE);
				return newOperation(assemblage);
			}
		}
		return o;
	}

	/**
	 * IHM de creation d'un nouveau transport
	 * @return Le nouveau transport
	 */
	public Transport newTransport() {
		Transport t=null;

		JTextField duree = new JTextField();
		JTextField depart = new JTextField();
		JTextField arrive = new JTextField();

		JPanel pane = new JPanel();
		pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
		pane.add(new JLabel("Duree :"));
		pane.add(duree);
		pane.add(new JLabel("Depart :"));
		pane.add(depart);
		pane.add(new JLabel("Arrive"));
		pane.add(arrive);

		int i = JOptionPane.showConfirmDialog(container, pane, "Nouveau Transport", JOptionPane.OK_CANCEL_OPTION);
		if (i == JOptionPane.OK_OPTION) {
			if (duree.getText().trim().length()==0 || depart.getText().trim().length()==0 || arrive.getText().trim().length()==0) {
				JOptionPane.showMessageDialog(container, "Veuillez remplir tout les champs", "Erreur",JOptionPane.ERROR_MESSAGE);
				return newTransport();
			}
			try {
				t = new Transport(Integer.parseInt(duree.getText()), depart.getText(), arrive.getText());
			}catch (NumberFormatException e) {
				JOptionPane.showMessageDialog(container, "Erreur de format", "Erreur",JOptionPane.ERROR_MESSAGE);
				return newTransport();
			}
		}
		return t;
	}

	/**
	 * IHM de creation d'un nouveau stockage
	 * @return Le nouveau stockage
	 */
	public Stockage newStockage() {
		Stockage s=null;

		JTextField duree = new JTextField();
		JTextField lieu = new JTextField();

		JPanel pane = new JPanel();
		pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
		pane.add(new JLabel("Duree :"));
		pane.add(duree);
		pane.add(new JLabel("Lieu de stockage :"));
		pane.add(lieu);


		int i = JOptionPane.showConfirmDialog(container, pane, "Nouveau Stockage", JOptionPane.OK_CANCEL_OPTION);
		if (i == JOptionPane.OK_OPTION) {
			if (duree.getText().trim().length()==0 || lieu.getText().trim().length()==0) {
				JOptionPane.showMessageDialog(container, "Veuillez remplir tout les champs", "Erreur",JOptionPane.ERROR_MESSAGE);
				return newStockage();
			}
			try {
				s = new Stockage(Integer.parseInt(duree.getText()), lieu.getText());
			}catch (NumberFormatException e) {
				JOptionPane.showMessageDialog(container, "Erreur de format", "Erreur",JOptionPane.ERROR_MESSAGE);
				return newStockage();
			}
		}
		return s;
	}


	/**
	 * IHM de creation d'une nouvelle attente
	 * @return La nouvelle attente
	 */
	public Attente newAttente() {
		Attente a=null;

		JTextField duree = new JTextField();

		JPanel pane = new JPanel();
		pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
		pane.add(new JLabel("Duree :"));
		pane.add(duree);

		int i = JOptionPane.showConfirmDialog(container, pane, "Nouveau Stockage", JOptionPane.OK_CANCEL_OPTION);
		if (i == JOptionPane.OK_OPTION) {
			if (duree.getText().trim().length()==0) {
				JOptionPane.showMessageDialog(container, "Veuillez remplir tout les champs", "Erreur",JOptionPane.ERROR_MESSAGE);
				return newAttente();
			}
			try {
				a = new Attente(Integer.parseInt(duree.getText()));
			}catch (NumberFormatException e) {
				JOptionPane.showMessageDialog(container, "Erreur de format", "Erreur",JOptionPane.ERROR_MESSAGE);
				return newAttente();
			}
		}
		return a;
	}

	/**
	 * Permet d'ajouter une nouvelle activite a la gamme selectionnee
	 * @param a
	 */
	public void newActivite(Activite a) {
		if (a!=null) {
			g.addActivite(a);
			modelList.addElement(a);
			list.updateUI();
		}
	}
}