local Azurah		= _G['Azurah'] -- grab addon table from global
local LMP			= LibStub('LibMediaProvider-1.0')

-- UPVALUES --
local IsUnitVeteran					= IsUnitVeteran
local GetUnitVeteranPoints			= GetUnitVeteranPoints
local GetUnitVeteranPointsMax		= GetUnitVeteranPointsMax
local GetUnitXP						= GetUnitXP
local GetUnitXPMax					= GetUnitXPMax
local GetMaxVeteranRank				= GetMaxVeteranRank
local IsChampionSystemUnlocked		= IsChampionSystemUnlocked
local GetPlayerChampionXP			= GetPlayerChampionXP
local GetChampionXPInRank			= GetChampionXPInRank
local GetPlayerChampionPointsEarned	= GetPlayerChampionPointsEarned
local strformat						= string.format
local zo_callLater					= zo_callLater

local hasMaxXP						= false
local hasMaxCP						= false
local overlayExp, overlayChamp
local FormatExp
local isUpdating
local db

local function OnCraftStart()
	if (db.displayStyle == 2) then
		ZO_PlayerProgressBar:SetAlpha(0)
	end
end

local function OnCraftEnd()
	if (db.displayStyle == 2) then
		ZO_PlayerProgressBar:SetAlpha(1)
	end
end

local function UpdateExperienceBarOverlayValues()
	local isVeteran = IsUnitVeteran('player')

	if (not hasMaxXP) then
		local current, max

		if (isVeteran) then
			current, max = GetUnitVeteranPoints('player'), GetUnitVeteranPointsMax('player')
			hasMaxXP = (GetUnitVeteranRank('player') == GetMaxVeteranRank()) and (current >= max)
		else
			current, max = GetUnitXP('player'), GetUnitXPMax('player')
		end

		overlayExp:SetText(FormatExp(current, nil, max))
	end

	if (not hasMaxCP and isVeteran) then
		if (IsChampionSystemUnlocked()) then
			local earnedCP = GetPlayerChampionPointsEarned()
			local inRankCP = GetChampionXPInRank(earnedCP)
			if (inRankCP ~= nil) then
				local championXP = GetPlayerChampionXP()
				overlayChamp:SetText(strformat("%d - %s", earnedCP, FormatExp(championXP, nil, inRankCP)))
			end
			hasMaxCP = earnedCP == 3600
		end
	end

	isUpdating = false
end

local function OnExpGain(_, unit)
	if (unit ~= 'player') then return end -- only care about the player

	if (not isUpdating) then
		isUpdating = true
		zo_callLater(UpdateExperienceBarOverlayValues, 1000) -- called later as exp bar doesn't show new values immediately
	end
end

function Azurah:ConfigureExperienceBarOverlay()
	if (not IsInGamepadPreferredMode() and db.overlay > 1) then -- showing overlay, enable tracking
		local current, max, earnedCP, inRankCP
		local isVeteran = IsUnitVeteran('player')

		local fontStr = strformat('%s|%d|%s', LMP:Fetch('font', db.fontFace), db.fontSize, db.fontOutline)
		FormatExp = self.overlayFuncs[db.overlay + ((db.overlayFancy) and 10 or 0)]

		overlayExp:SetFont(fontStr)
		overlayExp:SetColor(db.fontColour.r, db.fontColour.g, db.fontColour.b, db.fontColour.a)
		overlayChamp:SetFont(fontStr)
		overlayChamp:SetColor(db.fontColour.r, db.fontColour.g, db.fontColour.b, db.fontColour.a)

		if (isVeteran) then
			current= GetUnitVeteranPoints('player')
			max	= GetUnitVeteranPointsMax('player')
			earnedCP = GetPlayerChampionPointsEarned()
			inRankCP = GetChampionXPInRank(earnedCP)
			hasMaxXP = (GetUnitVeteranRank('player') == GetMaxVeteranRank()) and (current >= max)
			hasMaxCP = earnedCP == 3600
		else
			current, max = GetUnitXP('player'), GetUnitXPMax('player')
		end

		if (not hasMaxXP) then
			--hide "LEVEL"/"VETERAN RANK" text
			ZO_PlayerProgressLevelType:SetAlpha(0)
			overlayExp:SetHidden(false)
			overlayExp:SetText(FormatExp(current, nil, max))
		else
			ZO_PlayerProgressLevelType:SetAlpha(1)
			overlayExp:SetHidden(true)
		end

		if (IsChampionSystemUnlocked() and isVeteran and not hasMaxCP) then
			--hide "CHAMPION POINT" text
			ZO_PlayerProgressSecondaryLevelType:SetAlpha(0)
			overlayChamp:SetHidden(false)
			overlayChamp:SetText(strformat("%d - %s", earnedCP, FormatExp(GetPlayerChampionXP(), nil, inRankCP)))
		else
			ZO_PlayerProgressSecondaryLevelType:SetAlpha(1)
			overlayChamp:SetHidden(true)
		end

		EVENT_MANAGER:RegisterForEvent(self.name .. 'Experience', EVENT_EXPERIENCE_UPDATE, OnExpGain)
		EVENT_MANAGER:RegisterForEvent(self.name .. 'Experience', EVENT_VETERAN_POINTS_UPDATE, OnExpGain)

	else -- no overlay being shown, disable tracking
		EVENT_MANAGER:UnregisterForEvent(self.name .. 'Experience', EVENT_EXPERIENCE_UPDATE)
		EVENT_MANAGER:UnregisterForEvent(self.name .. 'Experience', EVENT_VETERAN_POINTS_UPDATE)

		overlayExp:SetHidden(true)
		overlayChamp:SetHidden(true)

		--restore visibility of "LEVEL"/"VETERAN RANK" and "CHAMPION POINT" texts
		ZO_PlayerProgressLevelType:SetAlpha(1)
		ZO_PlayerProgressSecondaryLevelType:SetAlpha(1)
	end
end

function Azurah:ConfigureExperienceBarDisplay()
	-- Visibility code for Experience Bar is by Garkin (http://www.esoui.com/forums/member.php?u=524)\and used with permission.
	PLAYER_PROGRESS_BAR_FRAGMENT:SetConditional(function() return not (db.displayStyle == 3) end)
	PLAYER_PROGRESS_BAR_CURRENT_FRAGMENT:SetConditional(function() return not (db.displayStyle == 3) end)

	if (db.displayStyle == 2) then
		EVENT_MANAGER:RegisterForEvent(self.name .. 'Experience', EVENT_CRAFTING_STATION_INTERACT,	OnCraftStart)
		EVENT_MANAGER:RegisterForEvent(self.name .. 'Experience', EVENT_END_CRAFTING_STATION_INTERACT,OnCraftEnd)
		HUD_SCENE:AddFragment(PLAYER_PROGRESS_BAR_FRAGMENT)
		HUD_SCENE:AddFragment(PLAYER_PROGRESS_BAR_CURRENT_FRAGMENT)
		HUD_UI_SCENE:AddFragment(PLAYER_PROGRESS_BAR_FRAGMENT)
		HUD_UI_SCENE:AddFragment(PLAYER_PROGRESS_BAR_CURRENT_FRAGMENT)
	else
		EVENT_MANAGER:UnregisterForEvent(self.name .. 'Experience', EVENT_CRAFTING_STATION_INTERACT)
		EVENT_MANAGER:UnregisterForEvent(self.name .. 'Experience', EVENT_END_CRAFTING_STATION_INTERACT)
		HUD_SCENE:RemoveFragment(PLAYER_PROGRESS_BAR_FRAGMENT)
		HUD_SCENE:RemoveFragment(PLAYER_PROGRESS_BAR_CURRENT_FRAGMENT)
		HUD_UI_SCENE:RemoveFragment(PLAYER_PROGRESS_BAR_FRAGMENT)
		HUD_UI_SCENE:RemoveFragment(PLAYER_PROGRESS_BAR_CURRENT_FRAGMENT)
	end
end


-- ------------------------
-- INITIALIZATION
-- ------------------------
function Azurah:InitializeExperienceBar()
	db = self.db.experienceBar

	--I'm not sure where I have to show overlay, so I'll replace "VETERAN RANK" and "CHAMPION POINT" texts
	overlayExp = self:CreateOverlay(ZO_PlayerProgressBar, BOTTOMLEFT, TOPLEFT, 4, -2, nil, nil, nil, TEXT_ALIGN_LEFT)
	overlayChamp = self:CreateOverlay(ZO_PlayerProgressSecondaryLevelTypeIcon, LEFT, RIGHT, 8, 0, nil, nil, nil, TEXT_ALIGN_LEFT)

	if IsUnitVeteran('player') then
		overlayExp:ClearAnchors()
		overlayExp:SetAnchor(LEFT, ZO_PlayerProgressLevelTypeIcon, RIGHT, 8, 0)
	end

	-- set 'dummy' display function
	FormatExp = self.overlayFuncs[1]

	self:ConfigureExperienceBarDisplay()
end