#include "draw.h"

/*
 * draw a very small dot
 */
void plot(int x, int y, uint16 color)
{
	uint16 *buffer = VRAM_A + y * SCREEN_WIDTH + x;
	*buffer = color;
}

/*
 * draw a horizontal line using dma
 */
void draw_horizontal(int x, int y, int width, uint16 color)
{
	if (x % 2)
	{
		uint16 *start = VRAM_A + y * SCREEN_WIDTH + x + 1;
		memset(start, color, width * 2);
		draw_dot(x + width, y, color, 1);
	}
	else
	{
		uint16 *start = VRAM_A + y * SCREEN_WIDTH + x;
		memset(start, color, width * 2);
		draw_dot(x + width - 1, y, color, 1);
	}
}

// clear the screen to the background color
void clear_screen(uint16 *base, uint16 color)
{
	memset(base, color, 98304);
}

/*
 * Draw a single (square) dot of a specific color and thickness.
 */
void draw_dot(int x, int y, uint16 color, uint16 thickness)
{
	int i,j,width=thickness;
	
	if (width > 1 && width < 10)
	{
		for(i = 0; i < width; i++)
		{
			for(j = 0; j < width; j++)
			{
				plot(x + i - (width >> 1), y + j - (width >> 1), color);
			}
		}
	}
	else
	{
		plot(x, y, color);
	}
}

void draw_circle(int x1, int y1, int r, uint16 color, int thickness)
{
	int x = 0;
	int y = r;
	int d = -r;
	int x2m1 = -1;
	
	draw_dot(0 + x1, r + y1, color, thickness);
	draw_dot(0 + x1, -r + y1, color, thickness);
	draw_dot(-r + x1, 0 + y1, color, thickness);
	draw_dot(r + x1, 0 + y1, color, thickness);
	
	for(x = 1; x < r / sqrt(2); x++)
	{
		x2m1 += 2;
		d += x2m1;
		if (d >= 0)
		{
			y--;
			d -= (y<<1);  /* Must do this AFTER y-- */
		}
		draw_dot(x + x1, y + y1, color, thickness);
		draw_dot(-x + x1, -y + y1, color, thickness);
		draw_dot(x + x1, -y + y1, color, thickness);
		draw_dot(-x + x1, y + y1, color, thickness);
		
		draw_dot(y + x1, x + y1, color, thickness);
		draw_dot(-y + x1, -x + y1, color, thickness);
		draw_dot(-y + x1, x + y1, color, thickness);
		draw_dot(y + x1, -x + y1, color, thickness);
	}
}

/*
// i stole this from the internet. i tried several but only this one worked.
// http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
*/
void draw_line(int x0, int y0, int x1, int y1, uint16 color, int thickness)
{
        int dy = y1 - y0;
	int dx = x1 - x0;
	int stepx=0, stepy=0;
	int fraction=0;
	
	if (!dy)
	{
		if (dx > 0)
			draw_horizontal(x0, y1, dx, color);
		else if (dx < 0)
			draw_horizontal(x1, y1, -dx, color);
	}
	else
	{
		// figure out which direction and slope we are doing
		if (dy < 0) { dy = -dy;  stepy = -1; } else { stepy = 1; }
		if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
		dy <<= 1;
		dx <<= 1;
		
		draw_dot(x0, y0, color, thickness);
		
		if (dx > dy) 
		{
			fraction = dy - (dx >> 1);
			
			while (x0 != x1) 
			{
				if (fraction >= 0) 
				{
					y0 += stepy;
					fraction -= dx;
				}
				x0 += stepx;
				fraction += dy;
				draw_dot(x0, y0, color, thickness);
			}
		}
		else
		{
			fraction = dx - (dy >> 1);
			while (y0 != y1)
			{
				if (fraction >= 0) 
				{
					x0 += stepx;
					fraction -= dy;
				}
				y0 += stepy;
				fraction += dx;
				draw_dot(x0, y0, color, thickness);
			}
		}
	}
}

