/*
 * draw.c
 *
 *  Created on: Dec 24, 2009
 *      Author: ÓHerman van der MeulenÓ
 */

#include "draw.h"

// the buffer to be painted on
u16* video_buffer = VRAM_A;

// the global paint color for all drawing
u16 bgColor = PIXEL(RGB15(0, 0, 0));
u16 paintColor = PIXEL(RGB15(31, 31, 31));
u16 alphaColor = PIXEL(RGB15(0, 31, 0));

/*
 * check if a point (x, y) is in the limited range (play field)
 */
int pointInRangeLimit(u16 x, u16 y)
{
	if (x > 10 && x < 245 && y > 10 && y < 167)
		return 1;
	else
		return 0;
}

/*
 * check if an offset is in the limited range (play field)
 */
int offsetInRangeLimit(u16* offset)
{
	u16 x, y;
	y = (*offset / 256);
	x = *offset - (y * 256);
	return pointInRangeLimit(x, y);
}

/*
 * draw a point at x, y pixels (with the current paint color)
 */
void drawPoint(int x, int y)
{
	video_buffer[x + y * 256] = paintColor;
}

/*
 * draw an point at an offset point (with the current paint color)
 */
void drawOffsetPoint(u16 offset)
{
	video_buffer[offset] = paintColor;
}

/*
 * draw a line from x1, y1 to x2, y2 (with the current paint color)
 */
void drawLine(int x1, int y1, int x2, int y2)
{
	int yStep = SCREEN_WIDTH;
	int xStep = 1;
	int xDiff = x2 - x1;
	int yDiff = y2 - y1;

	int errorTerm = 0;
	u16 offset = y1 * SCREEN_WIDTH + x1;
	int i;

	//need to adjust if y1 > y2
	if (yDiff < 0)
	{
		yDiff = -yDiff; //absolute value
		yStep = -yStep; //step up instead of down
	}

	//same for x
	if (xDiff < 0)
	{
		xDiff = -xDiff;
		xStep = -xStep;
	}

	//case for changes more in X than in Y
	if (xDiff > yDiff)
	{
		for (i = 0; i < xDiff + 1; i++)
		{
			drawOffsetPoint(offset);

			offset += xStep;

			errorTerm += yDiff;

			if (errorTerm > xDiff)
			{
				errorTerm -= xDiff;
				offset += yStep;
			}
		}
	}//end if xdiff > ydiff
	//case for changes more in Y than in X
	else
	{
		for (i = 0; i < yDiff + 1; i++)
		{
			drawOffsetPoint(offset);

			offset += yStep;

			errorTerm += xDiff;

			if (errorTerm > yDiff)
			{
				errorTerm -= yDiff;
				offset += xStep;

			}
		}
	}
}

/*
 * draw a rectangle at x, y with a width and height (with the current paint color)
 */
void drawRect(int x, int y, int width, int height)
{
	width--;
	height--;
	drawLine(x, y, x + width, y);
	drawLine(x + width, y, x + width, y + height);
	drawLine(x + width, y + height, x, y + height);
	drawLine(x, y + height, x, y);
}

/*
 * fill a rectangle at x, y with a width and height (with the current paint color)
 */
void fillRect(int x, int y, int width, int height)
{
	height--;
	int i = x;
	while (i < x + width)
	{
		drawLine(i, y, i, y + height);
		i++;
	}
}

void drawBlockBackground(int x, int y)
{
	switch (blocksBackground[x][y])
	{
	case 0:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) nogoorange_img_bin), 0, 0, 26, 26);
		break;
	case 2:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) free_img_bin), 0, 0, 26, 26);
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) begin_img_bin), 0, 0, 26, 26);
		break;
	case 3:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) free_img_bin), 0, 0, 26, 26);
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) end_img_bin), 0, 0, 26, 26);
		break;
	case 4:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) free_img_bin), 0, 0, 26, 26);
		break;
	}
}

void drawBlock(int x, int y)
{
	switch (blocks[x][y])
	{
	case 0:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) nogoorange_img_bin), 0, 0, 26, 26);
		break;
	case 1:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) rock_img_bin), 0, 0, 26, 26);
		break;
	case 2:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) free_img_bin), 0, 0, 26, 26);
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) begin_img_bin), 0, 0, 26, 26);
		break;
	case 3:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) free_img_bin), 0, 0, 26, 26);
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) end_img_bin), 0, 0, 26, 26);
		break;
	case 4:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) free_img_bin), 0, 0, 26, 26);
		break;
	}

	if (blocks[x][y] == -1 || blocks[x][y] == -3)
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) vertical_img_bin), 0, 0, 26, 26);
	else if (blocks[x][y] == -2 || blocks[x][y] == -4)
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) horizontal_img_bin), 0, 0, 26, 26);
}

void drawLastBlockTurn(int x, int y, int turnType)
{ // type: 1=>east to north, 2=> east to south, 3=>west to north, 4=>west to south

	// first fill background again
	drawBlockBackground(x, y);

	switch (turnType)
	{
	case 1:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) eton_img_bin), 0, 0, 26, 26);
		break;
	case 2:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) etos_img_bin), 0, 0, 26, 26);
		break;
	case 3:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) wton_img_bin), 0, 0, 26, 26);
		break;
	case 4:
		drawBitmap(((x - 1) * 26) + 11, ((y - 1) * 26) + 11, ((u16*) wtos_img_bin), 0, 0, 26, 26);
		break;
	}
}

void drawField(int waitOrNot)
{
	int x, y;
	for (x = 1; x <= 9; x++)
	{
		if (currentLevel == 1)
		{
			y = 6;
			drawBitmap(0, 0, ((u16*) helplevel_img_bin), 0, 0, 256, 135);
		}
		else
			y = 1;
		for (; y <= 6; y++)
		{
			drawBlock(x, y);
			if (waitOrNot)
				wait(1);
		}
	}
	if (currentLevel == 1)
	{
		drawBitmap(115, 141, ((u16*) transparent_img_bin), 0, 0, 26, 26);
	}
}

void drawBitmap(u16 bufferX, u16 bufferY, u16* bitmap, u8 bitmapX, u8 bitmapY, u16 width, u8 height)
{
	u16 i, j, index;
	for (i = 0; i < height; i++)
	{
		for (j = 0; j < width; j++)
		{
			index = ((bitmapY + i) * width) + bitmapX + j;
			paintColor = PIXEL(bitmap[index]);
			if (paintColor != alphaColor)
				drawPoint(bufferX + j, bufferY + i);
		}
	}
}

void drawPartOfBitmap(u16 bufferX, u16 bufferY, u16* bitmap, u16 bitmapX, u16 bitmapY, u16 bitmapWidth, u16 bitmapHeight, u16 width, u16 height)
{
	u16 i, j, index;
	for (i = 0; i < height; i++)
	{
		for (j = 0; j < width; j++)
		{
			index = ((bitmapY + i) * bitmapWidth) + bitmapX + j;
			paintColor = PIXEL(bitmap[index]);
			if (paintColor != alphaColor)
				drawPoint(bufferX + j, bufferY + i);
		}
	}
}

void drawCharacter(u16 startX, u8 startY, char whichLetter, u16* font)
{
	if (whichLetter == 'a')
		drawPartOfBitmap(startX, startY, font, 0, 520, 8, 768, 8, 8);
	else if (whichLetter == 'b')
		drawPartOfBitmap(startX, startY, font, 0, 528, 8, 768, 8, 8);
	else if (whichLetter == 'c')
		drawPartOfBitmap(startX, startY, font, 0, 536, 8, 768, 8, 8);
	else if (whichLetter == 'd')
		drawPartOfBitmap(startX, startY, font, 0, 544, 8, 768, 8, 8);
	else if (whichLetter == 'e')
		drawPartOfBitmap(startX, startY, font, 0, 552, 8, 768, 8, 8);
	else if (whichLetter == 'f')
		drawPartOfBitmap(startX, startY, font, 0, 560, 8, 768, 8, 8);
	else if (whichLetter == 'g')
		drawPartOfBitmap(startX, startY, font, 0, 568, 8, 768, 8, 8);
	else if (whichLetter == 'h')
		drawPartOfBitmap(startX, startY, font, 0, 576, 8, 768, 8, 8);
	else if (whichLetter == 'i')
		drawPartOfBitmap(startX, startY, font, 0, 584, 8, 768, 8, 8);
	else if (whichLetter == 'j')
		drawPartOfBitmap(startX, startY, font, 0, 592, 8, 768, 8, 8);
	else if (whichLetter == 'k')
		drawPartOfBitmap(startX, startY, font, 0, 600, 8, 768, 8, 8);
	else if (whichLetter == 'l')
		drawPartOfBitmap(startX, startY, font, 0, 608, 8, 768, 8, 8);
	else if (whichLetter == 'm')
		drawPartOfBitmap(startX, startY, font, 0, 616, 8, 768, 8, 8);
	else if (whichLetter == 'n')
		drawPartOfBitmap(startX, startY, font, 0, 624, 8, 768, 8, 8);
	else if (whichLetter == 'o')
		drawPartOfBitmap(startX, startY, font, 0, 632, 8, 768, 8, 8);
	else if (whichLetter == 'p')
		drawPartOfBitmap(startX, startY, font, 0, 640, 8, 768, 8, 8);
	else if (whichLetter == 'q')
		drawPartOfBitmap(startX, startY, font, 0, 648, 8, 768, 8, 8);
	else if (whichLetter == 'r')
		drawPartOfBitmap(startX, startY, font, 0, 656, 8, 768, 8, 8);
	else if (whichLetter == 's')
		drawPartOfBitmap(startX, startY, font, 0, 664, 8, 768, 8, 8);
	else if (whichLetter == 't')
		drawPartOfBitmap(startX, startY, font, 0, 672, 8, 768, 8, 8);
	else if (whichLetter == 'u')
		drawPartOfBitmap(startX, startY, font, 0, 680, 8, 768, 8, 8);
	else if (whichLetter == 'v')
		drawPartOfBitmap(startX, startY, font, 0, 688, 8, 768, 8, 8);
	else if (whichLetter == 'w')
		drawPartOfBitmap(startX, startY, font, 0, 696, 8, 768, 8, 8);
	else if (whichLetter == 'x')
		drawPartOfBitmap(startX, startY, font, 0, 704, 8, 768, 8, 8);
	else if (whichLetter == 'y')
		drawPartOfBitmap(startX, startY, font, 0, 712, 8, 768, 8, 8);
	else if (whichLetter == 'z')
		drawPartOfBitmap(startX, startY, font, 0, 720, 8, 768, 8, 8);
	else if (whichLetter == '-')
		drawPartOfBitmap(startX, startY, font, 0, 104, 8, 768, 8, 8);
	else if (whichLetter == ',')
		drawPartOfBitmap(startX, startY, font, 0, 96, 8, 768, 8, 8);
	else if (whichLetter == 'A')
		drawPartOfBitmap(startX, startY, font, 0, 264, 8, 768, 8, 8);
	else if (whichLetter == 'B')
		drawPartOfBitmap(startX, startY, font, 0, 272, 8, 768, 8, 8);
	else if (whichLetter == 'C')
		drawPartOfBitmap(startX, startY, font, 0, 280, 8, 768, 8, 8);
	else if (whichLetter == 'D')
		drawPartOfBitmap(startX, startY, font, 0, 288, 8, 768, 8, 8);
	else if (whichLetter == 'E')
		drawPartOfBitmap(startX, startY, font, 0, 296, 8, 768, 8, 8);
	else if (whichLetter == 'F')
		drawPartOfBitmap(startX, startY, font, 0, 304, 8, 768, 8, 8);
	else if (whichLetter == 'G')
		drawPartOfBitmap(startX, startY, font, 0, 312, 8, 768, 8, 8);
	else if (whichLetter == 'H')
		drawPartOfBitmap(startX, startY, font, 0, 320, 8, 768, 8, 8);
	else if (whichLetter == 'I')
		drawPartOfBitmap(startX, startY, font, 0, 328, 8, 768, 8, 8);
	else if (whichLetter == 'J')
		drawPartOfBitmap(startX, startY, font, 0, 336, 8, 768, 8, 8);
	else if (whichLetter == 'K')
		drawPartOfBitmap(startX, startY, font, 0, 344, 8, 768, 8, 8);
	else if (whichLetter == 'L')
		drawPartOfBitmap(startX, startY, font, 0, 352, 8, 768, 8, 8);
	else if (whichLetter == 'M')
		drawPartOfBitmap(startX, startY, font, 0, 360, 8, 768, 8, 8);
	else if (whichLetter == 'N')
		drawPartOfBitmap(startX, startY, font, 0, 368, 8, 768, 8, 8);
	else if (whichLetter == 'O')
		drawPartOfBitmap(startX, startY, font, 0, 376, 8, 768, 8, 8);
	else if (whichLetter == 'P')
		drawPartOfBitmap(startX, startY, font, 0, 384, 8, 768, 8, 8);
	else if (whichLetter == 'Q')
		drawPartOfBitmap(startX, startY, font, 0, 392, 8, 768, 8, 8);
	else if (whichLetter == 'R')
		drawPartOfBitmap(startX, startY, font, 0, 400, 8, 768, 8, 8);
	else if (whichLetter == 'S')
		drawPartOfBitmap(startX, startY, font, 0, 408, 8, 768, 8, 8);
	else if (whichLetter == 'T')
		drawPartOfBitmap(startX, startY, font, 0, 416, 8, 768, 8, 8);
	else if (whichLetter == 'U')
		drawPartOfBitmap(startX, startY, font, 0, 424, 8, 768, 8, 8);
	else if (whichLetter == 'V')
		drawPartOfBitmap(startX, startY, font, 0, 432, 8, 768, 8, 8);
	else if (whichLetter == 'W')
		drawPartOfBitmap(startX, startY, font, 0, 440, 8, 768, 8, 8);
	else if (whichLetter == 'X')
		drawPartOfBitmap(startX, startY, font, 0, 448, 8, 768, 8, 8);
	else if (whichLetter == 'Y')
		drawPartOfBitmap(startX, startY, font, 0, 456, 8, 768, 8, 8);
	else if (whichLetter == 'Z')
		drawPartOfBitmap(startX, startY, font, 0, 464, 8, 768, 8, 8);
	else if (whichLetter == '0')
		drawPartOfBitmap(startX, startY, font, 0, 128, 8, 768, 8, 8);
	else if (whichLetter == '1')
		drawPartOfBitmap(startX, startY, font, 0, 136, 8, 768, 8, 8);
	else if (whichLetter == '2')
		drawPartOfBitmap(startX, startY, font, 0, 144, 8, 768, 8, 8);
	else if (whichLetter == '3')
		drawPartOfBitmap(startX, startY, font, 0, 152, 8, 768, 8, 8);
	else if (whichLetter == '4')
		drawPartOfBitmap(startX, startY, font, 0, 160, 8, 768, 8, 8);
	else if (whichLetter == '5')
		drawPartOfBitmap(startX, startY, font, 0, 168, 8, 768, 8, 8);
	else if (whichLetter == '6')
		drawPartOfBitmap(startX, startY, font, 0, 176, 8, 768, 8, 8);
	else if (whichLetter == '7')
		drawPartOfBitmap(startX, startY, font, 0, 184, 8, 768, 8, 8);
	else if (whichLetter == '8')
		drawPartOfBitmap(startX, startY, font, 0, 192, 8, 768, 8, 8);
	else if (whichLetter == '9')
		drawPartOfBitmap(startX, startY, font, 0, 200, 8, 768, 8, 8);
	else if (whichLetter == ':')
		drawPartOfBitmap(startX, startY, font, 0, 208, 8, 768, 8, 8);
}

void drawText(char msg[], u8 startX, u8 startY, u16* font)
{
	u8 i = 0;
	while (msg[i] != '\0')
	{
		drawCharacter(startX, startY, msg[i], font);
		startX += 8;
		i++;
	}
}

void drawLevel()
{
	char buffer[30];
	sprintf(buffer, "Level: %i", currentLevel);
	paintColor = PIXEL(RGB15(0, 0, 0));
	fillRect(10, 174, 235, 10);
	drawText(buffer, 11, 175, ((u16*) font_img_bin));
}

void drawWarning(char* warningText)
{
	paintColor = PIXEL(RGB15(0, 0, 0));
	fillRect(10, 174, 235, 10);
	drawText(warningText, 11, 175, ((u16*) fontred_img_bin));
}
