--[[
	Bongos_Exp.lua
		Scripts for the Bongos Experience/Reputation bar
--]]

local DEFAULT_HEIGHT = 14;
local DEFAULT_SIZE = 0.75;

--[[ Conversions ]]--

local function ToVerticalText(text)
	local vText = "";
	local length = strlen(text);
	for i = 1, length - 1 do
		vText = vText .. strsub(text, i, i) .. " ";
	end
	vText = vText .. strsub(text, length, length);
	
	return vText;
end

--[[ Update Functions ]]--

local function WatchExperience()
	BXPBar:UnregisterAllEvents();
	BXPBar:RegisterEvent("UPDATE_FACTION");
	BXPBar:RegisterEvent("PLAYER_LOGIN");
	BXPBar:RegisterEvent("PLAYER_LEVEL_UP");
	BXPBar:RegisterEvent("PLAYER_XP_UPDATE");
	BXPBar:RegisterEvent("UPDATE_EXHAUSTION");
	BXPBar:SetScript("OnEvent", BongosXP_OnXPEvent);
	
	BongosXP:SetStatusBarColor(0.6, 0, 0.6, 1);
	BongosXPRest:SetStatusBarColor(0.25,0.25,1,0.75);
	BongosXPRestBackground:SetVertexColor(0.6 * 0.25, 0, 0.6 * 0.25, 0.6);
	
	BongosXP_OnXPEvent();
end

local function WatchFaction()
	BXPBar:UnregisterAllEvents();
	BXPBar:RegisterEvent("UPDATE_FACTION");
	BXPBar:SetScript("OnEvent", BongosXP_OnRepEvent);
		
	BongosXP:SetStatusBarColor(0, 0, 0, 0);
	BongosXPRest:SetStatusBarColor(0.25,0.25,1,0.75);
	BongosXPRestBackground:SetVertexColor(0, 0.6 * 0.25, 0, 0.6);
	
	BongosXP_OnRepEvent();		
end

--[[  OnX Functions ]]--

function BongosXP_OnXPEvent()
	if GetWatchedFactionInfo() then
		WatchFaction();
	else
		BongosXP:SetMinMaxValues( 0, UnitXPMax("player") );
		BongosXPRest:SetMinMaxValues( 0, UnitXPMax("player") );
		BongosXP:SetValue( UnitXP("player") );

		if GetXPExhaustion() then
			BongosXPRest:SetValue( UnitXP("player") +  GetXPExhaustion() );
		else
			BongosXPRest:SetValue(0);
		end
		
		if BongosXPText:IsShown() then
			local text = UnitXPMax("player") - UnitXP("player") .. " tnl";
			if BXPBarSets.vertical then
				text = ToVerticalText(text);
			end
			BongosXPText:SetText(text);
		end
	end
end

function BongosXP_OnRepEvent()
	local name, reaction, min, max, value = GetWatchedFactionInfo();
	
	if not name then 
		WatchExperience();
	else
		max = max - min;
		value = value - min;
		min = 0;

		BongosXP:SetValue(0);
		BongosXPRest:SetMinMaxValues(min, max);
		BongosXPRest:SetValue(value);

		local color = FACTION_BAR_COLORS[reaction];
		BongosXPRest:SetStatusBarColor(color.r, color.g, color.b);

		if BongosXPText:IsShown() then
			local text = value .. " / " .. max;
			if BXPBarSets.vertical then
				text = ToVerticalText(text);
			end
			BongosXPText:SetText( text );
		end
	end
end

function BongosXP_OnEnter()
	local text;
	if GetWatchedFactionInfo() then
		local name, reaction, min, max, value = GetWatchedFactionInfo();				
		max = max - min;
		value = value - min;
		
		text = value .. " / " .. max;
	else
		text = UnitXPMax("player") - UnitXP("player") .. " tnl";
	end
	
	if BXPBarSets.vertical then
		text = ToVerticalText(text);
	end
	BongosXPText:SetText(text);
	BongosXPText:Show();
end

--[[ Configuration ]]--

local function SetSize(percent)
	if BXPBar.sets.vertical then
		BXPBar:SetHeight(UIParent:GetHeight() / UIParent:GetScale() * (percent or DEFAULT_SIZE));
	else
		BXPBar:SetWidth(UIParent:GetWidth() / UIParent:GetScale() * (percent or DEFAULT_SIZE));
	end
	BXPBar.sets.size = percent;
end

--yes, a weird name
local function SetHeight(value)
	if BXPBar.sets.vertical then
		BXPBar:SetWidth(value or DEFAULT_HEIGHT);
	else
		BXPBar:SetHeight(value or DEFAULT_HEIGHT);
	end
	BXPBar.sets.height = value;
end

--set how tall/wide the xp bar should be
local function SetVertical(vertical)
	if vertical then
		BongosXP:SetOrientation("VERTICAL");
		BongosXPRest:SetOrientation("VERTICAL");
		BongosXP:SetStatusBarTexture("Interface\\Addons\\Bongos_XP\\statusbar6v");
		BongosXPRest:SetStatusBarTexture("Interface\\Addons\\Bongos_XP\\statusbar6v");
		BXPBar.sets.vertical = 1;
	else
		BongosXP:SetOrientation("HORIZONTAL");
		BongosXPRest:SetOrientation("HORIZONTAL");
		BongosXP:SetStatusBarTexture("Interface\\Addons\\Bongos_XP\\statusbar6");
		BongosXPRest:SetStatusBarTexture("Interface\\Addons\\Bongos_XP\\statusbar6");
		BXPBar.sets.vertical = nil;
	end
	
	SetSize(BXPBar.sets.size);
	SetHeight(BXPBar.sets.height);
end

--[[ Right Click Menu Functions ]]--

local function CreateConfigMenu(name)
	local menu = CreateFrame("Button", name, UIParent, "BongosRightClickMenu");
	menu:SetText("XP Bar");
	menu:SetWidth(220);
	menu:SetHeight(264);
	
	local hideButton = CreateFrame("CheckButton", name .. "Hide", menu, "BongosHideButtonTemplate");
	
	local verticalButton = CreateFrame("CheckButton", name .. "Vertical", menu, "BongosCheckButtonTemplate");
	verticalButton:SetScript("OnClick", function()
		SetVertical(this:GetChecked());
		if this:GetChecked() then
			getglobal(this:GetParent():GetName() .. "SizeText"):SetText("Height");
			getglobal(this:GetParent():GetName() .. "HeightText"):SetText("Width");
		else
			getglobal(this:GetParent():GetName() .. "SizeText"):SetText("Width");
			getglobal(this:GetParent():GetName() .. "HeightText"):SetText("Height");
		end
	end);
	verticalButton:SetPoint("TOP", hideButton, "BOTTOM", 0, 4);
	verticalButton:SetText("Vertical");
	
	local sizeSlider = CreateFrame("Slider", name .. "Size", menu, "BongosSlider");
	sizeSlider:SetPoint("TOPLEFT", name .. "Vertical", "BOTTOMLEFT", 2, -10);
	sizeSlider:SetScript("OnValueChanged", function()
		if not this:GetParent().onShow then
			SetSize(this:GetValue() / 100);
		end
		getglobal(this:GetName() .. "ValText"):SetText(this:GetValue());
	end);
	sizeSlider:SetValueStep(1);
	sizeSlider:SetMinMaxValues( 0, 100 );
	getglobal(name .. "SizeLow"):SetText("0%");
	getglobal(name .. "SizeHigh"):SetText("100%");
	
	local heightSlider = CreateFrame("Slider", name .. "Height", menu, "BongosSlider");
	heightSlider:SetPoint("TOP", sizeSlider, "BOTTOM", 0, -24);
	heightSlider:SetScript("OnValueChanged", function()
		if not this:GetParent().onShow then
			SetHeight(this:GetValue());
		end
		getglobal(this:GetName() .. "ValText"):SetText(this:GetValue());
	end);
	heightSlider:SetValueStep(1);
	heightSlider:SetMinMaxValues( 0, 96 );
	getglobal(name .. "HeightLow"):SetText(0);
	getglobal(name .. "HeightHigh"):SetText(96);
	
	local scaleSlider = CreateFrame("Slider", name .. "Scale", menu, "BongosScaleSlider");
	scaleSlider:SetPoint("TOP", heightSlider, "BOTTOM", 0, -24);
	
	local opacitySlider = CreateFrame("Slider", name .. "Opacity", menu, "BongosOpacitySlider");
	opacitySlider:SetPoint("TOP", scaleSlider, "BOTTOM", 0, -24);
end

local function ShowMenu(bar)
	if not BongosXPBarMenu then
		CreateConfigMenu("BongosXPBarMenu");
	end
	
	BongosXPBarMenu.onShow = 1;
	BongosXPBarMenu.frame = bar;
	
	BongosXPBarMenuVertical:SetChecked(bar.sets.vertical);
	if bar.sets.vertical then
		BongosXPBarMenuSizeText:SetText("Height");
		BongosXPBarMenuHeightText:SetText("Width");
	else
		BongosXPBarMenuSizeText:SetText("Width");
		BongosXPBarMenuHeightText:SetText("Height");
	end
	
	BongosXPBarMenuSize:SetValue((bar.sets.size or DEFAULT_SIZE) * 100);
	BongosXPBarMenuHeight:SetValue(bar.sets.height or DEFAULT_HEIGHT);
	BongosXPBarMenuScale:SetValue(bar:GetScale() * 100);
	BongosXPBarMenuOpacity:SetValue(bar:GetAlpha() * 100);
	
	BMenu.ShowMenuForBar(BongosXPBarMenu, bar);
	BongosXPBarMenu.onShow = nil;
end

--[[ Startup ]]--
BScript.AddStartupAction(function()
	local bar = BBar.Create("xp", "BXPBar", "BXPBarSets", ShowMenu);
	bar:SetFrameStrata("LOW");
	if not bar:IsUserPlaced() then
		bar:SetPoint("TOP", UIParent, "TOP", 0, -32);
	end
	
	BongosXPRest:SetParent(BXPBar);
	BongosXPRest:SetAllPoints(BXPBar);
	BongosXPRest:SetFrameLevel(0);
	BongosXPRest:SetAlpha(bar:GetAlpha());
	
	--load settings
	--SetVertical(bar.sets.vertical);
	
	if GetWatchedFactionInfo() then
		WatchFaction();
	else
		WatchExperience();
	end
end)

Infield.AddRescaleAction(function() SetVertical(BXPBar.sets.vertical); end);