//	PlayerBehaviour.cpp - The behaviour for the player-controlled Prole.
//  ----------------------------------------------------------------------------
//	This file is part of 'The Future Will Only Be Dystopian if Capitalism
//	Remains Undefeated', a game.
//	Copyright (C) 2009  Niall Moody
//	
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
//	----------------------------------------------------------------------------

#include "PlayerBehaviour.h"
#include "states/GamePlay.h"

#include <cmath>
#include <vector>

using namespace std;

//------------------------------------------------------------------------------
PlayerBehaviour::PlayerBehaviour():
leftIsDown(false),
rightIsDown(false),
upIsDown(false),
downIsDown(false),
doAction(false)
{
	
}

//------------------------------------------------------------------------------
PlayerBehaviour::~PlayerBehaviour()
{
	
}

//------------------------------------------------------------------------------
void PlayerBehaviour::act(Prole *p, GamePlay *gp)
{
	int i;
	float xDir, yDir;
	float x = p->getX();
	float y = p->getY();
	vector<Prole *>& neighbours = p->getNeighbours();
	float neighbourSlow = 1.0f/(((float)neighbours.size()/8.0f)+1.0f);

	//Make sure the Prole is red.
	p->setColour(1.0f, 0.0f, 0.0f);
	p->setLifeFade(true);
	p->setTrail(false);

	if(neighbourSlow < 0.35f)
		neighbourSlow = 0.35f;

	neighbourSlow = 1.0f;

	//First update the player's position.
	if(leftIsDown && !rightIsDown)
	{
		x -= 3.0f * p->getLife() * neighbourSlow;
		xDir = -1.0f;
	}
	else if(rightIsDown && !leftIsDown)
	{
		x += 3.0f * p->getLife() * neighbourSlow;
		xDir = 1.0f;
	}
	if(upIsDown && !downIsDown)
	{
		y -= 3.0f * p->getLife() * neighbourSlow;
		yDir = -1.0f;
	}
	else if(downIsDown && !upIsDown)
	{
		y += 3.0f * p->getLife() * neighbourSlow;
		yDir = 1.0f;
	}

	if(x < 0.0f)
		x = 0.0f;
	else if(x > (1024.0f-32.0f))
		x = 1024.0f-32.0f;
	if(y < 0.0f)
		y = 0.0f;
	else if(y > (768.0f-32.0f))
		y = 768.0f-32.0f;

	p->setPosition(x, y);
	p->setDirection(xDir, yDir);

	//Then try and convince a nearby Prole if necessary.
	if(doAction)
	{
		float dist;
		float pX, pY;
		Prole *proles = gp->getProles();

		//Convince Prole.
		for(i=0;i<GamePlay::NumProles;++i)
		{
			if(&(proles[i]) != p)
			{
				pX = proles[i].getX() - x;
				pY = proles[i].getY() - y;
				dist = sqrtf((pX*pX) + (pY*pY));
				if(dist < 32.0f)
				{
					neighbours.push_back(&(proles[i]));
					proles[i].convince(p, gp);
				}
			}
		}

		doAction = false;
	}
}

//------------------------------------------------------------------------------
void PlayerBehaviour::keyDown(const SDL_keysym& keyPressed)
{
	if(keyPressed.sym == SDLK_UP)
		upIsDown = true;
	else if(keyPressed.sym == SDLK_DOWN)
		downIsDown = true;
	else if(keyPressed.sym == SDLK_LEFT)
		leftIsDown = true;
	else if(keyPressed.sym == SDLK_RIGHT)
		rightIsDown = true;
	else
		doAction = true;
}

//------------------------------------------------------------------------------
void PlayerBehaviour::keyUp(const SDL_keysym& keyPressed)
{
	if(keyPressed.sym == SDLK_UP)
		upIsDown = false;
	else if(keyPressed.sym == SDLK_DOWN)
		downIsDown = false;
	else if(keyPressed.sym == SDLK_LEFT)
		leftIsDown = false;
	else if(keyPressed.sym == SDLK_RIGHT)
		rightIsDown = false;
}
