##StartingPointsUtil
###MODDER READ THIS:
###You do not have to change anything in this file
###all changes have to be done in the CvEventManager.
###This file just has to be in the same folder like the CvEventManager.py.

from CvPythonExtensions import *
import sys
import CvUtil
gc = CyGlobalContext()
SpawnCivList = []
UsedValidCivList = []

###generic file reading function				
def ReadMyFile(MyFile,Debuging,AddPositionsToMap):
		del SpawnCivList[:]
		if Debuging:print "preparing to read"
		for CurString in MyFile.readlines():		
				if "CIVILIZATION_" in CurString:
						CurCiv = SpawningCiv()
						CurCiv.CivString = CutString(CurString)
				elif "StartX" in CurString:
						CurCiv.SpawnX = int(CutString(CurString))
				elif "StartY" in CurString:
						CurCiv.SpawnY = int(CutString(CurString))						 
						SpawnCivList.append(CurCiv)
		if Debuging: print "all civs have been read"
		ResortCivs(Debuging)
		if AddPositionsToMap:AddCoordinateSignsToMap()

###core function for resorting civs on the map
def ResortCivs(Debuging):
	iMaxPlayer = gc.getMAX_CIV_PLAYERS ()
	iMaxLoadedPlayer = len(SpawnCivList)
	iHumanPlayer = -1
	CounterInvalid = 0
###loop detects human player	
	for ip in xrange(iMaxPlayer):
			CurPlayer = gc.getPlayer(ip)
			# rucivfan_ai_auto_play raap[
			#if CurPlayer.isHuman():
			if CurPlayer.isHumanActive():
			# ]rucivfan_ai_auto_play raap
					iHumanPlayer = ip
					break		
	if Debuging:CyInterface().addMessage(iHumanPlayer,False,15,"Beginning to resort civs",'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), 1, 1, True,True)
	if Debuging:print "Beginning to resort civs"
	if not HumanPlayerIsValidCiv(iHumanPlayer,iMaxLoadedPlayer):
			CyInterface().addMessage(iHumanPlayer,False,15,"Invalid Civ for map has been chosen!!!",'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), 1, 1, True,True)
			CyInterface().addMessage(iHumanPlayer,False,15,"Civs will not start at correct positions!!!",'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), 1, 1, True,True)
			return

###following loop moves all the units off the map
###it prevents accidential contacts		
	for iMoveAway in xrange(iMaxPlayer):
		pLoopCiv = gc.getPlayer(iMoveAway)
		(loopUnit, iter) = pLoopCiv.firstUnit(false)
		while(loopUnit):
				unitOwner = loopUnit.getOwner()
				if ( not loopUnit.isNone() and loopUnit.getOwner() == pLoopCiv.getID() ): #only valid units
						# rucivfan_movement_system_extended rmse[
						#loopUnit.setXY(-1,-1, False,False,False)	 
						loopUnit.setPlotXY(gc.getINVALID_PLOT_COORD(),gc.getINVALID_PLOT_COORD(), False,False,False)	 
						# ]rucivfan_movement_system_extended rmse														
				(loopUnit, iter) = pLoopCiv.nextUnit(iter, false)

###this loop replaces the current units/moves them to the right place
###invalid civs are killed, and the number is counted
###IDs of used/invalid civs are stored in a global list, so that
###adding new ones is easier				
	for i in xrange(iMaxPlayer):
		pLoopCiv = gc.getPlayer(i)
		if Debuging:CyInterface().addMessage(iHumanPlayer,False,15,"Got a civ!",'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), 1, 1, True,True)
		if Debuging:print "Got a civ!"
		if not pLoopCiv.isAlive():continue
		iLoopCivName = pLoopCiv.getCivilizationType ()		
		for j in xrange(iMaxLoadedPlayer):
				if Debuging:CyInterface().addMessage(iHumanPlayer,False,15,"Cycling loaded coordinates!",'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), 1, 1, True,True)
				if Debuging:print "Cycling loaded coordinates!"
				if iLoopCivName == gc.getInfoTypeForString(SpawnCivList[j].CivString):
						if Debuging:CyInterface().addMessage(iHumanPlayer,False,15,"Preparing for re-placing current units!",'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), 1, 1, True,True)
						if Debuging:print "Preparing for re-placing current units!"
						if SpawnCivList[j].SpawnX ==-1 or SpawnCivList[j].SpawnY==-1:
								CounterInvalid = CounterInvalid+1
								if Debuging:CyInterface().addMessage(iHumanPlayer,False,15,"Counter invalid civs "+str(CounterInvalid),'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), 1, 1, True,True)
								(loopUnit, iter) = pLoopCiv.firstUnit(false)
								while(loopUnit):
										unitOwner = loopUnit.getOwner()
										if ( not loopUnit.isNone() and loopUnit.getOwner() == pLoopCiv.getID() ): #only valid units  
												# rucivfan_movement_system_extended rmse[
												#loopUnit.setXY(1,1, False,False,False)	
												loopUnit.setPlotXY(1,1, False,False,False)   
												# ]rucivfan_movement_system_extended rmse
										(loopUnit, iter) = pLoopCiv.nextUnit(iter, false)
								pLoopCiv.killUnits()
								UsedValidCivList.append(iLoopCivName) 
								continue
						else:
								UsedValidCivList.append(iLoopCivName)								
						(loopUnit, iter) = pLoopCiv.firstUnit(false)
						while(loopUnit):
								unitOwner = loopUnit.getOwner()
								if ( not loopUnit.isNone() and loopUnit.getOwner() == pLoopCiv.getID() ): #only valid units									   

										# rucivfan_movement_system_extended rmse[
										#loopUnit.setXY(SpawnCivList[j].SpawnX, SpawnCivList[j].SpawnY, False,False,False)
										loopUnit.setPlotXY(SpawnCivList[j].SpawnX, SpawnCivList[j].SpawnY, False,False,False)
										# ]rucivfan_movement_system_extended rmse
										
										if Debuging:
												idstring = pLoopCiv.getCivilizationAdjective(0)+"unit moved to X="+str(SpawnCivList[j].SpawnX)+"and Y="+str(SpawnCivList[j].SpawnY)
												print idstring
												CyInterface().addMessage(iHumanPlayer,False,15,idstring,'',0,'Art/Interface/Buttons/General/warning_popup.dds',ColorTypes(gc.getInfoTypeForString("COLOR_RED")), SpawnCivList[j].SpawnY, SpawnCivList[j].SpawnY, True,True)
								(loopUnit, iter) = pLoopCiv.nextUnit(iter, false)
	AddMissingCivs(CounterInvalid,iMaxLoadedPlayer,iMaxPlayer)
	FlushVisibleArea()


###checks, if the human player has selected a valid civ for the map								
def HumanPlayerIsValidCiv(iHumanPlayer,iMaxLoadedPlayer):
		pHumanPlayer = gc.getPlayer(iHumanPlayer)
		iHumanName = pHumanPlayer.getCivilizationType ()
		for iCivs in xrange(iMaxLoadedPlayer):				
				if iHumanName == gc.getInfoTypeForString(SpawnCivList[iCivs].CivString):
						if SpawnCivList[iCivs].SpawnX ==-1 or SpawnCivList[iCivs].SpawnY==-1:
								return False
						else:
								return True
		else:
			return False

###makes the old starting positions invisible for the teams		
def FlushVisibleArea():
		iMaxX = CyMap().getGridWidth ()
		iMaxY = CyMap().getGridHeight ()
		iMaxTeam = gc.getMAX_CIV_TEAMS ()
		for iX in xrange(iMaxX):
				for iY in xrange(iMaxY):
						pPlot = CyMap().plot(iX,iY)
						for iTeams in xrange(iMaxTeam):
								if not pPlot.isVisible(iTeams,False):
										pPlot.setRevealed(iTeams,False,False,iTeams)

###adds signs with the coordinates to the map
###so that potential starting positions can easier be modified										
def AddCoordinateSignsToMap():
		iMaxX = CyMap().getGridWidth ()
		iMaxY = CyMap().getGridHeight ()
		iMaxPlayer = gc.getMAX_CIV_PLAYERS ()
		iHumanPlayer = -1
		for iCivs in xrange(iMaxPlayer):
				pPlayer = gc.getPlayer(iCivs)
				# rucivfan_ai_auto_play raap[
				#if pPlayer.isHuman():
				if pPlayer.isHumanActive():
				# ]rucivfan_ai_auto_play raap
						iHumanPlayer = iCivs
						break
		for iX in xrange(iMaxX):
				for iY in xrange(iMaxY):
						pPlot = CyMap().plot(iX,iY)
						PrintString = "X = "+str(iX)+" Y = "+str(iY)
						CyEngine().addSign(pPlot,iHumanPlayer,PrintString)

###next 2 functions add new civs for the invalid chosen ones to the map						
def AddMissingCivs(CounterInvalid,iMaxLoadedPlayer,iMaxPlayer):
		iAllCivs = gc.getNumPlayableCivilizationInfos ()
		CounterCycles = 0
		while True:
				CounterCycles = CounterCycles+1
				if CounterCycles >=100:break
				if AddThisCiv(iAllCivs,CounterInvalid,iMaxLoadedPlayer,iMaxPlayer):
						CounterInvalid = CounterInvalid-1
				if CounterInvalid<=0:
						return
				
def AddThisCiv(iAllCivs,CounterInvalid,iMaxLoadedPlayer,iMaxPlayer):
		iCivID = -1
		iMaxUsed = len(UsedValidCivList)
		for i in xrange(iMaxPlayer):
				pLoopCiv = gc.getPlayer(i)
				if pLoopCiv.getNumUnits () ==0:
						iCivID = i						
						break
		else:
				return False
		
		for iCivs in xrange(iAllCivs):
				IsInList = False
				for iUsedCivs in xrange(iMaxUsed):
						if UsedValidCivList[iUsedCivs]==iCivs:
								IsInList=True								
								continue
				if IsInList:
						continue
				if not IsInList:
						for j in xrange(iMaxLoadedPlayer):
								if gc.getInfoTypeForString(SpawnCivList[j].CivString)==iCivs:
										if SpawnCivList[j].SpawnX ==-1 or SpawnCivList[j].SpawnY==-1:
												UsedValidCivList.append(iCivs)
												return False
										else:
												UseIt = gc.getGame().getMapRand().get(10 , "Will i use this civ, o oracle?" )
												if UseIt ==1: return False
												UsedValidCivList.append(iCivs)
												CurCiv = gc.getCivilizationInfo(iCivs)
												NumLeaders = CurCiv.getNumLeaders ()
												dice = gc.getGame().getMapRand()
												LeaderNum = dice.get(NumLeaders , "OracleSayMeTheLeader" )
												LeaderCounter=0
												for iLeaders in range(gc.getNumLeaderHeadInfos ()):
														if CurCiv.isLeaders(iLeaders):
																if NumLeaders==1:
																		NewLeaderID =iLeaders
																		break
																else:
																		if LeaderCounter==LeaderNum:
																				NewLeaderID=iLeaders
																				break
																		LeaderCounter=LeaderCounter+1
												CyGame().addPlayer(iCivID,NewLeaderID,iCivs)
												AddTechsAndUnits(iCivID,j,CurCiv)
												return True

###adds starting techs/techs from difficulty level/starting units/units from difficulty leven
###to the map, because just adding a player will give a civ really completly nothing										
def AddTechsAndUnits(iCivID,j,CurCiv):												
		ThisPlayer = gc.getPlayer(iCivID)
		ThisPlayer.initUnit( gc.getInfoTypeForString("UNIT_SETTLER"), SpawnCivList[j].SpawnX,SpawnCivList[j].SpawnY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
		ThisPlayer.initUnit( gc.getInfoTypeForString("UNIT_WARRIOR"), SpawnCivList[j].SpawnX,SpawnCivList[j].SpawnY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
		ThisTeam = gc.getTeam(ThisPlayer.getTeam())
		DifficultyLevel = gc. getHandicapInfo(CyGame().getHandicapType ())
		iWorkers = DifficultyLevel.getAIStartingWorkerUnits ()
		for iWorkUnits in xrange(iWorkers):														
				iCivWorker = CurCiv.getCivilizationUnits(gc.getInfoTypeForString("UNITCLASS_WORKER"))
				ThisPlayer.initUnit( iCivWorker, SpawnCivList[j].SpawnX,SpawnCivList[j].SpawnY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
		iArchers = DifficultyLevel.getAIStartingDefenseUnits ()
		for iArcher in xrange(iArchers):
				iCivArcher = CurCiv.getCivilizationUnits(gc.getInfoTypeForString("UNITCLASS_ARCHER"))
				ThisPlayer.initUnit( iCivArcher, SpawnCivList[j].SpawnX,SpawnCivList[j].SpawnY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
		iScouts = DifficultyLevel.getAIStartingExploreUnits ()
		for iScout in xrange(iScouts):														
				iCivScout = CurCiv.getCivilizationUnits(gc.getInfoTypeForString("UNITCLASS_SCOUT"))
				ThisPlayer.initUnit(iCivScout , SpawnCivList[j].SpawnX,SpawnCivList[j].SpawnY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
		iSettlers = DifficultyLevel.getAIStartingUnitMultiplier ()
		for iSettler in xrange(iSettlers):														
				iCivSettler = CurCiv.getCivilizationUnits(gc.getInfoTypeForString("UNITCLASS_SETTLER"))
				ThisPlayer.initUnit( iCivSettler, SpawnCivList[j].SpawnX,SpawnCivList[j].SpawnY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )														
														
		iNumTechs = gc.getNumTechInfos ()
		for iTechs in xrange(iNumTechs):
				if DifficultyLevel.isAIFreeTechs(iTechs)>0 or CurCiv.isCivilizationFreeTechs(iTechs):
						ThisTeam.setHasTech(iTechs,True,iCivID,False,False)															  
														
		return				

###generic string cutting function
###first < and > at the end are cut of, then the other
###> and < are searched, and what is between is used as value
def CutString(string):
		print "Cutting"
		string = str(string)		
		string = string.strip()		
		string = string[2:-1]
		BeginPos=-1
		EndPos = -1				
		for i in xrange(len(string)):
				if string[i]==">":
						BeginPos=i								
				elif string[i]=="<":
						EndPos=i								
						break
		else:
				return "-1"
		NewString = string[BeginPos+1:EndPos]		
		return str(NewString)

class SpawningCiv:
		def __init__(self):
				self.CivString = 0
				self.SpawnX = 0
				self.SpawnY = 0



