#include "DEM.h"


static void Adjust_Sea_Level(struct image_attr *ia){
	//unsigned int height = ia->height;
	//unsigned int width  = ia->width;
	//unsigned int count1, count2;
	//unsigned char rgb[3];
	int sea_level_chng = 100;
	int is_rising = 0;
	//if(change){
		if(is_rising){
			if(sea_level_chng == 100){
				is_rising = 0;
			}else{
				sea_level_chng++;
			}
		}else{
			if(sea_level_chng == -100){
				is_rising = 1;
			}else{
				sea_level_chng--;
			}
		}
	//}
	ia->cur_sealevel = sea_level_chng;

		/*
		for(count1=0; count1<height; count1++){
			for(count2=0; count2<width; count2++){
				if(ia->data[count1][count2]<sea_level_chng){
					rgb[0] = 0;
					rgb[1] = 0;
					rgb[2] = 255;
				}else{
					rgb[0] = 0;
					rgb[1] = 255;
					rgb[2] = 0;
				}
				ia->image[count1*width*3+(count2*3)] = rgb[0];
				ia->image[count1*width*3+(count2*3+1)] = rgb[1];
				ia->image[count1*width*3+(count2*3+2)] = rgb[2];
			}
		}
		//sleep(1);
	//}
	*/
	//return sea_level_chng;
}

int Load_Terrain(struct image_attr *ia, char *filename){
	FILE *fp = fopen(filename, "rb");
	if(!fp){
		printf("Error opening file: %s\n", filename);
		return 1;
	}
	//NROWS         6000
	//NCOLS         4800
	//unsigned int height = 41600;
	//unsigned int width = 43200;
	const int start_sealevel = 100;
	unsigned int height = 1800; //40
	unsigned int width  = 3600; //27
	ia->image = malloc(sizeof(unsigned char)*height*width*3);
    ia->width = width;
    ia->height = height;
	ia->cur_sealevel = start_sealevel;
	//ia->data = (int16_t **)malloc(sizeof(int16_t *)*height);

	//double temp[27][40];
	//unsigned int temp_x = 0;
	//unsigned int temp_y = 0;

	char two_b[2];
	//u_int16_t
	union{ char a[2]; int16_t b;}x;
	unsigned int count1, count2;
	//int result = 0;
	unsigned char rgb[3];
	//unsigned int data_pnt_x = 0;
	//unsigned int data_pnt_y = 0;
	//unsigned int data_sum = 0;

	ia->data = (int16_t **)malloc(sizeof(int16_t *)*height);
	for(count1=0; count1<height; count1++){
		ia->data[count1] = (int16_t *)malloc(sizeof(int16_t)*width);
	}
	for(count1=0; count1<height; count1++){
		//if(temp_y == 39)
		//	temp_y = 0;
		//for(temp_y=0; temp_y<40; temp_y++;
		/*
		temp_y++;
		if(temp_y!=40){
			for(count2=0; count2<src_width; count2++){
				fread(&two_b, 1, 2, fp);
			}
		}
		if(temp_y==40){
			temp_y = 0;
		*/
			for(count2=0; count2<width; count2++){

				fread(&two_b, 1, 2, fp);
				x.a[0] = two_b[0];
				x.a[1] = two_b[1];
				ia->data[count1][count2] = x.b;
				//temp_x++;
				//if(temp_x==27){
				//	temp_x=0;

					//data_sum += x.b;
					//data_pnt++;
					//if(x.b > 0){
					//	result = 
					//if(count1 < 20 && count2 < 20)
					//	printf("%d\n", x.b);
					//if(x.b != 12)
					//	printf("hmm\b");
					//1 -9999 5825 -2347.6 4873.5
					//the band number, minimum value, maximum value, mean value, and standard deviation of the values in the raster

					//if(data_pnt == src_width){
					//	x.b = ceil(data_sum/src_width);
					//	data_pnt = 0;
//						if(x.b < -9999)
//							printf("low !\n");
//						if(x.b > 5825)
//							printf("high !\n");

/*						if(x.b<-5000){
							rgb[0] = 0;
							rgb[1] = 0;
							rgb[2] = 0; //ceil(255-(x.b/-13000)*255);
						}else if(x.b<-2500){
							rgb[0] = 0;
							rgb[1] = 0; //ceil(255-(x.b/-2500)*255);
							rgb[2] = 255;
						}else if(x.b<-1000){
							rgb[0] = 0;
							rgb[1] = 0;
							rgb[2] = 128; //ceil(255-(x.b/-1000)*255);
						}else if(x.b<-500){
							rgb[0] = 0; //ceil((x.b/-500)*255);
							rgb[1] = 128;
							rgb[2] = 128;

						}else*/ if(x.b < start_sealevel){
							rgb[0] = 0;
							rgb[1] = 0; //ceil(255-(x.b/-50)*255);
							rgb[2] = 255;
						}else{
							rgb[0] = 0;
							rgb[1] = 255;
							rgb[2] = 0;
						}
/*						
						black -13000
						blue -4000
						turquise 0
						green 3000
						yellow 6000
						red 9000
						-13000
						-6000
						0
						4000
						9000
						*/
						ia->image[count1*width*3+(count2*3)] = rgb[0];
						ia->image[count1*width*3+(count2*3+1)] = rgb[1];
						ia->image[count1*width*3+(count2*3+2)] = rgb[2];
					
			
			
		}
	}

	

	fclose(fp);
	return 0;
}


void World_Thread(struct image_attr *ia){
	uint64_t year = 1;
	uint64_t turn_death_total;
	double turn_life_total;
	size_t height = ia->height;
	size_t width = ia->width;

	struct timeval starttime,endtime;

	struct timeval teststart,testend;
	

	double time1 = 0;

	unsigned char rgb[3];
	//int cur_sealevel = 0;

	const int w = 2200;
	const int h = 900;
	int n1, n2; 
	int n3 = 0;

	//initialize empty life array
	Allocate_Life_Array(height, width);
	printf("Allocated Life array\n");
	//"plant" first primate tribe [somewhere in africa :)]
	//H 1000 W 2500
	//Gen_Tribe_Color(life[1070][2400], rgb);


	for(n1=w-5; n1<w+5; n1++){
		for(n2=h-5; n2<h+5; n2++){
			//need to check terrain for water
			if(ia->data[n2][n1] > ia->cur_sealevel){
				life[n2][n1] = (struct Species *)malloc( sizeof(struct Species) );
				Add_First_Life( life[n2][n1] );
				//if(n1==-5)
				Gen_Tribe_Color(life[n2][n1], rgb);
				ia->image[width*n2*3 + n1*3]     = rgb[0];
				ia->image[width*n2*3 + n1*3 + 1] = rgb[1];
				ia->image[width*n2*3 + n1*3 + 2] = rgb[2];
				n3++;
			}
		}
	}
	printf("Added %d initial tribes!\n", n3);
	/*
	life[1071][2401] = (struct Species *)malloc( sizeof(struct Species) );
	life[1070][2399] = (struct Species *)malloc( sizeof(struct Species) );
	//life[1070][1938] = (struct Species *)malloc( sizeof(struct Species) );
	//life[1071][1940] = (struct Species *)malloc( sizeof(struct Species) );
	Add_First_Life( life[1070][2400] );
	Add_First_Life( life[1071][2401] );
	Add_First_Life( life[1070][2399] );
	//Add_First_Life( life[1070][1938] );
	//Add_First_Life( life[1071][1940] );

	Gen_Tribe_Color(life[1070][2400], rgb);
	//Gen_Tribe_Color(life[1000][2501], rgb);

	ia->image[width*1070*3 + 2400*3]     = rgb[0];
	ia->image[width*1070*3 + 2400*3 + 1] = rgb[1];
	ia->image[width*1070*3 + 2400*3 + 2] = rgb[2];

	ia->image[width*1071*3 + 2401*3]     = rgb[0];
	ia->image[width*1071*3 + 2401*3 + 1] = rgb[1];
	ia->image[width*1071*3 + 2401*3 + 2] = rgb[2];
	
    ia->image[width*1070*3 + 2399*3]     = rgb[0];
    ia->image[width*1070*3 + 2399*3 + 1] = rgb[1];
    ia->image[width*1070*3 + 2399*3 + 2] = rgb[2];

    ia->image[width*1070*3 + 1938*3]     = rgb[0];
    ia->image[width*1070*3 + 1938*3 + 1] = rgb[1];
    ia->image[width*1070*3 + 1938*3 + 2] = rgb[2];

    ia->image[width*1071*3 + 1940*3]     = rgb[0];
    ia->image[width*1071*3 + 1940*3 + 1] = rgb[1];
    ia->image[width*1071*3 + 1940*3 + 2] = rgb[2];
	*/

	FM_Alloc(height, width);


	//printf("Added First Life ~2000x1070\n");

	gettimeofday(&starttime, NULL);
	while(1){
		//start calculating years
		
		//raise sea level if right multiple (going by 1m per 1000yrs) based on data from past 140yrs for now ...
		//drawls terrain/land into image
		if(year%1000 == 0){ // 1000yrs = 1meter
			Adjust_Sea_Level(ia);
		}
		//else{
		//	Adjust_Sea_Level(ia, 0);
			//printf("adjusted sea level\n");
		//}
		//if sealevel rise encroaches on tribe either move or die (1px = 12KM)
			//if moved here, no migration (move twice)

		if(year == 15)
			exit(1);



		gettimeofday(&teststart, NULL);
		//migrate
		Tribe_Actions(ia);
		//printf("ran tribe_actions\n");
		gettimeofday(&testend, NULL);
		time1 = ((double)(testend.tv_sec*1000000-teststart.tv_sec*1000000+testend.tv_usec-teststart.tv_usec))/1000000;
		printf("Tribe Actions: %lf\n", time1);

		// ^^ initiate actions combat/desease/create_life/migrate/socialize

		gettimeofday(&teststart, NULL);
		//parse life array and drawl tribes into image
		Drawl_Image(ia);
		//printf("drew image\n");
		gettimeofday(&testend, NULL);
		printf("Drawl_Image(: %lf\n", time1);


		//gettimeofday(&teststart, NULL);
		//increment year
		year++;
		//print seconds/year every 10yrs 
		if(year%1000 == 0){
			gettimeofday(&endtime, NULL);
			time1 = ((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
			printf("\nYear: %lu Sec/Year: %lf\n", year, time1/1000);
			printf("sealevel: %u\n", ia->cur_sealevel);
			gettimeofday(&starttime, NULL);
			//process stats
			printf("deaths\n");
			printf("disease: %u drown: %u old_age: %u died_attacking: %u died_defending: %u\n",  stats.disease, stats.drown, stats.old_age, stats.died_attacking, stats.died_defending);
			turn_death_total = stats.disease + stats.drown + stats.old_age + stats.died_attacking + stats.died_defending;
			printf("\tsubtotal: %lu\n", turn_death_total);
			printf("life\n");
			printf("new_life: %u new_species: %u\n", stats.new_life, stats.new_species);
			turn_life_total = stats.new_life - turn_death_total;
			printf("\tnet subtotal: %.00lf\n", turn_life_total);

			printf("Totals:\n");
			stats.t_disease += stats.disease;
			stats.t_drown += stats.drown;
			stats.t_old_age += stats.old_age;
			stats.t_died_attacking += stats.died_attacking;
			stats.t_died_defending += stats.died_defending;
			stats.t_new_life += stats.new_life;
			stats.t_new_species += stats.new_species;
			//t_species_extinct;
			printf("\tdisease: %lu\n", stats.t_disease);
			printf("\tdrown: %lu\n", stats.t_drown);
			printf("\told_age: %lu\n", stats.t_old_age);
			printf("\tdied_attacking: %lu\n", stats.t_died_attacking);
			printf("\tdied_defending: %lu\n", stats.t_died_defending);
			printf("\tnew_life: %lu\n", stats.t_new_life);
			printf("\tnew_species: %lu\n", stats.t_new_species);

			stats.disease = 0;
			stats.drown = 0;
			stats.old_age = 0;
			stats.died_attacking = 0;
			stats.died_defending = 0;
			stats.new_life = 0;
			stats.new_species = 0;

		}
	}

}