#include "Life.h"

void KILL_Tribe(uint32_t y, uint32_t x){
	life[y][x]->alive = 0;
	fought[y][x] = 0;
	mated[y][x] = 0;
	//stats_t.total_living--;
}

void Allocate_Life_Array(void){
	uint32_t n1, n2;
	life = (struct Species ***)malloc(sizeof(struct Species **) * HEIGHT);
	for(n1=0; n1<HEIGHT; n1++){
		life[n1] = (struct Species **)malloc(sizeof(struct Species *) * WIDTH);
		for(n2=0; n2<WIDTH; n2++){
			life[n1][n2] = (struct Species *)malloc(sizeof(struct Species));
			(void)memset( (void *)life[n1][n2], '\0', sizeof(struct Species) );
		}
	}
}

void Gen_Tribe_Color(struct Species *one, unsigned char *rgb){
	// 6751269 possibilities based on species/traits
	rgb[0] = one->intelligence;
	rgb[1] = (unsigned char)floor((double)one->strength/2) + floor((double)one->speed/2);
	rgb[2] = one->temp_l + one->temp_h + one->max_age;
}

int Is_Same_Species(struct Species *one, struct Species *two){
	// "dna" determined by all variables, no one variable can deviate more than 4
	//better to implement steps instead ie: 0-3 4-7 8-11 etc.  4*(0->63)+(0->4)
	// y=mx+b   y range 0-255,  if x = x same species, b == subspecies deviation
	//must allow for subspecies deviation
	//unsigned char x = floor(num/4);
	//b = 255%4 * 4;
	//if(one == NULL || two == NULL)
	//	return 0;

	if( one->intelligence/4 != two->intelligence/4 )
		return 0;
	if( one->strength/4 != two->strength/4 )
		return 0;
	if( one->speed/4 != two->speed/4 )
		return 0;
	if( one->temp_l/4 != two->temp_l/4 )
		return 0;
	if( one->temp_h/4 != two->temp_h/4 )
		return 0;
	if( one->max_age/4 != two->max_age/4 )
		return 0;
	//if( floor((double)one->reproductive_rate/4) != floor((double)two->reproductive_rate/4) )
	//	return 0;

	return 1;
}

void Add_First_Life(struct Species *one){
	one->alive = 1;
	one->intelligence          = INTELLIGENCE;
	one->strength              = STRENGTH;
	one->speed                 = SPEED;
	one->imunity               = IMUNITY;
	one->temp_l                = TEMP_L;
	one->temp_h                = TEMP_H;
	//one->reproductive_rate     = REPRODUCTIVE_RATE;
	one->max_age               = MAX_AGE;
	one->cur_age               = CUR_AGE;
	one->fight_flight_balance  = FIGHT_FLIGHT_BALANCE;
	one->interspecies_violence = INTERSPECIES_VIOLENCE;
	one->migration_factor      = MIGRATION_FACTOR;
	one->social_factor         = SOCIAL_FACTOR;
	one->water_turns           = 0;
	one->water_direction       = 0;
}

float Location_Temp(uint32_t src_y, uint32_t src_x){
	//return temperature at any given src_y src_x
	float location_temp = (float)stats_t.cur_temp;
	float equator_dist = 0;

	//bordering water, degrees cooler maybe

	//elevation effect
	if(ia->dem[src_y][src_x] < 11001){
		location_temp -= TEMP_PER_1000M*((float)(ia->dem[src_y][src_x]-stats_t.cur_sealevel)/1000);
	}
		//else{
		//location_temp -= TEMP_11K_TO_20K;
	//}
	//dealing with 1/12th scale of 30 arc-second grid
	//1 arc minute = 1/60 of 1deg
	//30 arc-second = 1/30 of 1deg
	//1px = 12x 30 arc-second  = 2/5 of 1deg
	//1800px = 90-0-90  900px is equator

	//equatorial distance effect
	equator_dist = abs( (float)src_y - (float)HEIGHT/2 ) * 2 / 5;  //degrees from equator

	//45c different between eq and poles  .5C per 1deg  hmmmm
	location_temp -= equator_dist / DEM_SCALE;

	return location_temp;
}

int Climate_Fatal(struct Species *one, uint32_t src_y, uint32_t src_x){
	//return 1 if climate would kill tribe at this location
	// 6.49C/1000m 
	// -56.5 °C above 11000m

	//need to account for intelligence and strength to withstand
	float location_temp = Location_Temp(src_y, src_x);

	if(location_temp > (float)one->temp_h){ //if temp is higher than tribe can withstand
		//2 parts intel 1 part strength
		// 127 * 3 = 381
		//
		// initial tribes will have +/-4 added to their tolerance range
		// 
		if( ((float)one->temp_h + (float)floor( ((double)one->intelligence*2+(double)one->strength) / 10) ) < location_temp ){ //if it's still higher
			return 1;
		}
	}
	if(location_temp < (float)one->temp_l){ //if temp is lower than tribe can withstand
		if( ((float)one->temp_l + (float)floor( ((double)one->intelligence*2+(double)one->strength) / 10) ) > location_temp ){ //if it's still lower
			return 1;
		}
	}
	return 0;
}

void Create_Life(struct Species *one, struct Species *two, struct Species *three){
	//mix sub species 1 and 2 to create 3 (average of 1 and 2) [ ~8.3% chance of (+/-1pt) species deviation ]
	//chance of new species:  ~1% 
	uint32_t rand1, rand2;
	//uint32_t n1 = 0;
	int use_ceil = 0;
	float tmp;
	//double bigtmp;
	struct timeval cur;
	gettimeofday(&cur, NULL);
	uint64_t s = (unsigned int)cur.tv_usec + 3;
	rand1 = lrand(&s) % 2;
	if(rand1)
		use_ceil = 1;

	three->alive = 1;
	three->water_turns = 0;
	three->water_direction = 0;
	//genetic
	tmp = (float)((float)one->intelligence + (float)two->intelligence) / 2;
	three->intelligence = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );
	tmp = (float)((float)one->strength + (float)two->strength) / 2;
	three->strength = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );
	tmp = (float)((float)one->speed + (float)two->speed) / 2;
	three->speed = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );
	//keep within ranges
	tmp = (float)((float)one->temp_l + (float)two->temp_l) / 2;
	three->temp_l = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );
	tmp = (float)((float)one->temp_h + (float)two->temp_h) / 2;
	three->temp_h = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );
	tmp = (float)((float)one->max_age + (float)two->max_age) / 2;
	three->max_age = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );

	//non-genetic
	tmp = (float)((float)one->social_factor + (float)two->social_factor) / 2;
	three->social_factor = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );
	tmp = (float)((float)one->interspecies_violence + (float)two->interspecies_violence) / 2;
	three->interspecies_violence = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );
	tmp = (float)((float)one->fight_flight_balance + (float)two->fight_flight_balance) / 2;
	three->fight_flight_balance = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );
	tmp = (float)((float)one->migration_factor + (float)two->migration_factor) / 2;
	three->migration_factor = (unsigned char)( use_ceil ? ceil(tmp) : floor(tmp) );

	//fixed to 1 for now
	//three->reproductive_rate = 1;
	//three->reproductive_rate = (one->reproductive_rate+two->reproductive_rate)/2
	//starts at 0yrs old
	three->cur_age = 0;
	three->imunity = (unsigned char)IMUNITY;
	//suseconds_t signed integer type capable of storing values at least in the range [-1, 1000000].

	//rand1 = (int)ceil((double)1/( CHANCE_OF_EVOLUTION ));
	//rand1 = (int)ceil((double)1/( CHANCE_OF_EVOLUTION )*80/3*100);
	//if(lrand(&s) % 100 > rand1)
	//	return;

	//bigtmp = 1/CHANCE_OF_DEVIATION;

	//rand1 = (uint32_t)ceil(bigtmp*2147483648);
	//rand2 = (uint32_t)ceil(lrand(&s)/2);

	//rand2 = lrand(&s) % 2;
	rand1 = (int32_t)ceil(CHANCE_OF_EVOLUTION*3/10);
	rand2 = lrand(&s) % rand1;
	rand1 = lrand(&s) % rand1;
	if(rand2 != rand1)
		return;
	//for(n1=0; n1<CHANCE_OF_DEVIATION; n1++){
	//	rand1 = lrand(&s) % 2;
	//	rand2 = lrand(&s) % 2;
	//	if(rand2 == rand1)
	//		return;
	//}

	//3/80 total chance of new species after here !!!!!

	//1/2 chance we do a deviation
	unsigned char deviation = (unsigned char)lrand(&s) % 2;
	//+1 deviation, otherwise -1
	//if(deviation)
	//	deviation = 1;
	//else
	//	deviation = 0;
	rand1 = lrand(&s) % 9; //which feild will be modified
	// 7/16 chance the selected feild is at an upper/lower limit
	// 7/32 chance deviation is the +1/-1 needed to create new species
	// 5/9 genetic deviation selected
	// ~ 1/1000 chance ultimately of new species (1/20 * 1/50)
	if(rand1 == 0){
		if(deviation){
			if(three->intelligence < 255)
				three->intelligence++;
		}else{
			if(three->intelligence > 4)
				three->intelligence--;
		}
		return;
	}

	if(rand1 == 1){
		if(deviation){
			if(three->strength < 255)
				three->strength++;
		}else{
			if(three->strength > 4)
				three->strength--;
		}
		return;
	}
	if(rand1 == 2){
		if(deviation){
			if(three->speed < 255)
				three->speed++;
		}else{
			if(three->speed > 4)
				three->speed--;
		}
		return;
	}
	if(rand1 == 3){
		//stay within ranges
		if(deviation){
			if(three->temp_h < 39){
				three->temp_h++;
				three->temp_l++;
			}
		}else{
			if(three->temp_l > 4){
				three->temp_h--;
				three->temp_l--;
			}
		}
		return;
	}
	if(rand1 == 4){
		//stays within range 30 - 128yrs
		if(deviation){
			 if(three->max_age < 100)
				three->max_age++;
		}else{
			if(three->max_age > 26)
				three->max_age--;
		}
		return;
	}
	if(rand1 == 5){
		if(deviation){
			if(three->social_factor < 255)
				three->social_factor++;
		}else{
			if(three->social_factor > SOCIAL_FACTOR)
				three->social_factor--;
		}
		return;
	}
	if(rand1 == 6){
		if(deviation){
			if(three->interspecies_violence < 255)
				three->interspecies_violence++;
		}else{
			if(three->interspecies_violence > INTERSPECIES_VIOLENCE)
				three->interspecies_violence--;
		}
		return;
	}
	if(rand1 == 7){
		if(deviation){
			if(three->fight_flight_balance < 255)
				three->fight_flight_balance++;
		}else{
			if(three->fight_flight_balance > FIGHT_FLIGHT_BALANCE)
				three->fight_flight_balance--;
		}
		return;
	}
	//if(rand1 == 8){  //else
	if(deviation){
		if(three->migration_factor != 255)
			three->migration_factor++;
	}else{
		if(three->migration_factor > MIGRATION_FACTOR)
			three->migration_factor--;
	}
}

void Moves_Populate(uint32_t src_y, uint32_t src_x, struct Moves *moves){
	//populate struct moves with 4 surrounding coordinates
	const uint32_t width = WIDTH - 1;
	const uint32_t height = HEIGHT - 1;
	if(src_x != 0)
		moves[0].x = src_x - 1;
	else
		moves[0].x = width;
	moves[0].y = src_y;
	moves[0].valid  = 1;
	moves[0].rating = 4;

	if(src_x != width)
		moves[1].x = src_x + 1;
	else
		moves[1].x = 0;

	moves[1].y = src_y;
	moves[1].valid  = 1;
	moves[1].rating = 4;
	moves[2].x = src_x;

	if(src_y != 0)
		moves[2].y = src_y-1;
	else
		moves[2].y = height;

	moves[2].valid  = 1;
	moves[2].rating = 4;
	moves[3].x = src_x;

	if(src_y != height)
		moves[3].y = src_y+1;
	else
		moves[3].y = 0;

	moves[3].valid  = 1;
	moves[3].rating = 4;

}

int Tribe_Borders_Water(uint32_t src_y, uint32_t src_x){
	//return 1 if a tribe is bordering open water
	uint32_t n1 = 0;
	//uint32_t n2 = 0;
	struct Moves moves[4];
	Moves_Populate(src_y, src_x, moves);
	for(n1=0; n1<4; n1++){
		if(ia->dem[moves[n1].y][moves[n1].x] <= stats_t.cur_sealevel){
			if(!life[moves[n1].y][moves[n1].x]->alive){
				//n2++;
				return 1;
			}
		}
	}

	return 0;
	//return n2==0 ? 0 : 1;
}

int Tribe_Water_Migrate(uint32_t src_y, uint32_t src_x, uint32_t *dest){
	//migrate while at sea
	//return 1 if migrated onto land, 0 if still at sea
	uint32_t n1 = 0;
	uint32_t n2 = 0;
	//uint32_t width = WIDTH - 1;
	//uint32_t height = HEIGHT - 1;
	struct timeval cur;
	uint32_t rand1;
	gettimeofday(&cur, NULL);
	uint64_t s = (unsigned int)cur.tv_usec + 3;
	//uint32_t dest[2];
	struct Moves moves[4];
	Moves_Populate(src_y, src_x, moves);
	int ret_val = 0;

	for(n1=0; n1<4; n1++){
		if(!life[moves[n1].y][moves[n1].x]->alive){
			moves[n1].valid = 1;
		}
	}
/*
            rand1 = (int)ceil((double)life[src_y][src_x]->intelligence/256*100);
            if(lrand(&s) % 100 < rand1){
                //search for spot continuing direction
                n1 = life[src_y][src_x]->water_direction;
                if(moves[n1].valid){
                    dest[0] = moves[n1].y;
                    dest[1] = moves[n1].x;
                    (void)memcpy((void *)life[dest[0]][dest[1]], (const void *)life[src_y][src_x], sizeof(struct Species));
                    if(life[dest[0]][dest[1]]->imunity < 255)
                        life[dest[0]][dest[1]]->imunity++;
                    life[dest[0]][dest[1]]->water_turns++;

                    return 0;
                }
                dest[0] = src_y;  //Don't move
                dest[1] = src_x;  //Don't move
                life[src_y][src_x]->water_turns++;
                return ret_val;
            }

*/	

	n2 = 0;
	//see if a neightbor is unoccupied land
	for(n1=0; n1<4; n1++){
		//moves[n1].valid = 1;
		if(life[moves[n1].y][moves[n1].x]->alive){
			moves[n1].valid = 0;
			n2++;
			continue;
		}
		if(ia->dem[moves[n1].y][moves[n1].x] <= stats_t.cur_sealevel){
			//if(!life[moves[n1].y][moves[n1].x]->alive){
			
				moves[n1].valid = 0;
				n2++;
				continue;
			//}
		}
		moves[n1].valid = 1;
		//if(life[moves[n1].y][moves[n1].x]->alive){
		//	moves[n1].valid = 0;
		//	n2++;
		//}
	}
	if(n2 < 4){
		//if 1 or more land (unoccupied) choice choose one randomly
		rand1 = lrand(&s) %  (4 - n2);
		n2 = 0;
		for(n1=0; n1<4; n1++){
			if(moves[n1].valid){
				if(n2 == rand1){
					//this is your choice
					dest[0] = moves[n1].y;
					dest[1] = moves[n1].x;
					//life[moves[n1].y][moves[n1].x]->water_turns = 0;
					ret_val = 1;
					continue;
				}
				n2++;
			}
		}
	}else{
		n2 = 0;
		//choose a water spot randomly
		for(n1=0; n1<4; n1++){
			if(ia->dem[moves[n1].y][moves[n1].x] <= stats_t.cur_sealevel){
				if(!life[moves[n1].y][moves[n1].x]->alive){
					moves[n1].valid = 1;
					n2++;
				}
			}
		}
		//use intelligence to determine if we take straight line path
		if(n2 != 0){ //one or more open water spots exists

			rand1 = (uint32_t)ceil((double)life[src_y][src_x]->intelligence/256*100);
			if(lrand(&s) % 100 < rand1){
				//search for water spot continuing direction
				n1 = life[src_y][src_x]->water_direction;
				if(moves[n1].valid){
					dest[0] = moves[n1].y;
					dest[1] = moves[n1].x;
					(void)memcpy((void *)life[dest[0]][dest[1]], (const void *)life[src_y][src_x], sizeof(struct Species));
					if(life[dest[0]][dest[1]]->imunity < 255)
						life[dest[0]][dest[1]]->imunity++;
					life[dest[0]][dest[1]]->water_turns++;

					return 0;
				}
				dest[0] = src_y;  //Don't move
				dest[1] = src_x;  //Don't move
				life[src_y][src_x]->water_turns++;
				return ret_val;
			}


			rand1 = lrand(&s) %  n2;
			n2 = 0;
			for(n1=0; n1<4; n1++){
				if(moves[n1].valid){
					if(n2 == rand1){
						dest[0] = moves[n2].y;
						dest[1] = moves[n2].x;
						//life[src_y][src_x]->water_direction = n2;
						//life[moves[n2].y][moves[n2].x]->water_turns++;
						continue;
					}
					n2++;
				}
			}
			//continue;
		}else{
			dest[0] = src_y;  //Don't move
			dest[1] = src_x;  //Don't move
			life[dest[0]][dest[1]]->water_turns++;
			return ret_val;
		}
	}

	(void)memcpy((void *)life[dest[0]][dest[1]], (const void *)life[src_y][src_x], sizeof(struct Species));
	if(life[dest[0]][dest[1]]->imunity < 255)
		life[dest[0]][dest[1]]->imunity++;
	//set water_turns
	if(ret_val)
		life[dest[0]][dest[1]]->water_turns = 0;
	else
		life[dest[0]][dest[1]]->water_turns++;
	//life[dest[0]][dest[1]ter_turns++;
    //clear old data
    KILL_Tribe(src_y, src_x);
	return ret_val;
}

int Tribe_Move_To_Water(uint32_t src_y, uint32_t src_x, uint32_t *dest){
	//move a tribe onto water, return 1 if no open water available
	uint32_t n1 = 0;
	uint32_t n2 = 0;
	//uint32_t width = WIDTH - 1;
	//uint32_t height = HEIGHT - 1;
	struct timeval cur;
	uint32_t rand1;
	gettimeofday(&cur, NULL);
	uint64_t s = (unsigned int)cur.tv_usec + 3;
	//uint32_t dest[2] = {0, 0};
	struct Moves moves[4];
	Moves_Populate(src_y, src_x, moves);

	//set to invalid moves that aren't water, or are occupied
	for(n1=0; n1<4; n1++){
		if(ia->dem[moves[n1].y][moves[n1].x] > stats_t.cur_sealevel){
			//if(!life[moves[n1].y][moves[n1].x]->alive){
			moves[n1].valid = 0;
			//n2++;
			continue;
			//}
		}
		if(life[moves[n1].y][moves[n1].x]->alive){
			moves[n1].valid = 0;
			//n2++;
			continue;
		}
		if( Climate_Fatal(life[src_y][src_x], moves[n1].y, moves[n1].x) ){
			moves[n1].valid = 0;
			//n2++;
			continue;
		}
		n2++;
	}

	//error condition
	if(n2 == 0){
		//printf("This tribe is not surrounded by any open water !\n");
		//kill him
		dest[0] = src_y;
		dest[1] = src_x;
		return 1;
		//KILL_Tribe(src_y, src_x);
		//return;
	}
	//randomly choose one of the valid choices
	rand1 = lrand(&s) %  n2;
	n2 = 0;
	for(n1=0; n1<4; n1++){
		if(moves[n1].valid){
			if(n2 == rand1){
				//this is your choice
				dest[0] = moves[n1].y;
				dest[1] = moves[n1].x;
				life[src_y][src_x]->water_direction = n1;
				break;
			}
			n2++;
		}
	}

	//if( Climate_Fatal(life[src_y][src_x], dest[0], dest[1]) ){
	//	KILL_Tribe(src_y, src_x);
	//	stats[t].exposure++;
	//	return;
	//}
	//move to destination
	//life[dest[0]][dest[1]]->alive = 1;
	(void)memcpy((void *)life[dest[0]][dest[1]], (const void *)life[src_y][src_x], sizeof(struct Species));
	if(life[dest[0]][dest[1]]->imunity < 255)
		life[dest[0]][dest[1]]->imunity++;
	//set water_turns to 1
	life[dest[0]][dest[1]]->water_turns = 1;
	//clear old data
	KILL_Tribe(src_y, src_x);
	//life_speed_up_Y[dest[0]] = 1;
	//life_speed_up_X[dest[1]] = 1;
	return 0;
}

int Tribe_Migrate(uint32_t src_y, uint32_t src_x, uint32_t *dest){
	//return 1 if moved
	//put new location in dest

	uint32_t n1, n2;
	const uint32_t width = WIDTH - 1;
	const uint32_t height = HEIGHT - 1;
	struct Moves moves[4];
	//float temp_preferred = 0;
	//float temp_diff = 0;
	//float temp_actual = 0;

	//if any of these are greater/less than height or width they need to be set to 0
	//same goes for all neighbors calculations

	//4 potential destination initialization
	Moves_Populate(src_y, src_x, moves);

/*
	if(src_x != 0)
		moves[0].x = src_x - 1;
	else
		moves[0].x = width;

	moves[0].y = src_y;
	moves[0].valid  = 1;
	moves[0].rating = 4;

	if(src_x != width)
		moves[1].x = src_x + 1;
	else
		moves[1].x = 0;

	moves[1].y = src_y;
	moves[1].valid  = 1;
	moves[1].rating = 4;
	moves[2].x = src_x;

	if(src_y != 0)
		moves[2].y = src_y-1;
	else
		moves[2].y = height;

	moves[2].valid  = 1;
	moves[2].rating = 4;
	moves[3].x = src_x;

	if(src_y != height)
		moves[3].y = src_y+1;
	else
		moves[3].y = 0;

	moves[3].valid  = 1;
	moves[3].rating = 4;
*/
	//4 neighors of a move destination
	struct Neighbors{unsigned int x; unsigned int y;}neighbors[4];

	//to store candidate destination with highest rating
	struct Dest_Cand{int h_rating; unsigned int m_index;}dest_cand = {0, 0};
	int cand_ties[4];

    struct timeval cur;
    uint32_t rand1;
    gettimeofday(&cur, NULL);
	uint64_t s = (unsigned int)cur.tv_usec + 3;

	for(n1=0; n1<4; n1++){
		//rule out moving to water
		if(stats_t.cur_sealevel >= ia->dem[moves[n1].y][moves[n1].x]){
			moves[n1].valid = 0;
			continue;
		}
		//rule out moving to occupied coordinates
		if(life[moves[n1].y][moves[n1].x]->alive){
			moves[n1].valid = 0;
			continue;
		}
		//rule out moving to fatal climates
		if( Climate_Fatal(life[src_y][src_x], moves[n1].y, moves[n1].x) )
			moves[n1].valid = 0;
	}
	for(n1=0; n1<4; n1++){
		//if all ruled out return 0;
		if(moves[n1].valid == 1)
			break;
		if(n1 == 3)
			return 0;
	}
	//calculate ratings for valid destinations
	for(n1=0; n1<4; n1++){
		if(!moves[n1].valid)
			continue;
		//Moves_Populate(moves[n1].y, moves[n1].x, neighbors);
		//initialize neighbors for this potential move
		if(moves[n1].x != 0)
			neighbors[0].x = moves[n1].x-1;
		else
			neighbors[0].x = width;
		neighbors[0].y = moves[n1].y;
		if(moves[n1].x != width)
			neighbors[1].x = moves[n1].x+1;
		else
			neighbors[1].x = 0;
		neighbors[1].y = moves[n1].y;
		neighbors[2].x = moves[n1].x;
		if(moves[n1].y != 0)
			neighbors[2].y = moves[n1].y-1;
		else
			neighbors[2].y = height;
		neighbors[3].x = moves[n1].x;
		if(moves[n1].y != height)
			neighbors[3].y = moves[n1].y+1;
		else
			neighbors[3].y = 0;
		//calculate rating for this move threat/reward
			//if neighbor is empty terrain inc if climate is more favorable
			//ie: more toward the middle of temp_l - temp_h range than current position

			/*
			if(!life[moves[n1].y][moves[n1].x]->alive){
				temp_actual = Location_Temp(src_y, src_x);
				temp_diff = Location_Temp(moves[n1].y, moves[n1].x) - temp_actual;
				temp_preferred = (float)(life[src_y][src_x]->temp_l + life[src_y][src_x]->temp_h)/2;

				if(temp_diff < 0){ //am in a higher temp area
					//if lower temp is better than current location
					if( temp_preferred < temp_actual ){
						moves[n1].rating++;
						//continue;
					}
					//if(life[src_y][src_x]->temp_h
					//	moves[n1].rating++;
				}
				if(temp_diff > 0){ //am in a lower temp area
					//if higher temp is better
					if( temp_preferred > temp_actual ){
						moves[n1].rating++;
						//continue;
					}
				}
				//moves[n1].rating++;
				//continue;
			}
		*/
        for(n2=0; n2<4; n2++){
            if(neighbors[n2].y == src_y){  //if a neighbor is src_x/src_y don't count self
                if(neighbors[n2].x == src_x)
                    continue;
            }
			if(!life[neighbors[n2].y][neighbors[n2].x]->alive){
				moves[n1].rating++;
				continue;
			}
			//if neighbor is different species dec rating
			if(!Is_Same_Species(life[src_y][src_x], life[neighbors[n2].y][neighbors[n2].x]) ){
				moves[n1].rating--;
				continue;
			}
			//if neighbor is same inc rating, or water
			moves[n1].rating++;

			//unless already on water ...
			
		}
	}
	dest_cand.h_rating = -1;
	//find destination with highest rating
	for(n1=0; n1<4; n1++){
		if(!moves[n1].valid){
			moves[n1].rating = 0;
			continue;
		}
		if(	moves[n1].rating >= dest_cand.h_rating){
			dest_cand.h_rating = moves[n1].rating;
			dest_cand.m_index  = n1;
		} 

	}
	n2=0;
	//if rating tie should pick a random choice out of them
	//count rating ties
	for(n1=0; n1<4; n1++)
		cand_ties[n1] = 0;
	for(n1=0; n1<4; n1++){
		if(!moves[n1].valid)
			continue;
		if(dest_cand.h_rating == moves[n1].rating){
			cand_ties[n1] = 1;
			n2++;
		}
	}
	if(n2){ //was no tie
		dest[0] = moves[dest_cand.m_index].y;
		dest[1] = moves[dest_cand.m_index].x;
	}
	if(n2 > 1){ //was a tie
		//n2 can be  2  3  or 4
		rand1 = lrand(&s) %  n2 + 1; // 1 to 2, 1 to 3, or 1 to 4
		for(n1=0; n1<4; n1++){
			if(!cand_ties[n1])
				continue;
			//n2++;
			if(n2 == rand1){
				//moves[n1] is dest choice
				dest[0] = moves[n1].y;
				dest[1] = moves[n1].x;
				break;
			}
			n2++;
		}
	}

	if(stats_t.cur_sealevel < ia->dem[dest[0]][dest[1]]){
		//Move to destination
		life[dest[0]][dest[1]]->alive = 1;
		(void)memcpy((void *)life[dest[0]][dest[1]], (const void *)life[src_y][src_x], sizeof(struct Species));
		if(life[dest[0]][dest[1]]->imunity < 255)
			life[dest[0]][dest[1]]->imunity++;
		//clear old data
		KILL_Tribe(src_y, src_x);
		return 1;
	}
	return 0;
}

int Fight_Tribe(struct Species *one, struct Species *two){
	//simulate outcome of a potential combat between these two tribes
	// return 1 *one won, 0 *one lost
	uint32_t rand1, rand2;
	struct timeval cur;
    gettimeofday(&cur, NULL);
    uint64_t s = (unsigned int)cur.tv_usec + 2;

	//if(!one->alive || !two->alive)
	//	printf("Warning! Fight_Tribe called with non-alive tribe/s\n");

	//fight determined by  1 part strength, 1 part speed, 2 parts intelligence, and 1 part chance
	rand1 = lrand(&s) % 256;
	rand2 = lrand(&s) % 256;
	uint32_t rating1 = one->intelligence*2 + one->strength + one->speed + rand1;
	uint32_t rating2 = two->intelligence*2 + two->strength + two->speed + rand2;
	//cur_age ?
	// 1 in 256 chance they are equal
	if(rating1 > rating2)
		return 1;
	if(rating2 > rating1)
		return 0;
	//if(rating1 == rating2)
	return (int)lrand(&s) % 2;
	//equal
	//while(rand1 == rand2){
	//	rand1 = lrand(&s) % 2;
		//gettimeofday(&cur, NULL);
		//srand ( (unsigned int)cur.tv_usec+rand1 );
	//	rand2 = lrand(&s) % 2;
	//}
	//return rand1>rand2 ? 1 : 0;
}

void Tribe_Interactions(uint32_t src_y, uint32_t src_x, uint32_t tid){
	//evaluate all surrounding tribes for threat/reward take proper actions
	uint32_t n1, n2, n3;
	uint32_t rand1, rand2, rand3;
	int out_come;
	struct timeval cur;
	struct Neighbors{uint32_t y; uint32_t x; uint32_t occupied;}neighbors[4];
	struct Neighbors_T{uint32_t y; uint32_t x;}tmp[4];
	uint32_t width = WIDTH - 1;
	uint32_t height = HEIGHT - 1;
	//if(!life[src_y][src_x]->alive)
	//	printf("Warning Tribe_Interactions: Called for dead tribe!\n");
    gettimeofday(&cur, NULL);
    uint64_t s = (unsigned int)cur.tv_usec * 3 + 2;

	//need to be randomly assigned, 24 possible permutations of the 4 structures
	//n×(n - 1)×(n - 2)×...×2×1

	//for map wrap
	tmp[0].y = src_y;
	if(src_x != 0)
		tmp[0].x = src_x - 1;
	else
		tmp[0].x = width;

	tmp[1].y = src_y;
	if(src_x != width)
		tmp[1].x = src_x + 1;
	else
		tmp[1].x = 0;

	if(src_y != 0)
		tmp[2].y = src_y - 1;
	else
		tmp[2].y = height;
	tmp[2].x = src_x;

	if(src_y != height)
		tmp[3].y = src_y + 1;
	else
		tmp[3].y = 0;
	tmp[3].x = src_x;

	//mix them randomly
	rand1 = lrand(&s) % 4;  //pick of any
	rand2 = lrand(&s) % 3;  //pick of remaining 3
	rand3 = lrand(&s) % 2;  //pick of remaining 2

	neighbors[0].y = tmp[rand1].y;
	neighbors[0].x = tmp[rand1].x;
	neighbors[0].occupied = 0;
	n2 = 0;
	for(n1=0; n1<4; n1++){ //pick second one randomly out of 3 remaining
		if(n1 != rand1){ //if not already taken
			if(n2 == rand2){
				neighbors[1].y = tmp[n1].y;
				neighbors[1].x = tmp[n1].x;
				neighbors[1].occupied = 0;
				break;
			}
			n2++;
		}
	}
	n3 = 0;
	for(n2=0; n2<4; n2++){ //pick third one
		if(n2 != rand1){
			if(n2 != n1){
				if(n3 == rand3){
					neighbors[2].y = tmp[n2].y;
					neighbors[2].x = tmp[n2].x;
					neighbors[2].occupied = 0;
					break;
				}
				n3++;
			}
		}
	}
	for(n3=0; n3<4; n3++){ //last one is the remaining 
		if(n3 != rand1){
			if(n3 != n1){
				if(n3 != n2){
					neighbors[3].y = tmp[n3].y;
					neighbors[3].x = tmp[n3].x;
					neighbors[3].occupied = 0;
					break;
				}
			}
		}
	}

	for(n1=0; n1<4; n1++){
		if(life[neighbors[n1].y][neighbors[n1].x]->alive){
			if(life[neighbors[n1].y][neighbors[n1].x]->water_turns == 0) //don't interact with water migraters
				neighbors[n1].occupied = 1;
		}
	}

	for(n1=0; n1<4; n1++){
		if(neighbors[n1].occupied){
			if( Is_Same_Species(life[src_y][src_x], life[neighbors[n1].y][neighbors[n1].x]) ){
				//check to see if we'll fight first !
				if(!fought[src_y][src_x]){
					rand1 = (uint32_t)ceil((double)life[src_y][src_x]->interspecies_violence/256*100);
					if(lrand(&s) % 100 < rand1){

					//rand1 = floor(INTERSPECIES_A_RANGE / life[src_y][src_x]->interspecies_violence);
					//rand2 = lrand(&s) % rand1;
					//if(lrand(&s) % rand1){
					//rand2 = lrand(&s) % INTERSPECIES_A_RANGE;  // 1/16 at 127
					//if(life[src_y][src_x]->interspecies_violence > rand2){//attacking
						fought[src_y][src_x] = 1;
						out_come = Fight_Tribe( life[src_y][src_x], life[neighbors[n1].y][neighbors[n1].x] );
						if(out_come){//if the fight was won
							KILL_Tribe(neighbors[n1].y, neighbors[n1].x);
							stats[tid].died_defending++;
							if(life[src_y][src_x]->imunity < 255)
								life[src_y][src_x]->imunity++;
							continue;
						}
						if(!out_come){ //died
							KILL_Tribe(src_y, src_x);
							stats[tid].died_attacking++;
							if(life[neighbors[n1].y][neighbors[n1].x]->imunity < 255)
								life[neighbors[n1].y][neighbors[n1].x]->imunity++;
							return;
						}
					}
				}
				if(mated[src_y][src_x])
					continue;
				if(mated[neighbors[n1].y][neighbors[n1].x])
					continue;
				rand1 = (uint32_t)ceil((double)life[src_y][src_x]->social_factor/256*100);
				if(lrand(&s) % 100 < rand1){
				//rand2 = lrand(&s) % life[src_y][src_x]->social_factor + 1; // 1/2 at 127
				//rand1 = lrand(&s) % INTERSPECIES_M_RANGE + 1;  //high chance
				//if(rand2 > rand1){
				//if(life[src_y][src_x]->social_factor > rand1){ //are mating
					out_come = 0;
					//choose open space for offspring
					for(n2=0; n2<4; n2++){
						if(neighbors[n2].occupied == 0){
							if(stats_t.cur_sealevel < ia->dem[neighbors[n2].y][neighbors[n2].x] ){
								out_come = 1;
								break;
							}
						}
					}
					//choose random open space if multiple
					//if space available create life
					if(out_come){
						mated[src_y][src_x] = 1;
						mated[neighbors[n1].y][neighbors[n1].x] = 1;
						mated[neighbors[n2].y][neighbors[n2].x] = 1; //to keep it from mating/fighting during it's first year of life
						fought[neighbors[n2].y][neighbors[n2].x] = 1; //
						life[neighbors[n2].y][neighbors[n2].x]->alive = 1;
						Create_Life(life[src_y][src_x], life[neighbors[n1].y][neighbors[n1].x], life[neighbors[n2].y][neighbors[n2].x]);
						stats[tid].new_life++;
						life_speed_up_Y[neighbors[n2].y] = 1;
						life_speed_up_X[neighbors[n2].x] = 1;
						if( !Is_Same_Species(life[src_y][src_x], life[neighbors[n2].y][neighbors[n2].x]) )
							stats[tid].new_species++;
						if(life[src_y][src_x]->imunity < 255)
							life[src_y][src_x]->imunity++;
						if(life[neighbors[n1].y][neighbors[n1].x]->imunity < 255)
							life[neighbors[n1].y][neighbors[n1].x]->imunity++;
					}
				}
			}else{ 
				if(!fought[src_y][src_x]){ //havn't already fought
					rand1 = (uint32_t)ceil((double)life[src_y][src_x]->fight_flight_balance/256*100);
					if(lrand(&s) % 100 < rand1){
					//rand2 = lrand(&s) % ENEMY_A_RANGE;
					//if(life[src_y][src_x]->fight_flight_balance > rand2){//attacking
						fought[src_y][src_x] = 1;
						out_come = Fight_Tribe( life[src_y][src_x], life[neighbors[n1].y][neighbors[n1].x] );
						if(out_come){//fight was won
							KILL_Tribe(neighbors[n1].y, neighbors[n1].x);
							stats[tid].died_defending++;
							if(life[src_y][src_x]->imunity < 255)
								life[src_y][src_x]->imunity++;
						}
						if(!out_come){ //died
							KILL_Tribe(src_y, src_x);
							stats[tid].died_attacking++;
							if(life[neighbors[n1].y][neighbors[n1].x]->imunity < 255)
								life[neighbors[n1].y][neighbors[n1].x]->imunity++;
							return;
						}
					}
				}
			}
		}
		if(fought[src_y][src_x]){
			if(mated[src_y][src_x]){
				return;
			}
		}
	}
}

void FM_Alloc(void){
	uint32_t h;
	fought = (char **)malloc(sizeof(char *)*HEIGHT);
	for(h=0; h<HEIGHT; h++)
		fought[h] = (char *)malloc(sizeof(char)*WIDTH);
	mated = (char **)malloc(sizeof(char *)*HEIGHT);
	for(h=0; h<HEIGHT; h++)
		mated[h] = (char *)malloc(sizeof(char)*WIDTH);
}

void FM_Reset(uint32_t start, uint32_t end){
	uint32_t h;
	for(h=start; h<end; h++){
		(void)memset( (void *)fought[h], '\0', sizeof(char)*WIDTH);
		(void)memset( (void *)mated[h], '\0', sizeof(char)*WIDTH);
	}
}

void *Tribe_Actions(void *tid){
	//master thread
	//initiate actions migrate/combat/desease/create_life/migrate/socialize
	uint32_t t = *(unsigned int *)tid;
	uint32_t y = 0;
	uint32_t x = 0;
	uint32_t x_s = 0;
	//uint32_t x_h = 0;
	int right_to_left = 0;
	//int dec = 0;
	int stop = 0;
	int first_member = 0;
	uint32_t dest[] = {0, 0}; //y x
	char did_move = 0;
	//struct timeval starttime,endtime;
	struct timeval cur;
    uint32_t rand1 = 0;
	uint32_t rand2 = 0;
	//int cur_sealevel = ia->cur_sealevel;
    gettimeofday(&cur, NULL);
	//printf("%u\n", Thread_Step);
    uint64_t s = (unsigned int)cur.tv_usec * 3 + 3;
	//char *life_speed_up_H = (char *)malloc(Thread_Step);
	//char life_speed_up_W[WIDTH]; //= (char *)malloc(WIDTH);
	int row_half = 0;
	int row_ceiling = 0;
	//double year_runtime = 0;

	//do first half of rows

	//sychronize threads

	//second half

	//sychronize threads

	//stats / image handled

	//reset arrays as necesary

	//check for exit signals and clean up

	//(void)memset( (void *)life_speed_up_H, '\0', sizeof(char)*HEIGHT );
	//(void)memset( (void *)&life_speed_up_W, '\0', sizeof(char)*WIDTH );
	//printf("%u Here !\n", t);
	//sleep(5);
	if(t == 0)
		gettimeofday(&Year_Starttime, NULL);

	while(No_Exit == 1){
		//(void)memset( (void *)life_speed_up_H, '\0', sizeof(char)*HEIGHT );
		//(void)memset( (void *)life_speed_up_W, '\0', sizeof(char)*WIDTH );
		for(row_half=0; row_half<2; row_half++){

		//row_half = (row_half) ? 0 : 1;
			if(row_half){
				y = Actions_t_info[t].start_h;
				row_ceiling = y + Thread_Step/2;
			}else{
				y = Actions_t_info[t].start_h + Thread_Step/2;
				row_ceiling = Actions_t_info[t].end_h;
			}
			for(; y < row_ceiling; y++){
				if(!life_speed_up_Y[y])
					continue;
					//randomly choose to start from right or left of row
					rand1 = lrand(&s) % 2;
					//rand2 = lrand(&s) % 511;
				if( rand1 ){
					right_to_left = 0;
					x_s = WIDTH - 1;
					x = 0;
				}else{
					right_to_left = 1;
					x_s = 0;
					x = WIDTH - 1;
				}
				stop = 0;
				first_member = 1;
				while(!stop){
					//if(stop)
					//	break;
					if(right_to_left){
						if(!first_member)
							x--;
						else
							first_member = 0;
					}else{
						if(!first_member)
							x++;
						else
							first_member = 0;
					}
					if(x == x_s)
						stop = 1;
					if(!life_speed_up_X[x])
						continue;
					if(life[y][x]->alive){ //if there is life at this location
						//get one year older
						life[y][x]->cur_age++;
						//die from old age?  // 1/36 chance for initial tribes
						if(life[y][x]->cur_age == life[y][x]->max_age ){
							KILL_Tribe(y, x);
							stats[t].old_age++;
							continue;
						}
						rand1 = (uint32_t)ceil((double)life[y][x]->imunity/256*100);
						rand2 = lrand(&s) % 100;
						if(rand2 > rand1){
						//rand2 = lrand(&s) % IMUNITY_RANGE; // 1/16 at 127   1/32 at 255
						//if(life[y][x]->imunity > rand2){
							//printf("year: %u rand1: %d rand2: %d\n", stats_t.year, rand1, rand2);
							KILL_Tribe(y, x);
							stats[t].disease++;
							continue;
						}

						if(life[y][x]->water_turns == 0){
							if( Tribe_Borders_Water(y, x) ){
								//rand1 = ceil(life[src_y][src_x]->imunity/256*100);
								rand1 = (uint32_t)ceil((double)WATER_MIGRATION_RANGE/256*100);
								//rand1 = lrand(&s) % WATER_MIGRATION_RANGE;
								if(lrand(&s) % 100 < rand1){
									if( !Tribe_Move_To_Water(y, x, dest) ){ //if found Open water
										if( Climate_Fatal(life[dest[0]][dest[1]], dest[0], dest[1]) ){
											KILL_Tribe(dest[0], dest[1]);
											stats[t].exposure++;
											continue;
										}
										//moved
										life_speed_up_Y[dest[0]] = 1;
										life_speed_up_X[dest[1]] = 1;
										//no interactions for water migraters
										continue;
									}
									//did not move 
									if(stats_t.cur_sealevel >= ia->dem[y][x]){ //drown
										KILL_Tribe(y, x);
										stats[t].drown++;
										continue;
									}
									if( Climate_Fatal(life[y][x], y, x) ){
										KILL_Tribe(y, x);
										stats[t].exposure++;
										continue;
									}
									life_speed_up_Y[y] = 1;
									life_speed_up_X[x] = 1;
									Tribe_Interactions(y, x, t);
									continue;
								}
							}
							//continue;
						}

						if(life[y][x]->water_turns == 0){ //if tribe is not water migrating
							rand1 = (uint32_t)ceil((double)life[y][x]->migration_factor/256*100);
							//rand2 = lrand(&s) % MIGRATION_RANGE;  // 1/4 at 127 
							//if(life[y][x]->migration_factor > rand2){  //tribe will attempt to migrate
							if(lrand(&s) % 100 < rand1){
								did_move = Tribe_Migrate(y, x, dest);

								if(did_move == 0){ //couldn't find a spot, try to water migrate
									rand1 = (uint32_t)ceil((double)WATER_MIGRATION_RANGE/256*100);
									if(lrand(&s) % 100 < rand1){
										if( Tribe_Borders_Water(y, x) ){
										//rand2 = lrand(&s) % WATER_MIGRATION_RANGE; //1/16 at 256
										//if(rand2 < 16){
											//if( Tribe_Move_To_Water(y, x, dest) ){
												//return 1 if no Open water
												//that means stayed in same place, check for drowning 
											//	if(stats_t.cur_sealevel >= ia->dem[dest[0]][dest[1]]){ //drown
											//		KILL_Tribe(dest[0], [dest[1]);
											//		stats[t].drown++;
													//stats[t].drown++;
											//		continue;
											//	}
											//	Tribe_Interactions(dest[0], dest[1], t);
											//	continue;
											//}
											if( !Tribe_Move_To_Water(y, x, dest) ){ //if found Open water
												if( Climate_Fatal(life[dest[0]][dest[1]], dest[0], dest[1]) ){
													KILL_Tribe(dest[0], dest[1]);
													stats[t].exposure++;
													continue;
												}
												life_speed_up_Y[dest[0]] = 1;
												life_speed_up_X[dest[1]] = 1;
												continue;
												//no interactions for water migraters
											}

											did_move = 0; //didn't move
										//}
										}
									}
								}

							}
							//else{
							
								//this tribe won't/can't migrate regardless 
							if(stats_t.cur_sealevel >= ia->dem[y][x]){ //drown
								KILL_Tribe(y, x);
								stats[t].drown++;
								continue;
							}
							//	did_move = 0; //didn't move lived
							//}
							if(did_move){
								if( Climate_Fatal(life[dest[0]][dest[1]], dest[0], dest[1]) ){
									KILL_Tribe(dest[0], dest[1]);
									stats[t].exposure++;
									continue;
								}
								Tribe_Interactions(dest[0], dest[1], t);
							}else{
								if( Climate_Fatal(life[y][x], y, x) ){
									KILL_Tribe(y, x);
									stats[t].exposure++;
									continue;
								}
								//if(life[y][x]->water_turns == 0)
								Tribe_Interactions(y, x, t);
							}
							continue;
						}
						did_move = Tribe_Water_Migrate(y, x, dest); //1 if found land 
						life_speed_up_Y[dest[0]] = 1;
						life_speed_up_X[dest[1]] = 1;
						if(!did_move){
							if(life[dest[0]][dest[1]]->water_turns == WATER_MIGRATION_T_MAX){
								KILL_Tribe(dest[0], dest[1]);
								stats[t].drown++;
								continue;
							}
						}
						if( Climate_Fatal(life[dest[0]][dest[1]], dest[0], dest[1]) ){
							KILL_Tribe(dest[0], dest[1]);
							stats[t].exposure++;
						}
						
						//if( Climate_Fatal(life[y][x], y, x) ){
						//	KILL_Tribe(y, x);
						//	stats[t].exposure++;
						//}

						//}else{
						//	rand2 = lrand(&s) % WATER_MIGRATION_RANGE;
						//	if(rand2 < 16){
						//did_move = Tribe_Water_Migrate(y, x, dest);
						

					}//end of if life != NULL
				}//end of X loop
			}//end of Y loop
			//thread_i[t].row_synch = 1;
			//synchronize threads
			//pthread_cond_signal( &condition_var );
			//pthread_cond_wait( &Condition1, &Mutex1 );

			pthread_barrier_wait(&Barrier1);  //half year barried to stop overlaps
		}//end of year

		FM_Reset(Actions_t_info[t].start_h, Actions_t_info[t].end_h);
		
		//Actions_t_info[t].seed

		//for(y=Actions_t_info[t].start_h; y<Actions_t_info[t].end_h; y++){
		//	for(x=0; x<WIDTH; x++){
		//		if(life[y][x]->alive){
		//			stats[t].total_living++;
		//		}
		//	}
		//}
		//pthread_barrier_wait(&Barrier2);  //barrier for ^

		//first thread to reach it
		//if(Stats_Handled){
		pthread_mutex_lock( &Mutex1 );
		//Stats_Handled++;
		if(!Stats_Handled){
			//pthread_mutex_lock( &mutex1 );
			Stats_Handled = 1;
			stats_t.year++;
			//Drawl_Image();
			//FM_Reset();
			//Adjust_Sea_Level(0);
			//Adjust_Climate(0);
			gettimeofday(&Year_Endtime, NULL);
			Year_Runtime += ((double)(Year_Endtime.tv_sec*1000000-Year_Starttime.tv_sec*1000000+Year_Endtime.tv_usec-Year_Starttime.tv_usec))/1000000;
			//stats_t.total_runtime += time1;
			if(stats_t.year % CLIMATE_YEARS == 0){
				Adjust_Sea_Level(0);
				Adjust_Climate(0);
			}
			if(stats_t.year % Backup_Freq == 0){
				//Adjust_Sea_Level(0);
				//Adjust_Climate(0);
				Backup_Freq_Runtime += Year_Runtime;
				//Year_Runtime = 0;
				Gen_Detailed_Counts();
				pthread_mutex_unlock( &Mutex3 );
				No_Exit = !Save_Current_State();  //cause an exit if failed
				pthread_mutex_unlock( &Mutex3 );
			}else if(No_Exit == 0){  //save and exit
				Backup_Freq_Runtime += Year_Runtime;
				Gen_Detailed_Counts();
				(void)Save_Current_State();  //will still exit gracefully
			}
			//No_Exit = 2 exit no save
			gettimeofday(&Year_Starttime, NULL);
			//if(stats_t.sea_rising){
			//	printf("Current: Sec/Year %fs cur_sealevel %dm rising +1m/1Kyears", (float)time1/1000, ia->cur_sealevel);
			//}else{
			//}
			//Stats_Handled = 1;
			//pthread_mutex_unlock( &mutex1 );
		}
		//Stats_Handled++;
		pthread_mutex_unlock( &Mutex1 );

		pthread_barrier_wait(&Barrier2); //barrier for full year

		pthread_mutex_lock( &Mutex2 );
		Stats_Handled = 0;
		pthread_mutex_unlock( &Mutex2 );

	}//main thread loop

	//free(life_speed_up_H);
	//free(life_speed_up_W);
	pthread_exit(NULL);
}



void Drawl_Image(void){
	uint32_t n1, n2;
	unsigned char rgb[3];
	for(n1=0; n1<HEIGHT; n1++){
		for(n2=0; n2<WIDTH; n2++){
			//if(ia->dem[n1][n2] > stats_t.cur_sealevel){
			if(!life[n1][n2]->alive){
				if(ia->dem[n1][n2] > stats_t.cur_sealevel){
					rgb[0] = 0;
					rgb[1] = 255;
					rgb[2] = 0;
				}else{
					rgb[0] = 0;
					rgb[1] = 0;
					rgb[2] = 255;
				}
			}else{
				Gen_Tribe_Color(life[n1][n2], rgb);
			}
			//}else{
			//	rgb[0] = 0;
			//	rgb[1] = 0;
			//	rgb[2] = 255;
			//}
			ia->image[n1*WIDTH*3+(n2*3)]   = rgb[0];
			ia->image[n1*WIDTH*3+(n2*3+1)] = rgb[1];
			ia->image[n1*WIDTH*3+(n2*3+2)] = rgb[2];
		}
	}
}