package com.danitheskunk.skunkworks.nodes;

import com.danitheskunk.skunkworks.Vec2f;
import com.danitheskunk.skunkworks.gfx.IRenderContext;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

//todo: figure out the whole translation position thingie

public class Node implements Iterable<Node> {
	protected final List<Node> children;
	protected Node parent;
	protected Vec2f pos;

	public Node() {
		children = new ArrayList<>();
		parent = null;
		pos = Vec2f.ZERO;
	}

	public void add(Node node) {
		if(node.parent != null) {
			throw new RuntimeException("Can't add node to two nodes");
		}
		node.parent = this;
		children.add(node);
	}

	public Vec2f getAbsolutePos() {
		if(parent == null) return pos;
		return Vec2f.add(parent.getAbsolutePos(), pos);
	}

	public int getCurrentFrame() {
		return getRoot().getCurrentFrame();
	}

	public Node getParent() {
		return parent;
	}

	public Vec2f getPos() {
		return pos;
	}

	public NodeRoot getRoot() {
		var node = this;
		while(node.parent != null) {
			node = node.parent;
		}
		//todo: check if right class
		return (NodeRoot) node;
	}

	@Override
	public Iterator<Node> iterator() {
		return children.iterator();
	}

	protected void prepareTween(BaseTween tween, int frames) {
		var root = getRoot();
		tween.startFrame = root.getCurrentFrame();
		tween.endFrame = tween.startFrame + frames;
	}

	public void remove(Node node) {
		node.parent = null;
		children.remove(node);
	}

	public void render(IRenderContext rc) {
		for(var child : this) {
			child.render(rc);
		}
	}

	public void setPos(Vec2f pos) {
		this.pos = pos;
	}

	public TweenPos tweenPos(Vec2f to, int frames) {
		var tween = new TweenPos();
		tween.start = pos;
		tween.end = to;
		prepareTween(tween, frames);
		getRoot().getTweener().add(tween);
		return tween;
	}


	public class TweenPos extends BaseTween {
		private Vec2f end;
		private Vec2f start;

		@Override
		protected void apply() {
			pos = Vec2f.tween(start, end, progress);
		}
	}
}
