/** 
 *  _   _        _  _                           _             
 * | |_| |  ___ | || |  ___   __ _  _ __  _ __ (_)  ___  _ __ 
 * |  _  | / _ \| || | / __| / _` || '__|| '__|| | / _ \| '__|
 * | | | ||  __/| || || (__ | (_| || |   | |   | ||  __/| |   
 * |_| |_| \___||_||_| \___| \__,_||_|   |_|   |_| \___||_|   
 * 
 *  (c) 2001 Free Lunch Design, Teknisk-IT, AerotechTelub
 *			  http://www.freelunchdesign.com
 * 
 * This source code is released as is under GPL (General Public
 * License). Please refer to license.txt for more information.
 * 
 */
 
#include <stdio.h>
#include "allegro.h"
#include "soldier.h"
#include "dime.h"
#include "name.h"
#include "projectile.h"
#include "config.h"

// constructor
soldier :: soldier(int t) {
	type = t;
	if (type != OBJ_SOLDIER && type != OBJ_FOOT_SOLDIER && type != OBJ_BAZOOKA_SOLDIER)  {
		my_alert("soldier :: soldier", "unknown soldier type\ndefaulting to SOLDIER (normal)");
		type = OBJ_SOLDIER;
	}

	reset_wp();
	get_random_name(name);
	altitude = GL_GROUND_UNIT;

	smoking = 0;
	x = y = w = h = 0;
	exist = TRUE;
	target = FALSE;
	detail_level = DETAIL_LOW;
	angle = 0;
	ammo_count = 0;
	frame_count = 0;
	target_angle = angle;
	wp_dir = 1;
	wp_pos = 0;
	shadow_dist	= 3;
	may_fire = FALSE;
	target_thrust = 0;
	current_target = NULL;
	angle_counter = 5;
	wanna_ride = 0;
	team = 2;
	event = 0;
	jumping = FALSE;
	burning = 0;
	pup_collector = FALSE;
	carrying_pup = 0;
	essential = FALSE;
	pup_search_time = 0;

	anim_pos = 0;
	anim_count = 0;
	mode = AI_IDLE;

	max_armour = armour;
}


// destructor
soldier :: ~soldier() {}


// returns a random based upon the string
// ex: AA-BB-CC = AA + rand()%BB - CC
int soldier::get_random(char *rnd) {
	rnd[2] = rnd[5] = '\0';
	int AA = atoi(rnd);
	int BB = atoi(&rnd[3])+1;
	int CC = atoi(&rnd[6]);
	return AA + rand()%BB - CC;
}


void soldier::to_string(char *str) {
	sprintf(str, "%s", name);
}

// shows a property dialog
void soldier::props_dialog(DATAFILE *df) {
	char buf[64];
	if (type == OBJ_SOLDIER) sprintf(buf, "Soldier Properties [SOLDIER]");
	if (type == OBJ_FOOT_SOLDIER) sprintf(buf, "Soldier Properties [FOOT SOLDIER]");
	if (type == OBJ_BAZOOKA_SOLDIER) sprintf(buf, "Soldier Properties [BAZOOKA SOLDIER]");
	dialogf(buf , ALIGN_CENTER, ALIGN_CENTER, 300,
		"Name: %string[32]"
		"Team: %int[0,5]"
		"Active at event: %int[0,32]"
		"Ride to zone: %int[0,15]",
		name, &team, &event, &wanna_ride);
}

// saves all stats to disk
void soldier::save(PACKFILE *fp) {
	pack_fwrite(name, sizeof(name), fp);
	pack_fwrite(&index, sizeof(index), fp);
	pack_fwrite(&inside, sizeof(inside), fp);
	pack_fwrite(&type, sizeof(type), fp);
	pack_fwrite(&altitude, sizeof(altitude), fp);
	pack_fwrite(&x, sizeof(x), fp);
	pack_fwrite(&y, sizeof(y), fp);
	pack_fwrite(&w, sizeof(w), fp);
	pack_fwrite(&h, sizeof(h), fp);
	pack_fwrite(&exist, sizeof(exist), fp);
	pack_fwrite(&target, sizeof(target), fp);
	pack_fwrite(&detail_level, sizeof(detail_level), fp);
	pack_fwrite(&angle, sizeof(angle), fp);
	pack_fwrite(&base_image, sizeof(base_image), fp);
	pack_fwrite(&shadow_image, sizeof(base_image), fp);
	pack_fwrite(&wreck_image, sizeof(base_image), fp);
	pack_fwrite(&anim_frames, sizeof(anim_frames), fp);
	pack_fwrite(&anim_rate, sizeof(anim_rate), fp);
	pack_fwrite(&armour, sizeof(armour), fp);
	pack_fwrite(file, sizeof(file), fp);
	pack_fwrite(&essential, sizeof(essential), fp);

	pack_fwrite(&event, sizeof(event), fp);
	pack_fwrite(&team, sizeof(team), fp);
	pack_fwrite(&sight_range, sizeof(sight_range), fp);
	pack_fwrite(&sight_angle, sizeof(sight_angle), fp);
	pack_fwrite(&fire_range, sizeof(fire_range), fp);
	pack_fwrite(wp, sizeof(wp), fp);

	pack_fwrite(&fire_rate, sizeof(fire_rate), fp);
	pack_fwrite(&reload_rate, sizeof(reload_rate), fp);
	pack_fwrite(&fire_sound, sizeof(fire_sound), fp);
	pack_fwrite(&reload_sound, sizeof(reload_sound), fp);
	pack_fwrite(&die_sound, sizeof(die_sound), fp);
	pack_fwrite(&burn_sound, sizeof(burn_sound), fp);
	pack_fwrite(&mode, sizeof(mode), fp);
	pack_fwrite(&jeep_skill, sizeof(jeep_skill), fp);
	pack_fwrite(&truck_skill, sizeof(truck_skill), fp);
	pack_fwrite(&tank_skill, sizeof(tank_skill), fp);
	pack_fwrite(&heli_skill, sizeof(heli_skill), fp);
	pack_fwrite(&wanna_ride, sizeof(wanna_ride), fp);
}

// loads from disk
void soldier::load(PACKFILE *fp) {
	pack_fread(name, sizeof(name), fp);
	pack_fread(&index, sizeof(index), fp);
	pack_fread(&inside, sizeof(inside), fp);
	pack_fread(&type, sizeof(type), fp);
	pack_fread(&altitude, sizeof(altitude), fp);
	pack_fread(&x, sizeof(x), fp);
	pack_fread(&y, sizeof(y), fp);
	pack_fread(&w, sizeof(w), fp);
	pack_fread(&h, sizeof(h), fp);
	pack_fread(&exist, sizeof(exist), fp);
	pack_fread(&target, sizeof(target), fp);
	pack_fread(&detail_level, sizeof(detail_level), fp);
	pack_fread(&angle, sizeof(angle), fp);
	pack_fread(&base_image, sizeof(base_image), fp);
	pack_fread(&shadow_image, sizeof(base_image), fp);
	pack_fread(&wreck_image, sizeof(base_image), fp);
	pack_fread(&anim_frames, sizeof(anim_frames), fp);
	pack_fread(&anim_rate, sizeof(anim_rate), fp);
	pack_fread(&armour, sizeof(armour), fp);
	pack_fread(file, sizeof(file), fp);
	pack_fread(&essential, sizeof(essential), fp);

	pack_fread(&event, sizeof(event), fp);
	pack_fread(&team, sizeof(team), fp);
	pack_fread(&sight_range, sizeof(sight_range), fp);
	pack_fread(&sight_angle, sizeof(sight_angle), fp);
	pack_fread(&fire_range, sizeof(fire_range), fp);
	pack_fread(wp, sizeof(wp), fp);

	pack_fread(&fire_rate, sizeof(fire_rate), fp);
	pack_fread(&reload_rate, sizeof(reload_rate), fp);
	pack_fread(&fire_sound, sizeof(fire_sound), fp);
	pack_fread(&reload_sound, sizeof(reload_sound), fp);
	pack_fread(&die_sound, sizeof(die_sound), fp);
	pack_fread(&burn_sound, sizeof(burn_sound), fp);
	pack_fread(&mode, sizeof(mode), fp);
	pack_fread(&jeep_skill, sizeof(jeep_skill), fp);
	pack_fread(&truck_skill, sizeof(truck_skill), fp);
	pack_fread(&tank_skill, sizeof(tank_skill), fp);
	pack_fread(&heli_skill, sizeof(heli_skill), fp);
	pack_fread(&wanna_ride, sizeof(wanna_ride), fp);
}

// draws soldier to any BITMAP
void soldier::draw(BITMAP *bmp, DATAFILE *gfx, fixed ca, bool shadow) {
	int im = base_image + anim_pos;
	if (!target_thrust) im = base_image;
	if (jumping) im = jump_image;
	if (burning) im = 109 + anim_pos;
	
	// shadow
	if (shadow) {
		BITMAP *s1 = create_bitmap(w, h);
		BITMAP *s2 = create_bitmap(radius*2, radius*2);
		clear(s1);
		clear(s2);
		draw_character(s1, (BITMAP *)gfx[im].dat, 0, 0, 15);
		rotate_sprite(s2, s1, radius-w/2, radius-h/2, angle - ca);
		draw_trans_sprite(bmp, s2, render_x+shax*shadow_dist-radius, render_y+shay*shadow_dist-radius);
		destroy_bitmap(s1);
		destroy_bitmap(s2);
	}

	rotate_sprite(bmp, (BITMAP *)gfx[im].dat, render_x-w/2, render_y-h/2, angle - ca);
//	textprintf(bmp, font, render_x+10, render_y, 1, "%d", pup_search_time);
//	textprintf(bmp, font, render_x+10, render_y, 1, "%d", index);
}

// fires a shot, returns projectile *
projectile *soldier::fire(int pt) {
	projectile *p;
	if (type == OBJ_BAZOOKA_SOLDIER) p = new projectile(this, P_BAZOOKA);
	else p = new projectile(this, P_BULLET);

	return p;
}

// reads config from file
void soldier::set_from_file(char *fname) {
	config *c = new config();
	if (c->load_data(fname)) {
		// object stuff
		anim_frames = c->get_data_int("anim_frames");
		anim_rate = c->get_data_int("anim_rate");
		base_image = c->get_data_int("base_image");
		shadow_image = c->get_data_int("shadow_image");
		wreck_image = c->get_data_int("wreck_image");
		armour = c->get_data_int("armour");
	
		rot_step = c->get_data_float("rot_step");
		rot_fric = c->get_data_float("rot_fric");
		thr_step = c->get_data_float("thr_step");
		thr_fric = c->get_data_float("thr_fric");
		str_step = c->get_data_float("str_step");
		str_fric = c->get_data_float("str_fric");
		f_fric = c->get_data_float("force_fric");
	
		// unit stuff
		//normal_speed = ftofix(get_config_float(section, "normal_speed", 1.0));
		//panic_speed = ftofix(get_config_float(section, "panic_speed", 2.0));
		max_turn_angle = c->get_data_int("max_turn_angle");
		mag_size = c->get_data_int("mag_size");
		
		fire_range = c->get_data_int("fire_range");
		sight_range = c->get_data_int("sight_range");
		sight_angle = c->get_data_int("sight_angle");
	
		// soldier stuff
		jump_image = c->get_data_int("jump_image");
		fire_rate = c->get_data_float("fire_rate");
		reload_rate = c->get_data_float("reload_rate");
		fire_sound = c->get_data_int("fire_sound");
		reload_sound = c->get_data_int("reload_sound");
		die_sound = c->get_data_int("die_sound");
		burn_sound = c->get_data_int("burn_sound");
	/*
		jeep_skill = get_random((char *)get_data_string(section, "jeep_skill", "00r99-00"));
		truck_skill = get_random((char *)get_data_string(section, "truck_skill", "00r99-00"));
		tank_skill = get_random((char *)get__string(section, "tank_skill", "00r99-00"));
		heli_skill = get_random((char *)get_config_string(section, "heli_skill", "00r99-00"));
		*/
	}
	else my_alert("file not found", fname);
	c->~config();
}

void soldier::start_fire(int time) {
	burning = time;
	anim_rate = 3+rand()%5;
}
