#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include "Globals.h"
#include "Life.h"

int main(int argc, char **argv){
	uint32_t w=0, h=0;
	uint32_t width = 3600, height = 1800;
	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];
	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;


	FILE *fp = fopen("BACKUP.lr", "rb");
	if(!fp){
		printf("error opening file!\n");
		return 0;
	}
	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){
				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 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;

	n2 = species_c < 10 ? species_c : 10;
	printf("%u most populous:\n", n2);
	for(n1=0; n1<n2; n1++){
		Gen_Tribe_Color(&ten_s[n1], rgb);
		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("\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",
			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);
	}

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

	return 0;
}