package at.oefai.aaa.animation;

import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGPoint;
import org.w3c.dom.svg.SVGSVGElement;

/**
 * SVG anim for Using the key on an object, possible opening the treasure.
 * @author Stefan Rank
 */
public class UseKeyOnObject extends BaseSVGAnim {
    private static final float ANIM_DISTANCE_FACTOR = 0.75f; // how far to slide the key towards object
    private static final float ROTATION_STEP_DEGREES = 45f; // starting rotation
    private String theObject = null;
    private String theTarget = null;
    private volatile boolean done = false;
    private boolean reversed = false;
    private SVGPoint dest = null;
    private SVGPoint origPos = null;
    private float rotation = 0f;

    public BaseAnim newInstance() { return new UseKeyOnObject(); }

    protected void doFirstTime() {
        assert (this.args.size() == 2) : "wrong arguments for UseKeyOnObject";
        this.theObject = this.args.get(0).getString();
        // get the target objects pos:
        this.theTarget = this.args.get(1).getString();
        SVGSVGElement eleTarget = getNamedElement(this.theTarget);
        this.dest = getElementsPos(eleTarget);
        if (this.dest == null) {
            this.dest = this.svgDoc.getRootElement().createSVGPoint();
            this.done = true;
        } else {
            // get the objects absolute pos
            SVGSVGElement eleObject = getNamedElement(this.theObject);
            this.origPos = getElementsPos(eleObject);
            SVGPoint curr = getElementsDocumentPos(eleObject);
            if (curr == null || this.origPos == null) {
                assert false : "could not get key position";
                this.done = true;
            } else {
                // calculate the direction vector in dest
                this.dest.setX(this.dest.getX() - curr.getX());
                this.dest.setY(this.dest.getY() - curr.getY());
                // rotation of the sword ? (starting rotation = degrees constant)
                this.rotation = (float) Math.toDegrees(Math.atan2(this.dest.getY(), this.dest.getX()))
                                        + ROTATION_STEP_DEGREES;
                setElementsRotate(eleObject, this.rotation);
                // calculate the destination point (object local coords) in dest
                this.dest.setX(this.origPos.getX() + ANIM_DISTANCE_FACTOR * this.dest.getX());
                this.dest.setY(this.origPos.getY() + ANIM_DISTANCE_FACTOR * this.dest.getY());
                // change the sword to active ???
            }
        }
    }



    public boolean isFinished() {
        return this.done;
    }

    protected void doIt() {
        // move the object if it is still away from the destination
        SVGSVGElement eleObject = getNamedElement(this.theObject);
        SVGPoint curr = getElementsPos(eleObject);
        if (curr == null) {
            this.done = true;
        } else {
            SVGPoint nextPos = getNextObjectPos(curr, this.dest);
            if (nextPos == this.dest) {
                if (this.reversed) {
                    this.done = true;
                    setElementsRotate(eleObject, 0f);
                    // change the treasure to active (open)
                    Element ele = showElement(this.theTarget + "Active");
                    if (ele == null) {
                        showTextElement(this.theTarget, "Active", 0f);
                    }
                    hideElement(this.theTarget + "Inactive");
                } else { // not reversed yet...
                    this.reversed = true;
                    this.dest = this.origPos;
                }
            }
            setElementsPos(eleObject, nextPos);
        }

    }
}
