package adecWatt.view;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.TreeSet;
import java.util.Vector;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.filechooser.FileNameExtensionFilter;

import misc.Bundle;
import misc.Config;
import misc.ImagePreview;
import misc.OwnFrame;
import misc.RemoteUpdateManager;
import misc.Util;
import static misc.Util.GBC;
import static misc.Util.GBCNL;

import adecWatt.model.AdecWatt;
import adecWatt.model.Editable;
import adecWatt.model.PermanentDB;
import adecWatt.model.Unit;
import adecWatt.model.User;
import adecWatt.model.unit.Workspace;

public class JAdecWattDialog implements SwingConstants {

    // ========================================
    OwnFrame controller;
    public OwnFrame getOwnFrame () { return controller; }
    public JAdecWattDialog (OwnFrame controller) {
	this.controller = controller;
    }

    // ========================================
    public void todo () {
	JOptionPane.showMessageDialog (controller.getJFrame (), "TODO !\n Oui, cette fonction n'est pas encore r\u00E9alis\u00E9 :-(");
    }
    public String getSimpleMessage (String msg, String value) {
	return JOptionPane.showInputDialog (controller.getJFrame (), msg, value);
    }

    // ========================================
    public void magnetPolicies (AdecWatt adecWatt) {
	JPanel content = Util.getGridBagPanel ();
	JCheckBox jHandleCD = Util.addCheckIcon ("HandleGlue", null, adecWatt.getHandleGlue (), content, GBC);
	Util.addLabel ("HandleGlue", LEFT, content, GBCNL);
	JCheckBox jBoundCB = Util.addCheckIcon ("BoundGlue", null, adecWatt.getBoundGlue (), content, GBC);
	Util.addLabel ("BoundGlue", LEFT, content, GBCNL);
	JCheckBox jGridCB = Util.addCheckIcon ("GridGlue", null, adecWatt.getGridGlue (), content, GBC);
	Util.addLabel ("GridGlue", LEFT, content, GBCNL);
	JCheckBox jInSegCB = Util.addCheckIcon ("InSegmentGlue", null, adecWatt.getInSegmentGlue (), content, GBC);
	Util.addLabel ("InSegmentGlue", LEFT, content, GBCNL);
	if (JOptionPane.showConfirmDialog (controller.getJFrame (), content, Bundle.getTitle ("MagnetPolicies"),
					   JOptionPane.YES_NO_OPTION)
	    != JOptionPane.YES_OPTION)
	    return;
	adecWatt.setHandleGlue (jHandleCD.isSelected ());
	adecWatt.setBoundGlue (jBoundCB.isSelected ());
	adecWatt.setGridGlue (jGridCB.isSelected ());
	adecWatt.setInSegmentGlue (jInSegCB.isSelected ());
    }

    // ========================================
    public void patch (Workspace workspace) {
	JPanel content = new JPatch (workspace.getPatch ());
	JDialog jDialog = removeDisplay (workspace);
	boolean center = false;
	if (jDialog == null) {
	    center = true;
	    jDialog = new JDialog (controller.getJFrame (), "Patch "+workspace.getLocalName (), false);
	}
	Container container = jDialog.getContentPane ();
	container.removeAll ();
	container.add (content, BorderLayout.CENTER);
	addDisplay (workspace, jDialog, center);
    }
    private Hashtable<Editable<?, ?, ?, ?>, JDialog> currentDisplays = new Hashtable<Editable<?, ?, ?, ?>, JDialog> ();
    public JDialog removeDisplay (Editable<?, ?, ?, ?> editable) {
	try {
	    JDialog jDialog = currentDisplays.get (editable);
	    jDialog.setVisible (false);
	    currentDisplays.remove (editable);
	    return jDialog;
	} catch (Exception e) {
	    return null;
	}
    }
    public void removeAllDisplay () {
	for (Editable<?, ?, ?, ?> editable : currentDisplays.keySet ())
	    currentDisplays.get (editable).setVisible (false);
	currentDisplays.clear ();
    }
    private void addDisplay (final Editable<?, ?, ?, ?> editable, JDialog jDialog, boolean center) {
	currentDisplays.put (editable, jDialog);
	jDialog.addWindowListener (new WindowAdapter () {
		public void windowClosing (WindowEvent e) {
		    // XXX confirmBundle
		    removeDisplay (editable);
		}
	    });
	jDialog.pack ();
	if (center)
	    jDialog.setLocation ((int) controller.getJFrame ().getLocation ().getX () - (jDialog.getWidth () - controller.getJFrame ().getWidth ())/2,
				 (int) controller.getJFrame ().getLocation ().getY () - (jDialog.getHeight() - controller.getJFrame ().getHeight ())/2);
	jDialog.setVisible (true);
	jDialog.toFront ();
    }
    public void display (boolean edit, List<Editable<?, ?, ?, ?>> editables) {
	Editable<?, ?, ?, ?> editable = editables.get (0);
	JDialog jDialog = removeDisplay (editable);
	JEditable jEditable = new JEditable (editables);
	JPanel content = jEditable.getDislay (edit);
	if (!edit) {
	    boolean center = false;
	    if (jDialog == null) {
		center = true;
		jDialog = new JDialog (controller.getJFrame (), editable.getLocalName (), false);
	    }
	    Container container = jDialog.getContentPane ();
	    container.removeAll ();
	    container.add (content, BorderLayout.CENTER);
	    addDisplay (editable, jDialog, center);
	    return;
	}
	if (JOptionPane.showConfirmDialog (controller.getJFrame (), content, Bundle.getTitle ("Edit"),
					   JOptionPane.YES_NO_OPTION)
	    != JOptionPane.YES_OPTION)
	    return;
	jEditable.confirmChange ();
	jEditable.confirmBundle ();
    }
    public void transform (Editable<?, ?, ?, ?> editable) {
 	JTransform jTransform = new JTransform (editable);
	for (;;) {
	    if (JOptionPane.showConfirmDialog (controller.getJFrame (), jTransform, Bundle.getTitle ("Transform"), JOptionPane.YES_NO_OPTION)
		!= JOptionPane.YES_OPTION)
		return;
	    if (jTransform.valideChange ())
		break;
	    // XXX message prop en double ou text en cours
	}
	jTransform.confirmChange ();
    }

    // ========================================
    public boolean validation (String message, String name, PermanentDB.UnitLocation location) {
	return
	    JOptionPane.showConfirmDialog (controller.getJFrame (),
					   MessageFormat.format (Bundle.getMessage (message), name, location),
					   null, JOptionPane.YES_NO_OPTION)
	    == JOptionPane.YES_OPTION;
    }
    
    public boolean validation (String message, String name, PermanentDB.UnitLocation location,
			       HashSet<Unit<?>> units, TreeSet<String> icons, TreeSet<String> images) {
	JPanel msgPanel = Util.getGridBagPanel ();
	Util.addComponent (new JLabel (MessageFormat.format (Bundle.getMessage (message), name, location)), msgPanel, GBCNL);
	Util.addLabel ("Units", LEFT, msgPanel, GBC);
	Util.addLabel ("Icons", LEFT, msgPanel, GBC);
	Util.addLabel ("Images", LEFT, msgPanel, GBCNL);
	Vector<String> unitsVector = new Vector<String> ();
	for (Unit<?> unit : units)
	    unitsVector.add (unit.toString ());
	if (icons.size () == 0)
	    icons = new TreeSet<String> (Arrays.asList ("            "));
	if (images.size () == 0)
	    images = new TreeSet<String> (Arrays.asList ("            "));
	Util.addComponent (Util.getJScrollPane (new JList<String> (unitsVector)), msgPanel, GBC);
	Util.addComponent (Util.getJScrollPane (new JList<String> (new Vector<String> (icons))), msgPanel, GBC);
	Util.addComponent (Util.getJScrollPane (new JList<String> (new Vector<String> (images))), msgPanel, GBCNL);
	return
	    JOptionPane.showConfirmDialog (controller.getJFrame (), msgPanel, null, JOptionPane.YES_NO_OPTION)
	    == JOptionPane.YES_OPTION;
    }

    public String getName (String answer) {
	return JOptionPane.showInputDialog (controller.getJFrame (), Bundle.getMessage ("GiveName"), answer);
    }

    public Double getSpace () {
	String answer = JOptionPane.showInputDialog (controller.getJFrame (), Bundle.getMessage ("GiveSpace"), "");
	if (answer == null)
	    return -1.;
	try {
	    return Double.parseDouble (answer.replace (",", "."));
	} catch (Exception e) {
	    return null;
	}
    }

    public void checkAdmin (User user, RemoteUpdateManager remoteUpdateManager) {
	JUser jUser = new JUser (user, remoteUpdateManager);
	switch (JOptionPane.showConfirmDialog (controller.getJFrame (), jUser, Bundle.getTitle ("ChangeRole"),
					       JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE)) {
	case JOptionPane.YES_OPTION:
	    jUser.confirm ();
	    return;
	case JOptionPane.NO_OPTION:
	    return;
	}
    }

    public boolean abortModification () {
	return JOptionPane.showConfirmDialog (controller.getJFrame (), Bundle.getMessage ("QuitJAdecWatt"),
					      Bundle.getTitle ("AdecWattStillRunning"),
					      JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION;
    }

    // ========================================
    public File getChooseOpenFile (File lastFile) {
	JFileChooser jFileChooser = new JFileChooser (Config.getString ("ExportDirName", "data/export"));
	jFileChooser.setFileFilter (new FileNameExtensionFilter (Bundle.getLabel ("ExportFilter"), PermanentDB.exportExtention));
	jFileChooser.setFileSelectionMode (JFileChooser.FILES_ONLY);
	jFileChooser.setAccessory (new ImagePreview (jFileChooser, 1024*1024));
	if (lastFile != null)
	    jFileChooser.setSelectedFile (lastFile);
	if (jFileChooser.showOpenDialog (controller.getJFrame ()) != JFileChooser.APPROVE_OPTION)
	    return null;
	File file = jFileChooser.getSelectedFile ();
	Config.setFile ("ExportDirName", file.getParentFile ());
	return file;
    }

    public File getChooseSaveFile (File lastFile) {
	JFileChooser jFileChooser = new JFileChooser (Config.getString ("ExportDirName", "data/export"));
	jFileChooser.setFileFilter (new FileNameExtensionFilter (Bundle.getLabel ("ExportFilter"), PermanentDB.exportExtention));
	jFileChooser.setFileSelectionMode (JFileChooser.FILES_ONLY);
	jFileChooser.setAccessory (new ImagePreview (jFileChooser, 1024*1024));
	if (lastFile != null)
	    jFileChooser.setSelectedFile (lastFile);
	if (jFileChooser.showSaveDialog (controller.getJFrame ()) != JFileChooser.APPROVE_OPTION)
	    return null;
	File file = jFileChooser.getSelectedFile ();
	Config.setFile ("ExportDirName", file.getParentFile ());
	return file;
    }

    // ========================================
}
