#include "TinyLibrary.hpp"
#include "BgMap.hpp"
#include "Enemy.hpp"

Enemy::Enemy(void)
:alive(false)
,dead_count(0)
,x(0)
,y(0)
,vx(0)
,vy(0)
,anime_count(0)
,bg_map(NULL)
,map_x(0)
,map_y(0)
,direction(0)
{
}

Enemy::~Enemy(void)
{
}

void Enemy::Initialize(BgMap* bg_map, int direction, int x, int y)
{
	this->alive = true;
	this->dead_count = 0;
	this->x = x;
	this->y = y;
	this->vx = 0;
	this->vy = 0;
	this->anime_count = 0;
	this->bg_map = bg_map;
	this->direction = direction;
	this->bg_map->GetPosition(this->map_x, this->map_y);
}

void Enemy::Update(void)
{
	if(this->alive == true)
	{
		// Alive?
		if((this->x < LIMIT_LEFT) || (this->x > LIMIT_RIGHT))
		{
			this->alive = false;
		}
		if((this->y < LIMIT_TOP) || (this->y > LIMIT_BOTTOM))
		{
			this->alive = false;
		}
		if(this->alive == false)
		{
			return;
		}
		// Gravity
		this->x += this->vx;
		this->y += this->vy;
		this->vy += GRAVITY;
		if(this->vy > VY_MAX)
		{
			this->vy = VY_MAX;
		}
		// BgMap synchronize
		int map_x = 0;
		int map_y = 0;
		this->bg_map->GetPosition(map_x, map_y);
		int x_diff = (map_x - this->map_x) * 1000;
		int y_diff = (map_y - this->map_y) * 1000;
		this->x += x_diff;
		this->y += y_diff;
		this->map_x = map_x;
		this->map_y = map_y;
		// BgMap collision
		int push_back;
		if(this->vy > 0)
		{
			push_back = this->bg_map->GetPushBackTop(this->x / 1000 + 2, this->y / 1000 + 10);
			if(push_back != 0)
			{
				this->vy = 0;
				this->y -= (push_back * 1000);
			}
			push_back = this->bg_map->GetPushBackTop(this->x / 1000 + 8, this->y / 1000 + 10);
			if(push_back != 0)
			{
				this->vy = 0;
				this->y -= (push_back * 1000);
			}
		}
	}
	else
	{
		this->y += this->vy;
		this->vy += GRAVITY;
		if(this->vy > VY_MAX)
		{
			this->vy = VY_MAX;
		}
	}
}

unsigned int Enemy::GetStatus(void)
{
	if(this->alive == false)
	{
		if(this->y > Screen::HEIGHT * 1000)
		{
			return STATUS_DEAD;
		}
	}
	return STATUS_ALIVE;
}

void Enemy::GetPosition(int& x, int& y)
{
	x = this->x;
	y = this->y;
}

void Enemy::SetAlive(bool alive)
{
	this->alive = alive;
}

bool Enemy::GetAlive(void)
{
	return this->alive;
}
