local this = class("worldMapTpl")

function this:init()
  self.worldDic = {}
end

function this:getWorldMap(worldId)
  local tab = self.worldDic[worldId]
  if tab == nil then
    tab = {
      cfg = L_Config:getConfig("worldmap_" .. worldId) or {},
      block = {},
      always = {},
      inGroupNpc = {},
      groups = {},
      spawnerGroup = {}
    }
    local npcInBlock = {}
    for _, v in pairs(tab.cfg) do
      if v.allBlockShow == 1 then
        tab.always[v.id] = v
      else
        local blockId = self:getBlockId(v)
        local block = tab.block[blockId]
        if block == nil then
          block = {}
          tab.block[blockId] = block
        end
        block[v.id] = v
        npcInBlock[v.id] = blockId
      end
      if tab.spawnerGroup[self:getSpawnerId(v)] == nil then
        tab.spawnerGroup[self:getSpawnerId(v)] = {}
      end
      if self:getInitStatus(v) == 0 then
        table.insert(tab.spawnerGroup[self:getSpawnerId(v)], v)
      end
    end
    local cfgMapGroup = L_GameTpl:getWorldMapGroupTpl()
    local inWorldGroups = cfgMapGroup:getAllGroupByWorldId(worldId)
    for _, v in ipairs(inWorldGroups) do
      local groupTplData = cfgMapGroup:getTplById(v)
      local groupNPC = cfgMapGroup:getObjects(groupTplData)
      local allOffset = cfgMapGroup:getOffsets(groupTplData)
      local center = cfgMapGroup:getPosition(groupTplData)
      local captain = cfgMapGroup:getCaptain(groupTplData)
      local ai = cfgMapGroup:getAI(groupTplData)
      local aiParam = cfgMapGroup:getAIParam(groupTplData)
      for index, nId in ipairs(groupNPC) do
        tab.inGroupNpc[nId] = {groupId = v, childIndex = index}
      end
      tab.groups[v] = {
        Id = v,
        centerPos = center,
        npc = groupNPC,
        npcOffsets = allOffset,
        captain = captain,
        ai = ai,
        aiParam = aiParam
      }
    end
    self.worldDic[worldId] = tab
  end
  return tab
end

function this:getTplById(worldId, id)
  local world = self:getWorldMap(worldId)
  return world.cfg[id]
end

function this:getAllTpl(worldId)
  local world = self:getWorldMap(worldId)
  return world.cfg
end

function this:getAllTplByBlockId(worldId, blockId)
  local world = self:getWorldMap(worldId)
  return world.block[blockId]
end

function this:getAllTplBySpawnerId(worldId, spawnerId)
  local world = self:getWorldMap(worldId)
  return world.spawnerGroup[spawnerId] or {}
end

function this:getAllBlockShowTpl(worldId)
  local world = self:getWorldMap(worldId)
  return world.always
end

function this:getId(tpl)
  return tpl.id
end

function this:getCityId(tpl)
  return tpl.cityId
end

function this:getType(tpl)
  return tpl.type
end

function this:getBlock(tpl)
  return tpl.block
end

function this:getBlockId(tpl)
  local x = math.floor(tpl.position[1] / L_Const.blockSize)
  local z = math.floor(tpl.position[3] / L_Const.blockSize)
  return (z + 500) * 1000 + x + 500
end

function this:getAlways(tpl)
  return tpl.always
end

function this:getPosition(tpl)
  if tpl == nil then
    return L_Vector3.new(0, 0, 0)
  end
  local pos = L_Vector3.new(tpl.position[1], tpl.position[2], tpl.position[3])
  return pos
end

function this:getRotation(tpl)
  return L_Vector3.new(tpl.rotation[1], tpl.rotation[2], tpl.rotation[3])
end

function this:getObjId(tpl)
  return tpl and tpl.objId or 0
end

function this:getExpandId(tpl)
  return tpl.expandId
end

function this:getServerSync(tpl)
  return tpl.serverSync == 1
end

function this:getInitStatus(tpl)
  return tpl.initStatus
end

function this:getCompletexId(tpl)
  return tpl.completexId
end

function this:getLogicType(tpl)
  return tpl.logicType
end

function this:getAllBlockShow(tpl)
  return tpl.allBlockShow == 1
end

function this:getCycle(tpl)
  return tpl.cycle
end

function this:getNpcTransform(tpl)
  return tpl.npcTransform
end

function this:getTriggerId(tpl)
  return tpl.worldTrigger
end

function this:getNpcBev(tpl)
  return tpl.npcBev
end

function this:getStatusReward(tpl)
  return tpl.statusReward
end

function this:getCostResource(tpl)
  return tpl.costResource
end

function this:getClientShowCondition(tpl)
  if not table.isEmpty(tpl.clientShowCondition) then
    return tpl.clientShowCondition
  end
end

function this:getGroupId(tpl)
  local city = tpl.cityId
  local mapData = self:getWorldMap(city)
  local inGroupNPC = mapData.inGroupNpc
  if mapData.groups and inGroupNPC then
    local inGroupData = inGroupNPC[tpl.id]
    if inGroupData then
      return inGroupData.groupId
    end
  end
  return 0
end

function this:getSpawnerId(tpl)
  return tpl and tpl.spawnerId or 0
end

function this:getBubbleTexts(tpl)
  return tpl.bubbleTexts or {}
end

function this:getInteractOptions(tpl)
  return tpl.interactOptions or {}
end

function this:getInteractParams(tpl)
  return tpl.interactParams or {}
end

function this:getAITree(tpl)
  return tpl and tpl.aiTree or 0
end

function this:getInteractOverrideParams(tpl)
  return tpl.interactOverrideParams or {}
end

function this:getFilterMark(tpl)
  return tpl.filterMark
end

function this:keepOnComplete(tpl)
  return tpl.keepOnComplete == 1
end

function this:getRandomEvtId(tpl)
  return tpl.randomEvtId
end

function this:getExpandParams(tpl)
  return tpl.expandParams or {}
end

function this:getScale(tpl)
  if tpl.scale == nil or tpl.scale <= 0.01 then
    return L_Vector3.new(0, 0, 0)
  end
  return L_Vector3.new(tpl.scale, tpl.scale, tpl.scale)
end

function this:isOverrideScale(tpl)
  if tpl.scale == nil or tpl.scale <= 0.01 then
    return false
  end
  return true
end

return this
