#include "bullet.h"
#include "collisionhandler.h"
#include "level.h"
#include "Screen.h"
#include "Command.h"
#include "CommandManager.h"

#include <iostream>

using namespace std;


Bullet::Bullet( Person* shooter, int bulletSpeed, int damage, int which )
: _shooter( shooter ),
  _xVelocity( 0 ),
  _yVelocity( 0 ),
  _xDirection( shooter->getXDirection() ),
  _yDirection( shooter->getYDirection() ),
  _damage( damage )
{
	_depth = 1;
			
	_solid = 0;
	string filename;
	if (_yDirection == MIDDLE)
	{
		_xVelocity = bulletSpeed * (int)_xDirection;
		filename = "sprites/bullet.png";
	}
	else if ( _yDirection == DOWN)
	{
		_yVelocity = bulletSpeed * (int)_yDirection;
		filename = "sprites/bulletDown.png";
	}
	else
	{
		_yVelocity = bulletSpeed * (int)_yDirection;
		filename = "sprites/bulletUp.png";
	}

	_type = BULLET;
	_sprite = Sprite::loadSprite(filename);
	_sprite->setDirection( _xDirection );
	_box.w = _sprite->width();
	_box.h = _sprite->height();

	SDL_Rect shooterBox = _shooter->getBox();

	if( _xDirection == LEFT )
	{
		_box.x = shooterBox.x - _box.w;
	}
	else
	{
		_box.x = shooterBox.x + shooterBox.w;
	}

	if ( _yDirection == UP )
	{
		_box.y = shooterBox.y - _box.h;

		switch(which) {
			case 0:
				_box.x = shooterBox.x + shooterBox.w/2;
				break;
			case 1:
				_box.x = shooterBox.x;
				break;
			case 2:
				_box.x = shooterBox.x + shooterBox.w/3;
				break;
			case 3:
				_box.x = shooterBox.x + shooterBox.w*2.0/3.0;
				break;
			case 4:
				_box.x = shooterBox.x + shooterBox.w;
				break;
		}
	}
	else if ( _yDirection == MIDDLE )
	{
		switch(which) {
			case 0:
				_box.y = shooterBox.y + shooterBox.h/3;
				break;
			case 1:
				_box.y = shooterBox.y;
				break;
			case 2:
				_box.y = shooterBox.y + shooterBox.h/4;
				break;
			case 3:
				_box.y = shooterBox.y + shooterBox.h/2;
				break;
			case 4:
				_box.y = shooterBox.y + shooterBox.h*3.0/4.0;
		}
	}
	else
	{
		_box.y = shooterBox.y + shooterBox.h;

		switch(which) {
			case 0:
				_box.x = shooterBox.x + shooterBox.w/2;
				break;
			case 1:
				_box.x = shooterBox.x;
				break;
			case 2:
				_box.x = shooterBox.x + shooterBox.w/3;
				break;
			case 3:
				_box.x = shooterBox.x + shooterBox.w*2.0/3.0;
				break;
			case 4:
				_box.x = shooterBox.x + shooterBox.w;
				break;
		}
	}
}

Object *Bullet::copy()
{
	Bullet *copy = new Bullet(*this);
	// NOTE: Shooter may be incorrect at this point, hopefully it gets set later.
	// FIXME: Lord, is there a better way?!
	return copy;
}

void Bullet::draw()
{
	_sprite->setDirection( _xDirection );
	_sprite->draw(_box.x,_box.y);
}

void Bullet::update()
{
	// TODO: Fix collisions
	_box.x += ((double)_xVelocity/Screen::FRAMERATE);
	CollisionHandler::instance()->checkCollision(this);
	
	_box.y += ((double)_yVelocity/Screen::FRAMERATE);
	CollisionHandler::instance()->checkCollision(this);

	SDL_Rect screenBox = Screen::instance()->getScreenRect();

	if(!glfuncs::intersect(_box, screenBox))
		Level::instance()->scheduleDelete(this);
}

void Bullet::collide( Object* o )
{
	if( o == _shooter || o->getType() == BULLET )
		return;

	if( o->getType() == PLAYER || o->getType() == ENEMY || o->getType() == BOSS )
	{
		((Person*)o)->addHealth( -_damage );
		//SOUNDFX
		if((o->getType() == PLAYER) && (((Person*)o)->getHealth() > 0))
			PlaySoundCommand("sounds/grunt_male30.wav").execute();
	}

	_collidable = false;
	Level::instance()->scheduleDelete( this );
}
