package ecs.core;

using Type;

class Entity {
	private static var nextID:Int = 1;

	public final name:String;
	public final id:Int;

	public final components:Map<String, Component> = [];

	@:allow(ecs)
	private var engine:Engine;

	public function new(?name:String) {
		id = nextID++;
		this.name = name;
	}

	public static function of(...components:Component) {
		var entity = new Entity();

		for (component in components) {
			entity.add(component);
		}

		return entity;
	}

	public function add(component:Component) {
		final className = component.getClass().getClassName();
		components[className] = component;

		if (engine != null)
			engine.rematch(this);

		return component;
	}

	public function get<T>(componentClass:Class<T>):T {
		return cast components[componentClass.getClassName()];
	}

	public function has(component:Class<Component>):Bool {
		return components.exists(component.getClassName());
	}

	public function hasComponents(query:Array<Class<Component>>):Bool {
		for (component in query) {
			if (!has(component))
				return false;
		}

		return true;
	}

	public function remove(component:Component) {
		final className = component.getClass().getClassName();
		if (components.exists(className)) {
			components.remove(className);

			if (engine != null)
				engine.rematch(this);
		}
	}

	public function matchSystem(system:System) {
		return hasComponents(system.components);
	}
}
