#include "empire.h"

int mapcolor(int set, int num, int owner, bool defaultcolors);

void _minimap::create(bool defaultcolors)
{
	int x, y, s, n, z;
	time = 0;
	draw_called = false;
	a = 0;

	if (bmp)
	{
		bmp->Destroy();
	}

	if ((worldmap.get_length() < 1) || (worldmap.get_height() < 1))
		return;

	bmp = new ol::Bitmap(worldmap.get_length() * 3, worldmap.get_height() * 3);

	minimap.l = worldmap.get_length() * 3;
	minimap.h = worldmap.get_height() * 3;

	ol::Canvas::SetTo(*bmp);
	ol::Canvas::SetPixelWriteMode(ol::COLOR_AND_ALPHA);

	ol::Rect(0, 0, worldmap.get_length() * 3, worldmap.get_height() * 3).Draw(ol::Rgba(BLACK, 255));
	_tile *t;
	y = 0;
	while (y < worldmap.get_height())
	{
		x = 0;
		while (x < worldmap.get_length())
		{
			t = worldmap.get_tile(x, y);
			s = t->get_set();
			n = t->get_number();
			z = x + y * worldmap.get_length();

			data_set[x + (y * worldmap.get_length())] = s;
			data_num[x + (y * worldmap.get_length())] = n;

			ol::Rect(float(x * 3), float(y * 3), 3.0, 3.0).Draw(ol::Rgba(mapcolor(s, n, t->get_owner(), defaultcolors), 255));

			if (s == 4)  //buildings
			{
				if (n > 0)  //if a normal building
				{
					ol::Rect(float(x * 3), float(y * 3), 2.0, 2.0).DrawOutline(ol::Rgba(GREY, 255));
				}
				else  //if an HQ
				{
					ol::Rect(float(x * 3), float(y * 3), 2.0, 2.0).DrawOutline(ol::Rgba(WHITE, 255));
				}
			}
			if (s == 6)  //special tiles
			{
				if (n == 0) //teleporter
				{
					ol::Point(float(x * 3 + 1), float(y * 3)).Draw(ol::Rgba(WHITE, 255));
					ol::Point(float(x * 3), float(y * 3 + 2)).Draw(ol::Rgba(WHITE, 255));
					ol::Point(float(x * 3 + 2), float(y * 3 + 3)).Draw(ol::Rgba(WHITE, 255));
				}
			}

			x++;
		}
		y++;
	}

	ol::Canvas::Refresh();
	ol::Canvas::SetTo(ol::SCREEN_BACKBUF);
}

void _minimap::check()
{  //this function should be called during the main game's logic loop
	if (draw_called)
	{  //if the minimap was drawn last logic loop
		draw_called = false;
		a += 0.03;
		if (a > 0.7) a = 0.7;
	}
	else
	{
		a -= 0.05;
		if (a <= 0) a = 0;
		if (a > 0) draw(false);
		draw_called = false;
	}
}

void _minimap::draw_scaled(int x, int y, float scale_factor, bool defaultcolors)
{
	const int color[4] = {player_color(0, 0), player_color(1, 0), player_color(2, 0), player_color(0, 2)};
	int z;

	const int topleftx = x;
	const int toplefty = y;
	const int width = int(150 * scale_factor);
	const int height = int(150 * scale_factor);
	const int bmpwidth = int(bmp->Width() * scale_factor);
	const int bmpheight = int(bmp->Height() * scale_factor);

	const float pixels_per_tile = 3.0 * scale_factor;

	draw_called = true;

	buffer_rectfill(topleftx, toplefty, x + width, y + height, BLACK);
	x += (width - bmpwidth) / 2;
	y += (height - bmpheight) / 2;

	disable_antialiasing();
	buffer_stretch_sprite(bmp, x, y, bmpwidth, bmpheight);
	enable_antialiasing();

	time++;
	if (time / 50 == 0)
	{  //show where the units are
		for (int j = 0; j < worldmap.get_height(); j++)
		{
			for (int i = 0; i < worldmap.get_length(); i++)
			{
				z = worldmap.get_tile(i, j)->unit_here();
				if (z != -1)
				{
					if (defaultcolors)
						buffer_mapblip(int(i * pixels_per_tile) + x - 2, int(j * pixels_per_tile) + y - 2, color[z / 100]);
					else
						buffer_mapblip(int(i * pixels_per_tile) + x - 2, int(j * pixels_per_tile) + y - 2, player[z / 100].tintcolor);
				}
			}
		}
	}

	if (time > 100)
		time = 0;
}

void _minimap::draw(bool mapeditor, int x, int y, bool outline, bool defaultcolors)
{
	const int color[4] = {player_color(0, 0), player_color(1, 0), player_color(2, 0), player_color(0, 2)};
	int z;

	const int topleftx = x;
	const int toplefty = y;

	draw_called = true;

	buffer_rectfill(topleftx, toplefty, x + 150, y + 150, BLACK);
	x += (150 - bmp->Width()) / 2;
	y += (150 - bmp->Height()) / 2;

	buffer_draw_sprite(bmp, x, y);//, a);

	time++;
	if (time / 50 == 0)
	{  //show where the units are
		for (int j = 0; j < worldmap.get_height(); j++)
		{
			for (int i = 0; i < worldmap.get_length(); i++)
			{
				z = worldmap.get_tile(i, j)->unit_here();
				if (z != -1)
				{
					if (defaultcolors)
						buffer_mapblip(i * 3 + x - 2, j * 3 + y - 2, color[z / 100]);
					else
						buffer_mapblip(i * 3 + x - 2, j * 3 + y - 2, player[z / 100].tintcolor);//, a + 0.2);
				}
			}
		}
	}

	if (time > 100)
		time = 0;

	if (outline)
	{
		const int scrollx = worldmap.camera.get_scroll_x();
		const int scrolly = worldmap.camera.get_scroll_y();

		int rectx = (scrollx * 3) + x;
		int recty = (scrolly * 3) + y - 1;
		int rectw = (XTILES * 3);
		int recth = (YTILES * 3);

		if (rectx < topleftx)  //make sure the viewbox thingy doesn't go beyond the minimap area
		{
			rectw = (XTILES * 3) - (topleftx - rectx);
			rectx = topleftx;
		}
		if (recty < toplefty)
		{
			recth = (YTILES * 3) - (toplefty - recty);
			recty = toplefty;
		}
		if (rectx + rectw > topleftx + 150)
		{
			rectw = topleftx + 150 - rectx;
		}
		if (recty + recth > toplefty + 150)
		{
			recth = toplefty + 150 - recty;
		}

		if ((rectw > 0) && (recth > 0))
		{
			if (mapeditor)  //show where the viewable area is if in the map editor
			{
				buffer_rect(rectx, recty, rectx + rectw, recty + recth, BLACK);
			}
			else
			{
				buffer_rect(rectx, recty, rectx + rectw, recty + recth, WHITE);
			}
		}
	}
}

void _minimap::destroy()
{
	if (bmp)
	{
		bmp->Destroy();
		delete bmp;
		bmp = NULL;
	}
}

int mapcolor(int set, int num, int owner, bool defaultcolors)
{
	const int dcolor[4] = {player_color(0, 0), player_color(1, 0), player_color(2, 0), player_color(0, 2)};
	int color = BLUE;

	if (set == 0)
	{
		if ((num == 0) || (num == 1) || (num > 4))
		{  //if it is a road
			color = DGREY;
		}
		else if (num == 2)
		{
			color = makecol(0, 100, 0);
		}
		else if (num == 3)
		{
			color = GREEN;
		}
		else if (num == 4)
		{
			color = makecol(190, 180, 20);
		}
	}
	else if ((set == 2) && (num == 1))  //reef
	{
		color = makecol(200, 200, 250);
	}
	else if (set == 3)  //shoal
	{
		color = makecol(225, 220, 140);
	}
	else if (set == 4)  //buildings
	{
		if (owner != -1)
		{
			if (defaultcolors)
				color = dcolor[owner];
			else
				color = player[owner].tintcolor;
		}
		else
		{
			color = LGREY;
		}
	}
	else if (set == 6)
	{
		switch (num)
		{
		case 0:  //teleport
			color = makecol(128, 128, 255);
			break;
		case 1:  //barrier
			color = BLACK;
			break;
		}
	}

	return color;
}
