
local XP_COLOR   = { r = 0.6, g = 0,   b = 0.5 }
local REST_COLOR = { r = 0.2, g = 0.2, b = 0.8 }

------------------------------------------------------------------------
-- Object creation

local f = CreateFrame("Frame", "derXPBar", XPFrame)
f:SetPoint("CENTER", 0, 0)
f:SetHeight(17)
f:SetWidth(UIParent:GetWidth() * 0.33)

f:SetBackdrop({
	bgFile = --[["Interface\\BUTTONS\\WHITE8X8"]]"Interface\\AddOns\\_Deranjata\\Media\\cast\\Lines",
	--edgeFile = "Interface\\BUTTONS\\WHITE8X8", edgeSize = 1,
	--insets = { left = 1, right = 1, top = 1, bottom = 1 }
})
f:SetBackdropColor(0.1, 0.1, 0.1)
f:SetBackdropBorderColor(0.6, 0.6, 0.6)

local restBar = CreateFrame("StatusBar", nil, f)
restBar:SetPoint("BOTTOMLEFT", 1, 1)
restBar:SetPoint("TOPRIGHT", -1, -1)
restBar:SetStatusBarTexture("Interface\\AddOns\\_Deranjata\\Media\\cast\\Waterline")
restBar:SetStatusBarColor(REST_COLOR.r, REST_COLOR.g, REST_COLOR.b, 0.5)

local bar = CreateFrame("StatusBar", nil, restBar)
bar:SetAllPoints(true)
bar:SetStatusBarTexture("Interface\\AddOns\\_Deranjata\\Media\\cast\\Waterline")

local text = bar:CreateFontString(nil, "OVERLAY", "GameFontNormal")
text:SetPoint("CENTER")

------------------------------------------------------------------------
-- Display logic

local mode = "XP"

function f:Update(event, arg1)
	if event == "PET_BATTLE_OPENING_START" or C_PetBattles.IsInBattle() then
		return f:Hide()
	end

	local level = event == "PLAYER_LEVEL_UP" and arg1 or UnitLevel("player")
	if level == MAX_PLAYER_LEVEL or mode == "REP" then
		local name, standing, min, max, rep = GetWatchedFactionInfo()
		if name then
			text:SetFormattedText("%s: %d / %d %s", name, max - rep, max - min, UnitSex("player") == 3 and _G["FACTION_STANDING_LABEL"..standing.."_FEMALE"] or  _G["FACTION_STANDING_LABEL"..standing])

			bar:SetMinMaxValues(min, max)
			bar:SetValue(rep)

			local color = FACTION_BAR_COLORS[standing]
			bar:SetStatusBarColor(color.r, color.g, color.b)

			restBar:SetMinMaxValues(0, 1)
			restBar:SetValue(0)

			return
		end
	end

	local xp, max, rest = UnitXP("player"), UnitXPMax("player"), GetXPExhaustion()
	text:SetFormattedText("Level %d XP: %d / %d", level, xp, max)

	bar:SetMinMaxValues(0, max)
	bar:SetValue(xp)

	if rest then
		bar:SetStatusBarColor(REST_COLOR.r, REST_COLOR.g, REST_COLOR.b)
		restBar:SetMinMaxValues(0, max)
		restBar:SetValue( (xp + rest > max) and max or (xp + rest) )
	else
		bar:SetStatusBarColor(XP_COLOR.r, XP_COLOR.g, XP_COLOR.b)
		restBar:SetMinMaxValues(0, 1)
		restBar:SetValue(0)
	end
end

------------------------------------------------------------------------
-- Update on events

f:RegisterEvent("PET_BATTLE_OPENING_START")
f:RegisterEvent("PET_BATTLE_CLOSE")
f:RegisterEvent("PLAYER_ENTERING_WORLD")
f:RegisterEvent("PLAYER_LEVEL_UP")
f:RegisterEvent("PLAYER_XP_UPDATE")
f:RegisterEvent("UPDATE_EXHAUSTION")
f:RegisterEvent("UPDATE_FACTION")

f:SetScript("OnEvent", f.Update)
hooksecurefunc("SetWatchedFactionIndex", f.Update)

------------------------------------------------------------------------
-- Toggle mode on click

f:EnableMouse(true)
f:SetScript("OnMouseUp", function(self, button)
	if button == "RightButton" and IsShiftKeyDown() then
		mode = mode == "XP" and "REP" or "XP"
	end
	self:Update()
end)