#include "Resource.hpp"
#include "TinyLibrary.hpp"
#include "BgMap.hpp"

BgMap::BgMap(void)
:map_number(0)
,width(0)
,height(0)
,x(0)
,y(0)
{
}

BgMap::~BgMap(void)
{
}

void BgMap::Initialize(int map_number, int width, int height)
{
	this->map_number = map_number;
	this->width = width;
	this->height = height;
}

void BgMap::SetPosition(int x, int y)
{
	this->x = x;
	this->y = y;
}

void BgMap::Draw(void)
{
	Screen& screen = Screen::GetInstance();
	BgMapData* bg_map_data = GetBgMapData(this->map_number);
	ImageData* image_data = GetImageData(1);
	int width = image_data->width;
	int height = image_data->height;
	for(int x = 0; x < bg_map_data->width; ++ x)
	{
		int draw_x = this->x + x * width;
		if((draw_x < -image_data->width) || (draw_x > Screen::WIDTH))
		{
			continue;
		}
		for(int y = 0; y < bg_map_data->height; ++ y)
		{
			int chip = bg_map_data->buffer[y * bg_map_data->width + x];
			if((chip > 0) && (chip < 192))
			{
				ImageData* image_data = GetImageData(chip);
				screen.DrawSprite(image_data->buffer, draw_x, this->y + y * height, image_data->width, image_data->height, -1);
			}
		}
	}
}

unsigned char BgMap::GetChip(int x, int y)
{
	if((x < 0) || (y < 0))
	{
		return 0;
	}
	BgMapData* bg_map_data = GetBgMapData(this->map_number);
	ImageData* image_data = GetImageData(1);
	int width = bg_map_data->width * image_data->width;
	int height = bg_map_data->height * image_data->height;
	if((x >= width) || (y >= height))
	{
		return 0;
	}
	int chip_x = x / image_data->width;
	int chip_y = y / image_data->height;
	return bg_map_data->buffer[chip_y * bg_map_data->width + chip_x];
}

// x: 0-95
// y: 0-63
unsigned char BgMap::GetScreenChip(int x, int y)
{
	x += -this->x;
	y += -this->y;
	return GetChip(x, y);
}

int BgMap::GetPushBackLeft(int x, int y)
{
	unsigned char chip = GetScreenChip(x, y);
	if((chip == 0) || (chip >= 192))
	{
		return 0;
	}
	ImageData* image_data = GetImageData(1);
	return x - ((x - this->x) / image_data->width * image_data->width + this->x);
}

int BgMap::GetPushBackRight(int x, int y)
{
	unsigned char chip = GetScreenChip(x, y);
	if((chip == 0) || (chip >= 192))
	{
		return 0;
	}
	ImageData* image_data = GetImageData(1);
	return -(x - ((x - this->x + image_data->width) / image_data->width * image_data->width + this->x));
}

int BgMap::GetPushBackTop(int x, int y)
{
	unsigned char chip = GetScreenChip(x, y);
	if((chip == 0) || (chip >= 192))
	{
		return 0;
	}
	ImageData* image_data = GetImageData(1);
	return y - ((y - this->y) / image_data->height * image_data->height + this->y);
}

int BgMap::GetPushBackBottom(int x, int y)
{
	unsigned char chip = GetScreenChip(x, y);
	if((chip == 0) || (chip >= 192))
	{
		return 0;
	}
	ImageData* image_data = GetImageData(1);
	return -(y - ((y - this->y + image_data->height) / image_data->height * image_data->height + this->y));
}

unsigned char BgMap::BackColor8(void)
{
	BgMapData* bg_map_data = GetBgMapData(this->map_number);
	return COLOR8(bg_map_data->back_red, bg_map_data->back_green, bg_map_data->back_blue);
}

unsigned short BgMap::BackColor16(void)
{
	BgMapData* bg_map_data = GetBgMapData(this->map_number);
	return COLOR16(bg_map_data->back_red, bg_map_data->back_green, bg_map_data->back_blue);
}

void BgMap::GetSize(int& width, int& height)
{
	BgMapData* bg_map_data = GetBgMapData(this->map_number);
	ImageData* image_data = GetImageData(1);
	width = bg_map_data->width * image_data->width;
	height = bg_map_data->height * image_data->height;
}

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