package net.alcuria.umbracraft.engine.entities;

import net.alcuria.umbracraft.definitions.component.ComponentDefinition;
import net.alcuria.umbracraft.engine.components.Component;

import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;

/** A top-level game object. Players, enemies, decorations, and so on, all should
 * be instantiated as GameObjects with logic separated out in the
 * {@link Component}.
 * @author Andrew Keturi */
public class Entity implements BaseEntity, Comparable<Entity> {

	public static final String PLAYER = "Player";

	// TODO: instead of passing a reference to the entity in our components, do something more sophisticated so all components don't have read/write access to these?
	private final Array<Component> components;
	private String name;
	public boolean onGround = true;
	public Vector3 position;
	public Vector3 velocity;

	/** Creates an entity with no components */
	public Entity() {
		components = new Array<Component>();
		position = new Vector3();
		velocity = new Vector3();
	}

	/** Creates an entity with several pre-defined components
	 * @param components the initial components */
	public Entity(Component... components) {
		this();
		for (Component component : components) {
			component.create(this);
			this.components.add(component);
		}
	}

	/** Adds a single component after instantiation
	 * @param component the component to add */
	public void addComponent(Component component) {
		component.create(this);
		components.add(component);
	}

	/** Adds a component from a definition
	 * @param definition */
	public void addComponent(ComponentDefinition definition) {
		addComponent(definition.create());
	}

	@Override
	public int compareTo(Entity arg0) {
		return (int) (arg0.position.y - position.y);
	}

	/** Disposes/kills all components */
	public void dispose() {
		for (int i = 0; i < components.size; i++) {
			components.get(i).dispose(this);
		}
	}

	/** Gets a component
	 * @param clazz the component type
	 * @return the component */
	public <T extends Component> T getComponent(Class<T> clazz) {
		for (int i = 0; i < components.size; i++) {
			if (clazz.isInstance(components.get(i))) {
				return (T) components.get(i);
			}
		}
		return null;
	}

	/** @return the name */
	public String getName() {
		return name;
	}

	/** Removes a component
	 * @param clazz the component type */
	public void removeComponent(Class<? extends Component> clazz) {
		for (Component component : components) {
			if (clazz.isInstance(component)) {
				components.removeValue(component, true);
				return;
			}
		}
	}

	/** Renders all components */
	@Override
	public void render() {
		for (int i = 0; i < components.size; i++) {
			components.get(i).render(this);
		}
	}

	/** @param name the name to set */
	public void setName(String name) {
		this.name = name;
	}

	/** Updates all components
	 * @param delta time since last update */
	@Override
	public void update() {
		for (int i = 0; i < components.size; i++) {
			components.get(i).update(this);
		}
	}
}

@@ -42,16 +42,52 @@
 ities;%0A%0A
+import net.alcuria.umbracraft.Game;%0A
 import n
@@ -151,16 +151,16 @@
 nition;%0A
-
 import n
@@ -602,171 +602,8 @@
 %22;%0A%0A
-%09// TODO: instead of passing a reference to the entity in our components, do something more sophisticated so all components don't have read/write access to these?%0A
 %09pri
@@ -1181,24 +1181,190 @@
 t);%0A%09%09%7D%0A%09%7D%0A%0A
+%09/** Creates an entity with no components and a given name%0A%09 * @param name the name %7B@link String%7D */%0A%09public Entity(String name) %7B%0A%09%09this();%0A%09%09this.name = name;%0A%09%7D%0A%0A
 %09/** Adds a 
@@ -2849,24 +2849,24 @@
 ing name) %7B%0A
-
 %09%09this.name 
@@ -2873,24 +2873,321 @@
 = name;%0A%09%7D%0A%0A
+%09/** Sets the position vector equal to the value of another vector%0A%09 * @param position a %7B@link Vector3%7D */%0A%09public void setPosition(Vector3 position) %7B%0A%09%09if (position == null) %7B%0A%09%09%09Game.error(%22position is null%22);%0A%09%09%09return;%0A%09%09%7D%0A%09%09this.position.x = position.x;%0A%09%09this.position.y = position.y;%0A%09%7D%0A%0A
 %09/** Updates

Add setters for position