//#include "Png_Funcs.h"
#include "OpenGL.h"

#define TOGGLE 0
#define PAUSED 1
#define EXIT_AND_SAVE 2
#define EXIT_NO_SAVE 3
//struct image_attr *im_p;
GLuint Image_Texture;
double Eye_X = 0;
double Eye_Y = 0;
double Eye_Z = -3;
char scorestring[32];
//char ignoreRepeats = ;
//struct timespec ts;
struct timeval starttime,endtime;
int Toggle_Image_Type = 1;
int Toggle_Paused = -1;
//GLUquadric* QuadricObject;

unsigned char rgb2[10][3] = {
        {255, 0, 0}, //red
        {170, 170, 38}, //puke
        {255, 255, 0}, //yellow
        {255, 127, 0}, //orange
        {127, 0, 127}, //purple
        {0, 127, 127}, //turqois
        {0, 255, 255}, //light blue
        {127, 64, 0}, //brown
        {127, 127, 127}, //grey
        {255, 255, 255} //white
};

//unsigned char Legend[] = {
//};


static void GL_Draw_Image(void);
static void processMenuEvents(int option);
static void special(int key, int x, int y);
static void Frames(double fps);
static void BindTexture(GLuint texture);

static void createGLUTMenus(void){
	int menu;
	menu = glutCreateMenu(processMenuEvents);
	glutAddMenuEntry("Toggle Show Top 10",TOGGLE);
    glutAddMenuEntry("Pause",PAUSED);
    glutAddMenuEntry("Save & Exit",EXIT_AND_SAVE);
	glutAddMenuEntry("Exit Without Saving",EXIT_NO_SAVE);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
}

static void processMenuEvents(int option) {
	switch(option){
		case TOGGLE :
			if(Toggle_Image_Type)
				Toggle_Image_Type = 0;
			else
				Toggle_Image_Type = 1;
			//printf("not implemented !\n");
			break;
		case PAUSED :
			Toggle_Paused *= -1;
			printf("not implemented !\n");
			break;
		case EXIT_AND_SAVE :
			printf("Saving and Exiting Program !!\n");
			No_Exit = 0;
			pthread_exit(NULL);
			break;
		case EXIT_NO_SAVE :
			printf("Exiting Program Without Saving!!\n");
			No_Exit = 2;
			pthread_exit(NULL);
			break;
	}
}

static void special(int key, int x, int y){
	switch(key){
		case GLUT_KEY_UP:
			Eye_Y-=.1;
			break;
		case GLUT_KEY_DOWN:
			Eye_Y+=.1;
			break;
		case GLUT_KEY_RIGHT:
			Eye_X+=.1;
			//printf("increment num1: %lf\n", num1);
			break;
		case GLUT_KEY_LEFT: 
			Eye_X-=.1;
			//printf: %lf\n", num1);
			break;
		case GLUT_KEY_PAGE_UP:
			Eye_Z+=Eye_Z/10;
			break;
		case GLUT_KEY_PAGE_DOWN:
			Eye_Z-=Eye_Z/10;
			break;
	}
}

static void Frames(double fps){
	//scorestring[strlen(scorestring)-1]='\0';
	(void)memset(scorestring, '\0', 32);
	//if(fps > 10)
	//	return;
	//	printf("Error!\n");
	int empty = 0;
	const char ten[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	empty = sprintf(scorestring, "%.02lf", fps);

	float pos[3] = {-1, 10, -25};
	//printf("%.02lf\n", fps);
	int i = 0;
    glPushMatrix();
    glLoadIdentity();

	//GLint param
	//glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
	//glPushAttrib(GL_PIXEL_MODE_BIT);
	//glPushMatrix();
	//glLoadIdentity();
	//glColor3f(1.0, 1.0, 1.0);
	//glGetIntegerv(GL_CURRENT_RASTER_POSITION, &params);
	//printf("%d\n", params);
	//glColor3f(1.0, 1.0, 1.0);
	//glRasterPos3i(-3, 8, -15);
	//glRasterPos3f((GLfloat)0.0, (GLfloat)0.0, (GLfloat)0.0);
	//glRasterPos3f((GLfloat)-0.75, (GLfloat)1.1, (GLfloat)0.0);
	//glColor3f(1.0, 0.0, 0.0);
	//glRasterPos3f(1, 8, -15);


	if(!Toggle_Image_Type){
		for(i=0; i<10; i++){
			pos[0]+=0.5;
			//glPushAttrib(GL_CURRENT_BIT);
			glColor3f(rgb2[i][0], rgb2[i][1], rgb2[i][2]);
			glRasterPos3f(pos[0], pos[1], pos[2]);
			glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'C');
			glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,' ');
			//glPopAttrib();
		}
	}

	pos[0]+=0.1;
	//glPushMatrix();
	//glPushAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
	//glPushAttrib(GL_CURRENT_BIT);
	glColor3f(1.0, 0.0, 0.0);
	//glColor(red);
	glRasterPos3f(pos[0], pos[1], pos[2]);
	//glColor3f(1.0, 0.0, 0.0);
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'F');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'P');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'S');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'(');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'c');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'a');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'p');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'2');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'0');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,')');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,':');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	//scorestring[strlen(scorestring)-1]='\0';
	//empty = sprintf(scorestring, "%.02lf", fps);
	for(i = 0; scorestring[i] != '\0'; i++){
		//glColor3f(1.0, 0.0, 0.0);
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, scorestring[i]);
	}
	//glPopAttrib();
	/*
	//ia->cur_sealevel
	glLoadIdentity();
	glColor3f(1.0, 1.0, 1.0);
	glRasterPos3f(3, 6, -15);
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	*/
	//glPopClientAttrib();
	//glPopAttrib(GL_PIXEL_MODE_BIT);
	glPopMatrix();
	glutSwapBuffers();
	glutPostRedisplay();
}



//GLuint LoadTexture(void){
    //static struct timespec ts;
    //ts.tv_sec = 0;
    //ts.tv_nsec = 100000;
	//static int loaded = 0;
	//GLuint texture;

	//glDeleteTextures( 1, &texture );
	//glGenTextures( 1, &Image_Texture );

	//glBindTexture( GL_TEXTURE_2D, Image_Texture );

	//glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
	//glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
//	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
//	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
//	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	//while(Image_Locked){
	//	nanosleep (&ts, NULL);
	//}
	//Image_Locked = 1;
	//if(loaded)
	//	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ia->width, ia->height, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)ia->image);
	//else
//	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ia->width, ia->height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)ia->image);
	//Image_Locked = 0;
	//loaded = 1;
//	return 1;
//}

//static void FreeTexture( GLuint texture ){
//	glDeleteTextures( 1, &texture );
//}

static void BindTexture(GLuint texture){
	glEnable(GL_TEXTURE_2D);
	//glDeleteTextures( 1, &texture );
	//glGenTextures( 1, &Image_Texture );
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ia->width, ia->height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)ia->image);
	glBindTexture( GL_TEXTURE_2D, Image_Texture );
	glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

	//glRotatef( 180, 0.0f, 0.0f, 1.0f );
	//float aspect = im_p->width / im_p->height;
	//float aspect2 = im_p->height / im_p->width;
//	float y = 1;
	//float y = (aspect>1)? x/aspect: x*aspect;
//	float x = y*aspect;
	float x = 1;
	float y = 1;
	//glScalef(aspect1, aspect2, 1);
/*
    glBegin (GL_QUADS);
    glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0); //with 
    glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0); //so that
    glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);
    glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);
    glEnd();
	

*/

/*
glRotatef( 180, Eye_X, Eye_Y, Eye_Z );
glTranslatef(0.0, 0.0, -10.0 );
glColor3f(1.0f,1.0f,1.0f);
gluSphere( QuadricObject, 286.4789, 500, 1000);
*/


	glColor3f(1.0f,1.0f,1.0f);
    glBegin (GL_QUADS);
    glTexCoord2d(0.0,y); glVertex2d(x,-1.0*y);
    glTexCoord2d(0.0,0.0); glVertex2d(x,y);
    glTexCoord2d(x,0.0); glVertex2d(-1.0*x,y);
    glTexCoord2d(x,y); glVertex2d(-1.0*x,-1.0*y);
    glEnd();


	//This is how texture coordinates are arranged
	//
	//  0,1   ---   1,1
	//       |     |
	//       |     |
	//       |     |
	//  0,0   ---   1,0
	glDisable(GL_TEXTURE_2D); 
	glutSwapBuffers();
	glutPostRedisplay();

}

static void display(void){
	static struct timespec ts;
    ts.tv_sec = 0; 

    ts.tv_nsec = 50000000; //1/10th of a second

	//uint32_t skip = 25;
	static double time1 = 2;
	static double frame_c = 0;
	static double fps = 0;
	static uint32_t frame_c_draw = 9;

	//while(Toggle_Paused)
	//	sleep(1);


    glClearColor (0.0,0.0,0.0,1.0);
    //glClear (GL_COLOR_BUFFER_BIT);
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//glPushMatrix();
    glLoadIdentity();
	//glClearColor (0.0,0.0,0.0,1.0);
    //glEnable( GL_TEXTURE_2D );
	//glRasterPos3i(0, 0, 0);
	//GLuint texture;
	//texture = LoadTexture( im_p );

	//glRotatef( 180, 0.0f, 0.0f, 1.0f );
	//glTranslatef(
	gluLookAt ( Eye_X, Eye_Y, Eye_Z,  Eye_X, Eye_Y, 0.0, 0.0, 0.1, 0.0);
	//gluLookAt( , Eye_Y, Eye_Z, Look_X, Look_Y, 20, 0, .1, 0);

	//while(Image_Locked){
	//	sleep(
	//}
	//nanosleep (&ts, NULL);

	if(Toggle_Image_Type){
		nanosleep (&ts, NULL);
		Drawl_Image();
		//BindTexture(Image_Texture);
	}else{
		frame_c_draw++;
		if( (frame_c_draw % 25) == 0){
			GL_Draw_Image();
			frame_c_draw = 0;
			//BindTexture(Image_Texture);
		}else{
			nanosleep (&ts, NULL);
		}
	}
	//might as well make these one func
	//(void)LoadTexture();
	//glLoadIdentity();
	//gluLookAt ( Eye_X, Eye_Y, Eye_Z,  Eye_X, Eye_Y, 0.0, 0.0, 0.1, 0.0);
	//glPushAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
	//glPushMatrix();
	//glEnable( GL_TEXTURE_2D );
	
	BindTexture(Image_Texture);
	//glDisable( GL_TEXTURE_2D );
	//glPopAttrib();
	//glPopMatrix();

	frame_c++; //frame counter
	if(time1 > 1){
		gettimeofday(&endtime, NULL);
		time1=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
		fps = frame_c / time1;
		gettimeofday(&starttime, NULL);
		frame_c = 0;
	}else{
		gettimeofday(&endtime, NULL);
		time1=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
	}
	//glPushMatrix();
	//glEnable( GL_TEXTURE_2D );
	//glLoadIdentity();
	//gluLookAt ( Eye_X, Eye_Y, Eye_Z,  Eye_X, Eye_Y, 0.0, 0.0, 0.1, 0.0);
	Frames(fps);
	//glDisable( GL_TEXTURE_2D );
	//glPopMatrix();
	//glutSwapBuffers();
	//glFlush();
    //glutSwapBuffers();
	//sleep(1);
	//glutPostRedisplay();
	//nanosleep (&ts, NULL);
	
	


	//FreeTexture( Image_Texture );

	//sleep(1);
	//FreeTexture(texture);

}


static void reshape(int w, int h){
	GLfloat aspect = (GLfloat)ia->width / (GLfloat)ia->height;
	//GLsizei width;
	//GLzisei height; 
	

    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
	gluPerspective (60, (GLfloat)w / (GLfloat)h/aspect, 0.0 , 100.0);
    //gluPerspective (60, (GLfloat)im_p->width / (GLfloat)im_p->height, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);

}



void *Run_GL(void *bla){
	//im_p = im;

	//int bla1;
	//char **bla2 = NULL;
    //glutInit (&bla1, bla2);

    //query_ext(); 
    glutInitDisplayMode (GLUT_DOUBLE| GLUT_RGB | GLUT_DEPTH);
	//	glutInitDisplayMode (GLUT_DOUBLE);

	printf("w: %zu h: %zu\n", ia->width, ia->height);
    //glutInitWindowSize((int)im->width/4, (int)im->height/4);
	glutInitWindowSize(1200, 1200); 

   glutInitWindowPosition (0, 0);
    glutCreateWindow ("A basic OpenGL Window");
    glutDisplayFunc (display);
    //glutIdleFunc (display);
    glutReshapeFunc (reshape);
    //glutMotionFunc(mouse_active);
    //glutPassiveMotionFunc(mouse_passive); 
    //query_ext();
	glutIgnoreKeyRepeat(0); 
    glutSpecialFunc(special);
	//(void)LoadTexture( im_p );

	//sleep(4);
	glGenTextures( 1, &Image_Texture );

//	QuadricObject = gluNewQuadric();
//	gluQuadricTexture(QuadricObject, 1);


	//(void)LoadTexture();
	//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ia->width, ia->height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)ia->image); 
	//gettimeofday(&starttime, NULL); 
	createGLUTMenus();
	glutMainLoop ();
	//FreeTexture( Image_Texture ); 
   //return 0;
	pthread_exit(NULL);
}

//#include <stdio.h>
//#include <stdlib.h>
//#include <stdint.h>
//#include <math.h>
//#include "lrstats-gl.h"
//#include "Globals.h"
//#include "Life.h"
//#include "DEM.h"

//unsigned char rgb2[10][3] = { {255, 0, 0}, {0, 0, 255}, {255, 255, 0}, {255, 127, 0}, {127, 0, 127}, {0, 127, 127}, {0, 255, 255}, {127, 0, 255}, {127, 127, 127}, {255, 0, 127} } ;;


static void GL_Draw_Image(void){
	uint32_t w=0, h=0;
	uint32_t width = ia->width;
	uint32_t height = ia->height;
	//uint64_t year = 0;
	uint32_t n1=0, n2=0, n3=0;
	uint32_t species_c = 1;
	size_t size_of_species_t = 1000;
	uint32_t ten_most[10];
	unsigned char rgb[3] = {0, 0, 0};
/*
	unsigned char rgb2[10][3] = {
		{255, 0, 0}, //red
		{170, 170, 38}, //puke
		{255, 255, 0}, //yellow
		{255, 127, 0}, //orange
		{127, 0, 127}, //purple
		{0, 127, 127}, //turqois
		{0, 255, 255}, //light blue
		{127, 64, 0}, //brown
		{127, 127, 127}, //grey
		{0, 0, 0} //white
	};
*/
	//64, 127, 127
	struct Species *ten_s = malloc(sizeof(struct Species)*10);
	struct Species *species_t = malloc(sizeof(struct Species) * size_of_species_t);
	uint32_t *species_totals = malloc(sizeof(uint32_t) * size_of_species_t);
	//size_t total_read = 0;
	uint32_t total_population = 0;

	//No_Exit = 1;

/*
	FILE *fp = fopen("BACKUP.lr", "rb");
	if(!fp){
		printf("error opening file!\n");
		return 0;
	}
    char *filename = (char *)malloc(strlen("myout.test") + 1);
    strcpy(filename, "myout.test");
    if( (int)Load_Terrain( (char *)filename) ){
        printf("Load Terrain Error!\n");
        exit(1);
    }
    printf("read DEM!\n");
*/

	//Load_Terrain(char *filename);

//	Allocate_Life_Array(height, width);


/*
	//stats = (struct Stats *)malloc( sizeof(struct Stats) * regions);
    total_read += fread((void *)&stats_t, sizeof(struct Stats_T), 1, fp);
    for(h=0; h<height; h++){
        for(w=0; w<width; w++){
            total_read += fread((void *)life[h][w], 1, sizeof(struct Species), fp);
        }
    }
*/

//    ia = malloc(sizeof(struct image_attr));
    //ia->image = malloc(sizeof(unsigned char)*height*width*3);
//    ia->width = width;
//    ia->height = height;
    //ia->cur_sealevel = start_sealevel;
/*
    total_read += fread((void *)&ia->cur_sealevel, 1, sizeof(int),fp);
    total_read += fread((void *)&ia->sea_rising, 1, sizeof(int), fp);
    total_read += fread((void *)&year, 1, sizeof(uint64_t), fp);
	printf("Total_read(bytes):%zu\n", total_read);

*/
	species_totals[0] = 9;
	//(void)memset((void *)species_totals, '\0', sizeof(uint32_t)*species_c);

	for(h=0; h<height; h++){
		for(w=0; w<width; w++){
			if(life[h][w]->alive){
				(void)memcpy((void *)&species_t[0], (const void *)life[h][w], sizeof(struct Species) );
				species_totals[0] = 0;
				break;
			}//else{
			//	(void)memset((void *)&stats[n1], '\0', sizeof(struct Stats) );
			//}
		}
		if(species_totals[0] == 0)
			break;
	}
	for(h=0; h<height; h++){
		for(w=0; w<width; w++){

			if(life[h][w]->alive){
				total_population++;
				for(n1=0; n1<species_c; n1++){
					if( Is_Same_Species(&species_t[n1], life[h][w]) ){
						species_totals[n1]++;
						//continue;
						goto Next_Tribe;
					}
				}
				species_c++;
				if(species_c > size_of_species_t){
					size_of_species_t += 500;
					species_t = (struct Species *)realloc(species_t, sizeof(struct Species) * size_of_species_t);
					species_totals = (uint32_t *)realloc(species_totals, sizeof(uint32_t) * size_of_species_t);
					//set all new species_totals = 0;
					for(n3=species_c; n3<size_of_species_t; n3++){
						(void)memset((void *)&species_t[n3], '\0', sizeof(struct Species) );
						//(void)memset((void *)&species_totals[n3], '\0', sizeof(struct Species) );
						species_totals[n3] = 0;
					}
				}
				species_totals[species_c-1] = 1;
				(void)memcpy((void *)&species_t[species_c-1], (const void *)life[h][w], sizeof(struct Species) );
			}
			Next_Tribe:
			;
		}
	}
	for(n1=0; n1<10; n1++)
		ten_most[n1] = 0;

//	printf("%u total population\n", total_population);
//	printf("%u unique species alive\n", species_c);
	uint32_t last_highest = 0;
	last_highest--;
	uint32_t highest = 0;

	for(n2=0; n2<10; n2++){
		for(n1=0; n1<species_c; n1++){
			if(species_totals[n1] < last_highest){
				if(species_totals[n1] > highest){
				//if(species_totals[n1] < last_highest){
					highest = species_totals[n1];
					ten_most[n2] = highest;
					(void)memcpy((void *)&ten_s[n2], (const void *)&species_t[n1], sizeof(struct Species) );
				}
			}
		}
		last_highest = highest;
		highest = 0;
	}

	/*
	for(n1=0; n1<species_c; n1++){
		for(n2=0; n2<10; n2++){

			if(species_totals[n1] > ten_most[n2]){
				ten_most[n2] = species_totals[n1];
				//species_totals[n1] = 0;
				(void)memcpy((void *)&ten_s[n2], (const void *)&species_t[n1], sizeof(struct Species) );
				break;
			}

		}
	}
	*/


/*
	//sums up to 1658880000 maximum value
	float social_factor = 0;
	float migration_factor = 0;
	float fight_flight_balance = 0;
	float interspecies_violence = 0;
	float imunity = 0;
	float avg_age = 0;
	//unsigned char c_count[] = {0, 0, 0};

	n2 = species_c < 10 ? species_c : 10;

	printf("%u most populous:\n", n2);
	printf("black color for all others\n");

	printf("\t\t\tSpecies_Traits(0 to +3)\t\t:\t\tSub_Species_Traits(avgs)\n\n");
	printf("%%Pop_t  Pop rgb(stats)/(sim)  intel  stren  speed  temp_l  temp_h  max_age : ");
	printf("social_factor  migration_f  fight/flight  interspecies_violence  imunity  avg_age\n");

	for(n1=0; n1<n2; n1++){
		Gen_Tribe_Color(&ten_s[n1], rgb);
		//printf("%u\t %u\t %u,%u,%u\t: %u\t %u\t %u\t %u\t %u\t %u\n", 
		printf("%.03lf%%\t%u\t%u,%u,%u/%u,%u,%u\t", ( (double)ten_most[n1]/(double)total_population ), ten_most[n1], rgb2[n1][0], rgb2[n1][1], rgb2[n1][2], rgb[0], rgb[1], rgb[2]);
		//printf("#%u population: %u map rgb: %u,%u,%u\n", n1, ten_most[n1], rgb[0], rgb[1], rgb[2]);
		//printf("\tspecies traits (0 to +3 range):\n");
		ten_s[n1].intelligence = floor(ten_s[n1].intelligence/4)*4;
		ten_s[n1].strength = floor(ten_s[n1].strength/4)*4;
		ten_s[n1].speed = floor(ten_s[n1].speed/4)*4;
		ten_s[n1].temp_l = floor(ten_s[n1].temp_l/4)*4;
		ten_s[n1].temp_h = floor(ten_s[n1].temp_h/4)*4;
		ten_s[n1].max_age = floor(ten_s[n1].max_age/4)*4;

		printf("%u\t%u\t%u\t%u\t%u\t%u\t:\t",ten_s[n1].intelligence, ten_s[n1].strength,
		//printf("\t\tintelligence: %u strength: %u speed: %u temp_l: %u temp_h: %u max_age: %u\n", ten_s[n1].intelligence, ten_s[n1].strength,
				ten_s[n1].speed, ten_s[n1].temp_l, ten_s[n1].temp_h, ten_s[n1].max_age);
		for(h=0; h<height; h++){
			for(w=0; w<width; w++){
				if(life[h][w]->alive){
					if( Is_Same_Species(&ten_s[n1], life[h][w]) ){
						social_factor += life[h][w]->social_factor;
						migration_factor += life[h][w]->migration_factor;
						fight_flight_balance += life[h][w]->fight_flight_balance;
						interspecies_violence += life[h][w]->interspecies_violence;
						imunity += life[h][w]->imunity;
						avg_age += life[h][w]->cur_age;
					}
				}
			}
		}
		social_factor /= ten_most[n1];
		migration_factor /= ten_most[n1];
		fight_flight_balance /= ten_most[n1];
		interspecies_violence /= ten_most[n1];
		imunity /= ten_most[n1];
		avg_age /= ten_most[n1];

		//printf("\tsub-species traits (averaged):\n");
		 //printf("\t\tsocial_factor: %u migration_factor: %u fight/flight: %u interspecies_violence: %u imunity: %u\n", ten_s[n1].social_factor, 
		 //		ten_s[n1].migration_factor, ten_s[n1].fight_flight_balance, ten_s[n1].interspecies_violence, ten_s[n1].imunity);
		//printf("\t\tsocial_factor: %.02f migration_factor: %.02f fight/flight: %.02f interspecies_violence: %.02f imunity: %.02f avg_age: %.02f\n",
		printf("%.02f\t%.02f\t%.02f\t%.02f\t%.02f\t%.02f\n",
			social_factor, migration_factor, fight_flight_balance, interspecies_violence, imunity, avg_age);

		social_factor = 0;
		migration_factor = 0;
		fight_flight_balance = 0;
		interspecies_violence = 0;
		imunity = 0;
		avg_age = 0;

			//printf("\t\tintelligence: %u strength: %u speed: %u social_factor: %u\n", ten_s[n1].intelligence, ten_s[n1].strength,
			//		ten_s[n1].speed, ten_s[n1].social_factor);
			//printf("\t\tffb: %u iv: %u ma: %u mf: %u th: %u tl: %u\n", ten_s[n1].fight_flight_balance, ten_s[n1].interspecies_violence,
			//		ten_s[n1].max_age, ten_s[n1].migration_factor, ten_s[n1].temp_h, ten_s[n1].temp_l);
	}

*/

	n2 = species_c < 10 ? species_c : 10;
	//remove all species from map that aren't in the top 10, and add better coloring


    for(h=0; h<height; h++){
        for(w=0; w<width; w++){
            if(ia->data[h][w] > ia->cur_sealevel){
                if(!life[h][w]->alive){
                    rgb[0] = 0;
                    rgb[1] = 255;
                    rgb[2] = 0;
                    //continue;
                }else{
					for(n1=0; n1<n2; n1++){
						if( Is_Same_Species(&ten_s[n1], life[h][w]) ){
							rgb[0] = rgb2[n1][0];
							rgb[1] = rgb2[n1][1];
							rgb[2] = rgb2[n1][2];
							break;
						}
						//if(n1 == n2-1){
						rgb[0] = 0;
						rgb[1] = 0;
						rgb[2] = 0;
						//}
					}
					//rgb[0] = 0;
					//rgb[1] = 0;
					//rgb[2] = 0;
                    //Gen_Tribe_Color(life[n1][n2], rgb);
                }
            }else{
				rgb[0] = 0;
				rgb[1] = 0;
				rgb[2] = 255;
			}
            ia->image[h*width*3+(w*3)]   = rgb[0];
            ia->image[h*width*3+(w*3+1)] = rgb[1];
            ia->image[h*width*3+(w*3+2)] = rgb[2];
        }
    }


	//glutInit(&argc,argv);
	//Run_GL(NULL);

	free(ten_s);
	free(species_t);
	free(species_totals);
	//free(species_t);
	//fclose(fp);

	//return 0;
}