/* shoot the colored enemies with the correct colored shot
   to select shot color, press 1-4 keys (color is indicated at lower-right of screen */

#include <allegro.h>

typedef struct
{
	
	int color;
	float x, y;
	float vx, vy;
	int active;
	
} ENEMY;

int score = 0;
int ticks = 0;
int done = 0;
int vstoggle = 0;
char map[240 / 16][320 / 16];
BITMAP * buffer;
int ship_x = 0;
int ship_y = 112;
int ship_color = 1;
int shot_x = 0;
int shot_y = 112;
int shot_color = 1;
int shot_active = 0;
int color[5];
int gen_ticks = 120;
int gen_count = 0;
int health = 5;

ENEMY enemy[512];

void ticker(void)
{
	ticks++;
}

int main(int argc, char * argv[])
{
	int i, j;
	
	/* check arguments */
	for(i = 1; i < argc; i++)
	{
		if(!stricmp(argv[i], "-vsync"))
		{
			vstoggle = 1;
		}
	}
	allegro_init();
	set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
	buffer = create_bitmap(320, 240);
	install_timer();
	install_keyboard();
	install_int_ex(ticker, BPS_TO_TIMER(60));
	color[0] = makecol(255, 0, 0);
	color[1] = makecol(255, 0, 0);
	color[2] = makecol(0, 255, 0);
	color[3] = makecol(0, 0, 255);
	color[4] = makecol(255, 255, 0);
	for(i = 0; i < 512; i++)
	{
		enemy[i].active = 0;
	}
	while(!done)
	{
		/* logic */
		for(i = 0; i < ticks; i++)
		{
			if(key[KEY_ESC])
			{
				done = 1;
			}
			if(key[KEY_UP])
			{
				ship_y -= 2;
			}
			if(key[KEY_DOWN])
			{
				ship_y += 2;
			}
			if(key[KEY_1])
			{
				ship_color = 1;
			}
			if(key[KEY_2])
			{
				ship_color = 2;
			}
			if(key[KEY_3])
			{
				ship_color = 3;
			}
			if(key[KEY_4])
			{
				ship_color = 4;
			}
			if(key[KEY_SPACE] && !shot_active)
			{
				shot_color = ship_color;
				shot_x = ship_x + 2;
				shot_y = ship_y + 2;
				shot_active = 1;
			}
			gen_count++;
			if(gen_count >= gen_ticks)
			{
				gen_count = 0;
				if(gen_ticks > 1)
				{
					gen_ticks--;
				}
				for(j = 0; j < 512; j++)
				{
					if(!enemy[j].active)
					{
						enemy[j].x = 320;
						enemy[j].y = rand() % 224;
						enemy[j].color = rand() % 4 + 1;
						enemy[j].vx = -0.25;
						enemy[j].vy = 0;
						enemy[j].active = 1;
						break;
					}
				}
			}
			for(j = 0; j < 512; j++)
			{
				enemy[j].x += enemy[j].vx;
				enemy[j].y += enemy[j].vy;
				if(enemy[j].x < -15)
				{
					enemy[j].active = 0;
					health--;
					if(health <= 0)
					{
						done = 1;
					}
				}
			}
			if(shot_active)
			{
				shot_x += 4;
				if(shot_x > 320)
				{
					shot_active = 0;
				}
				for(i = 0; i < 512; i++)
				{
					if(enemy[i].active)
					{
						if(shot_x + 12 > enemy[i].x && enemy[i].x + 16 > shot_x && shot_y + 12 > enemy[i].y && enemy[i].y + 16 > shot_y)
						{
							shot_active = 0;
							if(enemy[i].color == shot_color)
							{
								enemy[i].active = 0;
								score += 50;
							}
							break;
						}
					}
				}
			}
		}
		ticks = 0;
		
		/* rendering */
		clear_bitmap(buffer);
		rect(buffer, ship_x, ship_y, ship_x + 15, ship_y + 15, makecol(255, 255, 255));
		if(shot_active)
		{
			rectfill(buffer, shot_x, shot_y, shot_x + 11, shot_y + 11, color[shot_color]);
		}
		else
		{
			rectfill(buffer, ship_x + 2, ship_y + 2, ship_x + 13, ship_y + 13, color[ship_color]);
		}
		for(i = 0; i < 512; i++)
		{
			if(enemy[i].active)
			{
				rectfill(buffer, enemy[i].x, enemy[i].y, enemy[i].x + 15, enemy[i].y + 15, color[enemy[i].color]);
			}
		}
		textprintf_ex(buffer, font, 224, 0, makecol(255, 255, 255), -1, "Score: %5d", score);
		textprintf_ex(buffer, font, 224, 8, makecol(255, 255, 255), -1, "Health: %4d", health);
		textprintf_ex(buffer, font, 288, 232, color[1], -1, "1");
		textprintf_ex(buffer, font, 296, 232, color[2], -1, "2");
		textprintf_ex(buffer, font, 304, 232, color[3], -1, "3");
		textprintf_ex(buffer, font, 312, 232, color[4], -1, "4");
		if(vstoggle)
		{
			vsync();
		}
		stretch_blit(buffer, screen, 0, 0, 320, 240, 0, 0, 640, 480);
	}
	allegro_message("Final Score: %d", score);
	return 0;
}
END_OF_MAIN()
