
#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#include <assert.h>
#include <cmath>
#include <iostream>

//---------------------------------------------------------------------

#include <GlobalDevice.h>
#include <Player.h>

//---------------------------------------------------------------------

Player::Player():node(NULL), shadow(NULL)
{
	vector3df previousPos = vector3df(0.f, 0.f, 0.f);
	vector3df previousAngle = vector3df(0.f, 0.f, 0.f);
	if (node != NULL)
	{
		previousPos = node->getPosition();
		previousAngle = node->getRotation();
		node->remove();
	}
	node = GlobalDevice::loadAnimatedNodeFromMeshFile("data/robot1.3ds");	
	shadow = node->addShadowVolumeSceneNode(0, -1, false);
	node->setPosition(previousPos);
	node->setRotation(previousAngle);
	//shadow->setMaterialFlag(video::EMF_ZBUFFER, false);
	//node->setDebugDataVisible(irr::scene::EDS_BBOX);
	
	//node->setVisible(false);
}

//---------------------------------------------------------------------

void Player::manage(const GameObjectVector& gameObjects)
{
	float period = GlobalDevice::getFrameDuration();
	if (GlobalDevice::getEventManager()->keys[KEY_F2] && shadow != NULL) {shadow->setVisible(false);}
	if (GlobalDevice::getEventManager()->keys[KEY_F3] && shadow != NULL) {shadow->setVisible(true);}
	
	if (GlobalDevice::getEventManager()->keys[KEY_LEFT])
		node->setRotation(node->getRotation() + vector3df(0.f, -(GlobalDevice::getEventManager()->keys[KEY_DOWN]?-1.f:1.f)* 80.f*period, 0.f));
	else if (GlobalDevice::getEventManager()->keys[KEY_RIGHT])
		node->setRotation(node->getRotation() + vector3df(0.f, (GlobalDevice::getEventManager()->keys[KEY_DOWN]?-1.f:1.f)*80.f*period, 0.f));
	
	float angleRadians = (-node->getRotation().Y -90.f ) * 3.14159265f/180.f;

	if (GlobalDevice::getEventManager()->keys[KEY_UP])
	{
		vector3df newpos = node->getPosition() + vector3df(-30.f*period*cos(-angleRadians),0.f,-20.f*period*sin(angleRadians));
		vector3df testpos = node->getPosition() + vector3df(-30.f*10.f*period*cos(-angleRadians),0.f,-20.f*10.f*period*sin(angleRadians));
		if (!isColliding(newpos, gameObjects) && !isColliding(testpos, gameObjects))
			node->setPosition(newpos);
	}
	else if (GlobalDevice::getEventManager()->keys[KEY_DOWN])
	{
		vector3df newpos = node->getPosition() + vector3df(30.f*period*cos(-angleRadians),0.f,20.f*period*sin(angleRadians));
		vector3df testpos = node->getPosition() + vector3df(30.f*10.f*period*cos(-angleRadians),0.f,20.f*10.f*period*sin(angleRadians));
		if (!isColliding(newpos, gameObjects) && !isColliding(testpos, gameObjects))
			node->setPosition(newpos);
	}
}

//---------------------------------------------------------------------

bool Player::isColliding(const vector3df& pos, const GameObjectVector& gameObjects)
{
	if (pos.X < -93.f || pos.X > 93.f || pos.Z < -25 || pos.Z > 75) return true;
	if ((pos.X < -80.f || pos.X > 80.f) && pos.Z > 60) return true;

	for (GameObjectVector::const_iterator it = gameObjects.begin(); it != gameObjects.end(); it++)
		if ((*it)!=NULL && (*it)->isCollidingPos(node->getBoundingBox(), pos))
			return true;
	return false;
}

//---------------------------------------------------------------------

vector3df Player::getDirectionVector() const
{
	float angleRadians = (-node->getRotation().Y -90.f ) * 3.14159265f/180.f;
	return vector3df(-cos(angleRadians), 0.f, -sin(angleRadians));
}

//---------------------------------------------------------------------

Player::~Player()
{
	node->remove();
}

//---------------------------------------------------------------------
