## SpyUtil
##
## Tracks each player's espionage point values per player to provide access to spending levels.
##
## Copyright (c) 2009 The BUG Mod.
##
## Author: EmperorFool, ruff_hi

from CvPythonExtensions import *
import BugUtil
import PlayerUtil
import BugData

gc = CyGlobalContext()


## Tracking Values for Previous and Current Turns

g_iTurn = None
g_values = None

# rucivfan_espionage_system_extended rese[
# # gets the total spending over the prior turn by playerOrID
# # limits the spending to players known to 'ActiveplayerOrID' if provided
# def getSpending(playerOrID, ActiveplayerOrID=None):
	# if ActiveplayerOrID != None:
		# pActiveTeam = PlayerUtil.getPlayerTeam(ActiveplayerOrID)

	# pPlayerTeam = PlayerUtil.getPlayerTeam(playerOrID)

	# iTotal = 0
	# for targetTeam in PlayerUtil.teams(True, None, False):
		# if (ActiveplayerOrID == None
		# or pActiveTeam.isHasMet(targetTeam.getID())):
			# iTotal += getDifferenceByTeam(, targetTeam.getID())
	# return iTotal

# gets the total spending over the prior turn by playerOrID
# limits the spending to players known to 'ActiveplayerOrID' if provided
def getSpending(playerOrID, ActiveplayerOrID=None):
	if playerOrID == None:
		return 0

	pPlayerTeam = PlayerUtil.getPlayerTeam(playerOrID)
	if ActiveplayerOrID != None:
		pActiveTeam = PlayerUtil.getPlayerTeam(ActiveplayerOrID)

	iTotal = 0
	for pTargetTeam in PlayerUtil.teams(True, None, False):
		if (ActiveplayerOrID == None 
		or (pActiveTeam.isHasMet(pTargetTeam.getID()) and pActiveTeam.isForeignEspionageTeamAgainstTeamVisible(pPlayerTeam.getID(), pTargetTeam.getID()))):
			iTotal += getDifferenceByTeam(pPlayerTeam.getID(), pTargetTeam.getID())
	return iTotal
# ]rucivfan_espionage_system_extended rese


def getDifferenceByPlayer(playerOrID, targetPlayerOrID=None):
	if targetPlayerOrID is None:
		return getDifferenceByTeam(PlayerUtil.getPlayerTeam(playerOrID))
	else:
		return getDifferenceByTeam(PlayerUtil.getPlayerTeam(playerOrID), PlayerUtil.getPlayerTeamID(targetPlayerOrID))

def getDifferenceByTeam(teamOrID, targetTeamOrID=None):
	eTeam, team = PlayerUtil.getTeamAndID(teamOrID)
	if targetTeamOrID is None:
		eTargetTeam = PlayerUtil.getActiveTeamID()
	else:
		eTargetTeam = PlayerUtil.getTeamID(targetTeamOrID)
	iPrevious = getPreviousValueByTeam(eTeam, eTargetTeam)
	if iPrevious is not None:
		return team.getEspionagePointsAgainstTeam(eTargetTeam) - iPrevious
	else:
		return 0

def getPreviousValueByTeam(teamOrID, targetTeamOrID=None):
	global g_values, g_iTurn

	# fout = file("Test.txt", "a")
	# fout.write(u"getPreviousValueByTeam: %i, %i\ng_iTurn: %i, %i\nGameTurn: %i\ng_values: %i\n" %(teamOrID, targetTeamOrID, g_iTurn is None, g_iTurn, gc.getGame().getGameTurn(), g_values is None))
	# fout.close()

	if g_iTurn is None:
		load()
		# fout = file("Test.txt", "a")
		# fout.write(u"load!")
		# fout.close()
	if g_iTurn == gc.getGame().getGameTurn() - 1 and g_values:
		eTeam = PlayerUtil.getTeamID(teamOrID)
		if targetTeamOrID is None:
			eTargetTeam = PlayerUtil.getActiveTeamID()
		else:
			eTargetTeam = PlayerUtil.getTeamID(targetTeamOrID)

		# fout = file("Test.txt", "a")
		# fout.write(u"g_values: %i, %i\n" %(eTeam, eTargetTeam))
		# fout.close()

		if eTeam in g_values:
			return g_values[eTeam][eTargetTeam]
	return None

def getCurrentValuesByTeam():
	valuesByTeam = {}
	for eTeam in range(gc.getMAX_TEAMS()):
		valuesByTeam[eTeam] = values = []
		for eTargetTeam in range(gc.getMAX_TEAMS()):
			values.append(gc.getTeam(eTeam).getEspionagePointsAgainstTeam(eTargetTeam))
	return valuesByTeam

def updateCurrentPlayerValuesByTeam(iPlayerActive=None):
	global g_values, g_iTurn

	if(iPlayerActive is None):
		g_values = getCurrentValuesByTeam()
		return

	if(not g_values or g_values is None):
		g_values = {}

	if(iPlayerActive != -1):
		pPlayer = PlayerUtil.getPlayer(iPlayerActive)
		if(not pPlayer is None):
			eTeam = pPlayer.getID()

		if(pPlayer is None or eTeam == -1):
			eTeam = PlayerUtil.getActiveTeamID()

		if(eTeam != -1):
			# fout = file("Test.txt", "a")
			# fout.write(u"updateCurrentPlayerValuesByTeam: Spieler %i\n" % (iPlayerActive))
			# fout.close()
			g_values[eTeam] = values = []
			for eTargetTeam in range(gc.getMAX_TEAMS()):
				values.append(gc.getTeam(eTeam).getEspionagePointsAgainstTeam(eTargetTeam))

## Storing Values for Previous Turn

STORAGE_VERSION = 1

SD_MOD_ID = "SpyUtil"
SD_VERSION_ID = "version"
SD_TURN_ID = "turn"
SD_VALUES_ID = "values"

def clear():
	global g_values, g_iTurn
	g_iTurn = gc.getGame().getGameTurn() - 1
	g_values = None

def load():
	global g_values, g_iTurn
	clear()
	data = BugData.getTable(SD_MOD_ID).data
	BugUtil.debug("SpyUtil - loaded: %s", data)
	if SD_VERSION_ID in data:
		if data[SD_VERSION_ID] == 1:
			g_iTurn = data[SD_TURN_ID]

			# fout = file("Test.txt", "a")
			# fout.write(u"set g_iTurn in load(): Runde %i\n" % (g_iTurn))
			# fout.close()

			if g_iTurn != gc.getGame().getGameTurn() - 1:
				BugUtil.warn("SpyUtil - incorrect previous game turn found, ignoring")
			else:
				g_values = data[SD_VALUES_ID]
		elif data[SD_VERSION_ID] > 1:
			BugUtil.warn("SpyUtil - newer format version detected, ignoring")
	else:
		BugUtil.debug("SpyUtil - no data found")

def store(iTurnOffset=None, iPlayerActive=None):
	global g_values, g_iTurn
	g_iTurn = gc.getGame().getGameTurn()
	if(not iTurnOffset is None):
		g_iTurn = g_iTurn + iTurnOffset

	# fout = file("Test.txt", "a")
	# fout.write(u"set g_iTurn in store(): Runde %i\n" % (g_iTurn))
	# fout.close()

	updateCurrentPlayerValuesByTeam(iPlayerActive)

	data = {
		SD_VERSION_ID: STORAGE_VERSION,
		SD_TURN_ID: g_iTurn,
		SD_VALUES_ID: g_values
	}
	BugData.getTable(SD_MOD_ID).setData(data)
	BugUtil.debug("SpyUtil - stored: %s", data)


## Event Handlers

def onGameStart(argsList):
	clear()

def onGameLoad(argsList):
	load()

def onPythonReloaded(argsList):
	load()

def onBeginGameTurn(argsList):
	global g_values, g_iTurn
	'Called at the beginning of the end of each turn'
	iGameTurn = argsList[0]

	# fout = file("Test.txt", "a")
	# fout.write(u"BeginGameTurn: Runde %i\n" % (iGameTurn))
	# fout.close()

	if (not gc.getGame().isMPOption(MultiplayerOptionTypes.MPOPTION_SIMULTANEOUS_TURNS)):
		store(0, -1)
		return

	if g_iTurn is None or g_iTurn != iGameTurn + 1:
		store(0, None)
	

def onBeginPlayerTurn(argsList):
	iGameTurn, iPlayer = argsList

	# fout = file("Test.txt", "a")
	# fout.write(u"BeginPlayerTurn: Runde %i, Spieler %i, aktiver Spieler %i\n" % (iGameTurn, iPlayer, PlayerUtil.getActivePlayerID()))
	# fout.close()
	
	if (gc.getGame().isMPOption(MultiplayerOptionTypes.MPOPTION_SIMULTANEOUS_TURNS)):
		return

	store(-1, iPlayer)

	# if iPlayer == PlayerUtil.getActivePlayerID():
		# store(-1, iPlayer)
	


