# Unit Statistics Mod
#  by
# Teg_Navanis
# based on Kill List Mod by Roger Bacon

from UnitStatisticsDefines import *


class UnitStatisticsTools:

	#checks highscores for all units.
	def	checkHighScoresAllUnits(self, htype, iPlayer, objIgnoreUnit):
		
		if (not g_bTrackHighScore):
			return

		objPlayer = gc.getPlayer(iPlayer)
		unitList = []
		
		if (g_bGlobalHighScore and (g_bTrackAllPlayers or gc.getGame().isGameMultiPlayer())):
			for iPlayer in range(gc.getMAX_PLAYERS()):
				if (gc.getPlayer(iPlayer).isEverAlive()):
					pyPlayer = PyPlayer(iPlayer)
					unitList = unitList + pyPlayer.getUnitList()	
		else:
			unitList = PyPlayer(iPlayer).getUnitList()
			


		self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnits", htype, -1)
	
		try:
			InoreUnitID = str(objIgnoreUnit.getID())+ "X" + str(objIgnoreUnit.getOwner())
			for objUnit in unitList:
				UnitID = str(objUnit.getID())+ "X" + str(objUnit.getOwner())
				if UnitID == InoreUnitID:
					unitList.pop(unitList.index(objUnit))
					break
		except:
			pass

		if (len(unitList) == 0):
			print "no units left"
			self.setHighScoreVal("UnitStats", objPlayer, "Highscores", htype, HighScoreTypes[htype])
			self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnits", htype, -1)
			return		
		

		datalist = []

		if (htype == UNITAGE):
			for objUnit in unitList:
				startturn = sdObjectGetVal("UnitStats", objUnit, STARTTURN)
				iScore = (gc.getGame().getGameTurn() - startturn)
				datalist.append(iScore)

		if (htype == MAXTURNSFORTIFIED):		
			for objUnit in unitList:
				turninformation = sdObjectGetVal("UnitStats", objUnit, TURNINFORMATION)
				datalist.append(turninformation[2])

		elif (htype == TOTALTURNSFORTIFIED):
			for objUnit in unitList:
				turninformation = sdObjectGetVal("UnitStats", objUnit, TURNINFORMATION)
				datalist.append(turninformation[0])

		elif (htype == COMMANDO):
			for objUnit in unitList:
				turninformation = sdObjectGetVal("UnitStats", objUnit, TURNINFORMATION)
				datalist.append(turninformation[3])	

		elif (htype == AVERAGEODDSLOWEST or htype == AVERAGEODDSHIGHEST):
			for objUnit in unitList:
				datalist.append(sdObjectGetVal("UnitStats", objUnit, AVERAGEODDS))
			
		elif (htype == BODYCOUNT or htype == BATTLECOUNT):	
			for objUnit in unitList:
				combatcount = sdObjectGetVal("UnitStats", objUnit, COMBATCOUNT)
				if (htype == BODYCOUNT):
					data = combatcount[ATTACK][1] + combatcount[DEFENCE][1]
				else:
					data = combatcount[ATTACK][0] + combatcount[DEFENCE][0]
				datalist.append(data)
	
		else:
			
			for i in range(10):
				if (htype == DAMAGETYPE[i]):
					for objUnit in unitList:
						damagestats = sdObjectGetVal("UnitStats", objUnit, DAMAGESTATS)
						data = damagestats[i]
						datalist.append(data)
					break
			
			else:
			
				for objUnit in unitList:
					datalist.append(sdObjectGetVal("UnitStats", objUnit, htype))

		
		#in order to check the luckiest unit or the unit with the luckiest fight, we want the lowest score			
		if (htype == BESTODDS or htype == AVERAGEODDSLOWEST or htype == LIFEODDS):
			while min(datalist) == -1:
				datalist[datalist.index(-1)] = 6000
			highest = datalist.index(min(datalist))		
			objUnit = unitList[highest]
			# Get an ID string that is unique (unit.getID() isn't unique)
			UnitID = str(objUnit.getID())+ "X" + str(objUnit.getOwner())

			if (min(datalist) < 101):

				self.setHighScoreVal("UnitStats", objPlayer, "Highscores", htype, min(datalist))
				self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnits", htype, UnitID)				
				if (min(datalist) < self.getHighScoreVal("UnitStats", objPlayer, "HighscoresHoF", htype)):
					self.setHighScoreVal("UnitStats", objPlayer, "HighscoresHoF", htype, min(datalist))
					self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnitsHoF", htype, UnitID)

			else:
				
				self.setHighScoreVal("UnitStats", objPlayer, "Highscores", htype, min(datalist))
				self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnits", htype, -1)	


		else:
			highest = datalist.index(max(datalist))
			objUnit = unitList[highest]
			# Get an ID string that is unique (unit.getID() isn't unique)
			UnitID = str(objUnit.getID())+ "X" + str(objUnit.getOwner())
			if (max(datalist) > 0):
						
				self.setHighScoreVal("UnitStats", objPlayer, "Highscores", htype, max(datalist))
				self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnits", htype, UnitID)
				if (max(datalist) > self.getHighScoreVal("UnitStats", objPlayer, "HighscoresHoF", htype)):
					self.setHighScoreVal("UnitStats", objPlayer, "HighscoresHoF", htype, max(datalist))
					self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnitsHoF", htype, UnitID)
			else:

				self.setHighScoreVal("UnitStats", objPlayer, "Highscores", htype, max(datalist))
				self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnits", htype, -1)


	def	checkTop10(self, htype, iPlayer):

		if (not g_bTrackHighScore):
			return

		objPlayer = gc.getPlayer(iPlayer)
		unitList = []
		UnitIDList = []
		ValList = []
		
		if (g_bGlobalHighScore and (g_bTrackAllPlayers or gc.getGame().isGameMultiPlayer())):
			for iPlayer in range(gc.getMAX_PLAYERS()):
				if (gc.getPlayer(iPlayer).isEverAlive()):
					pyPlayer = PyPlayer(iPlayer)
					unitList = unitList + pyPlayer.getUnitList()
		else:
			unitList = PyPlayer(iPlayer).getUnitList()
			
		if (len(unitList) == 0):
			return [], []

		datalist = []

		if (htype == UNITAGE):
			for objUnit in unitList:
				startturn = sdObjectGetVal("UnitStats", objUnit, STARTTURN)
				iScore = (gc.getGame().getGameTurn() - startturn)
				datalist.append(iScore)

		if (htype == MAXTURNSFORTIFIED):		
			for objUnit in unitList:
				turninformation = sdObjectGetVal("UnitStats", objUnit, TURNINFORMATION)
				datalist.append(turninformation[2])

		elif (htype == TOTALTURNSFORTIFIED):
			for objUnit in unitList:
				turninformation = sdObjectGetVal("UnitStats", objUnit, TURNINFORMATION)
				datalist.append(turninformation[0])	

		elif (htype == COMMANDO):
			for objUnit in unitList:
				turninformation = sdObjectGetVal("UnitStats", objUnit, TURNINFORMATION)
				datalist.append(turninformation[3])	

		elif (htype == AVERAGEODDSLOWEST or htype == AVERAGEODDSHIGHEST):
			for objUnit in unitList:
				datalist.append(sdObjectGetVal("UnitStats", objUnit, AVERAGEODDS))
			
		elif (htype == BODYCOUNT or htype == BATTLECOUNT):	
			for objUnit in unitList:
				combatcount = sdObjectGetVal("UnitStats", objUnit, COMBATCOUNT)
				if (htype == BODYCOUNT):
					data = combatcount[ATTACK][1] + combatcount[DEFENCE][1]
				else:
					data = combatcount[ATTACK][0] + combatcount[DEFENCE][0]
				datalist.append(data)
	
		else:
			
			for i in range(10):
				if (htype == DAMAGETYPE[i]):
					for objUnit in unitList:
						damagestats = sdObjectGetVal("UnitStats", objUnit, DAMAGESTATS)
						data = damagestats[i]
						datalist.append(data)
					break
			
			else:
			
				for objUnit in unitList:
					datalist.append(sdObjectGetVal("UnitStats", objUnit, htype))

		
		#in order to check the luckiest unit or the unit with the luckiest fight, we want the lowest score			
		if (htype == BESTODDS or htype == AVERAGEODDSLOWEST or htype == LIFEODDS):
			while min(datalist) == -1:
				datalist[datalist.index(-1)] = 6000
			
			for i in range(10):
				if (len(unitList) == 0):
					return UnitIDList, ValList
				if (min(datalist) < 101):
					highest = datalist.index(min(datalist))
					value = datalist.pop(highest)
					objUnit = unitList.pop(highest)
					UnitID = str(objUnit.getID())+ "X" + str(objUnit.getOwner())
					UnitIDList.append(UnitID)
					ValList.append(value)


		else:
			for i in range(10):
				if (len(unitList) == 0):
					return UnitIDList, ValList
				if (max(datalist) > 0):
					highest = datalist.index(max(datalist))
					value = datalist.pop(highest)
					objUnit = unitList.pop(highest)
					UnitID = str(objUnit.getID())+ "X" + str(objUnit.getOwner())
					UnitIDList.append(UnitID)
					ValList.append(value)

		return UnitIDList, ValList
			
	#check if a current unit has the high score
	def	checkHighScoresCurrentUnit(self, highscorelist, objUnit):

		if (not g_bTrackHighScore):
			return

		objPlayer = gc.getPlayer(objUnit.getOwner())

		# Get an ID string that is unique (unit.getID() isn't unique)
		UnitID = str(objUnit.getID())+ "X" + str(objUnit.getOwner())

		#for every high score that is checked
		for htype in highscorelist:	

			
			#get the value of the unit that shall be tested
			if (htype == UNITAGE):
				startturn = sdObjectGetVal("UnitStats", objUnit, STARTTURN)
				iScore = (gc.getGame().getGameTurn() - startturn)
			elif (htype == AVERAGEODDSLOWEST or htype == AVERAGEODDSHIGHEST):				
				iScore = sdObjectGetVal("UnitStats", objUnit, AVERAGEODDS)
			elif (htype == BODYCOUNT):
				combatcount = sdObjectGetVal("UnitStats", objUnit, COMBATCOUNT)
				iScore = combatcount[ATTACK][1] + combatcount[DEFENCE][1]
			elif (htype == BATTLECOUNT):
				combatcount = sdObjectGetVal("UnitStats", objUnit, COMBATCOUNT)
				iScore = combatcount[ATTACK][0] + combatcount[DEFENCE][0]

			else:
				for i in range(10):
					if (htype == DAMAGETYPE[i]):
						damagestats = sdObjectGetVal("UnitStats", objUnit, DAMAGESTATS)
						iScore = damagestats[i]
						break
				else:
					iScore = sdObjectGetVal("UnitStats", objUnit, htype)

			
			#get the current high score
			iHighScore = self.getHighScoreVal("UnitStats", objPlayer, "Highscores", htype)

					
			#in order to check the unit with the luckiest fight, we want the lowest score			
			if (htype == BESTODDS or htype == AVERAGEODDSLOWEST or htype == LIFEODDS):
			#if the current unit's score is lower than the high score, mark the unit as the best

				if(iScore < iHighScore or iHighScore == -1):
					self.setHighScoreVal("UnitStats", objPlayer, "Highscores", htype, iScore)
					self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnits", htype, UnitID)				
					if (iScore < self.getHighScoreVal("UnitStats", objPlayer, "HighscoresHoF", htype)):
						self.setHighScoreVal("UnitStats", objPlayer, "HighscoresHoF", htype, iScore)
						self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnitsHoF", htype, UnitID)


			#if the current unit's score is higher than the high score, mark the unit as the best
			else:

				if (iScore > iHighScore):
					self.setHighScoreVal("UnitStats", objPlayer, "Highscores", htype, iScore)
					self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnits", htype, UnitID)
					if (iScore > self.getHighScoreVal("UnitStats", objPlayer, "HighscoresHoF", htype)):
						self.setHighScoreVal("UnitStats", objPlayer, "HighscoresHoF", htype, iScore)
						self.setHighScoreVal("UnitStats", objPlayer, "HighscoreUnitsHoF", htype, UnitID)

	# Get a list with all units that hold at least one high score. Needed for the unitstats screen.
	def getHighScoreUnits(self, strHSorHOF):
		highscorelist = self.getAllHighScores()
		HSIDList = []
		for htype in highscorelist:
			strUnit = self.getHSUnit(htype, strHSorHOF)

			if (not isinstance(strUnit, (int))):
				if (HSIDList.count(strUnit) == 0):
					HSIDList.append(strUnit)
		return HSIDList

	# Get a list with all high scores a specific unit holds. Needed for the unitstats screen.
	def getHighScoresCurrentUnit(self, objUnit, strHSorHOF):
		highscorelist = self.getAllHighScores()
		HSList = []
		if (strHSorHOF == "top10"):
			strHSorHOF = "highscore"
		# Get an ID string that is unique (unit.getID() isn't unique)
		UnitID = sdObjectGetVal("UnitStats", objUnit, UNITID)

		for htype in highscorelist:
			strUnit = self.getHSUnit(htype, strHSorHOF)
			
			if (not isinstance(strUnit, (int))):
				if (UnitID == strUnit):
					HSList.append(htype)
		return HSList

	# Get a the unit that holds a certain high score. Needed for the unitstats screen.	
	def getHSUnit(self, htype, strHSorHOF):

		strUnit = 0

		if (strHSorHOF == "top10"):
			strHSorHOF = "highscore"

		if (g_bGlobalHighScore):
			if (htype == BESTODDS or htype == AVERAGEODDSLOWEST or htype == LIFEODDS):
				lowScore = 1
				highscoreTemp = 101
			else:
				lowScore = 0
				highscoreTemp = 0
			if strHSorHOF == "highscore":
				for iPlayer in range(gc.getMAX_PLAYERS()):
					if (gc.getPlayer(iPlayer).isEverAlive()):
						highscoreNew = self.getHighScoreVal("UnitStats", gc.getPlayer(iPlayer), "Highscores", htype)
						if ((highscoreNew > highscoreTemp and lowScore == 0) or (highscoreNew < highscoreTemp and lowScore == 1)):
							highscoreTemp = highscoreNew
							strUnit = self.getHighScoreVal("UnitStats", gc.getPlayer(iPlayer), "HighscoreUnits", htype)
			elif strHSorHOF == "halloffame":
				for iPlayer in range(gc.getMAX_PLAYERS()):
					if (gc.getPlayer(iPlayer).isEverAlive()):
						highscoreNew = self.getHighScoreVal("UnitStats", gc.getPlayer(iPlayer), "HighscoresHoF", htype)
						if ((highscoreNew > highscoreTemp and lowScore == 0) or (highscoreNew < highscoreTemp and lowScore == 1)):
							highscoreTemp = highscoreNew
							strUnit = self.getHighScoreVal("UnitStats", gc.getPlayer(iPlayer), "HighscoreUnitsHoF", htype)

		else:
			if strHSorHOF == "highscore":
				strUnit = self.getHighScoreVal("UnitStats", gc.getActivePlayer(), "HighscoreUnits", htype)
			elif strHSorHOF == "halloffame":
				strUnit = self.getHighScoreVal("UnitStats", gc.getActivePlayer(), "HighscoreUnitsHoF", htype)
		if (not isinstance(strUnit, (int))):
			return strUnit
		return 0

	# Get a certain high score. Needed for the unitstats screen.
	def getHSVal(self, htype, strHSorHOF):
		if (g_bGlobalHighScore):
			if (htype == BESTODDS or htype == AVERAGEODDSLOWEST or htype == LIFEODDS):
				lowScore = 1
				strHighScore = 101
			else:
				lowScore = 0
				strHighScore = 0
			if strHSorHOF == "highscore":
				for iPlayer in range(gc.getMAX_PLAYERS()):
					if (gc.getPlayer(iPlayer).isEverAlive()):
						highscoreTemp = self.getHighScoreVal("UnitStats", gc.getPlayer(iPlayer), "Highscores", htype)
						if ((highscoreTemp > strHighScore and lowScore == 0) or (highscoreTemp < strHighScore and lowScore == 1)):
							strHighScore = highscoreTemp
			elif strHSorHOF == "halloffame":
				for iPlayer in range(gc.getMAX_PLAYERS()):
					if (gc.getPlayer(iPlayer).isEverAlive()):
						highscoreTemp = self.getHighScoreVal("UnitStats", gc.getPlayer(iPlayer), "HighscoresHoF", htype)
						if ((highscoreTemp > strHighScore and lowScore == 0) or (highscoreTemp < strHighScore and lowScore == 1)):
							strHighScore = highscoreTemp
		else:
			if strHSorHOF == "highscore":
				strHighScore = self.getHighScoreVal("UnitStats", gc.getActivePlayer(), "Highscores", htype)
			elif strHSorHOF == "halloffame":
				strHighScore = self.getHighScoreVal("UnitStats", gc.getActivePlayer(), "HighscoresHoF", htype)

		return strHighScore
	
	# Get a list with all high scores. Needed for the unitstats screen.	
	def getAllHighScores(self):
		messagestringlist = []

		if (g_bShowCombatCount):
			messagestringlist.extend([
								BODYCOUNT,
								BATTLECOUNT])

		if(g_bShowDamageInformation):				
			messagestringlist.extend([
								DAMAGETYPE[0],
					   			DAMAGETYPE[1],
					   			DAMAGETYPE[2],
					    		DAMAGETYPE[3],
					    		DAMAGETYPE[4],
					    		DAMAGETYPE[5],
					    		DAMAGETYPE[6],
					    		DAMAGETYPE[7],
					    		DAMAGETYPE[8],
					    		DAMAGETYPE[9]])

		if (g_bTrackMovement):
			messagestringlist.extend([
							  	MOVEMENT_COUNTER,
								WARP,
								CARGO_COUNTER])

		if (g_bShowExperience):	
			messagestringlist.append(
								EXPERIENCE)

		if (g_bShowOdds):
			messagestringlist.extend([
							  	BESTODDS,
								AVERAGEODDSHIGHEST,
								AVERAGEODDSLOWEST,
								LIFEODDS])
			
		if (g_bTrackTurnInformation):
			messagestringlist.extend([	
								TOTALTURNSFORTIFIED,
								MAXTURNSFORTIFIED,
								COMMANDO,
								UNITAGE])

		return messagestringlist

	# Get an explanatory string for this high score. Needed for the unitstats screen.
	# strPlayerUnit is either "player" or "unit"
	# Use "player" for strings such as "Most collateral damage inflicted: 0 (living units: 0)"
	# Use "units" for strings such as "This unit has inflicted the most collateral damage"
	def getHSString(self, htype, strPlayerUnit):

		objPlayer = gc.getActivePlayer()

		if (strPlayerUnit == "player"):

			# The high score and the hall of fame high score for this high score type are loaded
			htypeHS = self.getHSVal(htype, "highscore")
			htypeHSHOF = self.getHSVal(htype, "halloffame")

			if (htype == BESTODDS):

				if (htypeHSHOF >= 101):			
					strHS = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n- (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" -)"
				elif (htypeHS >= 101):
					temp = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n%.1f%% (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" -)" 
					strHS = temp %(htypeHSHOF)
				else:
					temp = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n%.1f%% (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" %.1f%%)" 
					strHS = temp %(htypeHSHOF, htypeHS)
				return strHS	

			elif (htype == AVERAGEODDSHIGHEST):

				if (htypeHSHOF == -1):			
					strHS = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n- (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" -)"
				elif (htypeHS == -1):
					temp = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n%.1f%% (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" -)"
					strHS = temp %(htypeHSHOF)
				else:
					temp = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n%.1f%% (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" %.1f%%)" 
					strHS = temp %(htypeHSHOF, htypeHS)
				return strHS	

			elif (htype == AVERAGEODDSLOWEST):	

				if (htypeHSHOF >= 101):			
					strHS = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n- (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" -)"
				elif (htypeHS >= 101):
					temp = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n%.1f%% (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" -)" 
					strHS = temp %(htypeHSHOF)
				else:
					temp = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n%.1f%% (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" %.1f%%)" 
					strHS = temp %(htypeHSHOF, htypeHS)
				return strHS
			
			elif (htype == LIFEODDS):

				if (htypeHSHOF >= 101):			
					strHS = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n- (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" -)"
				elif (htypeHS >= 101):
					temp = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n%.1f%% (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" -)" 
					strHS = temp %(htypeHSHOF)
				else:
					temp = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + "\n%.1f%% (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) +" %.1f%%)" 
					strHS = temp %(htypeHSHOF, htypeHS)
				return strHS

			elif (htype == UNITAGE):

				if (htypeHSHOF == -1 and htypeHS == -1):			
					strHS = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, (0,0))
				elif (htypeHSHOF == -1 and htypeHS != -1):			
					strHS = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, (htypeHS, htypeHS))
				elif (htypeHSHOF != -1 and htypeHS == -1):
					strHS = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, (htypeHSHOF, 0))
				else:
					strHS = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, (htypeHSHOF, htypeHS))
				return strHS	
			
			elif (htype == DAMAGETYPE[0] or htype == DAMAGETYPE[1] or htype == DAMAGETYPE[2] or htype == DAMAGETYPE[3] or htype == DAMAGETYPE[4] or htype == DAMAGETYPE[5] or htype == DAMAGETYPE[6] or htype == DAMAGETYPE[7] or htype == DAMAGETYPE[8] or htype == DAMAGETYPE[9]):	
				str2ndpartstring = "\n %.2f (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) + " %.2f)"
			else:
				str2ndpartstring = "\n%s (" + localText.getText("TXT_KEY_LIVING_UNITS", ()) + " %s)"
		
			strHS = localText.getText("TXT_KEY_PLAYERHIGHSCORE_" + htype, ()) + str2ndpartstring

			
			# A message is added, using the string saved in the messagestringlist and actual high scores.
			strHS = strHS %(htypeHSHOF, htypeHS)
			return strHS

		if (strPlayerUnit == "unit"):

			strHS = localText.getText("TXT_KEY_UNITHIGHSCORE_" + htype, ())

			return strHS

	def getUnitStatisticsString(self, objUnit):	

		# Return immediately if we got an invalid unit
		if(objUnit == None):
			return 0
		
		# Return immediately if the unit passed in doesn't belong to the 
		# currently active player. If objUnit.getExperience() fails, 
		# this is probably because a dead unit is processed (objPlot instead of objUnit)
		try:
			test = objUnit.getExperience()
			if(objUnit.getOwner() != gc.getGame().getActivePlayer() and not (g_bTrackAllPlayers or gc.getGame().isGameMultiPlayer())):
				return 0
		except:
			pass

		message1 = sdObjectGetVal("UnitStats", objUnit, LIST)	
		
		turninformation = sdObjectGetVal("UnitStats", objUnit, TURNINFORMATION)
		totalturnsfortified = turninformation[0]
		maxturnsfortified = turninformation[2]
		commando = turninformation[3]
		
		capturecount = sdObjectGetVal("UnitStats", objUnit, CAPTURECOUNT)
		
		combatcount = sdObjectGetVal("UnitStats", objUnit, COMBATCOUNT)
		numberOfKills = combatcount[ATTACK][1] + combatcount[DEFENCE][1]
		numberOfKillsAttacking = combatcount[ATTACK][1]
		numberOfKillsDefending = combatcount[DEFENCE][1]
		battlecount = combatcount[ATTACK][0] + combatcount[DEFENCE][0]
		battlecountAttacking = combatcount[ATTACK][0]
		battlecountDefending = combatcount[DEFENCE][0]
		withdrawalcount = combatcount[ATTACK][3] + combatcount[DEFENCE][3]
		withdrawalcountAttacking = combatcount[ATTACK][3]
		withdrawalcountDefending = combatcount[DEFENCE][3]
		
		airnumberOfKills = combatcount[AIRATTACK][1] + combatcount[AIRDEFENCE][1]
		airnumberOfKillsAttacking = combatcount[AIRATTACK][1]
		airnumberOfKillsDefending = combatcount[AIRDEFENCE][1]
		airbattlecount = combatcount[AIRATTACK][0] + combatcount[AIRDEFENCE][0]
		airbattlecountAttacking = combatcount[AIRATTACK][0]
		airbattlecountDefending = combatcount[AIRDEFENCE][0]
		airstrikecount = combatcount[AIRSTRIKE][0]
		airstrikecountdefending = combatcount[AIRSTRIKE][1]
		
		cargocounter = sdObjectGetVal("UnitStats", objUnit, CARGO_COUNTER)
		movecounter = sdObjectGetVal("UnitStats", objUnit, MOVEMENT_COUNTER)
		distancewarped = sdObjectGetVal("UnitStats", objUnit, WARP)
		distancetransported = sdObjectGetVal("UnitStats", objUnit, WARP) - sdObjectGetVal("UnitStats", objUnit, MOVEMENT_COUNTER)
		#sdObjectSetVal("UnitStats", objUnit, TRANSPORT, distancetransported)

		damagestats = sdObjectGetVal("UnitStats", objUnit, DAMAGESTATS)
		damageinflicted = str("%.2f") %(damagestats[0])
		damageinflictedattacking = str("%.2f") %(damagestats[1])
		damageinflicteddefending = str("%.2f") %(damagestats[2])
		damagesuffered = str("%.2f") %(damagestats[3])
		damagesufferedattacking = str("%.2f") %(damagestats[4])
		damagesuffereddefending = str("%.2f") %(damagestats[5])
		collateraldamageinflicted = str("%.2f") %(damagestats[6])
		collateraldamagesuffered = str("%.2f") %(damagestats[7])
		airstrikedamageinflicted = str("%.2f") %(damagestats[8])
		airstrikedamagesuffered = str("%.2f") %(damagestats[9])
		
		averageodds = str("%.1f%%") %(sdObjectGetVal("UnitStats", objUnit, AVERAGEODDS))
		bestodds = sdObjectGetVal("UnitStats", objUnit, BESTODDS)
		if (not isinstance(bestodds, (str))):
			bestodds = str("%.1f%%") %(sdObjectGetVal("UnitStats", objUnit, BESTODDS))
		oddsdata = sdObjectGetVal("UnitStats", objUnit, ODDSDATA)
		lifeodds = str("%.1f%%") %(sdObjectGetVal("UnitStats", objUnit, LIFEODDS))	
		
		strCombatCount = ""
		if(g_bShowCombatCount):
			strCombatCount = localText.getText("TXT_KEY_BATTLES_FOUGHT", (battlecount, battlecountAttacking, battlecountDefending)) + "\n"
			#strCombatCount = strCombatCount %(battlecount, battlecountAttacking, battlecountDefending)
			strCombatCount = strCombatCount + localText.getText("TXT_KEY_UNITS_KILLED", (numberOfKills, numberOfKillsAttacking, numberOfKillsDefending)) + "\n"
			strCombatCount = strCombatCount + localText.getText("TXT_KEY_UNDECIDED_BATTLES", (withdrawalcount, withdrawalcountAttacking, withdrawalcountDefending)) + "\n\n"
#			strCombatCount = strCombatCount + "Cities captured: %s\n\n" %(capturecount)

		# In case that there is a dead unit processed through (objUnit actually being a plot object, the domain type is calculated differently)
		try:
			domaintype = objUnit.getDomainType()
		except:	
			unittype = sdObjectGetVal("UnitStats", objUnit, UNITTYPE)
			domaintype = gc.getUnitInfo(unittype).getDomainType()
			
		if (domaintype == 1):
			strCombatCount = localText.getText("TXT_KEY_NUM_AIR_STRIKES", (airstrikecount)) + "\n"
			strCombatCount = strCombatCount + localText.getText("TXT_KEY_NUM_AIR_COMBATS", (airbattlecount, airbattlecountAttacking, airbattlecountDefending)) + "\n"
			strCombatCount = strCombatCount + localText.getText("TXT_KEY_NUM_AIR_KILLS", (airnumberOfKills, airnumberOfKillsAttacking, airnumberOfKillsDefending)) + "\n\n"

		strDistanceInformation = ""
		
		if(g_bTrackMovement):
			strDistanceInformation = localText.getText("TXT_KEY_MOVECOUNTERS", (movecounter, distancetransported, distancewarped))
			if (cargocounter > 0):
				strDistanceInformation = strDistanceInformation + "\n" + localText.getText("TXT_KEY_CARGOCOUNTER", (cargocounter, ()))

		# If some distance information is being displayed then add the blank 
		# line spacers.
			if(len(strDistanceInformation) > 0):
				strDistanceInformation = strDistanceInformation + " \n \n"
					
		if(not g_bShowUnitEventLog):
			message1 = ""

		strDamageInformation = ""
		if(g_bShowDamageInformation):	
			strDamageInformation = strDamageInformation + localText.getText("TXT_KEY_DAMAGE_INFLICTED", (damageinflicted, damageinflictedattacking, damageinflicteddefending, collateraldamageinflicted, airstrikedamageinflicted)) + "\n"	
			strDamageInformation = strDamageInformation + localText.getText("TXT_KEY_DAMAGE_SUFFERED", (damagesuffered, damagesufferedattacking, damagesuffereddefending, collateraldamagesuffered, airstrikedamagesuffered)) + "\n\n"
		
		strOddsInformation = "\n\n\n"
		
		if (g_bShowOdds and averageodds != "-1.0%"):
			strOddsInformation = localText.getText("TXT_KEY_ODDSINFORMATION", (averageodds, lifeodds, oddsdata[2])) + "\n"

		strTurnInformation = ""
		if (g_bTrackTurnInformation):
			strTurnInformation = localText.getText("TXT_KEY_TOTALTIMEFORTIFIED", (totalturnsfortified,())) + "\n"
			strTurnInformation = strTurnInformation + localText.getText("TXT_KEY_MAXTIMEFORTIFIED", (maxturnsfortified, ())) + "\n"
			strTurnInformation = strTurnInformation + localText.getText("TXT_KEY_UNITSTATS_COMMANDO", (commando, ())) + "\n\n"

			
		return "%s%s%s%s%s%s" %(strCombatCount, strOddsInformation, strDamageInformation, strDistanceInformation, strTurnInformation, message1)

	# Launches the player statistics 
	def getPlayerStatisticsString(self, iPlayer):

		# Get the currently active player
		PlayerID = "PlayerStats" + str(iPlayer)
		objPlayer = gc.getPlayer(iPlayer)

		combatcount = sdObjectGetVal("UnitStats", objPlayer, COMBATCOUNT)
		numberOfKills = combatcount[ATTACK][1] + combatcount[DEFENCE][1]
		numberOfKillsAttacking = combatcount[ATTACK][1]
		numberOfKillsDefending = combatcount[DEFENCE][1]
		battlecount = combatcount[ATTACK][0] + combatcount[DEFENCE][0]
		battlecountAttacking = combatcount[ATTACK][0]
		battlecountDefending = combatcount[DEFENCE][0]
		losscount = combatcount[ATTACK][2] + combatcount[DEFENCE][2]
		losscountAttacking = combatcount[ATTACK][2]
		losscountDefending = combatcount[DEFENCE][2]
		withdrawalcount = combatcount[ATTACK][3] + combatcount[DEFENCE][3]
		withdrawalcountAttacking = combatcount[ATTACK][3]
		withdrawalcountDefending = combatcount[DEFENCE][3]

		airnumberOfKills = combatcount[AIRATTACK][1] + combatcount[AIRDEFENCE][1]
		airnumberOfKillsAttacking = combatcount[AIRATTACK][1]
		airnumberOfKillsDefending = combatcount[AIRDEFENCE][1]
		airbattlecount = combatcount[AIRATTACK][0] + combatcount[AIRDEFENCE][0]
		airbattlecountAttacking = combatcount[AIRATTACK][0]
		airbattlecountDefending = combatcount[AIRDEFENCE][0]
		airstrikecount = combatcount[AIRSTRIKE][0]
		airstrikecountdefending = combatcount[AIRSTRIKE][1]
		airlosscount = combatcount[AIRATTACK][2] + combatcount[AIRDEFENCE][2]
		airlosscountAttacking = combatcount[AIRATTACK][2]
		airlosscountDefending = combatcount[AIRDEFENCE][2]

		highestDefeatOdds = sdObjectGetVal("UnitStats", objPlayer, HIGHEST_DEFEAT_ODDS)
		highestDefeatOdds = str("%.1f%%") %(highestDefeatOdds)


		lowestVictoryOdds = self.getHighScoreVal("UnitStats", objPlayer, "HighscoresHoF", BESTODDS)
		if lowestVictoryOdds >= 101:
			lowestVictoryOdds = "0.0%"
		else:
			lowestVictoryOdds = str("%.1f%%") %(lowestVictoryOdds)
		
		
		turninformation = sdObjectGetVal("UnitStats", objPlayer, TURNINFORMATION)
		totalturnsfortified = turninformation[0]
		maxturnsfortified = turninformation[2]
		
		cargocounter = sdObjectGetVal("UnitStats", objPlayer, CARGO_COUNTER)
		movecounter = sdObjectGetVal("UnitStats", objPlayer, MOVEMENT_COUNTER)
		distancewarped = sdObjectGetVal("UnitStats", objPlayer, WARP)
		distancetransported = sdObjectGetVal("UnitStats", objPlayer, WARP) - sdObjectGetVal("UnitStats", objPlayer, MOVEMENT_COUNTER)
		#sdObjectSetVal("UnitStats", objPlayer, TRANSPORT, distancetransported)

		damagestats = sdObjectGetVal("UnitStats", objPlayer, DAMAGESTATS)
		damageinflicted = str("%.2f") %(damagestats[0])
		damageinflictedattacking = str("%.2f") %(damagestats[1])
		damageinflicteddefending = str("%.2f") %(damagestats[2])
		damagesuffered = str("%.2f") %(damagestats[3])
		damagesufferedattacking = str("%.2f") %(damagestats[4])
		damagesuffereddefending = str("%.2f") %(damagestats[5])
		collateraldamageinflicted = str("%.2f") %(damagestats[6])
		collateraldamagesuffered = str("%.2f") %(damagestats[7])
		airstrikedamageinflicted = str("%.2f") %(damagestats[8])
		airstrikedamagesuffered = str("%.2f") %(damagestats[9])

		goodies = sdObjectGetVal("UnitStats", objPlayer, GOODIES)
		experience = sdObjectGetVal("UnitStats", objPlayer, EXPERIENCE)
				
		strCombatCount = ""
		if(g_bShowCombatCount):
			strCombatCount = localText.getText("TXT_KEY_BATTLES_FOUGHT", (battlecount, battlecountAttacking, battlecountDefending)) + "\n"
			strCombatCount = strCombatCount + localText.getText("TXT_KEY_UNITS_KILLED", (numberOfKills, numberOfKillsAttacking, numberOfKillsDefending)) + "\n"
			strCombatCount = strCombatCount + localText.getText("TXT_KEY_UNITS_LOST", (losscount, losscountAttacking, losscountDefending)) + "\n"
			strCombatCount = strCombatCount + localText.getText("TXT_KEY_UNDECIDED_BATTLES", (withdrawalcount, withdrawalcountAttacking, withdrawalcountDefending)) + "\n\n"

		strAirCombatCount = ""
		if(g_bShowCombatCount):
			strAirCombatCount = localText.getText("TXT_KEY_NUM_AIR_STRIKES", (airstrikecount, ())) + "\n"
			strAirCombatCount = strAirCombatCount + localText.getText("TXT_KEY_NUM_AIR_COMBATS", (airbattlecount, airbattlecountAttacking, airbattlecountDefending)) + "\n"
			strAirCombatCount = strAirCombatCount + localText.getText("TXT_KEY_NUM_AIR_KILLS", (airnumberOfKills, airnumberOfKillsAttacking, airnumberOfKillsDefending)) + "\n\n"

		strOddsInformation = ""
		strOddsInformation = localText.getText("TXT_KEY_LOWEST_VICTORY_ODDS", (lowestVictoryOdds, ())) + "\n"
		strOddsInformation = strOddsInformation + localText.getText("TXT_KEY_HIGHEST_DEFEAT_ODDS", (highestDefeatOdds, ())) + "\n\n"


		strDistanceInformation = ""	
		if(g_bTrackMovement):
			strDistanceInformation = localText.getText("TXT_KEY_MOVECOUNTERS", (movecounter, distancetransported, distancewarped))
			if (cargocounter > 0):
				strDistanceInformation = strDistanceInformation + "\n" + localText.getText("TXT_KEY_CARGOCOUNTER", (cargocounter, ()))
		# If some distance information is being displayed then add the blank 
		# line spacers.
			if(len(strDistanceInformation) > 0):
				strDistanceInformation = strDistanceInformation + " \n \n"
					
		if(not g_bShowUnitEventLog):
			message1 = ""

		strTurnInformation = ""	
		if (g_bTrackTurnInformation):		
			strTurnInformation = strTurnInformation + localText.getText("TXT_KEY_TOTALTIMEFORTIFIED", (totalturnsfortified, ())) + "\n"
			strTurnInformation = strTurnInformation + localText.getText("TXT_KEY_MAXTIMEFORTIFIED", (maxturnsfortified, ())) + "\n\n"

		strDamageInformation = ""
	
		if(g_bShowDamageInformation):		
			strDamageInformation = strDamageInformation + localText.getText("TXT_KEY_DAMAGE_INFLICTED", (damageinflicted, damageinflictedattacking, damageinflicteddefending, collateraldamageinflicted, airstrikedamageinflicted)) + "\n"	
			strDamageInformation = strDamageInformation + localText.getText("TXT_KEY_DAMAGE_SUFFERED", (damagesuffered, damagesufferedattacking, damagesuffereddefending, collateraldamagesuffered, airstrikedamagesuffered)) + "\n\n"
			
		strMiscInformation = ""
		
		if (g_bShowExperience):
			strMiscInformation = strMiscInformation + localText.getText("TXT_KEY_EXPERIENCE_GAINED", (experience, ())) + "\n"
		if (g_bTrackGoodyReceived):
			strMiscInformation = strMiscInformation + localText.getText("TXT_KEY_GOODIES_RECEIVED", (goodies,()))
			

		return "%s%s%s%s%s%s%s" %(strCombatCount, strDamageInformation, strOddsInformation, strAirCombatCount, strDistanceInformation, strTurnInformation, strMiscInformation)
	
	
	# This removes any data that was saved for the hall of fame and is now obsolete	
	def cleanGraveYardList(self, iPlayer):
		graveyardlist = sdObjectGetVal("UnitStats", gc.getPlayer(iPlayer), GRAVEYARDLIST)
		graveyardlisttemp = graveyardlist[:]

		highscorelist = self.getAllHighScores()
		HSList = []
		for htype in highscorelist:
			strUnit = self.getHighScoreVal("UnitStats", gc.getActivePlayer(), "HighscoreUnitsHoF", htype)
			if (not isinstance(strUnit, (int))):
				if (HSList.count(strUnit) == 0):
					HSList.append(strUnit)

		for id in HSList:
			try:
				graveyardlisttemp.pop(graveyardlisttemp.index(id))
			except:
				continue
		for id in graveyardlisttemp:
			try:
				graveyardlist[graveyardlist.index(id)] = 0
				objPlot = gc.getMap().plot(graveyardlist.index(id), iPlayer)
				sdObjectWipe("UnitStats", objPlot)
			except:
				continue
		sdObjectSetVal("UnitStats", gc.getPlayer(iPlayer), GRAVEYARDLIST, graveyardlist)

	# Converts a number into its string representation. This is needed since
	# for whatever reason, numbers did not work very well when using them 
	# for all of the different panels in the screen. The
	# unit ID number 382343 is converted to: CHBCDC.
	def numberToAlpha(self, iNum):
		#             1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26
		alphaList = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
		strNum = str(iNum)
		strAlpha = ""
		
		# Go though the alphaList and convert the numbers to letters
		for i in range (len(strNum)):
			strAlpha = strAlpha + alphaList[int(strNum[i])]
			
		return strAlpha
	
	
	# Converts a number into its string representation. This is needed since
	# for whatever reason, numbers did not work very well when using them 
	# for all of the different panels in the screen. The
	# string "CHBCDC" is converted to: 382343.
	def alphaToNumber(self, strAlpha):
		#             1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26
		alphaList = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
		
		strNum = ""

		# Go though the alphaList and convert the letters to numbers
		for i in range (len(strAlpha)):
			strNum = strNum + str(alphaList.index(strAlpha[i]))
		
		return int(strNum)

	# Input: UnitID in the form of 1235X1 or ABCD-A	
	# Output: unit object or plot object, depending on whether the unit is alive or dead.
	def unitIDToObject(self, UnitID):

		if (UnitID == None or isinstance(UnitID, (int))):
			return 0, 0, 0

		# Get the Player ID and the Unit ID (there are two different methods of storing them,
		# 1235X1 and ABCD-A	
		try:
			strUnitID, strPlayerID = UnitID.split("X")
			iPlayer = int(strPlayerID)
			iUnitID = int(strUnitID)
		except:
			strUnitID, strPlayerID = UnitID.split("-")
			iPlayer = self.alphaToNumber(strPlayerID)
			iUnitID = self.alphaToNumber(strUnitID)
			
		# Get the list of dead units
		graveyardlist = []
		if ((g_bTrackAllPlayers or gc.getGame().isGameMultiPlayer()) and g_bShowAllPlayers):
			for iLoopPlayer in range(gc.getMAX_PLAYERS()):
				if (gc.getPlayer(iLoopPlayer).isEverAlive()):
					newlist = sdObjectGetVal("UnitStats", gc.getPlayer(iLoopPlayer), GRAVEYARDLIST)
					if (len(newlist) > 0):
						graveyardlist.extend(newlist)
		else:	
			graveyardlist = sdObjectGetVal("UnitStats", gc.getActivePlayer(), GRAVEYARDLIST)

		UnitID = str(iUnitID)+ "X" + str(iPlayer)
		# Get the actual object. If the unit object is invalid, it returns the plot object
		# in which the lost unit's data is saved.
		try:
			object = gc.getPlayer(iPlayer).getUnit(iUnitID)
			unittype = object.getUnitType()
			if unittype == -1:
				playergraveyardlist = sdObjectGetVal("UnitStats", gc.getPlayer(iPlayer), GRAVEYARDLIST)
				object = gc.getMap().plot(playergraveyardlist.index(UnitID), iPlayer)
			return iUnitID, iPlayer, object
		except:	
			playergraveyardlist = sdObjectGetVal("UnitStats", gc.getPlayer(iPlayer), GRAVEYARDLIST)
			object = gc.getMap().plot(playergraveyardlist.index(UnitID), iPlayer)
			return iUnitID, iPlayer, object

	# This is just a placeholder. 
	def isModOption(self, argument):
		return True

	# Due to a bug with too many dictionaries within each other, the high scores
	# will be stored in plot objects from now on. This function assigns a plot
	# to each of the different high score lists necessary and then runs the normal
	# SdToolKit code for them.
	def getHighScoreVal(self, ModID, playerobject, strHighScoreListType, htype):

		mapwidth = gc.getMap().getGridWidth()

		# Depending on the high score list type passed in, a different X coordinate
		# is selected for the plot.
		if strHighScoreListType == "HighscoresHoF":
			plotX = mapwidth - 1
		elif strHighScoreListType == "Highscores":
			plotX = mapwidth - 2
		elif strHighScoreListType == "HighscoreUnits":
			plotX = mapwidth - 3
		elif strHighScoreListType == "HighscoreUnitsHoF":
			plotX = mapwidth - 4

		# Get the plot object.
		objPlot = gc.getMap().plot(plotX, playerobject.getID())

		# Initialize the object if necessary.
		if (sdObjectExists(ModID, objPlot) == False):
			sdObjectInit(ModID, objPlot, HighScoreTypes)
			
		return sdObjectGetVal(ModID, objPlot, htype)

	# Due to a bug with too many dictionaries within each other, the high scores
	# will be stored in plot objects from now on. This function assigns a plot
	# to each of the different high score lists necessary and then runs the normal
	# SdToolKit code for them.
	def setHighScoreVal(self, ModID, playerobject, strHighScoreListType, htype, val):
		
		mapwidth = gc.getMap().getGridWidth()

		# Depending on the high score list type passed in, a different X coordinate
		# is selected for the plot.
		if strHighScoreListType == "HighscoresHoF":
			plotX = mapwidth - 1
		elif strHighScoreListType == "Highscores":
			plotX = mapwidth - 2
		elif strHighScoreListType == "HighscoreUnits":
			plotX = mapwidth - 3
		elif strHighScoreListType == "HighscoreUnitsHoF":
			plotX = mapwidth - 4

		# Get the plot object.
		objPlot = gc.getMap().plot(plotX, playerobject.getID())

		# Initialize the object if necessary.
		if (sdObjectExists(ModID, objPlot) == False):
			sdObjectInit(ModID, objPlot, HighScoreTypes)
			
		sdObjectSetVal(ModID, objPlot, htype, val)