package de.renew.gui.pnml.creator;

import java.awt.Color;
import java.awt.Point;

import org.w3c.dom.Element;

import CH.ifa.draw.framework.FigureWithID;
import de.renew.gui.ArcConnection;
import de.renew.gui.VirtualPlaceFigure;
import de.renew.gui.VirtualTransitionFigure;
import de.renew.gui.pnml.converter.Converter;
import de.renew.simulatorontology.shadow.ShadowArc;


/**
 * Creates PNML {@code arc} tags from an {@link ArcConnection} object.
 */
public class ArcCreator extends ObjectCreator {
    private VirtualPlaceFigure virPlaceStart = null;
    private VirtualPlaceFigure virPlaceEnd = null;

    private VirtualTransitionFigure virTransitionStart = null;
    private VirtualTransitionFigure virTransitionEnd = null;

    /**
     * Create an XMLCreator that parses Renew arcs
     */
    public ArcCreator(Converter converter) {
        super("arc", converter);
    }

    /**
     * Sets the arc's start to be a virtual place.
     * @param vir The place that is to be set as start.
     */
    public void setVirStart(VirtualPlaceFigure vir) {
        virPlaceStart = vir;
    }

    /**
     * Sets the arc's end to be a virtual place.
     * @param vir The place that is to be set as end.
     */
    public void setVirEnd(VirtualPlaceFigure vir) {
        virPlaceEnd = vir;
    }

    /**
     * Sets the arc's start to be a virtual transition.
     * @param vir The transition that is to be set as start.
     */
    public void setVirStart(VirtualTransitionFigure vir) {
        virTransitionStart = vir;
    }

    /**
     * Sets the arc's end to be a virtual tranisiton.
     * @param vir The tranistion that is to be set as end.
     */
    public void setVirEnd(VirtualTransitionFigure vir) {
        virTransitionEnd = vir;
    }

    /**
     * The ArcConnection returned is the figure saved with this object cast to an ArcConnection
     * @return an ArcConnection
     */
    protected ArcConnection getArc() {
        return (ArcConnection) getFigure();
    }

    /* (non-Javadoc)
     * @see de.renew.gui.pnml.ObjectCreator#doCreateAttribute()
     */
    @Override
    protected void doCreateAttribute(PNMLCreator pnmlCreator, Element element) {
        String attributeValue;
        switch (getArc().getArcType()) {
            case ShadowArc.BOTH:
                attributeValue = "both";
                break;
            case ShadowArc.INHIBITOR:
                attributeValue = "inhibitor";
                break;
            case ShadowArc.TEST:
                attributeValue = "test";
                break;
            case ShadowArc.DOUBLE_HOLLOW:
                attributeValue = "clear";
                break;
            case ShadowArc.DOUBLE_ORDINARY:
                attributeValue = "multi-ordinary";
                break;

            // case ShadowArc.ordinary:
            default:
                // Abort: don't store the ordinary type.
                // In the case of P/T nets no type attribute is allowed,
                // but since all P/T net arcs are ordinary, none will be added.
                return;
        }

        AttributeCreator creator = new AttributeCreator(pnmlCreator, "type");
        element.appendChild(creator.createElement(attributeValue));
    }

    /* (non-Javadoc)
     * @see de.renew.gui.pnml.ObjectCreator#doCreateGraphic(de.renew.gui.pnml.GraphicCreator)
     */
    @Override
    protected void doCreateGraphic(GraphicCreator creator) {
        int count = getArc().pointCount();
        for (int pos = 1; pos < count - 1; pos++) {
            Point p = getArc().pointAt(pos);
            creator.addPosition(p.x, p.y);
        }
        Color c = (Color) (getFigure()).getAttribute("FrameColor");
        creator.addLineColor(c);
        String s = (String) (getFigure()).getAttribute("LineStyle");
        creator.addLineStyle(s);
        creator.addLine();
    }

    /* (non-Javadoc)
     * @see de.renew.gui.pnml.ObjectCreator#doCreateObject()
     */
    @Override
    protected void doCreateObject(PNMLCreator pnmlCreator, Element element) {
        FigureWithID source = (FigureWithID) getArc().startFigure();
        FigureWithID target = (FigureWithID) getArc().endFigure();

        element.setAttribute("source", xmlID(source));
        element.setAttribute("target", xmlID(target));

        if (virPlaceStart != null || virPlaceEnd != null || virTransitionStart != null
            || virTransitionEnd != null) {
            Element toolSpecific = pnmlCreator.createToolspecific();

            if (virPlaceStart != null) {
                toolSpecific.setAttribute("source", xmlID(virPlaceStart));
            }
            if (virPlaceEnd != null) {
                toolSpecific.setAttribute("target", xmlID(virPlaceEnd));
            }
            if (virTransitionStart != null) {
                toolSpecific.setAttribute("source", xmlID(virTransitionStart));
            }
            if (virTransitionEnd != null) {
                toolSpecific.setAttribute("target", xmlID(virTransitionEnd));
            }

            element.appendChild(toolSpecific);
        }
    }
}