
_G.FunctionsToDoAfterFrame = {}

function OldClickEnabled()
    if s.sys_current_scene == "s01_0505_photopuzzle" or 
    s.sys_current_scene == "s03_0105_table" or 
    s.sys_current_scene == "s02_0306_niche" or 
    s.sys_current_scene == "s03_0119_luggage" or 
    s.sys_current_scene == "s03_0118_pool" or
    s.sys_current_scene == "s03_0113_chest_left" or
    s.sys_current_scene == "s03_0114_chest_right" or 
    s.sys_current_scene == "s03_0118_pool"  or 
    s.sys_current_scene == "s04_0111_sun_fresco" or
    s.sys_current_scene == "s00_0000_menu" or
    s.sys_current_scene == "s02_0313_niche_moss_puzzle" or
    s.sys_current_scene == "s02_0110_valves" or 
    s.sys_current_scene == "s02_0101_necropolisentrance" then 
        return true 
    end
    
    return false
end

local function DoFunctions()
  if #_G.FunctionsToDoAfterFrame == 0 then return end
  
  for _, f in pairs(_G.FunctionsToDoAfterFrame) do
    f()
  end
  _G.FunctionsToDoAfterFrame = {}
end


------  hints -------

s.syst_hint_start_anim_time = Time:GetTime() / 1000000

local hintAnimTotalFrames = 45

local hintAnimTotalTime = 3  -- sec
if Config["hint_loading_time"] ~= "" then
  hintAnimTotalTime = Config["hint_loading_time"]
end

function SetHintAnimOnZero()
     s.syst_hint_start_anim_time = Time:GetTime() / 1000000
     s.sys_hint_started = 1
end

function CanTakeHintClue()
--[[
     hintCtrl = StaticImage(Widget( GetGUIControlName("hint_anim")))
     return hintCtrl:GetCurrentIndex() >= hintAnimTotalFrames
     ]]
     return true
end

function SetHintAnimFrame(frame)
	  if frame < 0 then frame = 0 end
    if frame >  hintAnimTotalFrames then frame =  hintAnimTotalFrames end
    for k, v in ipairs({"Inventory", "ho_counter_list", "ObjectsList"}) do
        local wnd = Widgets[v]
        if wnd then
            wnd = wnd.self
            local hint_anim = StaticImage(wnd:FindChild(GetGUIControlName("hint_anim")))
            local hint_button = wnd:FindChild(GetGUIControlName("hint_button"))

            hint_anim:SetItemIndex(frame)
            
            local hint_anim_visible = not (frame >= hintAnimTotalFrames)
            local hint_button_visible = not hint_anim_visible
            if hint_anim:IsVisible() ~=  hint_anim_visible then
                hint_anim:SetVisible(hint_anim_visible)    
            end
            
            if not hint_anim_visible then
              s.sys_hint_started = 0 
            end
            
            if hint_button:IsVisible() ~=  hint_button_visible then
                hint_button:SetVisible(hint_button_visible)           
            end
        end
    end
end

function OnHintsUpdate()
    if s.sys_hint_started == 0 then return end
    local normalizedAnimTime = ((Time:GetTime()/1000000) - s.syst_hint_start_anim_time) / hintAnimTotalTime
    
    if normalizedAnimTime > 1 then
        normalizedAnimTime = 1
    end

    local currentFrame = normalizedAnimTime * hintAnimTotalFrames
    
    if currentFrame <= hintAnimTotalFrames then
         SetHintAnimFrame(currentFrame)
    end
end

---------------------

function EventLoop()
  DoFunctions()

  local notifyClick = Mouse.LeftClick()
  
  local viewport = MystViewportManager:GetInstance():GetFocusedViewport()
  if viewport == nil then
    return
  end

  local view = viewport:GetView()
  if view == nil then
    return
  end

  local hero = Character:GetMainActor()
  local heroWent = false
  local hasHero = view:HasCharacter(hero)
  ClearEnvironment()
  elemCount = view:GetSelectedNodeCount()
  selectedItem = MystInventory:GetActive():GetSelectedItem()
  
  if elemCount > 0 then
    local node = view:GetSelectedNode(0) 
    
    if Cursors:GetAttachmentName() == node:GetName() then
      if elemCount > 1  then
        node = view:GetSelectedNode(1)
      else
        return 
      end
    end
    
    local pickable2D = node:CastPickable2D()
    local pickable3D = node:CastPickable3D()
    if pickable2D  then 
      if  pickable2D:IsInteractive() then --and pickable2D:GetClassName() ~= "MystHiddenObject"
        notifyClick = false
        local cur = pickable2D:GetCursor()
        if cur ~= "-1" then
          SetCursor(pickable2D)
          CreateCaption(pickable2D)
        end
      end
      
      if Mouse.LeftClick() then
        if hasHero then
          local approach = pickable2D:GetApproachTarget()
          if approach then 
            hero:GoToTarget(approach, true)
            StartGoTrack(hero, pickable2D, selectedItem)
            heroWent = true
          end
        else
          if not OldClickEnabled() then
              if selectedItem == "" then
                pickable2D:OnClick()
              else
                pickable2D:OnItem(selectedItem)
              end
          end
        end
      elseif Mouse.RightClick() then
        pickable2D:OnRightClick()
      elseif Mouse.OldLeftClick() then
          if OldClickEnabled() then
              if selectedItem == "" then
                pickable2D:OnClick()
              else
                pickable2D:OnItem(selectedItem)
              end
          end
      end
      
    elseif pickable3D then
      if pickable3D:IsInteractive() then
        notifyClick = false
        CreateCaption(pickable3D)
        SetCursor(pickable3D)
        
        if Mouse.LeftClick() then
          -- TODO: goto
          heroWent = true
          local actorNode = tolua.cast(pickable3D, "MystActor3D")
          if not actorNode:OnClick() then
            local actor = actorNode:GetActor()
            local dialog = actor:GetDialog()
            if dialog ~= "" then
              Dialog(actor:GetDialog())
            end
          end
          
        end -- mouse click
      end -- is interactive
    end
  end

  if hasHero and not heroWent and Mouse.LeftClick() then
    local a = viewport:TargetToViewport(Mouse.GetPosition())
    local b = Ogre.Vector3()
    viewport:RayCast(a, b)
    hero:GoToPoint(b, true)
    StartGoTrack(hero, nil, selectedItem)
  end
  
  if notifyClick then
    Mouse.NotifyEmptyClick()
  end
  OnHintsUpdate()
end

function StartGoTrack(hero, pickable, itemInHand)
  local gotoTrack = Tracker:CreateTrack("herogo")
  local gotoAction = gotoTrack:AddAction(EMystGoToAction)
  local luaAction = gotoTrack:AddAction(EMystLuaAction)
  
  gotoAction:SetProperty("actor", "hero")
  RegisterLuaCallback(tolua.cast(luaAction, "MystLuaAction"), "Start", 
    function ()
      if pickable then
        if itemInHand ~= "" then
          pickable:OnItem(selectedItem)
        else
          pickable:OnClick()
        end
      end
    end)    
  Tracker:StartTrack(gotoTrack)
end

function ClearEnvironment()
  --if not MainMenu:IsVisible() then
    states["sys_region_under_mouse"] = ""
    Cursors:Default()
  --end
end

function CreateCaption(node)
  caption = node:GetCaption()
  if caption == "" then
    caption = node:GetName()
  end
  states["sys_region_under_mouse"] = caption
end

function SetCursor(node)
  
  if states["hold"] == 1 then
    Cursors:Default()
    return
  end
  
  cursor = node:GetCursor()
  if cursor ~= "" then
    Cursors:SetCursor(cursor)
  else
    Cursors:SetCursor("cur_hand")
  end
end