local this = class("uiListener")
local CONFIG_PAGE = require("ui.config").pages

function this:initialize()
  L_UI:addListener(L_UI.pageEvent.preOpen, self.onEvent_preOpenPage, self)
  L_UI:addListener(L_UI.pageEvent.opened, self.onEvent_openedPage, self)
  L_UI:addListener(L_UI.pageEvent.showed, self.onEvent_showPage, self)
  L_UI:addListener(L_UI.pageEvent.hided, self.onEvent_hidePage, self)
  L_UI:addListener(L_UI.pageEvent.reqClose, self.onEvent_reqClosePage, self)
  L_UI:addListener(L_UI.pageEvent.closed, self.onEvent_closedPage, self)
  self.lockCameraDic = {}
  self.lockTimeDic = {}
  self.lockInputMap = {}
  self.lockHide = {}
end

function this:initGameplayEvents()
  L_CameraManager:addListener(L_CameraManager.event.blendStart, self.onEvent_blendStart, self)
  L_CameraManager:addListener(L_CameraManager.event.blendEnd, self.onEvent_blendEnd, self)
  L_GuideManager:addListener(G_GuideClasses.GuideEvent.GuideControlMouse, self.onEvent_guideControlMouse, self)
end

function this:onEvent_preOpenPage(pageName)
  local list = C_VarList:Get()
  list:AddString(pageName)
  if G_Launcher.gameplayRequired then
    C_WorldEvent.instance:Dispatch(C_EWorldEvent.OnPrePageOpen, list)
  end
  self:controlState_preOpen(pageName)
end

function this:onEvent_openedPage(pageName)
end

function this:onEvent_showPage(pageName)
  self:controlState_show(pageName)
end

function this:onEvent_hidePage(pageName)
  self:controlState_hide(pageName)
end

function this:onEvent_reqClosePage(pageName)
  printf("REQ CLOSE ", pageName)
  if pageName then
    self:controlState_hide(pageName)
  end
end

function this:onEvent_closedPage(pageName)
  if AzurWorldInstance.inGame == false then
    return
  end
  if AzurWorld.actWaitMgr ~= nil then
    local list = C_VarList:Get()
    list:AddString(pageName)
    AzurWorld.actWaitMgr:Dispatch(C_EActWait.OnRewardOver, list)
  end
end

function this:onEvent_blendStart()
  L_UI:setGlobleMask("camera", true)
end

function this:onEvent_blendEnd()
  L_UI:setGlobleMask("camera", false)
end

function this:dispose()
end

local UI_INPUTMAPLOCK = {
  loading = true,
  pageMask = true,
  pageNetCommonTip = true
}

function this:controlState_preOpen(pageName)
  self:changeControlState(pageName, true)
end

function this:controlState_show(pageName)
  self:changeControlState(pageName, true)
end

function this:controlState_hide(pageName)
  self:changeControlState(pageName, false)
  L_ShortCutManager:removeShortCut(pageName)
end

function this:changeControlState(pageName, state)
  local cfg = CONFIG_PAGE[pageName]
  if not cfg.controlMove then
    self:controlCameraLock(pageName, state)
  end
  if not cfg.controlTime then
    self:controlTimeLock(pageName, state)
  end
  if cfg.controlHide then
    self:controlHide(pageName, state)
  end
  if UI_INPUTMAPLOCK[pageName] then
    self:controlInputMapLock(pageName, state)
  elseif cfg.uiType == L_UI.groupKeys.stack then
    self:refreshInputMap()
  end
end

function this:controlCameraLock(key, isLock)
  if isLock == false then
    isLock = nil
  end
  if self.lockCameraDic[key] ~= isLock then
    self.lockCameraDic[key] = isLock
    if isLock then
      C_InputManager.SetCameraFollowMouse(false)
    elseif not next(self.lockCameraDic) then
      C_InputManager.SetCameraFollowMouse(true)
    end
  end
end

function this:controlTimeLock(key, isLock)
  if isLock == false then
    isLock = nil
  end
  if self.lockTimeDic[key] ~= isLock then
    self.lockTimeDic[key] = isLock
    if not G_Launcher.gameplayRequired then
      return
    end
    if isLock then
      if L_WorldManager ~= nil then
        L_WorldManager:translateUpdate(false)
      end
    elseif L_WorldManager ~= nil and not next(self.lockTimeDic) then
      L_WorldManager:translateUpdate(true)
    end
  end
end

function this:controlHide(key, isHide)
  if isHide == false then
    isHide = nil
  end
  if self.lockHide[key] ~= isHide then
    self.lockHide[key] = isHide
    if isHide then
      L_PlayerManager:showOrHideAllPlayer(false)
      L_EntityManager:showOrHideRoot(L_Const.WorldNode.PLAYERPETNODE, false)
      AzurWorldInstance:SetNodeVisible(L_Const.WorldNode.ENEMY, false, L_Const.worldNodeHideType.LuaUIControlHide)
    elseif not next(self.lockHide) then
      L_PlayerManager:showOrHideAllPlayer(true)
      L_EntityManager:showOrHideRoot(L_Const.WorldNode.PLAYERPETNODE, true)
      AzurWorldInstance:SetNodeVisible(L_Const.WorldNode.ENEMY, true, L_Const.worldNodeHideType.LuaUIControlHide)
    end
  end
end

function this:controlInputMapLock(key, isLock)
  if isLock == false then
    isLock = nil
  end
  if self.lockInputMap[key] ~= isLock then
    self.lockInputMap[key] = isLock
    if isLock then
      C_InputManager.ForbidInput(true, C_InputManager_LockReason.LuaPageForbid)
    else
      C_InputManager.ForbidInput(false, C_InputManager_LockReason.LuaPageForbid)
      self:refreshInputMap()
    end
  end
end

function this:refreshInputMap()
  if next(self.lockInputMap) then
    return
  end
  if not G_Launcher.gameplayRequired then
    return
  end
  local mapType = C_InputManager_MapType.DefaultUIInputMap
  local enableUI = true
  local curPage = L_UI:currentPage(L_UI.groupKeys.stack)
  local cfg = L_ShortCutConst.inputMap[curPage]
  if cfg then
    mapType = cfg[1]
    enableUI = cfg[2]
  end
  local top = C_UIMgr.GetTopPage(0)
  if top and top.overrideInputMap and top.overrideInputMap ~= C_InputManager_MapType.BlanketInputMap then
    mapType = top.overrideInputMap
  end
  if mapType ~= -1 then
    self:setInputMap(mapType, enableUI)
  end
end

function this:setInputMap(mapType, enableUI)
  self.curMapType = mapType
  self.enableUI = enableUI
  C_InputManager.SetInputmap(mapType, enableUI)
end

function this:tmpPauseInput(isPause)
  if isPause then
    C_InputManager.SetInputmap(C_InputManager_MapType.BlanketInputMap, false)
  else
    if tonumber(self.curMapType) then
      printf("self.curMapType" .. tonumber(self.curMapType))
    else
      printf("set self.curMapType")
    end
    C_InputManager.SetInputmap(self.curMapType, self.enableUI)
  end
end

function this:onEvent_guideControlMouse(data)
  if not data then
    return
  end
  local key = data.key
  key = key or G_GuideClasses.GuideEvent.GuideControlMouse
  local showStr = data.isShow and "true" or "false"
  printf("guideControlMouse", "key: " .. key .. " isShow: " .. showStr)
  self:controlCameraLock(key, data.isShow)
end

return this
