package ac.essex.ooechs.treeanimator;

import java.util.Vector;
import java.awt.*;

public class AnimatedNode {

    static Vector<AnimatedNode> nodes = new Vector<AnimatedNode>();

    public static final int size = 60;

    public int depth = -1;

    public int x, y;

    public double currentX = -1, currentY = -1;

    public boolean drawConnection = false;

    public boolean visible = true;

    protected String name;

    protected Vector<AnimatedNode> children;

    public AnimatedNode parent = null;

    public AnimatedNode(String name) {
        this.name = name;
        children = new Vector<AnimatedNode>();
        nodes.add(this);
    }

    public static Vector<AnimatedNode> getNodesByDepth(int depth) {
        Vector<AnimatedNode> depthNodes = new Vector<AnimatedNode>();
        for (int i = 0; i < nodes.size(); i++) {
            AnimatedNode node = nodes.elementAt(i);
            if (node.depth == depth) {
                depthNodes.add(node);
            }
        }
        return depthNodes;
    }

    public boolean isLeafNode() {
        return children.size() == 0;
    }


    public static Vector<AnimatedNode> getLeafNodes() {
        Vector<AnimatedNode> leafNodes = new Vector<AnimatedNode>();
        for (int i = 0; i < nodes.size(); i++) {
            AnimatedNode node = nodes.elementAt(i);
            if (node.isLeafNode()) {
                leafNodes.add(node);
            }
        }
        return leafNodes;
    }

    public static int getDeepestNodeDepth() {
        int deepest = 1;
        for (int i = 0; i < nodes.size(); i++) {
            AnimatedNode node = nodes.elementAt(i);
            if (node.depth > deepest) {
                deepest = node.depth;
            }
        }
        return deepest;
    }

    public void add(AnimatedNode child) {
        children.add(child);
        child.parent = this;
    }

    public void calculateDepths() {
        this.depth = 1;
        for (int i = 0; i < children.size(); i++) {
            AnimatedNode node = children.elementAt(i);
            calculateDepths(node, this.depth + 1);
        }
    }



    private void calculateDepths(AnimatedNode child, int depth) {
        child.depth = depth;
        for (int i = 0; i < child.children.size(); i++) {
            AnimatedNode node = child.children.elementAt(i);
            calculateDepths(node, depth + 1);
        }
    }

    public Vector<AnimatedNode> getChildren() {
        return children;
    }

    public String getName() {
        return name;
    }

    public void draw(Graphics g) {

        if (visible) {

        final int halfSize = size / 2;

        int centerX = ((int) currentX) - halfSize;
        int centerY = ((int) currentY) - halfSize;

        g.setColor(new Color(0, 0, 0, 70));
        g.fillOval(centerX + 1, centerY + 3, size, size);

        g.setColor(new Color(186,215, 252));
        g.fillOval(centerX, centerY, size, size);

        g.setColor(Color.GRAY);
        g.drawOval(centerX, centerY, size, size);

        int textWidth = g.getFontMetrics().stringWidth(name);
        int textHeight = g.getFontMetrics().getHeight();

        g.setColor(Color.BLACK);
        g.drawString(name, (int) (currentX - (textWidth / 2)), (int) (currentY + (textHeight / 2) - 2));

        }

    }

    public AnimatedNode getFirstChild() {
        return children.firstElement();
    }

    public AnimatedNode getLastChild() {
        return children.lastElement();
    }

    public boolean inPosition() {
        return ((x - currentX < 1) && (y - currentY < 1));
    }

    private double mx;
    private double my;

    public void calculateVector(int frames) {
        mx = (x - currentX) / frames;
        my = (y - currentY) / frames;
    }

    public void move() {
        currentX += mx;
        currentY += my;
        /*if (currentX < x) currentX++;
        if (currentY < y) currentY++;
        if (currentX > x) currentX--;
        if (currentY > y) currentY--;*/
    }

    public void moveToPosition() {
        currentX = x;
        currentY = y;
    }

    public void moveToParentPosition() {
        currentX = parent.x;
        currentY = parent.y;
    }

}
