local CCOS = require("camera.camera_oneshot")
local timers = require("level.timer")
local thisLevel, thisObj, player, bWasInsidePreviously, bAlreadyTriggered, kStates, EntryExitCheck, bInsideZone, camOneShot, bDoSetup, bHideZoneAfterwards, bRetriggerable, kDefaultTimeInSeconds, kActivationDelayInSeconds, bOnlyInCamZone, cameraName, kTriggerOption, zoneName, IsReadyFunction, kEntityBoolName, ConditionCheck, temporaryValue, bUseCineLock
function OnScriptLoaded(level, obj)
  thisLevel = level
  thisObj = obj
  player = game.Player.FindPlayer()
  ExtractMayaTable()
  if ConditionCheck == nil then
    game.SubObject.Sleep(obj)
    thisLevel = nil
    thisObj = nil
    player = nil
    return
  elseif cameraName == "" then
    cameraName = nil
    assert(cameraName, "Fill in the CameraName field.")
  end
  kStates = {
    ExitCheck = CheckForExit,
    EntryCheck = CheckForEntry
  }
  bAlreadyTriggered = false
  bUseCineLock = false
end
function OnStart(level, obj)
  if ConditionCheck == nil then
    return
  end
  if game.World.IsInsideCameraZone(player.WorldPosition, zoneName) == true then
    EntryExitCheck = kStates.ExitCheck
    bWasInsidePreviously = true
  else
    EntryExitCheck = kStates.EntryCheck
    bWasInsidePreviously = false
  end
end
function GetCurrentZoneStatus()
  return game.World.IsInsideCameraZone(player.WorldPosition, zoneName)
end
function CheckForExit()
  if bWasInsidePreviously == true and bInsideZone == false then
    bWasInsidePreviously = false
    EntryExitCheck = kStates.EntryCheck
  end
end
function CheckForEntry()
  if bWasInsidePreviously == false and bInsideZone == true then
    bWasInsidePreviously = true
    EntryExitCheck = kStates.ExitCheck
  end
end
function OnUpdate(level, obj)
  bInsideZone = GetCurrentZoneStatus()
  if bAlreadyTriggered ~= true then
    CheckForReadyCondition()
  end
  EntryExitCheck()
  if camOneShot ~= nil then
    if bOnlyInCamZone == true and bInsideZone ~= true then
      camOneShot:StopCamera()
      camOneShot = nil
      return
    end
    camOneShot:Update()
  end
end
function CheckForReadyCondition()
  if bAlreadyTriggered == false then
    ConditionCheck()
    if bDoSetup == true then
      bAlreadyTriggered = true
      bDoSetup = false
      if 0 < kActivationDelayInSeconds then
        timers.StartLevelTimer(kActivationDelayInSeconds, ActivateCamera)
      else
        ActivateCamera()
      end
    end
  end
end
function ActivateCamera()
  InitializeStartCamera()
  camOneShot:SetCallback(OnFired)
  if bUseCineLock == true then
    camOneShot:ActivateCineLock()
  end
  camOneShot:Start()
  bAlreadyTriggered = true
end
function InitializeStartCamera()
  camOneShot = CCOS.OneShotCamera.New(cameraName, kDefaultTimeInSeconds)
end
function Reset()
  if game.World.IsInsideCameraZone(player.WorldPosition, zoneName) == true then
    EntryExitCheck = kStates.ExitCheck
    bWasInsidePreviously = true
  else
    EntryExitCheck = kStates.EntryCheck
    bWasInsidePreviously = false
  end
  bAlreadyTriggered = false
end
function PrintTrueOrFalse(varAsString, bValue)
  if bValue == false then
    print("[" .. string .. "]: FALSE")
  else
    print("[" .. string .. "]: TRUE")
  end
end
function ExtractMayaTable()
  if thisObj:FindLuaTableAttribute("HideZoneAfterwards") ~= nil then
    bHideZoneAfterwards = thisObj:FindLuaTableAttribute("HideZoneAfterwards")
  end
  if thisObj:FindLuaTableAttribute("Retriggerable") ~= nil then
    bRetriggerable = thisObj:FindLuaTableAttribute("Retriggerable")
  end
  if thisObj:FindLuaTableAttribute("SubmitTimeInSeconds") ~= nil then
    kDefaultTimeInSeconds = thisObj:FindLuaTableAttribute("SubmitTimeInSeconds")
  end
  if thisObj:FindLuaTableAttribute("OnlyWhileInCamZone") ~= nil then
    bOnlyInCamZone = thisObj:FindLuaTableAttribute("OnlyWhileInCamZone")
  end
  if thisObj:FindLuaTableAttribute("ActivationDelay") ~= nil then
    kActivationDelayInSeconds = thisObj:FindLuaTableAttribute("ActivationDelay")
  end
  if thisObj:FindLuaTableAttribute("CameraName") ~= nil then
    cameraName = thisObj:FindLuaTableAttribute("CameraName")
  end
  if thisObj:FindLuaTableAttribute("TriggerOption") ~= nil then
    kTriggerOption = thisObj:FindLuaTableAttribute("TriggerOption")
    SetUpCheckConditionFunction()
  end
  if thisObj:FindLuaTableAttribute("CameraZone") ~= nil then
    zoneName = thisObj:FindLuaTableAttribute("CameraZone")
  end
  if thisObj:FindLuaTableAttribute("EventListener") ~= nil then
    local functionname = thisObj:FindLuaTableAttribute("EventListener")
    SetIsReadyEventListener(functionname)
  end
  if thisObj:FindLuaTableAttribute("EntityBool") ~= nil then
    kEntityBoolName = thisObj:FindLuaTableAttribute("EntityBool")
  end
end
function SetIsReadyEventListener(nameoffunction)
  if nameoffunction ~= "" then
    IsReadyFunction = _G[nameoffunction]
    assert(IsReadyFunction, "SetIsReadyEventListener() couldn't find the function: " .. nameoffunction .. "for [" .. thisObj.Parent:GetName() .. "]")
  end
end
function SetUpCheckConditionFunction()
  if kTriggerOption == "Zone" then
    ConditionCheck = ZoneCheck
  elseif kTriggerOption == "EventListener" then
    ConditionCheck = EventCheck
  elseif kTriggerOption == "ZoneAndEventListener" then
    ConditionCheck = ZoneAndEventCheck
  elseif kTriggerOption == "EntityBool" then
    ConditionCheck = EntityBoolCheck
  elseif kTriggerOption == "ZoneAndEntityBool" then
    ConditionCheck = ZoneAndEntityBoolCheck
  elseif kTriggerOption == "Disabled" then
    ConditionCheck = nil
  else
    ConditionCheck = nil
  end
end
function ZoneCheck()
  if bInsideZone == true then
    bDoSetup = true
  end
end
function EventCheck()
  if IsReadyFunction() == true then
    bDoSetup = true
  end
end
function ZoneAndEventCheck()
  if bInsideZone == true and IsReadyFunction() == true then
    bDoSetup = true
  end
end
function EntityBoolCheck()
  temporaryValue = game.Level.GetVariable(kEntityBoolName)
  if temporaryValue == true then
    bDoSetup = true
  end
end
function ZoneAndEntityBoolCheck()
  if bInsideZone == true then
    local bValue = game.Level.GetVariable(kEntityBoolName)
    if bValue == true then
      bDoSetup = true
    end
  end
end
function OnFired()
  if bRetriggerable == false then
    game.SubObject.Sleep(thisObj)
  end
  if bHideZoneAfterwards == true then
    local camzone = thisLevel:GetGameObject(zoneName)
    camzone:HideCameraVolume()
  end
end
function UseCineLock()
  bUseCineLock = true
end
