#include <stdio.h>
#include <stdlib.h>	//for rand()
#include <allegro5/allegro.h>
#include <allegro5/allegro_opengl.h>

#define SCRW 640
#define SCRH 480

int *membuff;

void draw_lines(void)	//"draw" two red lines across our "frame buffer"
{
	int *pixelptr;
	int i;
	pixelptr = membuff;
	for(i=((SCRW-SCRH)/2);i<SCRW*SCRH;i+=SCRW+1)	//+1 so each next line is one further left (keeping in mind OGL starts from bottom left) for a 45 degree line
	{
		pixelptr[i] = 0x0FF000000;	//red, from our GL_RGBA in glDrawPixels
	}

	for(i=(((SCRH/2)) -(SCRW)/2);i<SCRW*SCRH;i+=SCRW-1)	//-1 so each next line is one further right for a 45 degree line
	{
		pixelptr[i] = 0x0000FF00;	//blue, from our GL_RGBA in glDrawPixels
	}
}

void draw_gradient(int scanline)
{
	int *pixelptr;
	int i;
	int red;
	int blue;
	int color;
	float tmp;
	pixelptr = &membuff[scanline * SCRW];
	tmp = 256.0/(float)SCRH * scanline;
	red = tmp;
	red <<= 8;
	blue = red ^ 0xFF00;
	color = red + (blue << 16);
	for(i=0;i<SCRW;i++)
	{
		pixelptr[i] = color;
	}
}

void add_some_random_dots(void)
{
	int *pixelptr;
	int i;
	pixelptr = membuff;
	for(i=0;i<1000;i++)	//add 1000 pixels per frame
	{
		pixelptr[rand() % (SCRW * SCRH)] = rand();
	}
}

int main(int argc, char **argv)
{
	ALLEGRO_DISPLAY *display;
	ALLEGRO_TIMER *timer;
	ALLEGRO_EVENT_QUEUE *queue;
	int *pixelptr;

	ALLEGRO_EVENT event;
	int frames = 0;
	int redraw = 0;

	int i;

	if (!al_init())
	{
		fprintf(stderr,"Could not init Allegro.\n");
		return 1;
	}

	al_install_keyboard();

	al_set_new_display_flags(ALLEGRO_OPENGL);

	display = al_create_display(SCRW, SCRH);
	if (!display)
	{
		fprintf(stderr,"Could not create display.\n");
		return 1;
	}

	timer = al_create_timer(1.0 / 60.0);

	//Didn't want to realloc anything, so make it as big as the largest conceivable display. 64mb isn't anything nowadays
	membuff = al_malloc(sizeof(int) * SCRW * SCRH);
	if(!membuff)
	{
		fprintf(stderr,"Out of mem\n");
		return 1;
	}

	//clear our "frame buffer" to white
	pixelptr = membuff;
	for(i=0;i<SCRW*SCRH;i++)
	{
		*(pixelptr++) = 0xFFFFFFFF;		//r = 0xFF, g = 0xFF, b = 0xFF, a = 0xFF
	}

	queue = al_create_event_queue();
	al_register_event_source(queue, al_get_keyboard_event_source());
	al_register_event_source(queue, al_get_timer_event_source(timer));
	al_start_timer(timer);

	while(true)
	{
		al_wait_for_event(queue, &event);
		{
			switch (event.type)
			{
				case ALLEGRO_EVENT_KEY_CHAR:
				{
					int k;
					k = event.keyboard.keycode;
					if (k == ALLEGRO_KEY_ESCAPE)
					{
						goto done;
					}
				}

				case ALLEGRO_EVENT_TIMER:
				{
					redraw++;
				}
			}
		}

		while( (redraw > 0) && al_is_event_queue_empty(queue))
		{
			if(frames == 120)
			{
				draw_lines();
			}

			if( (frames > 240) && (frames < (240+SCRH) ) )
			{
				draw_gradient(frames - 240);
			}

			if(frames > 480 + SCRH)
			{
				add_some_random_dots();
			}

			//This line isn't necessarily needed, depending on OGL version
			glRasterPos2i(0,SCRH);

			//blit memory buffer to display
			glDrawPixels(SCRW, SCRH, GL_RGBA,GL_UNSIGNED_INT_8_8_8_8, membuff);

			al_flip_display();
			glClear(GL_COLOR_BUFFER_BIT);
			frames++;
			if(frames > 1500)
			{
				goto done;
			}
			redraw--;
		}
	}
done:
	al_destroy_event_queue(queue);
	al_free(membuff);
	return 0;
}
