#include "globals.h"
#include "Player.h"

const float LANDING_DIST = 2;
const float VELOCITY = 250.0f;

const int INITIAL_LIVES = 3;

Player::Player(scene::ISceneManager* smgr, Entity* targetEnt)
: Entity(smgr, core::position2df(0,0)), draggingConnection(NULL), lives(INITIAL_LIVES)
{
	playerFly = device->getVideoDriver()->getTexture("../data/img/player.png");
	playerLanded = device->getVideoDriver()->getTexture("../data/img/playerlanded.png");
	sceneNode->setMaterialTexture(0, playerLanded);
	sceneNode->setScale(core::vector3df(0.5f, 0.5f, 0.5f));
	repulsiveForce = 0;
	landed = true;
	this->targetEnt = targetEnt;
}

Player::~Player()
{
}

void Player::update(float deltaTime)
{
	if (!targetEnt)
	{
		return;
	}
	else if (!landed)
	{
		// Pull towards target
		clearForce();
		core::vector2df f = targetEnt->getPos() - pos;
		if (VELOCITY*VELOCITY * deltaTime*deltaTime <= f.getLengthSQ())
		{
			f.normalize();
			setPos(getPos() + f * VELOCITY * deltaTime);
		}
		else
		{
			// Snap!
			landed = true;
		}

		// If close enough to target, land on it
		if (pos.getDistanceFromSQ(targetEnt->getPos()) < LANDING_DIST*LANDING_DIST)
		{
			landed = true;
		}
	}

	if (landed)
	{
		// Landed on target, so follow it around
		calcNewPos(0); // just to update the old position
		setPos(targetEnt->getPos());

		// Connect connection to new target entity
		if (draggingConnection)
		{
			draggingConnection->setTo(targetEnt);
			draggingConnection->startConstraining();
		}
	}

	if (landed)
	{
		sceneNode->setMaterialTexture(0, playerLanded);
	}
	else
	{
		sceneNode->setMaterialTexture(0, playerFly);
	}
}

Connection* Player::setTarget(Entity* newTarget)
{
	if (!targetEnt)
	{
		// Setting for first time
		targetEnt = newTarget;
		landed = true;
		return NULL;
	}
	if (landed && targetEnt != newTarget)
	{
		if (newTarget != NULL)
			draggingConnection = new Connection(device->getSceneManager(), targetEnt, this, false);
		targetEnt = newTarget;
		landed = false;
		if (newTarget != NULL)
			return draggingConnection;
	}
	return NULL;
}

void Player::die()
{
	--lives;
	if (draggingConnection)
	{
		targetEnt = draggingConnection->from;
	}
	landed = true;
}


void Player::reset()
{
	lives = INITIAL_LIVES;
}