#include <iostream>

#include "EntityFactoryBase.h"

#include "EntityBase.h"
#include "coll2d.h"

namespace Engine {

int EntityFactoryBase::OnInit (int argc, char* argv[]) {
	LogMessage ("Initializing EntityFactory");

	return 0;
}

EntityPhysicState* EntityFactoryBase::CreateEntityPhysicState (int type) {
	// In this simple factory the type is simply seen as the EntityBaseType.
	// However to prevent errors we do a simple check vor validity.
	if (type < 0 || type >> EntityBaseTypeLast ) {
		LogError ("Cannot create Entity with type %d: invalid type!", type);
	}
	EntityBaseType base_type = (EntityBaseType) type;

	// Create the Entity
	EntityPhysicState* entity_physics = new EntityPhysicState ();
	if (!entity_physics) {
		LogError ("Could not allocate enough memory for EntityPhysicState of type '%d'", type);
	}

	// default values for all entities
	entity_physics->mBaseType = base_type;

  // specific values for each Entity base_type
	if (base_type == EntityBaseTypeNone) {
		entity_physics->mShape = new coll2d::Sphere (0.01);
		assert (entity_physics->mShape);
	} else if (base_type == EntityBaseTypeActor) {
		entity_physics->mShape = new coll2d::Sphere (0.4);
		assert (entity_physics->mShape);
	} else if (base_type == EntityBaseTypeBlock) {
		entity_physics->mShape = new coll2d::Polygon (4);
		assert (entity_physics->mShape);

		static_cast<coll2d::Polygon*> (entity_physics->mShape)->setVertice (0, vector3d (-0.5, 0., 0.5));
		static_cast<coll2d::Polygon*> (entity_physics->mShape)->setVertice (1, vector3d (0.5, 0., 0.5));
		static_cast<coll2d::Polygon*> (entity_physics->mShape)->setVertice (2, vector3d (0.5, 0., -0.5));
		static_cast<coll2d::Polygon*> (entity_physics->mShape)->setVertice (3, vector3d (-0.5, 0., -0.5));
	} else if (base_type == EntityBaseTypeParticle) {
		entity_physics->mShape = new coll2d::Sphere (0.05);
		assert (entity_physics->mShape);
	} else {
		LogError ("No EntityPhysicState defined for Entity base_type '%d'", base_type);
	}

	return entity_physics;
}

EntityControllerState* EntityFactoryBase::CreateEntityControllerState (int type) {
	// In this simple factory the type is simply seen as the EntityBaseType.
	// However to prevent errors we do a simple check vor validity.
	if (type < 0 || type >> EntityBaseTypeLast ) {
		LogError ("Cannot create Entity with type %d: invalid type!", type);
	}
	EntityBaseType base_type = (EntityBaseType) type;

	// Create the Entity
	EntityControllerState* entity_controller = NULL;

	// specific values for each Entity base_type
	if (base_type == EntityBaseTypeNone) {
	} else if (base_type == EntityBaseTypeActor) {
		entity_controller = new EntityControllerState ();
		if (!entity_controller) {
			LogError ("Could not allocate enough memory for EntityControllerState of type '%d'", type);
		}
	} else if (base_type == EntityBaseTypeBlock) {
	} else if (base_type == EntityBaseTypeParticle) {
	} else {
		LogError ("No EntityPhysicState defined for Entity base_type '%d'", base_type);
	}

	return entity_controller;
}

EntityBase* EntityFactoryBase::CreateEntity (int type) {
	// In this simple factory the type is simply seen as the EntityBaseType.
	// However to prevent errors we do a simple check vor validity.
	if (type < 0 || type >> EntityBaseTypeLast ) {
		LogError ("Cannot create Entity with type %d: invalid type!", type);
	}
	EntityBaseType base_type = (EntityBaseType) type;

	// Create the Entity
	EntityBase *entity = new EntityBase;
	entity->mBaseType = base_type;

	if (!entity) {
		LogError ("Could not allocate enough memory for EntityVisualState of type '%d'", type);
	}

	entity->mPhysicState = CreateEntityPhysicState (type);
	entity->mControllerState = CreateEntityControllerState (type);

	return entity;
}

}


