/*
	C++ Country & Weapon & Team & Name & Soldier support for Combat Team 2
	Made by Ismo Horppu on 1996 - 1997
	
	Features:
	
	* very flexible C++ code (linked lists, memory allocation, etc...)
	
	* unlimited number (system's memory is the only limit):
		- countries
		- weapons 
		(weapons support only 32 countries, but special countryFlag can 
		be set for accessing weapons for any country)
		- teams
		- soldiers
		- names
		
	* accurate error report/detect code
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pc.h>
#include <math.h>
#include "cadd.h"
#include "rnd.h"

/*
	Country Class
*/

Country::Country ()
{
	countries = 1;
}

long Country::AddCountry ()
{
	if (!(CountryCurrent->Next = new Country)){
		return -1;
	}
	
	CountryLast = CountryCurrent->Next;
	CountryCurrent = CountryLast;
	countries++;
	return 0;
}

long Country::FreeCountries ()
{
	long cnt;
	Country *temp;
	
	CountryCurrent = CountryFirst;
	
	for (cnt = 0; cnt < countries; cnt++){
		temp = CountryCurrent->Next;
		delete CountryCurrent;
		CountryCurrent = temp;
	}
	
	countries = 0;
	return 0;
}

long Country::DisplayNames ()
{
	long cnt;
	Country *temp;
	
	temp = CountryFirst;
	
	for (cnt = 0; cnt < countries - 1; cnt++){
		printf ("%lu. %s\n", cnt + 1, temp->Name);
		temp = temp->Next;
	}
	
	return 0;
}

long Country::SearchCountry (char *CountryName)
{
	long cnt;
	Country *temp;
	
	temp = CountryFirst;
	
	for (cnt = 0; cnt < countries; cnt++){
		if (strcmp (temp->Name, CountryName) == 0) return cnt;
		temp = temp->Next;
	}
	
	return -1;
}

/*
	Weapon Class
*/

Weapon::Weapon ()
{
	weapons = 1;
	Country = 0;
}

long Weapon::AddWeapon ()
{
	if (!(WeaponCurrent->Next = new Weapon)){
		return -1;
	}
	
	WeaponLast = WeaponCurrent->Next;
	WeaponCurrent = WeaponLast;
	weapons++;
	return 0;
}

long Weapon::FreeWeapons ()
{
	long cnt;
	Weapon *temp;
	
	WeaponCurrent = WeaponFirst;
	
	for (cnt = 0; cnt < weapons; cnt++){
		temp = WeaponCurrent->Next;
		delete WeaponCurrent;
		WeaponCurrent = temp;
	}
	
	weapons = 0;
	return 0;
}

long Weapon::DisplayWeaponInfo (long weapon_index)
{
	int cnt;
	Weapon *temp;

	WeaponCurrent = WeaponFirst;
	
	if (weapon_index >= weapons) return -1;
	
	for (cnt = 0; cnt < weapon_index; cnt++){
		temp = WeaponCurrent->Next;
		WeaponCurrent = temp;
	}
	
	printf ("\nWeapon index %lu/%lu\n", weapon_index + 1, weapons);
	printf ("Name %s\n", WeaponCurrent->Name);
	printf ("HitAccuracy %lu\n", WeaponCurrent->HitAccuracy);
	printf ("Damage %lu\n", WeaponCurrent->Damage);
	printf ("Peneration %lu\n", WeaponCurrent->Peneration);
	printf ("Cost %lu$\n", WeaponCurrent->Cost);
	printf ("Magsize %lu\n", WeaponCurrent->MagSize);
	printf ("Magtype %lu\n", WeaponCurrent->MagType);
	printf ("Fire cost %lu APs\n", WeaponCurrent->Cost1);
	printf ("Reload cost %lu APs\n", WeaponCurrent->Cost2);
	printf ("WeaponType %lu\n", WeaponCurrent->WeaponType);
	printf ("Malfunction %lu/100\n", WeaponCurrent->Malfunction);
	printf ("DamageLoss %lu\n", WeaponCurrent->DamageLoss);
	printf ("HitAccuracyLoss %lu\n", WeaponCurrent->HitAccuracyLoss);
	printf ("Weight %lu KGs\n", WeaponCurrent->Weight);
	printf ("CountryFlag %lu\n", WeaponCurrent->Country);
	return 0;
}

/*
	Team Class
*/

Team::Team ()
{
	teams = 1;
}

long Team::AddTeam ()
{
	if (!(TeamCurrent->Next = new Team)){
		return -1;
	}
	
	TeamLast = TeamCurrent->Next;
	TeamCurrent = TeamLast;
	teams++;
	return 0;
}

long Team::SelectCurrentTeam (long teamindex)
{
	long cnt;
	
	if (teamindex >= teams) return -1;
	
	TeamCurrent = TeamFirst;
				
	for (cnt = 0; cnt < teamindex; cnt++){
		TeamCurrent = TeamCurrent->Next;
	}

	return 0;
}


long Team::FreeTeams ()
{
	long cnt;
	Team *temp;
	
	TeamCurrent = TeamFirst;
	
	for (cnt = 0; cnt < teams; cnt++){
		temp = TeamCurrent->Next;
		delete TeamCurrent;
		TeamCurrent = temp;
	}
	
	teams = 0;
	return 0;
}

long Team::DeleteTeam (long teamindex)
{
	long counter;
	Team *temp, *temp2;

	if (teams == 0) return -1;
	if (teamindex >= teams) return -2;

	// first ? (works)
	if (teamindex == 0){
		temp = TeamFirst->Next;	// get second team link
		delete TeamFirst;
		TeamFirst = temp;
		teams--;
		
		if (teams == 1){
			TeamCurrent = TeamFirst;
		}
	}

	// last ? (works)
	else if (teamindex == teams - 1){
		counter = 0;
		temp = TeamFirst;

		for (counter = 0; counter < teams - 2; counter++){
			temp = temp->Next;
		}

		// prev of last
		TeamCurrent = temp;
		delete temp->Next;
		teams--;
	}

	// middle ? (works now...)
	else if (teamindex > 0 && teamindex < teams - 1){
		temp = TeamFirst;

		for (counter = 0; counter < teamindex - 1; counter++){
			temp = temp->Next;
		}

		temp2 = temp->Next->Next;
		delete temp->Next;
		temp->Next = temp2;
		teams--;
	}

	return 0;
}

/*
	Name Class
*/

Name::Name ()
{
	names = 1;
}

long Name::AddName ()
{
	if (!(NameCurrent->Next = new Name)){
		return -1;
	}
	
	NameLast = NameCurrent->Next;
	NameCurrent = NameLast;
	names++;
	return 0;
}

long Name::FreeNames ()
{
	long cnt;
	Name *temp;
	
	NameCurrent = NameFirst;
	
	for (cnt = 0; cnt < names; cnt++){
		temp = NameCurrent->Next;
		delete NameCurrent;
		NameCurrent = temp;
	}
	
	names = 0;
	return 0;
}

long Name::GenerateAllPossibleNames ()
{
	long cnt, cnt2;
	Name *temp, *NameCurrent2;
	
	NameCurrent = NameFirst;
	NameCurrent2 = NameFirst;
	
	for (cnt2 = 0; cnt2 < names; cnt2++){
		NameCurrent = NameFirst;
		
		for (cnt = 0; cnt < names; cnt++){
			temp = NameCurrent->Next;
			printf ("%s %s\n", NameCurrent->FirstName, NameCurrent2->SurName);
			NameCurrent = temp;
		}
		
		temp = NameCurrent2->Next;
		NameCurrent2 = temp;
	}
	
	return 0;
}

long Name::GetName (long firstindex, long surindex)
{
	long cnt, cnt2;
	Name *temp, *NameCurrent2;
	
	if (firstindex >= names){
		return -1;
	}
	
	if (surindex >= names){
		return -1;
	}
	
	NameCurrent = NameFirst;
	NameCurrent2 = NameFirst;
	
	for (cnt2 = 0; cnt2 < surindex; cnt2++){
		NameCurrent = NameFirst;
		temp = NameCurrent2->Next;
		NameCurrent2 = temp;
	}
	
	for (cnt = 0; cnt < firstindex; cnt++){
		temp = NameCurrent->Next;
		NameCurrent = temp;
	}
	
	printf ("%s %s\n", NameCurrent->FirstName, NameCurrent2->SurName);
	return 0;
}

long Name::GetNameCountry (long nameindex)
{
	long cnt, cnt2;
	Name *temp;
	
	if (nameindex >= names){
		return -1;
	}
	
	NameCurrent = NameFirst;
	
	for (cnt = 0; cnt < nameindex; cnt++){
		temp = NameCurrent->Next;
		NameCurrent = temp;
	}
	
	return NameCurrent->Country;
}

long Name::DisplayNames ()
{
	long cnt;
	Name *temp;
	
	temp = NameFirst;
	
	printf ("%lu to go\n", names - 1);

	for (cnt = 0; cnt < names - 1; cnt++){
		printf ("%lu. %s %s (country %d)\n", cnt + 1, temp->FirstName, temp->SurName, temp->Country);
		temp = temp->Next;
	}
	
	return 0;
}

char *Name::GetFirstName (long nameindex)
{
	long cnt, cnt2;
	Name *temp;
	
	if (nameindex >= names){
		return NULL;
	}
	
	NameCurrent = NameFirst;
	
	for (cnt = 0; cnt < nameindex; cnt++){
		temp = NameCurrent->Next;
		NameCurrent = temp;
	}
	
	return NameCurrent->FirstName;
}

char *Name::GetSurName (long nameindex)
{
	long cnt, cnt2;
	Name *temp;
	
	if (nameindex >= names){
		return NULL;
	}
	
	NameCurrent = NameFirst;
	
	for (cnt = 0; cnt < nameindex; cnt++){
		temp = NameCurrent->Next;
		NameCurrent = temp;
	}
	
	return NameCurrent->SurName;
}

/*
	Soldier Class
*/

Soldier::Soldier ()
{
	Team = -1;
	soldiers = 1;
}

long Soldier::AddSoldier ()
{
	if (!(SoldierCurrent->Next = new Soldier)){
		return -1;
	}
	
	SoldierLast = SoldierCurrent->Next;
	SoldierCurrent = SoldierLast;
	soldiers++;
	return 0;
}

long Soldier::FreeSoldiers ()
{
	long cnt;
	Soldier *temp;
	
	SoldierCurrent = SoldierFirst;
	
	for (cnt = 0; cnt < soldiers; cnt++){
		temp = SoldierCurrent->Next;
		delete SoldierCurrent;
		SoldierCurrent = temp;
	}
	
	soldiers = 1;
	return 0;
}

long Soldier::DisplaySoldierInfo (long index)
{
	long cnt;
	Soldier *temp;
	
	if (index >= soldiers) return -1;
	
	temp = SoldierFirst;
	
	for (cnt = 0; cnt < index; cnt++){
		temp = temp->Next;
	}
	
	if (temp->FirstName < CaddName->names && temp->FirstName > -1){
		printf ("FirstName:%s(%lu),",
		CaddName->GetFirstName (temp->FirstName), temp->FirstName);
	}
	
	if (temp->SurName < CaddName->names && temp->SurName > -1){
		printf ("SurName:%s(%lu)\n",
		CaddName->GetSurName (temp->SurName), temp->SurName);
	}
	
	printf ("Strength %lu, Constitution %lu,",
	temp->Strength, temp->Constitution);
	printf ("cost %lu$\n", temp->Cost);
	
	printf ("HPHEAD %lu HPCHEST %lu HPLARM %lu HPRARM %lu HPABDO %lu HPLLEG %lu HPRLEG %lu\n",
	temp->HP[0], temp->HP[1], temp->HP[2], temp->HP[3], 
	temp->HP[4], temp->HP[5], temp->HP[6]);
	printf ("FireSkill %lu\n", temp->FireSkill);
	
	return 0;
}

/*
	generates new soldier
	known bug:
	rnd function doesn't work very well, so this
	routine generates same names after it has
	generated few names
*/

long Soldier::GenerateSoldier (long country, long mixednames)
{
	long names;
	long c1, c2;
	int loop, xloop;
	long BaseHitPoints;
	
	if (country >= CaddCountry->countries) return -1;
	
	names = CaddName->names;

	// mixed names ? -> mix all country names
	if (mixednames){
		while (1){
			randomize ();
			SoldierCurrent->FirstName = rnd (names - 1);
			randomize ();
			SoldierCurrent->SurName = rnd (names - 1);
			
			if (SoldierCurrent->FirstName != oc1 &&
			SoldierCurrent->SurName != oc2) break;
		}
	}
	
	// nope, then specified country names
	else{
		while (1){
			randomize ();
			SoldierCurrent->FirstName = rnd (names - 1);
			randomize ();
			SoldierCurrent->SurName = rnd (names - 1);
			c1 = CaddName->GetNameCountry (SoldierCurrent->FirstName);
			c2 = CaddName->GetNameCountry (SoldierCurrent->SurName);
			
			if (c1 == country && c2 == country){
				if (SoldierCurrent->FirstName != oc1 &&
				SoldierCurrent->SurName != oc2) break;
			}
		}
		
	}

	oc1 = SoldierCurrent->FirstName;
	oc2 = SoldierCurrent->SurName;

	randomize ();
	
	while (1){
		SoldierCurrent->Strength = rnd (14) + 1;
		SoldierCurrent->Constitution = rnd (14) + 1;
		if (SoldierCurrent->Strength != lstr &&
		SoldierCurrent->Constitution != lcon) break;
	}
	
	lstr = SoldierCurrent->Strength;
	lcon = SoldierCurrent->Constitution;

	SoldierCurrent->Cost = (long) 
	pow 
	((double) SoldierCurrent->Strength * 8 / (2 * 3) 
	+ (double) SoldierCurrent->Constitution * 8 / (3 * 3), M_E);
	SoldierCurrent->Cost += 1000 + (long) pow ((double) (SoldierCurrent->Cost / 300), M_E);

	/*
		fireskill will also affect to soldier's price !
	*/
	
	randomize ();
	// maximum start fireskill = 50 !!!
	SoldierCurrent->FireSkill = rand ()% 51 + 1;
	SoldierCurrent->Cost += (long) pow ((double) SoldierCurrent->FireSkill, M_E) / 4;
	
	BaseHitPoints = SoldierCurrent->Strength + SoldierCurrent->Constitution;

	SoldierCurrent->HP[HEAD_HPS] = BaseHitPoints;
	SoldierCurrent->HP[CHEST_HPS] = BaseHitPoints * 3;
	SoldierCurrent->HP[LEFTARM_HPS] = BaseHitPoints * 2;
	SoldierCurrent->HP[RIGHTARM_HPS] = BaseHitPoints * 2;
	SoldierCurrent->HP[ABDOMEN_HPS] = BaseHitPoints * 2;
	SoldierCurrent->HP[LEFTLEG_HPS] = BaseHitPoints * 2;
	SoldierCurrent->HP[RIGHTLEG_HPS] = BaseHitPoints * 2;
	return 0;
}

long Soldier::DeleteSoldier (long soldierindex)
{
	long counter;
	Soldier *temp, *temp2;

	if (soldiers == 0) return -1;
	if (soldierindex >= soldiers) return -2;

	// first ? (works)
	if (soldierindex == 0){
		temp = SoldierFirst->Next;	// get second Soldier link
		delete SoldierFirst;
		SoldierFirst = temp;
		soldiers--;
		
		if (soldiers == 1){
			SoldierCurrent = SoldierFirst;
		}
	}

	// last ? (works)
	else if (soldierindex == soldiers - 1){
		counter = 0;
		temp = SoldierFirst;

		for (counter = 0; counter < soldiers - 2; counter++){
			temp = temp->Next;
		}

		// prev of last
		SoldierCurrent = temp;
		delete temp->Next;
		soldiers--;
	}

	// middle ? (works now...)
	else if (soldierindex > 0 && soldierindex < soldiers - 1){
		temp = SoldierFirst;

		for (counter = 0; counter < soldierindex - 1; counter++){
			temp = temp->Next;
		}

		temp2 = temp->Next->Next;
		delete temp->Next;
		temp->Next = temp2;
		soldiers--;
	}

	return 0;
}

/*
	Init code for all Classes
*/

long ReadRow (FILE *xf)
{
	if (feof (xf)) return -1;
	fgets (textline, 80, xf);
	return 0;
}

long GrabRealPart (void)
{
	long c = 0;
	
	while (1){
		if (textline[c] == 0xD) break;
		if (textline[c] == 0xA) break;
		grabtext[c] = textline[c];
		c++;
		if (c > 79) break;
	}
	
	return 0;
}

long GrabItem (void)
{
	long cnt;
 	char equal = 0;
		
	itempos = 0;
	
	for (cnt = 0; cnt < strlen (grabtext); cnt++){
		if (grabtext[cnt] == '=') equal = 1;
	}

	if (equal){	
		while (1){
			if (grabtext[itempos] == '=') break;
			itempos++;
			if (itempos > 79) return -1;	// invalid item row
		}
			
		itempos++;
	}
	
	cnt = itempos;
	
	while (1){
		if (grabtext[itempos] == 0xD) break;
		if (grabtext[itempos] == 0xA) break;
		itemtext[itempos - cnt] = grabtext[itempos];
		itempos++;
		if (itempos > 79) break;
	}
	
//	printf ("item %s\n", itemtext);
	return 0;
}

// loads in country names (from country.ct2)
long InitCountry (void)
{
	FILE *f;
	long stat;
	char lstat, estat;
	char listFlag = 0, endFlag = 0;
	long cc = 0;
		
	if ((f = fopen ("country.ct2", "rb")) == NULL){
		return -1;
	}
	
	while (1){
		for (stat = 0; stat < 80; stat++) textline[stat] = 0;
		for (stat = 0; stat < 80; stat++) grabtext[stat] = 0;
		stat = ReadRow (f);
		if (stat != 0) break;
	
		// skip commented lines & 0xD+0xA starting rows !!!
		if (textline[0] != ';'){
			if (textline[0] != 0xD && textline[1] != 0xA){
				GrabRealPart ();
				
				lstat = strcmp (grabtext, "[LIST]");
				
				if (lstat == 0){
					listFlag = 1;
				}
				
				estat = strcmp (grabtext, "[END]");
				
				if (estat == 0){
					endFlag = 1;
				}
				
				if (lstat != 0 && estat != 0){
					if (strlen (grabtext) < 31){
						// store its name
						for (stat = 0; stat < 31; stat++){
							CaddCountry->CountryCurrent->Name[stat] = grabtext[stat];
						}
						
						CaddCountry->CountryCurrent->Name[31] = 0;
						// add country
						
						if (CaddCountry->AddCountry () != 0){
							printf ("Not enough memory for a new country link\n");
							fclose (f);
							return -2;
						}
					}
					
					else{
						fclose (f);
						printf ("Error: too long country name (31 is maximum length)\n");
						return -3;
					}
				}
			}
		}
	}
	
	fclose (f);
	
	if (listFlag == 0){
		printf ("Countryfile (country.ct2) error: [LIST] tag was missing\n");
		return -4;
	}
	
	if (endFlag == 0){
		printf ("Countryfile (country.ct2) error: [END] tag was missing\n");
		return -5;
	}

	return 0;
}

// checks if the given string is a digit string
char IsDigitString (char *str)
{
	int c;

	for (c = 0; c < strlen (str); c++){
		if (str[c] < '0') return 0;
		if (str[c] > '9') return 0;
	}
	
	return 1;
}

// loads in weapon (from weapon.ct2)
long InitWeapon (void)
{
	FILE *f;
	long stat, done = 0;
	char lstat, estat;
	char listFlag = 0, endFlag = 0;
	long index = 0;
		
	if ((f = fopen ("weapon.ct2", "rb")) == NULL){
		return -1;
	}
	
	while (1){
		for (stat = 0; stat < 80; stat++){
			textline[stat] = 0;
			grabtext[stat] = 0;
			itemtext[stat] = 0;
		}
		
		stat = ReadRow (f);
		if (stat != 0) break;
	
		// skip commented lines & 0xD+0xA starting rows !!!
		if (textline[0] != ';'){
			if (textline[0] != 0xD && textline[1] != 0xA){
				GrabRealPart ();
				done = 0;
				
				lstat = strcmp (grabtext, "[LIST]");
				
				if (lstat == 0){
					listFlag = 1;
					done = 1;
				}
				
				estat = strcmp (grabtext, "[END]");
				
				if (estat == 0){
					endFlag = 1;
					done = 1;
				}
				
				if (lstat != 0 && estat != 0 && done == 0){
					GrabItem ();
					
					if (index == 0){
						lstat = strcmp (grabtext, "[WEAPON]=");
					
						if (lstat == 0){
						}
						
						else{
							printf ("Tag [WEAPON]= expected\n");
							fclose (f);
							return -2;
						}
					}
					
					else if (index == 1){
						// store weapon name
						for (stat = 0; stat < 31; stat++){
							CaddWeapon->WeaponCurrent->Name[stat] = itemtext[stat];
						}
						
						CaddWeapon->WeaponCurrent->Name[31] = 0;
					}

					else if (index == 2){
						if (!IsDigitString (itemtext)){
							printf ("Exected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}
						
						CaddWeapon->WeaponCurrent->HitAccuracy = atoi (itemtext);
					}
					
					else if (index == 3){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->Damage = atoi (itemtext);
					}
					
					else if (index == 4){
						if (!IsDigitString (itemtext)){
							printf ("Expected a Expected string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->Peneration = atoi (itemtext);
					}
					
					else if (index == 5){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->Cost = atoi (itemtext);
					}
					
					else if (index == 6){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->MagSize = atoi (itemtext);
					}
					
					else if (index == 7){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->MagType = atoi (itemtext);
					}
					
					else if (index == 8){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->Cost1 = atoi (itemtext);
					}
					
					else if (index == 9){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->Cost2 = atoi (itemtext);
					}
					
					else if (index == 10){
						CaddWeapon->WeaponCurrent->WeaponType = -1;
						
						for (int c = 0; c < WEAPON_TYPES; c++){
							stat = strcmp (itemtext, WeaponType[c]);
							
							if (stat == 0){
								CaddWeapon->WeaponCurrent->WeaponType = c;
								c = 5;
							}
						}
						
						if (CaddWeapon->WeaponCurrent->WeaponType == -1){
							printf ("WeaponType %s is invalid\n", itemtext);
							fclose (f);
							return -4;
						}
					}
					
					else if (index == 11){
						CaddWeapon->WeaponCurrent->FireType = -1;
						
						for (int c = 0; c < FIRE_TYPES; c++){
							stat = strcmp (itemtext, FireType[c]);
							
							if (stat == 0){
								CaddWeapon->WeaponCurrent->FireType = c;
								c = 6;
							}
						}
						
						if (CaddWeapon->WeaponCurrent->FireType == -1){
							printf ("FireType %s is invalid\n", itemtext);
							fclose (f);
							return -4;
						}
					}
					
					else if (index == 12){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->Malfunction = atoi (itemtext);
					}
					
					else if (index == 13){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->DamageLoss = atoi (itemtext);
					}
					
					else if (index == 14){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->HitAccuracyLoss = atoi (itemtext);
					}
					
					else if (index == 15){
						if (!IsDigitString (itemtext)){
							printf ("Expected a digit string (from %s)\n", itemtext);
							fclose (f);
							return -3;
						}

						CaddWeapon->WeaponCurrent->Weight = atoi (itemtext);
					}
					
					else if (index == 16){
						// toggle country bit
						stat = CaddCountry->SearchCountry (itemtext);
							
						if (stat == -1){
							printf ("Country (%s) is invalid, it's not defined in country.ct2 file,\n", grabtext);
							printf ("Please define it there and rerun\n");
							fclose (f);
							return -5;
						}
						
						if (stat > 31){
							printf ("Country code can must be below 32\n");
							fclose (f);
							return -6;
						}
						
						// toggle country bit
						CaddWeapon->WeaponCurrent->Country |= (2 << stat);
						// (multicountry toggle code coming soon)
					}
					
					else if (index == 17){
						estat = strcmp (grabtext, "[ENDWEAPON]");
						
						if (estat == 0){
							// add new weapon link

							if (CaddWeapon->AddWeapon () != 0){
								fclose (f);
								printf ("Not enough memory for a new weapon link\n");
								return -7;
							}
						}
						
						else{
							fclose (f);
							printf ("Tag [ENDWEAPON] was expected\n");
							return -8;
						}
						
						index = -1;
					}
					
					index++;
				}
			}
		}
	}
	
	fclose (f);
	
	if (listFlag == 0){
		printf ("Weaponfile (weapon.ct2) error: [LIST] tag was missing\n");
		return -9;
	}
	
	if (endFlag == 0){
		printf ("Weaponfile (weapon.ct2) error: [END] tag was missing\n");
		return -10;
	}
	
	return 0;
}

// loads in team (from custom file)
long InitTeam (char *teamfile)
{
	CaddTeam->AddTeam ();
	CaddTeam->AddTeam ();
	CaddTeam->DeleteTeam (2);
	return 0;
}

// loads in names (from name.ct2)
long InitName (void)
{
	FILE *f;
	long stat, CurrentCountry;
	char listFlag = 0, endFlag = 0, countryFlag = 0, done = 0;
	char lstat, estat, cstat;
	int index = 0;

	if ((f = fopen ("name.ct2", "rb")) == NULL){
		return -1;
	}
	
	while (1){
		for (stat = 0; stat < 80; stat++) textline[stat] = 0;
		for (stat = 0; stat < 80; stat++) grabtext[stat] = 0;
		stat = ReadRow (f);
		if (stat != 0) break;
	
		// skip commented lines & 0xD+0xA starting rows !!!
		if (textline[0] != ';'){
			if (textline[0] != 0xD && textline[1] != 0xA){
				GrabRealPart ();
				done = 0;
				
				lstat = strcmp (grabtext, "[LIST]");

				if (lstat == 0){
					listFlag = 1;
					done = 1;
				}
				
				estat = strcmp (grabtext, "[END]");

				if (estat == 0){
					endFlag = 1;
					done = 1;
				}
				
				// end of country soldiers' names ?
				lstat = strcmp (grabtext, "[ENDNAME]");
				
				if (lstat == 0){
					countryFlag = 0;
					done = 1;
					index = 0;
				}
				
				if (lstat != 0 && estat != 0 && done == 0){
					// country tag ?
					
					if (countryFlag == 0){
						cstat = strcmp (grabtext, "[COUNTRY]=");
						if (cstat == 0) countryFlag = 1;
						
						else{
							printf ("Expected a [COUNTRY]= tag (from %s)\n", grabtext);
							fclose (f);
							return -2;
						}
					}
					
					// nope, read names
					else{
						if (index == 0){
							// story country name
							
							stat = CaddCountry->SearchCountry (grabtext);
							
							if (stat == -1){
								printf ("Country (%s) is invalid, it's not defined in country.ct2 file,\n", grabtext);
								printf ("please define it and rerun this game\n");
								fclose (f);
								return -3;
							}
							
							CurrentCountry = stat;
						}
						
						else if (index == 1){
							cstat = strcmp (grabtext, "FIRSTNAME=");
						
							if (cstat != 0){
								printf ("FIRSTNAME= tag was not found\n");
								fclose (f);
								return -4;
							}
						}
						
						else if (index == 2){
							// story firstname
	
							for (stat = 0; stat < 15; stat++){
								CaddName->NameCurrent->FirstName[stat] = grabtext[stat];
							}
						
							CaddName->NameCurrent->FirstName[15] = 0;
						}
						
						else if (index == 3){
							cstat = strcmp (grabtext, "SURNAME=");
							
							if (cstat != 0){
								printf ("SURNAME= tag was not found\n");
								fclose (f);
								return -5;
							}
						}
						
						else if (index == 4){
							// story surname
							
							for (stat = 0; stat < 15; stat++){
								CaddName->NameCurrent->SurName[stat] = grabtext[stat];
							}
						
							CaddName->NameCurrent->SurName[15] = 0;
							CaddName->NameCurrent->Country = CurrentCountry;
							
							if (CaddName->AddName () != 0){
								printf ("Not enough memory for a new name link\n");
								fclose (f);
								return -6;
							}
						}
						
						index++;
						if (index > 4) index = 1;
					}
				}
			}
		}
	}
	
	if (listFlag == 0){
		printf ("Namefile (name.ct2) error: [LIST] tag was missing\n");
		return -7;
	}
	
	if (endFlag == 0){
		printf ("Namefile (name.ct2) error: [END] tag was missing\n");
		return -8;
	}
	
	fclose (f);
	return 0;
}

int InitSoldier (void)
{
	long cnt;
	
	/*
	for (cnt = 0; cnt < 100; cnt++){
		CaddGeneratedSoldier->GenerateSoldier (0, 1);
		DuplicateGeneratedSoldier (cnt);
		CaddSoldier->DisplaySoldierInfo (cnt);
		CaddSoldier->AddSoldier ();
	}*/
			
	return 0;
}

long DuplicateGeneratedSoldier (long target)
{
	long cnt;
	unsigned char v;
	Soldier *temp;
	
	if (target >= CaddSoldier->soldiers) return -1;
	
	// current soldier ?
	if (target == -1){
		for (cnt = 0; cnt < sizeof (Soldier) & 65535; cnt++){
			*((unsigned char *) (CaddSoldier->SoldierCurrent) + cnt) =
			*((unsigned char *) (CaddGeneratedSoldier->SoldierCurrent) + cnt);
		}
	}
	
	// nope specified soldier...
	else{
		temp = CaddSoldier->SoldierFirst;
	
		for (cnt = 0; cnt < target; cnt++){
			temp = temp->Next;
		}
		
		for (cnt = 0; cnt < sizeof (Soldier) & 65535; cnt++){
			*((unsigned char *) (temp) + cnt) =
			*((unsigned char *) (CaddGeneratedSoldier->SoldierCurrent) + cnt);
		}
	}
	
	return 0;
}

/*
	Initialiazes CADD
*/

long InitCADD (void)
{
	int stat;
	
	if (!(CaddCountry = new Country)){
		printf ("Error: not enough memory for a new country class\n");
		return -1;
	}
	
	CaddCountry->CountryFirst = CaddCountry;
	CaddCountry->CountryCurrent = CaddCountry;
	
	if (!(CaddWeapon = new Weapon)){
		printf ("Error: not enough memory for a new weapon class\n");
		return -2;
	}
	
	CaddWeapon->WeaponFirst = CaddWeapon;
	CaddWeapon->WeaponCurrent = CaddWeapon;
	
	if (!(CaddTeam = new Team)){
		printf ("Error: not enough memory for a new team class\n");
		return -3;
	}
	
	CaddTeam->TeamFirst = CaddTeam;
	CaddTeam->TeamCurrent = CaddTeam;
	
	if (!(CaddName = new Name)){
		printf ("Error: not enough memory for a new name class\n");
		return -4;
	}
	
	CaddName->NameFirst = CaddName;
	CaddName->NameCurrent = CaddName;
	
	if (!(CaddGeneratedSoldier = new Soldier)){
		printf ("Error: not enough memory for a new soldier class\n");
		return -5;
	}
	
	CaddGeneratedSoldier->SoldierFirst = CaddGeneratedSoldier;
	CaddGeneratedSoldier->SoldierCurrent = CaddGeneratedSoldier;
	CaddGeneratedSoldier->SoldierLast = CaddGeneratedSoldier;
	CaddGeneratedSoldier->Next = CaddGeneratedSoldier;
	
	if (!(CaddSoldier = new Soldier)){
		printf ("Error: not enough memory for a new soldier class\n");
		return -5;
	}
	
	CaddSoldier->SoldierFirst = CaddSoldier;
	CaddSoldier->SoldierCurrent = CaddSoldier;
	CaddSoldier->SoldierLast = CaddSoldier;
	CaddSoldier->Next = CaddSoldier;
	
	stat = InitCountry ();
	
	if (stat != 0){
		CaddCountry->FreeCountries ();
		delete CaddWeapon;
		delete CaddTeam;
		delete CaddName;
		delete CaddGeneratedSoldier;
		delete CaddSoldier;
		return -6;
	}
	
	stat = InitWeapon ();
	
	if (stat != 0){
		CaddCountry->FreeCountries ();
		CaddWeapon->FreeWeapons ();
		delete CaddTeam;
		delete CaddName;
		delete CaddGeneratedSoldier;
		delete CaddSoldier;
		return -7;
	}
	
	stat = InitName ();
	
	if (stat != 0){
		CaddCountry->FreeCountries ();
		CaddWeapon->FreeWeapons ();
		CaddName->FreeNames ();
		delete CaddTeam;
		delete CaddGeneratedSoldier;
		delete CaddSoldier;
		return -8;
	}
	
	stat = InitTeam ("team.ct2");
	
	if (stat != 0){
		CaddCountry->FreeCountries ();
		CaddWeapon->FreeWeapons ();
		CaddTeam->FreeTeams ();
		CaddName->FreeNames ();
		delete CaddGeneratedSoldier;
		delete CaddSoldier;
		return -9;
	}
	
	stat = InitSoldier ();
	
	printf ("CADD initialized\n");
	return 0;	
}

/*
	Frees CADD
*/

long FreeCADD (void)
{
	// free linked lists
	CaddCountry->FreeCountries ();
	CaddWeapon->FreeWeapons ();
	CaddTeam->FreeTeams ();
	CaddName->FreeNames ();
	
	printf ("CADD deinitialized\n");
}