
require("Actors/AI/HumanBehaviors")		--dofile("Base.rte/Actors/AI/HumanBehaviors.lua")
require("Actors/AI/CrabBehaviors")		--dofile("Base.rte/Actors/AI/CrabBehaviors.lua")
require("Actors/AI/TurretBehaviors")	--dofile("Base.rte/Actors/AI/TurretBehaviors.lua")

NativeTurretAI = {}

function NativeTurretAI:Create(Owner)
	local Members = {}
	
	Members.Ctrl = Owner:GetController()
	Members.lateralMoveState = Actor.LAT_STILL
	Members.deviceState = ACrab.STILL
	Members.lastAIMode = Actor.AIMODE_NONE
	Members.SentryFacing = Owner.HFlipped
	Members.fire = false
	
	Members.ReloadTimer = Timer()
	Members.TargetLostTimer = Timer()
	
	Members.PlayerInterferedTimer = Timer()
	Members.PlayerInterferedTimer:SetSimTimeLimitMS(500)
	
	Members.AlarmTimer = Timer()
	Members.AlarmTimer:SetSimTimeLimitMS(500)
	
	-- check if this team is controlled by a human
	local Activ = ActivityMan:GetActivity()
	for player = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
		if Activ:PlayerActive(player) and Activ:PlayerHuman(player) then
			if Owner.Team == Activ:GetTeamOfPlayer(player) then
				Members.isPlayerOwned = true
				break
			end
		end
	end
	
	setmetatable(Members, self)
	self.__index = self
	return Members
end

function NativeTurretAI:Update(Owner)
	if self.PlayerInterferedTimer:IsPastSimTimeLimit() then
		self.Behavior = nil	-- remove the current behavior
		if self.BehaviorCleanup then
			self.BehaviorCleanup(self)	-- clean up after the current behavior
			self.BehaviorCleanup = nil
		end
		
		self.Target = nil
		self.fire = false
		self.lastAIMode = Actor.AIMODE_NONE
	end
	
	self.PlayerInterferedTimer:Reset()
	
	if self.Target and not MovableMan:IsActor(self.Target) then
		self.Target = nil
	end
	
	if self.UnseenTarget and not MovableMan:IsActor(self.UnseenTarget) then
		self.UnseenTarget = nil
	end
	
	-- switch to the next behavior, if avaliable
	if self.NextBehavior then
		if self.BehaviorCleanup then
			self.BehaviorCleanup(self)
		end
		
		self.Behavior = self.NextBehavior
		self.BehaviorCleanup = self.NextCleanup
		self.BehaviorName = self.NextBehaviorName
		self.NextBehavior = nil
	end
	
	-- check if the AI mode has changed or if we need a new behavior
	if Owner.AIMode ~= self.lastAIMode or not self.Behavior then
		self.Behavior = nil
		if self.BehaviorCleanup then
			self.BehaviorCleanup(self)	-- stop the current behavior
			self.BehaviorCleanup = nil
		end
		
		-- select a new behavior based on AI mode
		if Owner.AIMode == Actor.AIMODE_PATROL then
			self:CreatePatrolBehavior(Owner)
		else
			if Owner.AIMode ~= self.lastAIMode and Owner.AIMode == Actor.AIMODE_SENTRY then
				self.SentryFacing = Owner.HFlipped	-- store the direction in which we should be looking
			end
			
			self:CreateSentryBehavior(Owner)
		end
		
		self.lastAIMode = Owner.AIMode
	end
	
	-- cast a ray to find targets
	CrabBehaviors.LookForTargets(self, Owner)
	
	-- run the selected behavior and delete it if it returns true
	if self.Behavior then
		local msg, done = coroutine.resume(self.Behavior, self, Owner)
		if not msg then
			ConsoleMan:PrintString(Owner.PresetName .. " behavior " .. self.BehaviorName .. " error:\n" .. done)	-- print the error message
			done = true
		end
		
		if done then
			self.Behavior = nil
			if self.BehaviorCleanup then
				self.BehaviorCleanup(self)
				self.BehaviorCleanup = nil
			end
		end
	end
	
	-- listen and react to relevant AlarmEvents
	if not self.Target and not self.UnseenTarget then
		if self.AlarmTimer:IsPastSimTimeLimit() and HumanBehaviors.ProcessAlarmEvent(self, Owner) then
			self.AlarmTimer:Reset()
		end
	end
	
	-- controller states
	if self.fire then
		self.Ctrl:SetState(Controller.WEAPON_FIRE, true)
	end
	
	if self.deviceState == ACrab.AIMING then
		self.Ctrl:SetState(Controller.AIM_SHARP, true)
	end
end



function NativeTurretAI:CreatePatrolBehavior(Owner)
	self.NextBehavior = coroutine.create(TurretBehaviors.Patrol)
	self.NextCleanup = nil
	self.NextBehaviorName = "Patrol"
end

function NativeTurretAI:CreateSentryBehavior(Owner)
	if not Owner.FirearmIsReady and not Owner.ThrowableIsReady then
		return
	end
	
	self.NextBehavior = coroutine.create(CrabBehaviors.Sentry)
	self.NextCleanup = nil
	self.NextBehaviorName = "Sentry"
end

function NativeTurretAI:CreateAttackBehavior(Owner)
	if Owner.FirearmIsReady then
		self.NextBehavior = coroutine.create(CrabBehaviors.ShootTarget)
		self.NextBehaviorName = "ShootTarget"
	else
		if Owner.FirearmIsEmpty then
			Owner:ReloadFirearm()
		end
		
		return
	end
	
	self.NextCleanup = function(AI)
		AI.fire = false
		AI.Target = nil
		AI.deviceState = ACrab.STILL
	end
end

function NativeTurretAI:CreateSuppressBehavior(Owner)
	if Owner.FirearmIsReady then
		self.NextBehavior = coroutine.create(CrabBehaviors.ShootArea)
		self.NextBehaviorName = "ShootArea"
	else
		if Owner.FirearmIsEmpty then
			self:ReloadFirearm()
		end
		
		return
	end
	
	self.NextCleanup = function(AI)
		AI.fire = false
		AI.UnseenTarget = nil
		AI.deviceState = ACrab.STILL
	end
end

function NativeTurretAI:CreateFaceAlarmBehavior(Owner)
	self.NextBehavior = coroutine.create(HumanBehaviors.FaceAlarm)
	self.NextBehaviorName = "FaceAlarm"
	self.NextCleanup = nil
end
