local classlib = require("core.class")
local tablex = require("core.tablex")
local consts = require("ui.consts")
local fsm = require("ui.fsm")
local mapConsts = require("ui.mapConsts")
local mapUtil = require("ui.mapUtil")
local util = require("ui.util")
local colors = require("ui.colors")
local lamsIDs = require("ui.lamsConsts")
local UI = game.UI
local DiscoverMessage = classlib.Class("DiscoverMessage", fsm.UIState)
local DiscoverTextOff = DiscoverMessage:StateClass("DiscoverTextOff", fsm.UIState)
local DiscoverTextOn = DiscoverMessage:StateClass("DiscoverTextOn", fsm.UIState)
local discoverMessage = DiscoverMessage.New("discoverMessage", {DiscoverTextOff, DiscoverTextOn})
function DiscoverMessage:Enter()
  self.text = ""
  self.delay = ""
  self:Goto("DiscoverTextOff")
end
function DiscoverMessage:Restart()
  self.text = ""
  self.delay = ""
  self:Goto("DiscoverTextOff")
end
function DiscoverTextOff:Enter()
  util.Hide("DiscoverText", "DiscoverTextFlourish", "RunicTextFade", "FirstTimeDiscover")
  self.DM = self:GetState("discoverMessage")
  self.DM.text = ""
  self.DM.delay = ""
  self.DM.isDiscovered = false
  self.shared.discoverMessageText = ""
  self.shared.discoverMessageRunes = ""
  self.shared.discoverMessageFlourish = ""
  self.shared.discoverMessageRunesFade = ""
  self.shared.discoverHeaderText = ""
end
function DiscoverTextOff:SetTextColor(regionLevel)
  local player = game.Player.FindPlayer()
  local playerLevel = player:AttributeGetValue("PowerLevel")
  local color = colors.ANNOUNCE_NORMAL
  if regionLevel == nil or regionLevel == 0 then
    color = colors.ANNOUNCE_NORMAL
  else
    local levelDifference = regionLevel - playerLevel
    if levelDifference <= -2 then
      color = colors.DIFFICULTY_TWO_LESS
    elseif -2 < levelDifference and levelDifference <= -1 then
      color = colors.DIFFICULTY_ONE_LESS
    elseif -1 < levelDifference and levelDifference < 1 then
      color = colors.DIFFICULTY_EQUAL
    elseif 1 <= levelDifference and levelDifference < 2 then
      color = colors.DIFFICULTY_ONE_HIGHER
    else
      color = colors.DIFFICULTY_HARD
    end
  end
  util.SetColor("DiscoverText", color, "xlarge_text", "LayerX", "cst_EmissiveTint")
  util.SetColor("DiscoverTextFlourish", color, "discover_text_flourish", "Layer1", "cst_EmissiveTint")
  util.SetColor("DiscoverTextFlourish", color, "discover_text_flourish", "Layer0", "cst_EmissiveTint")
end
function DiscoverTextOff:EVT_DISCOVER_LOCATION(regionID, delay)
  local regionInfo = mapUtil.GetRegionInfo(regionID)
  local regionDisplayName = mapUtil.RegionInfo_GetNameLamsID(regionInfo)
  local isDiscovered = mapUtil.RegionInfo_IsDiscovered(regionInfo)
  local isExploration = mapUtil.Region_HasFlags(regionID, {
    mapConsts.REGION_FLAG_EXPLORATION
  })
  local showJournalTicker = mapUtil.Region_HasFlags(regionID, {
    mapConsts.REGION_FLAG_SHOW_TICKER
  })
  local regionLevel = mapUtil.RegionInfo_GetPowerLevel(regionInfo)
  self.DM.isDiscovered = isDiscovered
  if not isDiscovered then
    mapUtil.Region_SetState(regionID, tweaks.eTokenState.kDiscovered)
    if showJournalTicker then
      self:SendEventToUIFsm("textLog", "EVT_SEND_MSG_TO_JOURNAL_LOG", {
        Header = "Map_Updated",
        Body = "New_Area_Revealed",
        Icon = "MapArea"
      })
    end
    if isExploration then
      self.shared.discoverHeaderText = util.GetLAMSMsg(lamsIDs.HiddenAreaDiscovered)
    else
      self.shared.discoverHeaderText = util.GetLAMSMsg(lamsIDs.AreaDiscovered)
    end
    util.Show("FirstTimeDiscover")
  end
  self.DM.text = string.gsub(UI.GetLAMSMsg(regionDisplayName), " +$", "")
  self.DM.delay = delay
  if self.DM.text ~= nil then
    self:Goto("DiscoverTextOn")
  else
    self.DM.text = ""
    self.DM.delay = ""
  end
end
function DiscoverTextOn:Setup()
  self.spaces_style_open = "<HUDHeader2_Spaces>"
  self.spaces_style_close = "</HUDHeader2_Spaces>"
end
function DiscoverTextOn:Enter()
  self.DM = self:GetState("discoverMessage")
  game.Audio.PlaySound("SND_UX_Area_Discover")
  self:UpdateText()
end
function DiscoverTextOn:UpdateText()
  util.Show("DiscoverText", "DiscoverTextFlourish", "RunicTextFade")
  if self.DM.isDiscovered then
    self:ShowAlreadyDiscovered()
  else
    self:StartTranslation()
  end
end
function DiscoverTextOn:ShowAlreadyDiscovered()
  self.shared.discoverMessageText = self.DM.text
  UI.AlphaFade("DiscoverText", 0, 0)
  UI.Anim("DiscoverText", consts.AS_Forward, "", 6)
  UI.AlphaFade("DiscoverText", 1, 0.25)
  self:StartTimer("HoldTranslation", 2.5, function()
    self:AnimateOffText()
  end)
end
function DiscoverTextOn:SetDMTimer()
  self:StartTimer("DiscoverTimer", 8, function()
    self:AfterDMTimer()
  end)
end
function DiscoverTextOn:AfterDMTimer()
  self:Goto("DiscoverTextOff")
end
function DiscoverTextOn:StartTranslation()
  self.rune = consts.RUNIC_UNICODE
  self.preppedTransText = ""
  self.textLength = util.StringLengthUTF8(self.DM.text)
  self.DM.text_table = self:ConvertTextToTable(self.DM.text)
  self.DM.rune_table = self:SetRandomRunes()
  util.Show("RunicText")
  UI.Anim("RunicText", consts.AS_ForwardCycle, "", 0.2)
  self.shared.discoverMessageRunes = self:TableConcatSubstring(self.DM.rune_table, 1)
  UI.AlphaFade("DiscoverText", 0, 0)
  UI.Anim("DiscoverText", consts.AS_Forward, "", 4)
  UI.AlphaFade("DiscoverText", 1, 0.25)
  self:StartTimer("TranslateTimer", 1, function()
    self:NextTranslationStep(1)
  end)
end
function DiscoverTextOn:ConvertTextToTable(text)
  local t = {}
  for i = 1, util.StringLengthUTF8(text) do
    t[i] = util.SubUTF8(text, i, 1)
  end
  return t
end
function DiscoverTextOn:SetRandomRunes()
  local t = {
    n = self.textLength
  }
  for i = 1, self.textLength do
    if util.SubUTF8(self.DM.text, i, 1) ~= " " then
      local ran = 0
      ran = math.random(#self.rune)
      t[i] = self.rune[ran]
    else
      t[i] = " "
    end
  end
  return t
end
function DiscoverTextOn:TableConcatSubstring(stringTable, start, numChar)
  local temp = ""
  local finalIdx = #stringTable
  if numChar ~= nil then
    finalIdx = start + numChar - 1
  end
  for i = start, finalIdx do
    temp = temp .. stringTable[i]
  end
  return temp
end
function DiscoverTextOn:SetRuneText(counter)
  local temp = self.spaces_style_open .. self:TableConcatSubstring(self.DM.rune_table, 1, counter) .. self.spaces_style_close
  if counter < self.textLength then
    temp = temp .. self:TableConcatSubstring(self.DM.rune_table, counter + 1)
  end
  self.shared.discoverMessageRunes = temp
end
function DiscoverTextOn:SetIndividualChar(counter)
  local rune = self.DM.rune_table[counter]
  local transChar = self.DM.text_table[counter]
  local before = self.spaces_style_open
  for i = 1, counter - 1 do
    before = before .. self.DM.text_table[i]
  end
  before = before .. self.spaces_style_close
  local after = ""
  if counter < #self.DM.text_table then
    after = self.spaces_style_open
    for i = counter + 1, #self.DM.text_table do
      after = after .. self.DM.text_table[i]
    end
    after = after .. self.spaces_style_close
  end
  self.shared.discoverMessageRunesFade = before .. rune .. after
  self.shared.discoverMessageFlourish = before .. transChar .. after
end
function DiscoverTextOn:PrepTranslatedText(counter)
  local temp = self:TableConcatSubstring(self.DM.text_table, 1, counter)
  if counter < self.textLength then
    temp = temp .. self.spaces_style_open .. self:TableConcatSubstring(self.DM.text_table, counter + 1) .. self.spaces_style_close
  end
  self.preppedTransText = temp
end
function DiscoverTextOn:NextTranslationStep(counter)
  local transChar = self.DM.text_table[counter]
  self:SetRuneText(counter)
  self:SetIndividualChar(counter)
  self:PrepTranslatedText(counter)
  if transChar ~= " " then
    UI.AlphaFade("RunicTextFade", 1, 0)
    UI.AlphaFade("RunicTextFade", 0, 0.2)
    UI.Anim("DiscoverTextFlourish", consts.AS_Reverse, "", 5, 1)
    self:StartTimer("holdForFade", 0.2, function()
      self:FinishedTransition(counter + 1)
    end)
  else
    self:NextTranslationStep(counter + 1)
  end
end
function DiscoverTextOn:FinishedTransition(counter)
  self.shared.discoverMessageRunesFade = ""
  if counter <= self.textLength then
    self.shared.discoverMessageText = self.preppedTransText
    self.shared.discoverMessageFlourish = ""
    UI.Anim("DiscoverTextFlourish", consts.AS_Reverse, "", 0, 1)
    UI.Anim("RunicTextFade", consts.AS_Forward, "", 0, 1)
    self:NextTranslationStep(counter)
  else
    self.shared.discoverMessageFlourish = ""
    self.shared.discoverMessageText = self.preppedTransText
    self.shared.discoverMessageRunes = ""
    self:StartTimer("HoldTranslation", 2, function()
      self:AnimateOffText()
    end)
  end
end
function DiscoverTextOn:AnimateOffText()
  UI.Anim("DiscoverText", consts.AS_Reverse, "", 4)
  UI.AlphaFade("DiscoverText", 0, 0.25)
  self:StartTimer("HoldTranslation", 1, function()
    self:AfterDMTimer()
  end)
end
function DiscoverMessage:OnSaveCheckpoint(tab)
end
function DiscoverMessage:OnRestoreCheckpoint(tab)
end
