package adecWatt.view;

import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.Collection;
import java.util.TreeSet;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTextField;

import misc.Util;
import static misc.Util.GBC;
import static misc.Util.GBCNL;

import adecWatt.model.Embedded;
import adecWatt.model.Editable;
import adecWatt.model.Permanent;
import adecWatt.model.Prop;
import adecWatt.model.Unit;
import adecWatt.model.UnitNode;

@SuppressWarnings ("serial")
public class JTransform extends JPanel {
    // ========================================
    static public ArrayList<JCheckBox> getJModifiers (Collection<String> modifiersSet, Collection<String> modifiers, boolean isLock) {
	ArrayList<JCheckBox> result = new ArrayList<JCheckBox> ();
	for (String modifier : modifiersSet) {
	    JCheckBox button = Util.newCheckIcon (Util.toCapital (modifier), null);
  	    if (modifiers != null && modifiers.contains (modifier))
		button.setSelected (true);
	    Util.unBoxButton (button);
	    result.add (button);
	}
	if (isLock)
	    for (JCheckBox button : result)
		button.setEnabled (false);
	return result;
    }

    static public Collection<String> getModifiers (ArrayList<JCheckBox> buttons,
						   Collection<String> oldModifiers, boolean admin, Collection<String> hiddenModifiers) {
	TreeSet<String> modifiers = new TreeSet<String> ();
	for (JCheckBox button : buttons)
	    if (button.isSelected ())
		modifiers.add (button.getActionCommand ().toLowerCase ());
	if (!admin && oldModifiers != null)
	    for (String modifier : hiddenModifiers)
		if (oldModifiers.contains (modifier))
		    modifiers.add (modifier);
	return modifiers.size () < 1 ? null : modifiers;
    }

    public boolean isLock (String propName) {
	return editable.getDirectUnit ().getPropLock (propName);
    }

    // ========================================
    private Editable<?, ?, ?, ?> editable;
    private Unit<?> root;
    private boolean isRoot;
    private boolean isEmbedded;
    private ArrayList<JCheckBox> jModifiers;
    private ArrayList<Unit<?>> permanents;
    private JComboBox<String> jPermanents;
    private JTextField jName;
    private JDefPropTable jDefPropTable;
    private boolean admin;

    public boolean isAdmin () { return admin; }

    public JTransform (Editable<?, ?, ?, ?> editable) {
	super (new GridBagLayout ());
	this.editable = editable;
	root = editable.getDirectUnit ().getUnitRoot ();
	isRoot = root == editable;
	isEmbedded = editable instanceof Embedded;
	admin = editable.getDirectUnit ().getAdecWatt ().getUser ().isAdmin ();

	setAvailablePermanents ();
	jName = new JTextField (editable.getName (), 16);
	jDefPropTable = new JDefPropTable (this, editable);

	if (!isEmbedded) {
	    jModifiers = getJModifiers (editable.getModifiersSet (), editable.getModifiers (), editable.isLock ());
	    JPanel jDisplayModifiers = new JPanel ();
	    for (JCheckBox jModifier : jModifiers)
		jDisplayModifiers.add (jModifier);
	    Util.addComponent (jDisplayModifiers, this, GBC);
	}
	if (isRoot)
	    Util.addComponent (jName, this, GBCNL);	    
	else {
	    Util.addComponent (jPermanents, this, isEmbedded ? GBCNL : GBC);
	    if (!isEmbedded)
		Util.addComponent (jName, this, GBCNL);
	}
	Util.addComponent (Util.getJScrollPane (jDefPropTable), this, GBCNL);

	// XXX devrait être géré par jDefPropTable
    }

    // ========================================
    @SuppressWarnings ("unchecked")
    public void setAvailablePermanents () {
	if (isRoot)
	    return;
	permanents = (ArrayList<Unit<?>>) editable.getDirectUnit ().getAvailablePermanents (isEmbedded, editable);
	jPermanents = new JComboBox<String> ();
	for (Unit<?> unit : permanents)
	    jPermanents.addItem (unit.getLocalName ());
	jPermanents.setSelectedIndex (permanents.indexOf (editable.getParentUnit ()));
    }

    // ========================================
    public boolean valideChange () {
	if (!jDefPropTable.jNewPropName.getText ().isEmpty ())
	    return false;
	TreeSet<String> propNames = new TreeSet<String> ();
	for (JDefPropTable.PropShadow defProp : jDefPropTable.getObjectData ()) {
	    String propName = defProp.propName;
	    if (propName == null || propName.isEmpty () || propNames.contains (propName))
		return false;
	    propNames.add (propName);
	}
	return true;
    }

    @SuppressWarnings ("unchecked")
    public void confirmChange () {
	ArrayList<Prop[]> transProps = new ArrayList<Prop[]> ();
	int rank = 0;
	for (JDefPropTable.PropShadow defProp : jDefPropTable.getObjectData ())
	    transProps.add (new Prop[] {
		    defProp.prop,
		    new Prop (defProp.propName,
			      Prop.PropTypeEnum.values()[defProp.jType.getSelectedIndex ()],
			      new Integer (rank++),
			      defProp.getModifiers (),
			      defProp.jStringSet.getSet (),
			      defProp.jDefLabel.getLabels ())
		});
	Collection<String> newModifiers = jModifiers == null ? null : getModifiers (jModifiers, null, admin, null);
	editable.storyTransform (newModifiers, getPermanent (), jName.getText (), transProps);
    }
    public Unit<?> getPermanent () {
	return isRoot ? null : permanents.get (jPermanents.getSelectedIndex ());
    }

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