#include <stdio.h>
#include <stdlib.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_opengl.h>
#include <allegro5/allegro_ttf.h>

typedef struct
{
	float x;
	float y;
	float z;
}PLACEMENT;

PLACEMENT places[32];

ALLEGRO_BITMAP *bitmaparray[32];
int textures[32];

char sprintfbuff[256];

int err;

int main(int argc, char **argv)
{
	double start;
	char *font_file = "DejaVuSans.ttf";
	ALLEGRO_FONT *font;
	ALLEGRO_DISPLAY *display;
	ALLEGRO_EVENT_QUEUE *queue;
	ALLEGRO_TIMER *timer;
	ALLEGRO_EVENT event;
	ALLEGRO_COLOR transparent;
	ALLEGRO_COLOR white;
	int frames = 0;
	int display_width = 800;
	int display_height = 600;
	int i;
	
	if (!al_init())
	{
		fprintf(stderr,"Could not init Allegro.\n");
		return 1;
	}

	al_install_keyboard();

	al_set_new_display_option(ALLEGRO_RED_SIZE,8,ALLEGRO_REQUIRE);
	al_set_new_display_option(ALLEGRO_BLUE_SIZE,8,ALLEGRO_REQUIRE);
	al_set_new_display_option(ALLEGRO_GREEN_SIZE,8,ALLEGRO_REQUIRE);
	al_set_new_display_option(ALLEGRO_ALPHA_SIZE,8,ALLEGRO_REQUIRE);

	al_set_new_display_option(ALLEGRO_DEPTH_SIZE,24,ALLEGRO_REQUIRE);
	al_set_new_display_flags(ALLEGRO_OPENGL);
	display = al_create_display(display_width,display_height);
	if (!display)
	{
		fprintf(stderr,"Could not create display.\n");
		return 1;
	}

	al_init_font_addon();
	al_init_ttf_addon();
	
	font = al_load_font(font_file, 150, 0);
	if(!font)
	{
		fprintf(stderr,"Couldn't load font\n");
		return 1;
	}

	transparent = al_map_rgba(0.0,0.0,0.0,0.0);
	white = al_map_rgba(255,255,255,255);
	
	for(i=0;i<32;i++)
	{
		bitmaparray[i] = al_create_bitmap(256,256);
		if(!bitmaparray[i])
		{
			fprintf(stderr,"Out of mem\n");
			return 1;
		}
		textures[i] = al_get_opengl_texture(bitmaparray[i]);
		//printf("%d\n",textures[i]);
		sprintf(sprintfbuff,"%d",i);
		al_set_target_bitmap(bitmaparray[i]);
		al_clear_to_color(transparent);
		al_draw_text(font,al_map_rgba(rand()&255,rand()&255,rand()&255,255),0.0,0.0,0,sprintfbuff);
		al_set_target_backbuffer(display);
	}

	for(i=0;i<32;i++)
	{
		places[i].x = (((float)rand()/(float)RAND_MAX)-0.5) * 3.0;
		places[i].y = (((float)rand()/(float)RAND_MAX)-0.5) * 3.0;
		places[i].z = (((float)rand()/(float)RAND_MAX)-0.5) * 10.0;
		printf("%f %f %f\n",places[i].x,places[i].y,places[i].z);
	}
			
	timer = al_create_timer(1.0 / 60.0);
	
	queue = al_create_event_queue();
	al_register_event_source(queue, al_get_keyboard_event_source());
	al_register_event_source(queue, al_get_display_event_source(display));
	al_register_event_source(queue, al_get_timer_event_source(timer));

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 400.0);

	al_start_timer(timer);
	
	start = al_get_time();
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_ALPHA_TEST);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ONE_MINUS_SRC_ALPHA);
	
	while (true)
	{
		al_wait_for_event(queue, &event);
		{
			switch (event.type)
			{
				case ALLEGRO_EVENT_DISPLAY_CLOSE:
					goto done;
				
				case ALLEGRO_EVENT_KEY_DOWN:
					if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
						goto done;
					break;
			}
			
			glMatrixMode(GL_MODELVIEW);
			glLoadIdentity();
			glTranslatef(0, 0, -6);
			glRotatef(0.0, 1, 0, 0);
			glRotatef(0.0, 0, 1, 0);
			glRotatef(0.0, 0, 0, 1);
			glColor4f(1.0,1.0,1.0,1.0);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			for(i=0;i<32;i++)
			//for(i=31;i>-1;i--)	//testing backwards
			{
				glBindTexture(GL_TEXTURE_2D, textures[i]);
				glBegin(GL_QUADS);
					glTexCoord2f(0.0,0.0);
					glVertex3f(places[i].x-0.5,places[i].y-0.5,places[i].z);

					glTexCoord2f(0.0,1.0);
					glVertex3f(places[i].x-0.5,places[i].y+0.5,places[i].z);

					glTexCoord2f(1.0,1.0);
					glVertex3f(places[i].x+0.5,places[i].y+0.5,places[i].z);

					glTexCoord2f(1.0,0.0);
					glVertex3f(places[i].x+0.5,places[i].y-0.5,places[i].z);
				glEnd();
			}
			
			frames++;
			al_flip_display();
			err = glGetError();
			if(err)
			{
				printf("error %d\n",err);
			}
		}
	}

done:

	printf("%.1f FPS\n", frames / (al_get_time() - start));
	al_destroy_event_queue(queue);
	return 0;
}
