local this = class("mapBuilderData")
local _areaTpl = L_GameTpl:getWorldAreaTpl()

function this:ctor(areaId, isMini)
  self.areaId = nil
  self.sceneId = nil
  self.w2LMatrix = nil
  self.l2WMatrix = nil
  self.zRot = 0
  self.imgSize = nil
  self.imgScale = 1
  self.minScale = 1
  self.maxScale = 1
  self.mapDirection = 0
  self.sliderValue = 0
  self.isBigMap = true
  self:parseArea(areaId, isMini)
end

function this:parseArea(areaId, isMini)
  self.areaId = areaId
  local tpl = _areaTpl:getTplById(areaId)
  local zRot, scale, offset
  if tpl then
    offset = _areaTpl:getMapOffset(tpl, true)
    scale = _areaTpl:getSceneToMapScale(tpl)
    if isMini then
      scale = _areaTpl:getSceneToMiniMapScale(tpl)
    end
    zRot = _areaTpl:getMapRotation(tpl)
    self.sceneId = _areaTpl:getSceneId(tpl)
    self.maxScale = _areaTpl:getMapMaxScale(scale) * _areaTpl:getEnterScale(tpl)
    self.minScale = _areaTpl:getDefaultScale(tpl)
    self.mapDirection = _areaTpl:getNorthAngle(tpl)
    self.imgScale = self.minScale
    self.offset = offset
    self.scale = scale
    local imgSize = _areaTpl:getMapSize(tpl, true)
    self:setImgSize(imgSize)
  else
    offset = L_Vector3.new(100, 100, 0)
    scale = 4
    zRot = 0
    self.scale = scale
    self.offset = offset
    self.mapDirection = 0
    self.maxScale = _areaTpl:getMapMaxScale(scale) * _areaTpl:getEnterScale(tpl)
    self:setImgSize(L_Vector3.new(1600, 1600))
  end
  local translationMatrix = L_Matrix4x4.createTranslation(-offset.x, 0, -offset.y)
  local rotationMatrix = L_Matrix4x4.createRotationY(zRot)
  local scaleMatrix = L_Matrix4x4.createScale(scale, 1, scale)
  self.zRot = -zRot
  self.w2LMatrix = scaleMatrix * rotationMatrix * translationMatrix
  self.l2WMatrix = self.w2LMatrix:inverse()
end

function this:getImgSize()
  return self.imgSize * self.imgScale
end

function this:setShowSize(width, height)
  self.showSize = L_Vector3.new(width, height)
end

function this:setImgSize(size)
  self.imgSize = size
  self.halfX = size.x * 0.5
  self.halfY = size.y * 0.5
end

function this:setScale(min, max)
  self.minScale = min
  self.maxScale = max
end

function this:checkResolutionRatio()
  local offsetX = self.halfX * self.imgScale - self.showSize.x
  local offsetY = self.halfY * self.imgScale - self.showSize.y
  if offsetX < 0 and 0 <= offsetY then
    local scale = self.showSize.x / (self.halfX * self.imgScale)
    self.minScale = scale * self.minScale
    self.maxScale = scale * self.maxScale
    self:setSlider(0)
  elseif 0 <= offsetX and offsetY < 0 then
    local scale = self.showSize.y / (self.halfY * self.imgScale)
    self.minScale = scale * self.minScale
    self.maxScale = scale * self.maxScale
    self:setSlider(0)
  end
end

function this:miniMapCheckMinScale()
  local tpl = _areaTpl:getTplById(self.areaId)
  self.isBigMap = false
  self.isStream = true
  if tpl then
    local miniMapInitScale = _areaTpl:getMiniMapInitScale(tpl)
    if not math.isEmpty(miniMapInitScale) then
      self.minScale = miniMapInitScale
      self.imgScale = miniMapInitScale
    end
  end
end

function this:clampImgPos(imgPos)
  local offsetX = self.halfX * self.imgScale - self.showSize.x
  local offsetY = self.halfY * self.imgScale - self.showSize.y
  if offsetX < 0 then
    imgPos.x = 0
  else
    imgPos.x = math.clamp(imgPos.x, -offsetX, offsetX)
  end
  if offsetY < 0 then
    imgPos.y = 0
  else
    imgPos.y = math.clamp(imgPos.y, -offsetY, offsetY)
  end
  return imgPos
end

function this:worldToLocal(v3)
  v3 = self.w2LMatrix:multiplyPoint(v3)
  v3.y = v3.z
  v3.z = 0
  return v3
end

function this:localToWorld(v3)
  v3 = self.l2WMatrix:multiplyPoint(L_Vector3.getTemp(v3.x, 0, v3.y))
  return v3
end

function this:getPercent()
  local bottom = self.maxScale - self.minScale
  local up = self.imgScale - self.minScale
  local percent = up / bottom
  return percent
end

function this:setSlider(value)
  self.sliderValue = value
  self.imgScale = math.lerp(self.minScale, self.maxScale, self.sliderValue)
end

return this
