#include "Player.h"
#include "List.h"
#include "Command.h"
#include "CommandManager.h"
#include "glfuncs.h"
#include "Control.h"
#include "Screen.h"
#include "Weapon.h"
#include "Level.h"

#include <sstream>

using namespace std;

Player::Player(List * playerInfo, int x, int y)
:Person(playerInfo,x,y), _secondaryWeapon(NULL),_cDWait(30),_cDTime(30)
{
	//_secondaryWeapon = new Weapon("weapons/shotGun.txt",this);

	_depth = 2;
	_type = PLAYER;
}

Player::~Player()
{
	delete _secondaryWeapon;
}

void Player::collide(Object *o)
{
	Person::collide(o);
	if(o->getType() == BOSS && _cDTime > _cDWait) {
		AddHealthCommand(this,-2).execute();
		_cDTime = 0;
	}
}

void Player::die()
{
	Person::die();
	Level::instance()->setScore(Level::instance()->getScore()/2);
}

Object *Player::copy()
{
	Player *copy = new Player(*this);
	if(_primaryWeapon)
		copy->_primaryWeapon = _primaryWeapon->copy(copy);
	if(_punchWeapon)
		copy->_punchWeapon = _punchWeapon->copy(copy);
	if(_secondaryWeapon)
		copy->_secondaryWeapon = _secondaryWeapon->copy(copy);
	return copy;
}

void Player::addSecondary(std::string filename)
{
	Weapon* newSecondary = new Weapon(filename, this);
	if(_secondaryWeapon) {

		if(_secondaryWeapon->id() == newSecondary->id()) {
			_secondaryWeapon->addAmmo(newSecondary->getAmmo());
			delete newSecondary;
		}
		else {
			delete _secondaryWeapon;
			_secondaryWeapon = newSecondary;
		}
	}
	else
		_secondaryWeapon = newSecondary;
}

void Player::shootSecondary()
{
	if(_secondaryWeapon)
		_secondaryWeapon->shoot();
}

SDL_Rect Player::drawSecondaryAmmo(SDL_Rect raster)
{
	if(_secondaryWeapon)
		return _secondaryWeapon->drawAmmo(raster);

	return raster;
}

// FIXME: Take this out.
int saveTimer = 20;

void Player::update()
{
	Person::update();

	if(_secondaryWeapon) {
		_secondaryWeapon->update();

		if(_secondaryWeapon->getAmmo() == 0) {
			delete _secondaryWeapon;
			_secondaryWeapon = NULL;
		}
	}
	saveTimer++;
	_cDTime++;
}

void Player::control()
{
	Uint8 *keystates = SDL_GetKeyState( NULL );

	//SAVE DEMO BUTTON
	//if(keystates[SDLK_s])
	//{
	//	CommandManager::instance()->saveRecording("scripts/newDemo.txt");
	//}
	if(keystates[Control::leftKey])
	{
		CommandManager::instance()->execute(new MoveCommand(this,LEFT));
	}
	if(keystates[Control::rightKey])
	{
		CommandManager::instance()->execute(new MoveCommand(this,RIGHT));
	}

	// Jumping
	if(keystates[Control::jumpKey])
	{
		CommandManager::instance()->execute(new JumpCommand(this,_xDirection));
	
		//Keep the jump key state around so you can't jump by just holding the key
		
		//CommandManager::instance()->execute(new PlaySoundCommand("beat.wav"));
	}
	if(!keystates[Control::jumpKey])
		//Reset the jump keystate as soon as we poll and see that the key is no longer held.
		CommandManager::instance()->execute(new JumpResetCommand(this));
		
	
	//if neither are pressed, or we're crouching, we should be shooting left and right
	if( ((!keystates[Control::upKey])&&(!keystates[Control::downKey]))||
		( _crouching ))
		
		CommandManager::instance()->execute(new AimCommand(this,MIDDLE));

	//if up only, shoot up, or if you're holding both up and down, since you'll
	// be crouched soon and thats the only thing that makes any sense if you press
	// both up and down at the same time
	if(  keystates[Control::upKey] || 
		(keystates[Control::downKey] && keystates[Control::upKey]) )
		CommandManager::instance()->execute(new AimCommand(this,UP));

	//if down only, shoot down, unless crouching
	if(!_crouching && keystates[Control::downKey])
		CommandManager::instance()->execute(new AimCommand(this,DOWN));

	// Shooting
	if( keystates[Control::shoot2Key ] || keystates[ Control::shoot1Key] )
	{
		//CommandManager::instance()->execute(new AimCommand(this,DOWN));
		CommandManager::instance()->execute(new ShootCommand(this));
	}

	else if( keystates[ Control::altShoot1Key ] || keystates[ Control::altShoot2Key ] )
	{
		CommandManager::instance()->execute(new SecondaryShootCommand(this));
	}

	// Crouching
	if( _crouching && !keystates[ Control::downKey ] )
	{
		CommandManager::instance()->execute( new CrouchCommand( this, false ) );
	}
	if( keystates[ Control::downKey ] && !_crouching )
	{
		CommandManager::instance()->execute( new CrouchCommand( this, true ) );
	}

	if( keystates[ SDLK_q ] && saveTimer > 20 ) {
		CommandManager::instance()->startRecording();
		CommandManager::instance()->execute(new StopPersonCommand(this));
		CommandManager::instance()->execute(new SetPositionCommand(this,29*32, 31*32));
		saveTimer = 0;
	}
	if( keystates[ SDLK_w ] && saveTimer > 20 ) {
		CommandManager::instance()->saveRecording("demo.txt");
		CommandManager::instance()->stopRecording();
		saveTimer = 0;
	}
}

void Player::addHealth(int dHealth)
{
	if( _health >= MAXHEALTH && dHealth > 0 )
		return;
	else
		Person::addHealth( dHealth );
}
