#include <stdio.h>
#include <math.h>
#include <SDL.h>
#include <SDL_gfxPrimitives.h>

unsigned int Ss[] = {0, 20, 40, 60, 100, 150, 200, 250, 300, 350 };
unsigned int Ds[] = {8, 10, 12, 15, 20, 30, 50, 70, 100 };

struct TestStatus {
	char state;
	size_t index_s;
	unsigned int s;
	size_t index_d;
	unsigned int d;
	size_t n;
	Uint32 start_time;
};

void next_test(struct TestStatus* test_status)
{
	switch(test_status->state)
	{
	case 0: // start
		test_status->state = 1;
		test_status->index_s = 0;
		test_status->s = Ss[test_status->index_s];
		test_status->d = 16;
		test_status->n = 0;
		break;
	case 1: // const D
		if(test_status->n == 5)
		{
			if(test_status->index_s == sizeof(Ss)/sizeof(Ss[0]) - 1)
			{
				test_status->state = 2;
				test_status->index_d = 0;
				test_status->d = Ds[test_status->index_d];
				test_status->s = 150;
				test_status->n = 0;
			}
			else
			{
				test_status->index_s ++;
				test_status->s = Ss[test_status->index_s];
				test_status->n = 0;
			}
		}
		else
		{
			test_status->n ++;
		}
		break;
	case 2: // const S
		if(test_status->n == 5)
		{
			if(test_status->index_d == sizeof(Ds)/sizeof(Ds[0]) - 1)
			{
				test_status->state = 3;
				test_status->index_s = 0;
				test_status->s = Ss[test_status->index_s];
				test_status->index_d = 0;
				test_status->d = Ds[test_status->index_d];
				test_status->n = 0;
			}
			else
			{
				test_status->index_d ++;
				test_status->d = Ds[test_status->index_d];
				test_status->n = 0;
			}
		}
		else
		{
			test_status->n ++;
		}
		break;
	case 3:
		if(test_status->n == 3)
		{
			if(test_status->index_d == sizeof(Ds)/sizeof(Ds[0]) - 1)
			{
				if(test_status->index_s == sizeof(Ss)/sizeof(Ss[0]) - 1)
				{
					test_status->state = 4;
				}
				else
				{
					test_status->index_s ++;
					test_status->s = Ss[test_status->index_s];
					test_status->index_d = 0;
					test_status->d = Ds[test_status->index_d];
					test_status->n = 0;
				}
			}
			else
			{
				test_status->index_d ++;
				test_status->d = Ds[test_status->index_d];
				test_status->n = 0;
			}
		}
		else
		{
			test_status->n ++;
		}
		break;
	default:
		exit(0);
	}
	test_status->start_time = SDL_GetTicks();
}

void draw_test(SDL_Surface *screen, struct TestStatus *test_status, Uint16 mouse_x, Uint16 mouse_y)
{
	int res;
	SDL_LockSurface(screen);
	res = boxRGBA(screen, 0, 0, 1024, 768, 0, 0, 255, 255);
	if(res == -1)
	{
		fprintf(stderr, "Couldn't draw rect: %s\n", SDL_GetError());
	}
	
	double k = (test_status->s + test_status->d * sqrt(17.0) / 2.0) / sqrt((screen->w / 2.0 - mouse_x) * (screen->w / 2.0 - mouse_x) + (screen->h / 2.0 - mouse_y) * (screen->h / 2.0 - mouse_y));
	//k = 1;
	double xc = mouse_x + (screen->w / 2.0 - mouse_x) * k;
	double yc = mouse_y + (screen->h / 2.0 - mouse_y) * k;

	res = filledEllipseRGBA(screen, xc, yc, 2 * test_status->d, test_status->d / 2, 127, 127, 127, 255);
	if(res == -1)
	{
		fprintf(stderr, "Couldn't draw ellipse: %s\n", SDL_GetError());
	}
	SDL_UnlockSurface(screen);
	SDL_UpdateRect(screen, 0, 0, 0, 0);	
}

int main(int argc, char **argv)
{
	SDL_Surface *screen;
	if( SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		fprintf(stderr, "Couldn't initialize SDL: %s\n" , SDL_GetError());
		exit(1);
	}

	atexit(SDL_Quit);

	screen = SDL_SetVideoMode(1024, 768, 32, SDL_HWSURFACE);
	if( screen == NULL)
	{
		fprintf(stderr, "Couldn't set 1024x768x32 video mode: %s\n", SDL_GetError());
		exit(1);
	}

	int res;
	SDL_LockSurface(screen);
	res = boxRGBA(screen, 0, 0, 1024, 768, 0, 0, 255, 255);
	if(res == -1)
	{
		fprintf(stderr, "Couldn't draw rect: %s\n", SDL_GetError());
	}
	SDL_UnlockSurface(screen);
	SDL_UpdateRect(screen, 0, 0, 0, 0);

	struct TestStatus test_status = { 0, 0, 0, 0, 0};

	while(1)
	{
		SDL_Event event;
		while(SDL_PollEvent(&event))
		{
			switch(event.type)
			{
			case SDL_MOUSEBUTTONDOWN:
				//if(event.button.state == SDL_RELEASED)
				{
					Uint16 mouse_x = event.button.x;
					Uint16 mouse_y = event.button.y;
					next_test(&test_status);
					printf("state: %d\n d: %d\n s: %d\n n: %d\n", (int)test_status.state, (int)test_status.d, (int)test_status.s, (int)test_status.n);
					draw_test(screen, &test_status, mouse_x, mouse_y);
				}
				break;
			case SDL_KEYDOWN:
				if(event.key.keysym.sym == SDLK_ESCAPE)
				{
					exit(0);
				}
				break;
			case SDL_QUIT:
				exit(0);
				break;
			}
		}

	}
}


