local RaidFrames = _G['RaidFrames']
RaidFrames.Handler = {}

local Handler = RaidFrames.Handler
Handler.unitFrames = {}

function Handler.Initialize()
  -- Hide the default group
  ZO_UnitFramesGroups:SetHidden(true)

  local anchor = RaidFrames.settings.window.anchor
  local font = RaidFrames.settings.window.font

  Handler.MainAnchor = WINDOW_MANAGER:CreateTopLevelWindow('RaidFrames_MainAnchor')
  Handler.MainAnchor:SetAllowBringToTop(false)
	Handler.MainAnchor:SetDimensions(0, 0)
	Handler.MainAnchor:SetHidden(true)
  --Handler.SetMainAnchorPos(20, 20)

  Handler.MainAnchorBG = WINDOW_MANAGER:CreateControl('RaidFrames_MainAnchor_BG', Handler.MainAnchor, CT_BACKDROP)
  Handler.MainAnchorBG:SetAnchor(anchor, Handler.MainAnchor, anchor, 0, 0)
  Handler.MainAnchorBG:SetCenterColor(0.3, 0.3, 0.3, 0.8)
  Handler.MainAnchorBG:SetEdgeColor(1, 1, 1, 0)

  Handler.MainAnchorText = WINDOW_MANAGER:CreateControl('RaidFrames_MainAnchor_Text', Handler.MainAnchor, CT_LABEL)
  Handler.MainAnchorText:SetAnchorFill(Handler.MainAnchorBG)
  Handler.MainAnchorText:SetColor(0.9, 0.9, 0.9, 1)
  Handler.MainAnchorText:SetFont(font)
	Handler.MainAnchorText:SetHorizontalAlignment(TEXT_ALIGN_CENTER)
	Handler.MainAnchorText:SetVerticalAlignment(TEXT_ALIGN_CENTER)

  Handler.MainWindow = WINDOW_MANAGER:CreateTopLevelWindow('RaidFrames_MainWindow')
	Handler.MainWindow:SetDimensions(0, 0)
	Handler.MainWindow:SetHidden(false)
  Handler.MainWindow:SetAnchor(TOPLEFT, Handler.MainAnchor, TOPLEFT, 0, 0)

  Handler.CreateAllUnits(nil)
end

function Handler.CreateAllUnits()
  for index = 1, 24, 1 do
    local unitTag = 'group' .. index
    Handler.unitFrames[index] = Handler.CreateUnit(unitTag, index)
  end

  Handler.UpdateAllUnits()
end

function Handler.CreateUnit(unitTag, index)
  local unitFrame = {}
  unitFrame.unitTag = unitTag

  local settings = RaidFrames.settings.window

  -- Main
  local frameSize = settings.frameSize
  local frameColor = settings.frameColor

  unitFrame.main = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Main' .. unitTag, Handler.MainWindow, CT_CONTROL)
  unitFrame.main:SetDimensions(frameSize[1], frameSize[2])

  unitFrame.bg = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_BG' .. unitTag, unitFrame.main, CT_TEXTURE)
  unitFrame.bg:SetAnchorFill(unitFrame.main)
  unitFrame.bg:SetColor(frameColor[1], frameColor[2], frameColor[3], frameColor[4])
  unitFrame.bg:SetDrawLayer(10)

  -- Health
  local healthSize = settings.healthSize
  local healthOffset = settings.healthOffset
  local healthColor = settings.healthBorderColor -- Temp until borders are added
  local healthBGColor = settings.healthBGColor
  local healthTextColor = settings.healthTextColor

  unitFrame.healthBG = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Health_BG' .. unitTag, unitFrame.main, CT_TEXTURE)
  unitFrame.healthBG:SetAnchor(TOPLEFT, unitFrame.main, TOPLEFT, healthOffset[1], healthOffset[2])
  unitFrame.healthBG:SetDimensions(healthSize[1], healthSize[2])
  unitFrame.healthBG:SetColor(healthBGColor[1], healthBGColor[2], healthBGColor[3], healthBGColor[4])
  unitFrame.healthBG:SetDrawLayer(9)

  unitFrame.health = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Health' .. unitTag, unitFrame.main, CT_STATUSBAR)
  unitFrame.health:SetAnchorFill(unitFrame.healthBG)
  unitFrame.health:SetMinMax(0, 100)
  local curHealth, maxHealth = GetUnitPower(unitTag, POWERTYPE_HEALTH)
  unitFrame.health:SetValue(curHealth / maxHealth * 100)
  unitFrame.health:SetColor(healthColor[1], healthColor[2], healthColor[3], healthColor[4])
  unitFrame.health:SetDrawLayer(8)

  -- Shield
  unitFrame.shield = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Shield' .. unitTag, unitFrame.main, CT_STATUSBAR)
	unitFrame.shield:SetAnchorFill(unitFrame.main)
	unitFrame.shield:SetMinMax(0, 100)
	unitFrame.shield:SetValue(0)
  unitFrame.shield:SetDrawLayer(6)

  -- Magicka
  local magickaSize = settings.magickaSize
  local magickaOffset = settings.magickaOffset
  local magickaColor = settings.magickaColor
  local magickaBGColor = settings.magickaBGColor

  unitFrame.magickaBG = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Magicka_BG' .. unitTag, unitFrame.main, CT_TEXTURE)
  unitFrame.magickaBG:SetAnchor(TOPLEFT, unitFrame.main, TOPLEFT, magickaOffset[1], magickaOffset[2])
  unitFrame.magickaBG:SetDimensions(magickaSize[1], magickaSize[2])
  unitFrame.magickaBG:SetColor(magickaBGColor[1], magickaBGColor[2], magickaBGColor[3], magickaBGColor[4])
  unitFrame.magickaBG:SetDrawLayer(9)

  unitFrame.magicka = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Magicka' .. unitTag, unitFrame.main, CT_STATUSBAR)
  unitFrame.magicka:SetAnchorFill(unitFrame.magickaBG)
  unitFrame.magicka:SetMinMax(0, 100)
  local curMagicka, maxMagicka = GetUnitPower(unitTag, POWERTYPE_MAGICKA)
  unitFrame.magicka:SetValue(curMagicka / maxMagicka * 100)
  unitFrame.magicka:SetColor(magickaColor[1], magickaColor[2], magickaColor[3], magickaColor[4])
  unitFrame.magicka:SetDrawLayer(8)

  -- Stamina
  local staminaSize = settings.staminaSize
  local staminaOffset = settings.staminaOffset
  local staminaColor = settings.staminaColor
  local staminaBGColor = settings.staminaBGColor

  unitFrame.staminaBG = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Stamina_BG' .. unitTag, unitFrame.main, CT_TEXTURE)
  unitFrame.staminaBG:SetAnchor(TOPLEFT, unitFrame.main, TOPLEFT, staminaOffset[1], staminaOffset[2])
  unitFrame.staminaBG:SetDimensions(staminaSize[1], staminaSize[2])
  unitFrame.staminaBG:SetColor(staminaBGColor[1], staminaBGColor[2], staminaBGColor[3], staminaBGColor[4])
  unitFrame.staminaBG:SetDrawLayer(9)

  unitFrame.stamina = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Stamina' .. unitTag, unitFrame.main, CT_STATUSBAR)
  unitFrame.stamina:SetAnchorFill(unitFrame.staminaBG)
  unitFrame.stamina:SetMinMax(0, 100)
  local curStamina, maxStamina = GetUnitPower(unitTag, POWERTYPE_STAMINA)
  unitFrame.stamina:SetValue(curStamina / maxStamina * 100)
  unitFrame.stamina:SetColor(staminaColor[1], staminaColor[2], staminaColor[3], staminaColor[4])
  unitFrame.stamina:SetDrawLayer(8)

  -- Other
  unitFrame.text = {}

  local frameTextColor = settings.frameTextColor
  local frameTextOffset = settings.frameTextOffset

  unitFrame.text['name'] = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Name_Text' .. unitTag, unitFrame.main, CT_LABEL)
  unitFrame.text['name']:SetText(ZO_GetPrimaryPlayerNameFromUnitTag(unitTag) or index)
  unitFrame.text['name']:SetColor(frameTextColor[1], frameTextColor[2], frameTextColor[3], frameTextColor[4])
  unitFrame.text['name']:SetHeight(settings.frameTextSize)
  unitFrame.text['name']:SetWidth(settings.frameTextWidth)
  unitFrame.text['name']:SetFont(settings.font)
	unitFrame.text['name']:SetAnchor(TOPLEFT, unitFrame.main, TOPLEFT, frameTextOffset[1], frameTextOffset[2])
	unitFrame.text['name']:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
	unitFrame.text['name']:SetVerticalAlignment(TEXT_ALIGN_BOTTOM)
  unitFrame.text['name']:SetDrawLayer(2)

	unitFrame.text['health'] = WINDOW_MANAGER:CreateControl('RaidFrames_Unit_Health_Text' .. unitTag, unitFrame.main, CT_LABEL)
	unitFrame.text['health']:SetAnchor(TOPLEFT, unitFrame.main, TOPRIGHT, 3, 0)
	unitFrame.text['health']:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
	unitFrame.text['health']:SetVerticalAlignment(TEXT_ALIGN_BOTTOM)
  unitFrame.text['health']:SetDrawLayer(2)

  local isPlayer = true or IsUnitPlayer(unitTag)
  unitFrame.main:SetHidden(isPlayer == false)

  if ZO_GetPrimaryPlayerNameFromUnitTag(unitTag) then
    d(ZO_GetPrimaryPlayerNameFromUnitTag(unitTag) .. ' is ' .. index)
  end

  Handler.unitFrames[unitTag] = unitFrame

  if isPlayer then Handler.UpdateUnit(unitFrame, index) end

  return unitFrame
end

function Handler.UpdateAllUnits()
  for index, unitFrame in ipairs(Handler.unitFrames) do
    if unitFrame.main:IsHidden() == false then
      Handler.UpdateUnit(unitFrame, index)
      index = index + 1
    end
  end
end

function Handler.UpdateUnit(unitFrame, index)
  local settings = RaidFrames.settings.window
  local frameSize = settings.frameSize
  local frameOffset = settings.frameOffset

  -- Location
  local anchorX = math.ceil(index / settings.maxRows)
  anchorX = frameOffset[1] + ((anchorX - 1) * (frameSize[1] + settings.frameMargin))

  local anchorY = index % (settings.maxRows)
  if anchorY == 0 then anchorY = settings.maxRows end -- Make sure that the last row is measured properly
  anchorY = frameOffset[2] + ((anchorY - 1) * (frameSize[2] + settings.frameMargin))

  unitFrame.main:SetAnchor(TOPLEFT, Handler.MainWindow, TOPLEFT, anchorX, anchorY)

  -- Status
  local nameColor = IsUnitOnline(unitFrame.unitTag) and settings.nameColor or settings.nameColorOffline
  unitFrame.text['name']:SetColor(nameColor[1], nameColor[2], nameColor[3], nameColor[4])
end

function Handler.UpdateHealth(unitFrame, curHealth, maxHealth)
  unitFrame.health:SetValue(curHealth / maxHealth * 100)
end

function Handler.UpdateMagicka(unitFrame, curMagicka, maxMagicka)
  unitFrame.Magicka:SetValue(curMagicka / maxMagicka * 100)
end

function Handler.UpdateStamina(unitFrame, curStamina, maxStamina)
  unitFrame.Stamina:SetValue(curStamina / maxStamina * 100)
end