# AI_AUTO_PLAY_MOD
#
# by jdog5000
# version 2.0

from CvPythonExtensions import *
import CvScreenEnums
import CvTopCivs
import CvUtil
import PyHelpers
import Popup as PyPopup

import ChangePlayer

# rucivfan_profile_help rph[
#import profile_help
# ]rucivfan_profile_help rph

# globals
gc = CyGlobalContext()
PyPlayer = PyHelpers.PyPlayer
PyInfo = PyHelpers.PyInfo
game = CyGame()
localText = CyTranslator()

class AIAutoPlay :

	def __init__(self, customEM ) :

		print "Initializing AIAutoPlay Mod"

		self.LOG_DEBUG = False
		self.blockPopups = True
		self.refortify = True
		self.bSaveAllDeaths = False

		self.DefaultTurnsToAuto = 10
		
		self.customEM = customEM

		self.customEM.addEventHandler( "kbdEvent", self.onKbdEvent )
		self.customEM.addEventHandler( "BeginGameTurn", self.onBeginGameTurn )
		self.customEM.addEventHandler( "EndGameTurn", self.onEndGameTurn )
		self.customEM.addEventHandler( 'BeginPlayerTurn', self.onBeginPlayerTurn )
		self.customEM.addEventHandler( 'EndPlayerTurn', self.onEndPlayerTurn )
		self.customEM.addEventHandler( 'OnLoad', self.onGameLoad )
		self.customEM.addEventHandler( 'GameStart', self.onGameStart )
		self.customEM.addEventHandler( 'victory', self.onVictory )

		# rucivfan_ai_auto_play raap[
		self.iPopUpCount = 0

		self.iNetIDRefortify = 10057
		self.iNetIDrevivePlayer = 10058
		self.customEM.addEventHandler( 'ModNetMessage', self.onModNetMessage )
		self.customEM.addEventHandler( 'gameUpdate', self.onGameUpdate )
		# ]rucivfan_ai_auto_play raap

		self.customEM.setPopupHandler( 7050, ["toAIChooserPopup",self.AIChooserHandler,self.blankHandler] )
		self.customEM.setPopupHandler( 7052, ["pickHumanPopup",self.pickHumanHandler,self.blankHandler] )

		# Keep game from showing messages about handling these popups
		CvUtil.SilentEvents.extend([7050,7052])
		
		# if( self.blockPopups ) :
			# print "Removing some event handlers"
			# #try :
				# #self.customEM.removeEventHandler( "cityBuilt", customEM.onCityBuilt )
				# #self.customEM.addEventHandler( "cityBuilt", self.onCityBuilt )
			# #except ValueError :
			   # #print "Failed to remove 'onCityBuilt', perhaps not registered"
				# #self.customEM.setEventHandler( "cityBuilt", self.onCityBuilt )
			
			# try :
				# self.customEM.removeEventHandler( "BeginGameTurn", customEM.onBeginGameTurn )
				# self.customEM.addEventHandler( "BeginGameTurn", self.onBeginGameTurn )
			# except ValueError :
				# print "Failed to remove 'onBeginGameTurn', perhaps not registered"
				# self.customEM.setEventHandler( "BeginGameTurn", self.onBeginGameTurn )


	def removeEventHandlers( self ) :
		print "Removing event handlers from AIAutoPlay"
		
		self.customEM.removeEventHandler( "kbdEvent", self.onKbdEvent )
		self.customEM.removeEventHandler( "BeginGameTurn", self.onBeginGameTurn )
		self.customEM.removeEventHandler( "EndGameTurn", self.onEndGameTurn )
		self.customEM.removeEventHandler( 'BeginPlayerTurn', self.onBeginPlayerTurn )
		self.customEM.removeEventHandler( 'EndPlayerTurn', self.onEndPlayerTurn )
		self.customEM.removeEventHandler( 'OnLoad', self.onGameLoad )
		self.customEM.removeEventHandler( 'GameStart', self.onGameStart )
		self.customEM.removeEventHandler( 'victory', self.onVictory )

		# rucivfan_ai_auto_play raap[
		self.customEM.removeEventHandler( 'ModNetMessage', self.onModNetMessage )
		self.customEM.removeEventHandler( 'gameUpdate', self.onGameUpdate )
		# ]rucivfan_ai_auto_play raap

		self.customEM.setPopupHandler( 7050, ["toAIChooserPopup", self.blankHandler, self.blankHandler] )
		self.customEM.setPopupHandler( 7052, ["pickHumanPopup", self.blankHandler, self.blankHandler] )
		
		# if( self.blockPopups ) :
			# #self.customEM.removeEventHandler( "cityBuilt", self.onCityBuilt )
			# #self.customEM.addEventHandler( "cityBuilt", self.customEM.onCityBuilt )
			
			# self.customEM.removeEventHandler( "BeginGameTurn", self.onBeginGameTurn )
			# self.customEM.addEventHandler( "BeginGameTurn", self.customEM.onBeginGameTurn )
	
	def blankHandler( self, playerID, netUserData, popupReturn ) :
		# Dummy handler to take the second event for popup
		return


	def onGameStart( self, argsList ) :
		self.onGameLoad([])

	def onGameLoad( self, argsList ) :
		# Init things which require a game object or other game data to exist

		pass

	def onVictory( self, argsList ) :
		# rucivfan_ai_auto_play raap[
		# self.checkPlayer()
		# game.setAIAutoPlay(0)

		self.checkActivePlayer()
		game.setAIAutoPlay(0)
		# ]rucivfan_ai_auto_play raap
		
	   
	def onBeginGameTurn( self, argsList):
		# rucivfan_ai_auto_play raap[
		#if(game.getAIAutoPlay() == 1) :
			# # About to turn off automation
			# pass
			pass
		# ]rucivfan_ai_auto_play raap

	def onEndGameTurn( self, argsList ):
		# rucivfan_ai_auto_play raap[
		#if( game.getAIAutoPlay() == 1 ) :
			# # About to turn off automation
			# pass

		# Sync
		if CyInterface().isOOSVisible():
			self.checkActivePlayer()
			game.setAIAutoPlay(0)
		
		elif game.isMPOption(MultiplayerOptionTypes.MPOPTION_SIMULTANEOUS_TURNS):
			if not game.isPitbossHost():
				pActivePlayer = gc.getActivePlayer()
				if not pActivePlayer.isAlive():
					self.checkActivePlayer()
					if pActivePlayer.isAIAutoPlay():
						game.setPlayerAIAutoPlay(pActivePlayer.getID(), 0)
		# ]rucivfan_ai_auto_play raap
			

	def pickHumanHandler( self, iPlayerID, netUserData, popupReturn ) :
		CvUtil.pyPrint('Handling pick human popup')
		self.dekrementPopUpCount()

		if( popupReturn.getButtonClicked() == 0 ):  # if you pressed cancel
			CyInterface().addImmediateMessage("Kill your remaining units if you'd like to see end game screens","")
			return

		toKillPlayer = gc.getActivePlayer()

		newHumanIdx = popupReturn.getSelectedPullDownValue( 1 )
		newPlayer = gc.getPlayer(newHumanIdx)

		# game.setActivePlayer( newHumanIdx, False )
		# newPlayer.setIsHuman(True)

		# CvUtil.pyPrint("You now control the %s"%(newPlayer.getCivilizationDescription(0)))
		# CyInterface().addImmediateMessage("You now control the %s"%(newPlayer.getCivilizationDescription(0)),"")
		
		ChangePlayer.changeHuman( newHumanIdx, toKillPlayer.getID() )

		if( toKillPlayer.getNumCities() == 0 ) :
			# Kills off the lion in the ice field
			CvUtil.pyPrint("Killing off player %d"%(toKillPlayer.getID()))
			toKillPlayer.killUnits()
			toKillPlayer.setIsHuman(False)
			#success = game.changePlayer( toKillPlayer.getID(), toKillPlayer.getCivilizationType(), toKillPlayer.getLeaderType(), -1, False, False )
			#toKillPlayer.setNewPlayerAlive(False)
			#toKillPlayer.setFoundedFirstCity(True)

	def onBeginPlayerTurn( self, argsList ) :
		iGameTurn, iPlayer = argsList

		# rucivfan_ai_auto_play raap[
		# if( game.getAIAutoPlay() == 1 and iPlayer > game.getActivePlayer() and gc.getActivePlayer().isAlive() ) :
			# # Forces isHuman checks to come through positive for everything after human players turn

			# self.checkPlayer()
			# game.setAIAutoPlay(0)
		
		# elif( self.bSaveAllDeaths ) :
			# if( game.getAIAutoPlay() == 0 and not gc.getActivePlayer().isAlive() and iPlayer > game.getActivePlayer() ) :
				# self.checkPlayer()
				# game.setAIAutoPlay(0)

		if not game.isMPOption(MultiplayerOptionTypes.MPOPTION_SIMULTANEOUS_TURNS):
			if not game.isPitbossHost() and not game.isHotSeat() and not game.isPbem():
				pActivePlayer = gc.getActivePlayer()
				if not pActivePlayer.isAlive() and pActivePlayer.getID() != iPlayer:
					self.checkActivePlayer()
					if pActivePlayer.isAIAutoPlay():
						game.setPlayerAIAutoPlay(pActivePlayer.getID(), 0)
		# ]rucivfan_ai_auto_play raap

	def onEndPlayerTurn( self, argsList ) :
		iGameTurn, iPlayer = argsList

		# rucivfan_ai_auto_play raap[
		# # Can't use isHuman as isHuman has been deactivated by automation
		# if( self.refortify and iPlayer == game.getActivePlayer() and game.getAIAutoPlay() == 1 ) :
			# doRefortify( game.getActivePlayer() )

		 # if( iPlayer == gc.getBARBARIAN_PLAYER() and game.getAIAutoPlay() == 1 ) :
			# # About to turn off automation
			# #self.checkPlayer()
			# pass

		# Can't use isHuman as isHuman has been deactivated by automation
		if( self.refortify and iPlayer == game.getActivePlayer() and game.getPlayerAIAutoPlay(iPlayer) == 1 ) :
			self.doRefortifyByNetMassage(iPlayer)
		# ]rucivfan_ai_auto_play raap

	# rucivfan_ai_auto_play raap[
	def onGameUpdate(self, argsList):
		genericArgs = argsList[0][0]	# tuple of tuple of my args
		turnSlice = genericArgs[0]

		# if turnSlice % 10 != 0:
			# return

		if CyInterface().isOOSVisible():
			self.checkActivePlayer()
			game.setAIAutoPlay(0)
		elif not game.isPitbossHost() and (game.isMPOption(MultiplayerOptionTypes.MPOPTION_SIMULTANEOUS_TURNS) or (not game.isHotSeat() and not game.isPbem())):
			pActivePlayer = gc.getActivePlayer()
			if not pActivePlayer.isAlive():
				self.checkActivePlayer()
				if pActivePlayer.isAIAutoPlay():
					game.setPlayerAIAutoPlay(pActivePlayer.getID(), 0)
	# ]rucivfan_ai_auto_play raap

	# rucivfan_ai_auto_play raap[
	# def checkPlayer(self) :
		# pActivePlayer = gc.getActivePlayer()

		# if( not pActivePlayer.isAlive() ) :
			# popup = PyPopup.PyPopup(7052,contextType = EventContextTypes.EVENTCONTEXT_ALL)
			# popup.setHeaderString( localText.getText("TXT_KEY_AIAUTOPLAY_PICK_CIV", ()) )
			# popup.setBodyString( localText.getText("TXT_KEY_AIAUTOPLAY_CIV_DIED", ()) )
			# popup.addSeparator()

			# popup.createPythonPullDown( localText.getText("TXT_KEY_AIAUTOPLAY_TAKE_CONTROL_CIV", ()), 1 )
			# for i in range(0,gc.getMAX_CIV_PLAYERS()) :
				# pPlayer = gc.getPlayer(i)
				# if(not pPlayer.isNone() and not i == pActivePlayer.getID()):
					# if(pPlayer.isAlive()):
						# if(not pPlayer.isHuman()):
							# popup.addPullDownString(localText.getText("TXT_KEY_AIAUTOPLAY_OF_THE", ())%(pPlayer.getName(), pPlayer.getCivilizationDescription(0)), i, 1)

			# activePlayerIdx = gc.getActivePlayer().getID()
			# popup.popup.setSelectedPulldownID( activePlayerIdx, 1 )

			# popup.addSeparator()

			# popup.addButton( localText.getText("TXT_KEY_AIAUTOPLAY_NONE", ()) )
			# CvUtil.pyPrint('Launching pick human popup')
			# popup.launch()

			# #gc.getActivePlayer().setNewPlayerAlive( True )
			# iSettler = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_SETTLER')
			# gc.getActivePlayer().initUnit( iSettler, 0, 0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH )
			# #gc.getActivePlayer().setFoundedFirstCity( False )
			# gc.getActivePlayer().setIsHuman( True )

		# CvUtil.pyPrint('CDP: Setting autoplay to 0')
		# game.setAIAutoPlay(0)
		
		# if( not pActivePlayer.isHuman() ) :
			# CvUtil.pyPrint('Returning human player to control of %s'%(pActivePlayer.getCivilizationDescription(0)))
			# game.setActivePlayer( pActivePlayer.getID(), False )
			# pActivePlayer.setIsHuman( True )

		# #for idx in range(0,gc.getMAX_CIV_TEAMS()) :
		# #	pActivePlayer.setEspionageSpendingWeightAgainstTeam(idx, pActivePlayer.getEspionageSpendingWeightAgainstTeam(idx)/10)
	
	def isPopUp(self):
		return (self.iPopUpCount > 0)

	def inkrementPopUpCount(self):
		self.iPopUpCount += 1

	def dekrementPopUpCount(self):
		self.iPopUpCount += -1
		if self.iPopUpCount < 0:
			CvUtil.pyPrint('dekrementPopUpCount self.iPopUpCount = %d' % self.iPopUpCount)
			self.iPopUpCount = 0

	def revivePlayerByNetMassage(self, iPlayer):
		CyMessageControl().sendModNetMessage(self.iNetIDrevivePlayer, iPlayer, 0, 0, 0)

	def revivePlayer(self, iPlayer):
		pPlayer = gc.getPlayer(iPlayer)
		if pPlayer == 0:
			return
		if not pPlayer.isAlive():
			iSettler = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_SETTLER')
			pPlayer.initUnit( iSettler, 0, 0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH )

	def checkActivePlayer(self) :
		self.checkPlayer(game.getActivePlayer())

	def checkPlayer(self, iCheckPlayer) :
		if game.isPitbossHost() or game.isHotSeat() or game.isPbem():
			return
		pCheckPlayer = gc.getPlayer(iCheckPlayer)
		if pCheckPlayer == 0:
			return
		if not self.bSaveAllDeaths and pCheckPlayer.isHumanActive():
			return
		if self.isPopUp():
			return

		if not pCheckPlayer.isAlive():
			self.revivePlayerByNetMassage(iCheckPlayer)

			if iCheckPlayer == game.getActivePlayer():
				popup = PyPopup.PyPopup(7052,contextType = EventContextTypes.EVENTCONTEXT_ALL)
				popup.setHeaderString( localText.getText("TXT_KEY_AIAUTOPLAY_PICK_CIV", ()) )
				popup.setBodyString( localText.getText("TXT_KEY_AIAUTOPLAY_CIV_DIED", ()) )
				popup.addSeparator()

				popup.createPythonPullDown( localText.getText("TXT_KEY_AIAUTOPLAY_TAKE_CONTROL_CIV", ()), 1 )
				for iPlayer in range(0,gc.getMAX_CIV_PLAYERS()) :
					pPlayer = gc.getPlayer(iPlayer)
					if(not pPlayer.isNone() and not iPlayer == iCheckPlayer):
						if(pPlayer.isAlive()):
							if(not pPlayer.isHuman()):
								popup.addPullDownString(localText.getText("TXT_KEY_AIAUTOPLAY_OF_THE", ())%(pPlayer.getName(), pPlayer.getCivilizationDescription(0)), iPlayer, 1)
				popup.popup.setSelectedPulldownID(iCheckPlayer, 1)
				popup.addSeparator()
				popup.addButton( localText.getText("TXT_KEY_AIAUTOPLAY_NONE", ()) )
				CvUtil.pyPrint('Launching pick human popup')
				popup.launch()

				self.inkrementPopUpCount()
	# ]rucivfan_ai_auto_play raap

	# rucivfan_profile_help rph[
	#@profile_help.profile_func(output_dir="test",  mode="a", strip_dirs=True, sort_by="time") 
	# ]rucivfan_profile_help rph
	def onKbdEvent( self, argsList ) :
		'keypress handler'
		eventType,key,mx,my,px,py = argsList

		# folgende 2 Zeilen auskommentieren, wenn man AIAutoPlay im MP nutzen will
		if game.isGameMultiPlayer() and not CyGlobalContext().getPlayer(game.getActivePlayer()).getNameKey() == "Cybah" and not CyGlobalContext().getPlayer(game.getActivePlayer()).getNameKey() == "rucivfan":
			return 0

		if ( eventType == 6 ):
			theKey=int(key)

			# rucivfan_ai_auto_play raap[
			# if theKey == int(InputTypes.KB_SPACE) or theKey == int(InputTypes.KB_ESCAPE):
				# if CyGame().getAIAutoPlay():
					# CyGame().setAIAutoPlay(0)
					# return 1
			if theKey == int(InputTypes.KB_SPACE) or (theKey == int(InputTypes.KB_ESCAPE) and not game.isGameMultiPlayer()):
				if game.isPlayerAIAutoPlay(game.getActivePlayer()):
					self.checkActivePlayer()
					game.setPlayerAIAutoPlay(game.getActivePlayer(), 0)
			# ]rucivfan_ai_auto_play raap

			if( theKey == int(InputTypes.KB_X) and self.customEM.bShift and self.customEM.bCtrl ) :
				# Get it?  Shift ... control ... to the AI
				# rucivfan_ai_auto_play raap[
				 # if( game.getAIAutoPlay() > 0 ) :
					# if( self.refortify ) :
						# doRefortify( game.getActivePlayer() )
					# game.setAIAutoPlay( 0 )
					# self.checkPlayer()
				# else :
					# self.toAIChooser()

				if( game.isPlayerAIAutoPlay(game.getActivePlayer())) :
					if( self.refortify ) :
						self.doRefortifyByNetMassage(game.getActivePlayer())
					self.checkActivePlayer()
					game.setPlayerAIAutoPlay(game.getActivePlayer(), 0)
				else :
					self.toAIChooser()
				# ]rucivfan_ai_auto_play raap 
			   

			if( theKey == int(InputTypes.KB_M) and self.customEM.bShift and self.customEM.bCtrl ) :
				# Toggle auto moves
				if( self.LOG_DEBUG ) : CyInterface().addImmediateMessage("Moving your units...","")
				# rucivfan_ai_auto_play raap[
				#game.setAIAutoPlay( 1 )
				game.setPlayerAIAutoPlay(game.getActivePlayer(), 1)
				# ]rucivfan_ai_auto_play raap

			if( theKey == int(InputTypes.KB_O) and self.customEM.bShift and self.customEM.bCtrl ) :
				# rucivfan_ai_auto_play raap[
				# doRefortify(game.getActivePlayer())
				self.doRefortifyByNetMassage(game.getActivePlayer())
				# ]rucivfan_ai_auto_play raap
				
	
	# rucivfan_ai_auto_play raap[
	def onModNetMessage(self, argsList):
		'Called whenever CyMessageControl().sendModNetMessage() is called - this is all for you modders!'
		
		iData1, iData2, iData3, iData4, iData5 = argsList
		
		print("Modder's net message!")
		CvUtil.pyPrint('onModNetMessage')
	
		if(iData1 == self.iNetIDRefortify):
			self.doRefortify(iData2)
		elif(iData1 == self.iNetIDrevivePlayer):
			self.revivePlayer(iData2)
	# ]rucivfan_ai_auto_play raap

	def toAIChooser( self ) :
		'Chooser window for when user switches to AI auto play'

		# rucivfan_ai_auto_play raap[
		if self.isPopUp():
			return
		# ]rucivfan_ai_auto_play raap		

		screen = CyGInterfaceScreen( "MainInterface", CvScreenEnums.MAIN_INTERFACE )
		xResolution = screen.getXResolution()
		yResolution = screen.getYResolution()
		popupSizeX = 400
		popupSizeY = 250

		popup = PyPopup.PyPopup(7050, contextType = EventContextTypes.EVENTCONTEXT_ALL)
		popup.setPosition((xResolution - popupSizeX )/2, (yResolution-popupSizeY)/2-50)
		popup.setSize(popupSizeX,popupSizeY)
		popup.setHeaderString( localText.getText("TXT_KEY_AIAUTOPLAY_TURN_ON", ()) )
		popup.setBodyString( localText.getText("TXT_KEY_AIAUTOPLAY_TURNS", ()) )
		popup.addSeparator()
		popup.createPythonEditBox( '%d'%(self.DefaultTurnsToAuto), 'Number of turns to turn over to AI', 0)
		popup.setEditBoxMaxCharCount( 6, 2, 0 )

		popup.addSeparator()
		popup.addButton("OK")
		popup.addButton(localText.getText("TXT_KEY_AIAUTOPLAY_CANCEL", ()))

		popup.launch(False, PopupStates.POPUPSTATE_IMMEDIATE)

		# rucivfan_ai_auto_play raap[
		self.inkrementPopUpCount()
		# ]rucivfan_ai_auto_play raap		

	def AIChooserHandler( self, playerID, netUserData, popupReturn ) :
		'Handles AIChooser popup'
		self.dekrementPopUpCount()

		if( popupReturn.getButtonClicked() == 1 ):  # if you pressed cancel
			# rucivfan_ai_auto_play raap[
			self.checkActivePlayer()
			# ]rucivfan_ai_auto_play raap
			return

		numTurns = 0
		if( popupReturn.getEditBoxString(0) != '' ) :
			numTurns = int( popupReturn.getEditBoxString(0) )

		if( numTurns > 0 ) :
			if( self.LOG_DEBUG ) : CyInterface().addImmediateMessage("Fully automating for %d turns"%(numTurns),"")

			# rucivfan_ai_auto_play raap[
			#game.setAIAutoPlay(numTurns)
			game.setPlayerAIAutoPlay(playerID, numTurns)
			# ]rucivfan_ai_auto_play raap
			

	########################## Utility functions ###########################################
	   
	# rucivfan_ai_auto_play raap[
	def doRefortifyByNetMassage(self, iPlayer):
		CyMessageControl().sendModNetMessage(self.iNetIDRefortify, iPlayer, 0, 0, 0)
	# ]rucivfan_ai_auto_play raap
			
	def doRefortify(self, iPlayer) :
		 #pyPlayer = PyPlayer( iPlayer )
		pPlayer = gc.getPlayer(iPlayer)
		
		CvUtil.pyPrint( "Refortifying units for player %d"%(iPlayer))

		for groupID in range(0, pPlayer.getNumSelectionGroups()) :
			pGroup = pPlayer.getSelectionGroup(groupID)
			if( pGroup.getNumUnits() > 0 ) :
				headUnit = pGroup.getHeadUnit()
				#CvUtil.pyPrint( "%s fortTurns %d"%(headUnit.getName(),headUnit.getFortifyTurns()) )
				if( headUnit.getFortifyTurns() > 0 and headUnit.getDomainType() == DomainTypes.DOMAIN_LAND ) :
					if( headUnit.isHurt() ) :
						#CvUtil.pyPrint( "%s is hurt"%(headUnit.getName()) )
						#pGroup.setActivityType(ActivityTypes.ACTIVITY_HEAL)
						pass
					else :
						#CvUtil.pyPrint( "Starting mission ..." )
						#pGroup.pushMission( MissionTypes.MISSION_FORTIFY, 0, 0, 0, False, True, MissionAITypes.MISSIONAI_GUARD_CITY, pGroup.plot(), pGroup.getHeadUnit() )
						pGroup.setActivityType(ActivityTypes.ACTIVITY_SLEEP)
						headUnit.NotifyEntity( MissionTypes.MISSION_FORTIFY )
						pass

