// #include "Engine.h"

#include "Game.h"
#include "Controller.h"
#include "Model.h"
#include "EntityBase.h"
#include "EventBase.h"

#include "Controller.h"
#include "ShipEntity.h"

#include "AsteroidsEvents.h"

namespace asteroids {

static Controller *ControllerInstance = NULL;

/* +forward */
bool Cmd_ControllerForwardDown (std::vector<std::string> args) {
	assert (ControllerInstance);

	// only continue if the game is running
	if (GetModel()->GetGameState() != GameStateRunning)
		return false;

	Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
	if (player_entity) {
		player_entity->SetControllerKeyState (EntityKeyStateForward);

		Engine::EventBasePtr forward_event (new Engine::EventBase());
		forward_event->mEventType = EventAccelerateStart;
		QueueEvent (forward_event);

		return true;
	}

	return false;
}

/* -forward */
bool Cmd_ControllerForwardUp (std::vector<std::string> args) {
	assert (ControllerInstance);

	// only continue if the game is running
	if (GetModel()->GetGameState() != GameStateRunning)
		return false;

	Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
	if (player_entity) {
		player_entity->UnsetControllerKeyState (EntityKeyStateForward);

		Engine::EventBasePtr forward_event (new Engine::EventBase());
		forward_event->mEventType = EventAccelerateStop;
		QueueEvent (forward_event);

		return true;
	}

	return false;
}

/* +turnleft */
bool Cmd_ControllerTurnLeftDown (std::vector<std::string> args) {
	assert (ControllerInstance);

	// only continue if the game is running
	if (GetModel()->GetGameState() != GameStateRunning)
		return false;

	Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
	if (player_entity) {
		player_entity->SetControllerKeyState (EntityKeyStateTurnLeft);
		return true;
	}

	return false;
}

/* -turnleft */
bool Cmd_ControllerTurnLeftUp (std::vector<std::string> args) {
	assert (ControllerInstance);

	// only continue if the game is running
	if (GetModel()->GetGameState() != GameStateRunning)
		return false;

	Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
	if (player_entity) {
		player_entity->UnsetControllerKeyState (EntityKeyStateTurnLeft);
		return true;
	}

	return false;
}

/* +turnright */
bool Cmd_ControllerTurnRightDown (std::vector<std::string> args) {
	assert (ControllerInstance);

	// only continue if the game is running
	if (GetModel()->GetGameState() != GameStateRunning)
		return false;

	Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
	if (player_entity) {
		player_entity->SetControllerKeyState (EntityKeyStateTurnRight);
		return true;
	}

	return false;
}

/* -turnright */
bool Cmd_ControllerTurnRightUp (std::vector<std::string> args) {
	assert (ControllerInstance);

	// only continue if the game is running
	if (GetModel()->GetGameState() != GameStateRunning)
		return false;

	Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
	if (player_entity) {
		player_entity->UnsetControllerKeyState (EntityKeyStateTurnRight);
		return true;
	}

	return false;
}

/* attack */
bool Cmd_ControllerAttack (std::vector<std::string> args) {
	assert (ControllerInstance);

	// only continue if the game is running
	if (GetModel()->GetGameState() != GameStateRunning) {
		Engine::LogDebug ("Not running attack as game is not running");
		return false;
	}

	ShipEntity* player_entity = (ShipEntity*) Engine::GetEntity (Engine::GetPlayerEntityId ());
	if (player_entity) {
		player_entity->Attack ();
		return true;
	}
	
	return false;
}

void Controller::OnRegisterCommands () {
	ControllerBase::OnRegisterCommands ();

	ControllerInstance = this;

	Engine::AddCommand ("+forward", Cmd_ControllerForwardDown);
	Engine::AddCommand ("-forward", Cmd_ControllerForwardUp);

	Engine::AddCommand ("+turnleft", Cmd_ControllerTurnLeftDown);
	Engine::AddCommand ("-turnleft", Cmd_ControllerTurnLeftUp);
	Engine::AddCommand ("+turnright", Cmd_ControllerTurnRightDown);
	Engine::AddCommand ("-turnright", Cmd_ControllerTurnRightUp);

	Engine::AddCommand ("attack", Cmd_ControllerAttack);
}

}
