local this = class("areaStore", G_BaseStore)
this:importPartialClass(require(L_R.store .. "area.areaState"))
this:importPartialClass(require(L_R.store .. "area.areaAction"))
this.event = {
  areaChanged = "areaChanged",
  mapAreaChanged = "mapAreaChanged"
}
local _areaTpl = L_GameTpl:getWorldAreaTpl()

function this:ctor()
  this.super.ctor(self)
end

function this:switchScene(sceneId)
  if self.data._sceneId == sceneId then
    return
  end
  self.data._sceneId = sceneId
  self:clear()
  self:build(sceneId)
end

function this:refreshArea(point)
  local root = self.data.areaTree:getRoot()
  if root == nil then
    return
  end
  local areaId = self:queryAreaId(point)
  if self.data.curAreaId ~= areaId and areaId ~= nil then
    local souId = self.data.curAreaId
    self.data.curAreaId = areaId
    self:call(self.event.areaChanged, areaId, souId)
  end
  local mapAreaId = self:queryMapAreaId(point)
  if self.data.curMapAreaId ~= mapAreaId and mapAreaId ~= nil then
    local souId = self.data.curMapAreaId
    self.data.curMapAreaId = mapAreaId
    self:call(self.event.mapAreaChanged, mapAreaId, souId)
  end
end

function this:clear()
  self.data.curAreaId = nil
  self.data.curMapAreaId = nil
end

function this:build(sceneId)
  local allArea = _areaTpl:getAllArea(sceneId)
  if table.isEmpty(allArea) then
    return
  end
  local polyList = {}
  for _, tpl in pairs(allArea) do
    local polyhedron = self:buildPolyhedron(tpl)
    table.insert(polyList, polyhedron)
  end
  self.data.areaTree:initialize(polyList)
end

function this:buildPolyhedron(tpl)
  local id = _areaTpl:getId(tpl)
  local pos = _areaTpl:getAreaPos(tpl)
  local vertices = _areaTpl:getVertices(tpl)
  local height = _areaTpl:getHeight(tpl)
  local v3List = {}
  for _, ver in ipairs(vertices) do
    local v3 = L_Vector3.new(ver[1] + pos[1], ver[2], ver[3] + pos[3])
    table.insert(v3List, v3)
  end
  local p1 = L_Vector3.new(pos[1], pos[2], pos[3])
  local p2 = L_Vector3.new(pos[1], pos[2] + height, pos[3])
  local polyhedron = L_Struct:getPolyhedron(id)
  polyhedron:build(v3List, p1, p2)
  return polyhedron
end

local _matchMap = function(v)
  local tpl = _areaTpl:getTplById(v)
  return _areaTpl:getUseMap(tpl)
end

function this:queryMapAreaId(point)
  local polyhedronIds = self.data.areaTree:queryPoint(point)
  for i = #polyhedronIds, 1, -1 do
    if _matchMap(polyhedronIds[i]) then
      return polyhedronIds[i]
    end
  end
end

function this:queryAreaId(point)
  local polyhedronIds = self.data.areaTree:queryPoint(point)
  return 0 < #polyhedronIds and polyhedronIds[#polyhedronIds] or nil
end

function this:getTempAreaTreeId(sceneId, point)
  local allArea = _areaTpl:getAllArea(sceneId)
  if table.isEmpty(allArea) then
    return
  end
  local polyList = {}
  for _, tpl in pairs(allArea) do
    local polyhedron = self:buildPolyhedron(tpl)
    table.insert(polyList, polyhedron)
  end
  self.data.tempAreaTree:initialize(polyList)
  local polyhedronIds = self.data.tempAreaTree:queryPoint(point, _matchMap)
  return 0 < #polyhedronIds and polyhedronIds[#polyhedronIds]
end

return this
