package adecWatt.model;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.HashSet;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import misc.DimensionDouble;
import misc.ScaledImage;
import adecWatt.model.unit.NonWorkspace;
import adecWatt.model.unit.Workspace;
import adecWatt.model.xml.XmlComp;

public class Comp extends Item<XmlComp, Permanent.CompTypeEnum, Permanent.CompAttrEnum> {
    // ========================================
    public int available;

    // ========================================
    public Collection<String>	getModifiersSet ()			{ return CompModifiersSet; }
    public CompTypeEnum		getTypeToken ()				{ return CompTypeEnum.Component; }
    public CompAttrEnum		getNameToken ()				{ return CompAttrEnum.Name; }
    public CompAttrEnum		getModifierToken ()			{ return CompAttrEnum.Modifier; }
    public CompAttrEnum		getPlaceIdToken ()			{ return CompAttrEnum.Placeid; }
    public CompAttrEnum		getModelToken ()			{ return CompAttrEnum.Model; }

    public Comp		getLink (Editable<?, ?, ?, ?> workspace)	{ return new Comp (name, placeId, (Workspace) workspace, model); }

    // ========================================
    public Comp (Workspace workspace, XmlComp xmlComp) {
	super (workspace, xmlComp);
	try {
	    available = Integer.parseInt (xmlComp.getFacet (CompAttrEnum.Available));
	} catch (Exception e) {
	}
    }
    public Comp (String name, String placeName, Workspace workspace, NonWorkspace model) {
	super (name, placeName, workspace, model);
    }
    public Comp (Workspace workspace, NonWorkspace model) {
	super (null, null, workspace, model);
    }
    public Comp clone (Workspace workspace) {
	Comp result = new Comp (workspace, model);
	result.importFrom (this);
	return result;
    }

    // ========================================
    public Element getXml (Node parent, Document document) {
	Element child = super.getXml (parent, document);
	if (isReserved ())
	    XmlComp.putFacet (child, CompAttrEnum.Available, ""+available);
	return child;
    }

    // ========================================
    public void changeThetaDegree (double thetaDegree) {
	if (isSticky ())
	    return;
	getLocalProp (Prop.PropRot, Prop.PropTypeEnum.Cube).setThetaDegree (thetaDegree);
    }
    public void changeSize (DimensionDouble size) {
	if (isSticky ())
	    return;
	getLocalProp (Prop.PropSize, Prop.PropTypeEnum.Cube).setSize (size);
    }

    // ========================================
    public String getLine () {
	try {
	    String name = getPropVal (Prop.PropLine).sValue;
	    if (!name.isEmpty ())
		return name;
	} catch (Exception e) {
	}
	return null;
    }

    // ========================================
    public HashSet<Acc> allPlugs = new HashSet<Acc> ();
    public static String plugId;

    public void print (Graphics2D printGraphics, Workspace workspace, String plugId) {
	this.plugId = plugId;
	print (printGraphics, workspace, getPos (), getSize (), getThetaDegree ());
    }

    public void print (Graphics2D printGraphics, Workspace workspace, Point2D pos, DimensionDouble size, double thetaDegree) {
	accCenter.clear ();
	accSize.clear ();
	allPlugs.clear ();
	ScaledImage scaledImage = getIcon ();
	if (isLow ()) {
	    ScaledImage scaledLowImage = getLowIcon ();
	    if (scaledLowImage != null)
		scaledImage = scaledLowImage;
	}
	Color compColor = getColor ();
	if (compColor != null)
	    scaledImage = getAdecWatt ().getIconDB ().getColoredScaledImages (scaledImage, compColor);
	Workspace.printImage (printGraphics, scaledImage, pos, size, thetaDegree, getTileSize ());
	double minSide = Math.min (size.width, size.height);
	Workspace.printText (printGraphics, getLabel (), getLabelColor (), pos, new DimensionDouble (minSide, minSide));
	for (String accId : getEmbeddedIds ())
	    try {
		Acc acc = findEmbedded (accId);
		acc.print (printGraphics, this);
		if (acc.getDirectUnit ().isDescendingFrom (plugId)) {
		    workspace.addPlugedComps (this);
		    allPlugs.add (acc);
		}
	    } catch (Exception e) {
	    }
    }

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