------------------------------------------------
--               CT_BottomBar                 --
--                                            --
-- Breaks up the main menu bar into pieces,   --
-- allowing you to hide and move the pieces   --
-- independently of each other.               --
-- Please do not modify or otherwise          --
-- redistribute this without the consent of   --
-- the CTMod Team. Thank you.                 --
------------------------------------------------

--------------------------------------------
-- Initialization

local _G = getfenv(0);
local module = _G.CT_BottomBar;

-- Local copies
local min = min;

--------------------------------------------
-- Addons

-- Empty function
local function emptyFunc() end

-- Keyring Updater
function MainMenuBar_UpdateKeyRing()
	if ( SHOW_KEYRING == 1 ) then
		KeyRingButton:Show();
	end
end

--------------------------------------------
-- Experience Bar & Reputation Bar

module:registerAddon("Experience Bar", { "TOPLEFT", MainMenuBar, 0, 45 }, function(self)
		MainMenuBarMaxLevelBar:ClearAllPoints();
		MainMenuBarMaxLevelBar:SetPoint("TOPLEFT", MainMenuExpBar);
	end, nil, MainMenuExpBar, MainMenuBarMaxLevelBar, ExhaustionTick);
module:registerAddon("Reputation Bar", { "BOTTOMLEFT", MainMenuBar, "TOPLEFT", 0, 80 }, nil, nil, ReputationWatchBar);

--------------------------------------------
-- Action Bar

module:registerAddon("Action Bar", { "BOTTOMLEFT", MainMenuBarArtFrame, 0, 4 }, function(self)
		local ActionButton1 = ActionButton1;
		
		-- Hide the textures behind the bar
		MainMenuBarTexture0:Hide();
		MainMenuBarTexture1:Hide();
		BonusActionBarTexture0:Hide();
		BonusActionBarTexture1:Hide();
		
		-- Position the left gryphon to be left of the bar
		local leftGryphon = MainMenuBarLeftEndCap;
		leftGryphon:ClearAllPoints();
		leftGryphon:SetPoint("BOTTOMRIGHT", ActionButton1, "BOTTOMLEFT", 28, -5);
		
		local frame = CreateFrame("Frame");
		frame:SetPoint("TOPLEFT", ActionButton1);
		frame:SetPoint("BOTTOMRIGHT", ActionButton12);
		self.helperFrame = frame;
		
		frame = self.frame;
		ActionButton1:ClearAllPoints();
		ActionButton1:SetPoint("BOTTOMLEFT", frame);
		
		local bonusFrame = CreateFrame("Frame", nil, frame);
		bonusFrame:SetWidth(32);
		bonusFrame:SetHeight(32);
		bonusFrame:SetPoint("BOTTOMLEFT", frame);
		BonusActionBarFrame:SetParent(bonusFrame);
		BonusActionBarFrame:SetPoint("TOPLEFT", bonusFrame, "BOTTOMLEFT");
		
		local bonusOnShow = BonusActionBarFrame:GetScript("OnShow");
		local bonusOnHide = BonusActionBarFrame:GetScript("OnHide");
		BonusActionBarFrame:SetScript("OnShow", function(self, ...)
			if ( bonusOnShow ) then
				bonusOnShow(self, ...);
			end
			
			local obj;
			for i = 1, 12, 1 do
				obj = _G["ActionButton"..i];
				obj.alpha = obj:GetAlpha();
				obj:SetAlpha(0);
				obj:Disable();
			end
		end);
		BonusActionBarFrame:SetScript("OnHide", function(self, ...)
			if ( bonusOnHide ) then
				bonusOnHide(self, ...);
			end
			
			local obj;
			for i = 1, 12, 1 do
				obj = _G["ActionButton"..i];
				obj:SetAlpha(obj.alpha or 1);
				obj.alpha = nil;
				obj:Enable();
			end
		end);
		if ( BonusActionBarFrame:IsShown() ) then
			BonusActionBarFrame:Hide();
			BonusActionBarFrame:Show(); -- Force OnShow
		end
		
		module.updateMainBar = function(obj, type, value)
			if ( type == "barSpacing" ) then
				self:rotateFunc(self.orientation, value);
				return;
			end
			
			local func, obj, maxFunc;
			if ( type == "barScale" ) then
				func = ActionButton1.SetScale;
			elseif ( type == "barOpacity" ) then
				func = ActionButton1.SetAlpha;
				if ( ActionButton1.alpha ) then
					maxFunc = ActionButton1.GetAlpha;
				end
			end
			
			for i = 1, 12, 1 do
				obj = _G["ActionButton"..i];
				if ( maxFunc ) then
					func(obj,min(maxFunc(obj), value));
					obj.alpha = value;
				else
					func(obj, value);
				end
				func(_G["BonusActionButton"..i], value);
			end
		end
		
		return true;		
	end, function(self, orientation, spacing)
		spacing = spacing or module:getOption("barSpacing") or 6;
		
		local obj, obj2;
		for i = 1, 12, 1 do
			obj = _G["ActionButton"..i];
			obj2 = _G["BonusActionButton"..i];
			obj2:ClearAllPoints();
			obj2:SetPoint("CENTER", obj);
			
			if ( i > 1 ) then
				obj:superClearAllPoints();
				if ( orientation == "ACROSS" ) then
					obj:superSetPoint("LEFT", _G["ActionButton"..(i-1)], "RIGHT", spacing, 0);
				else
					obj:superSetPoint("TOP", _G["ActionButton"..(i-1)], "BOTTOM", 0, -spacing);
				end
			end
		end
	end, "A.B.", "helperFrame", ActionButton1, ActionButton2, ActionButton3, ActionButton4, ActionButton5, ActionButton6,
	ActionButton7, ActionButton8, ActionButton9, ActionButton10, ActionButton11, ActionButton12);
	
--------------------------------------------
-- Pet Bar

module:registerAddon("Pet Bar", 
	{ "BOTTOMLEFT", MainMenuBar, "TOPLEFT", 30, 60 },
	function(self)
		local obj = PetActionBarFrame;
		
		obj:EnableMouse(false);
		obj:SetAttribute("unit", "pet");
		RegisterUnitWatch(obj);
		
		SlidingActionBarTexture0:Hide();
		SlidingActionBarTexture1:Hide();
		SlidingActionBarTexture0.Show = emptyFunc;
		SlidingActionBarTexture1.Show = emptyFunc;
		
		local frame = CreateFrame("Frame");
		frame:SetPoint("TOPLEFT", PetActionButton1);
		frame:SetPoint("BOTTOMRIGHT", PetActionButton10);
		self.helperFrame = frame;
		
		PetActionButton1:ClearAllPoints();
		PetActionButton1:SetPoint("BOTTOMLEFT", self.frame);
		
		module.updatePetBar = function(obj, type, value)
			if ( type == "petBarSpacing" ) then
				self:rotateFunc(self.orientation, value);
				return;
			end
			
			local func;
			if ( type == "petBarScale" ) then
				func = PetActionButton1.SetScale;
			elseif ( type == "petBarOpacity" ) then
				func = PetActionButton1.SetAlpha;
			end
		
			for i = 1, 10, 1 do
				func(_G["PetActionButton"..i], value);
			end
		end
		
		return true;
	end, function(self, orientation, spacing)
		spacing = spacing or module:getOption("petBarSpacing") or 6;
		local obj;
		for i = 2, 10, 1 do
			obj = _G["PetActionButton"..i];
			obj:ClearAllPoints();
			if ( orientation == "ACROSS" ) then
				obj:SetPoint("LEFT", _G["PetActionButton"..(i-1)], "RIGHT", spacing, 0);
			else
				obj:SetPoint("TOP", _G["PetActionButton"..(i-1)], "BOTTOM", 0, -spacing);
			end
		end
	end, "P.B.", "helperFrame", PetActionBarFrame);
	
--------------------------------------------
-- Class Bar
	
module:registerAddon("Class Bar", 
	{ "BOTTOMLEFT", MainMenuBar, "TOPLEFT", 30, 105, ["perClass"] = true, ["ROGUE"] = true, ["DRUID"] = true, ["WARRIOR"] = true }, 
	function(self)
		local obj = ShapeshiftBarFrame;
		
		ShapeshiftBarLeft:Hide();
		ShapeshiftBarMiddle:Hide();
		ShapeshiftBarRight:Hide();
		ShapeshiftBarLeft.Show = emptyFunc;
		ShapeshiftBarMiddle.Show = emptyFunc;
		ShapeshiftBarRight.Show = emptyFunc;
		
		local frame = CreateFrame("Frame");
		frame:SetPoint("TOPLEFT", ShapeshiftButton1);
		frame:SetPoint("BOTTOMRIGHT", ShapeshiftButton10);
		self.helperFrame = frame;
		
		ShapeshiftButton1:ClearAllPoints();
		ShapeshiftButton1:SetPoint("BOTTOMLEFT", self.frame);
		
		return true;
	end, function(self, orientation)
		local obj;
		for i = 2, 10, 1 do
			obj = _G["ShapeshiftButton"..i];
			obj:ClearAllPoints();
			if ( orientation == "ACROSS" ) then
				obj:SetPoint("LEFT", _G["ShapeshiftButton"..(i-1)], "RIGHT", 6, 0);
			else
				obj:SetPoint("TOP", _G["ShapeshiftButton"..(i-1)], "BOTTOM", 0, -6);
			end
		end
	end, "C.B.", "helperFrame", ShapeshiftBarFrame);
	
--------------------------------------------
-- Menu Bar
	
module:registerAddon("Menu Bar", { "BOTTOMLEFT", MainMenuBarArtFrame, 540, 5 }, function(self)
		local CharacterMicroButton = CharacterMicroButton;
		
		-- Hide the textures behind the bar
		MainMenuBarTexture2:Hide();
		
		local frame = CreateFrame("Frame");
		frame:SetPoint("TOPLEFT", CharacterMicroButton, 0, -20);
		frame:SetPoint("BOTTOMRIGHT", HelpMicroButton);
		self.helperFrame = frame;
		
		CharacterMicroButton:ClearAllPoints();
		CharacterMicroButton:SetPoint("BOTTOMLEFT", self.frame, 0, -2);
		
		return true;		
	end, function(self, orientation)
		local frames, obj = self.frames;
		for i = 3, #frames, 1 do
			obj = frames[i];
			obj:superClearAllPoints();
			if ( orientation == "ACROSS" ) then
				obj:superSetPoint("LEFT", frames[i-1], "RIGHT", -3, 0);
			else
				obj:superSetPoint("TOP", frames[i-1], "BOTTOM", 0, 23);
			end
		end
	end, "M.B.", "helperFrame", CharacterMicroButton, SpellbookMicroButton, TalentMicroButton, QuestLogMicroButton,
	SocialsMicroButton, LFGMicroButton, MainMenuMicroButton, HelpMicroButton);

--------------------------------------------
-- Bags Bar

module:registerAddon("Bags Bar", { "BOTTOMLEFT", MainMenuBarArtFrame, 770, 5 }, function(self)
		local mainFrame = self.frame;
		local MainMenuBarTexture3 = MainMenuBarTexture3;
		local MainMenuBarPerformanceBarFrame = MainMenuBarPerformanceBarFrame;
		local MainMenuBarPerformanceBar = MainMenuBarPerformanceBar;
		
		local latencyKeyRing = CreateFrame("Frame");
		latencyKeyRing:SetWidth(37);
		latencyKeyRing:SetHeight(37);
		latencyKeyRing:SetPoint("BOTTOMLEFT", mainFrame);
		self.latencyKeyRing = latencyKeyRing;
		self.helperFrame = CreateFrame("Frame");
		
		local rightGryphon = MainMenuBarRightEndCap;
		rightGryphon:ClearAllPoints();
		rightGryphon:SetPoint("BOTTOMLEFT", MainMenuBarBackpackButton, "BOTTOMRIGHT", -28, -5);
		
		MainMenuBarPerformanceBar:ClearAllPoints();
		MainMenuBarPerformanceBar:SetPoint("TOPLEFT", MainMenuBarPerformanceBarFrame, "TOP", -5, 0);
		MainMenuBarPerformanceBar:SetPoint("BOTTOMRIGHT", MainMenuBarPerformanceBarFrame, "BOTTOM", 5, 0);
		MainMenuBarPerformanceBar:SetTexCoord(0.27, 0.6, 0.23, 0.78);
		MainMenuBarPerformanceBarFrame:SetWidth(16);
		MainMenuBarPerformanceBarFrame:SetHeight(40);
		MainMenuBarPerformanceBarFrame:ClearAllPoints();
		MainMenuBarPerformanceBarFrame:SetPoint("TOPRIGHT", latencyKeyRing, "TOP", -1, 0);
		
		MainMenuBarTexture3:SetParent(MainMenuBarPerformanceBarFrame);
		MainMenuBarTexture3:SetAllPoints(MainMenuBarPerformanceBarFrame);
		MainMenuBarTexture3:SetTexture("Interface\\MainMenuBar\\UI-MainMenuBar-KeyRing");
		MainMenuBarTexture3:SetTexCoord(0, 0.082, 0.16, 0.52);
		
		KeyRingButton:ClearAllPoints();
		KeyRingButton:SetPoint("TOPLEFT", latencyKeyRing, "TOP", -1, 0);
		
		local obj;
		for i = 3, 0, -1 do
			_G["CharacterBag"..i.."Slot"]:ClearAllPoints();
		end
		
		for i = 0, 3, 1 do
			obj = _G["CharacterBag"..i.."Slot"];
			obj:ClearAllPoints();
			obj:SetPoint("LEFT", _G["CharacterBag"..(i+1).."Slot"] or KeyRingButton, "RIGHT");
		end
		
		MainMenuBarBackpackButton:ClearAllPoints();
		MainMenuBarBackpackButton:SetPoint("LEFT", CharacterBag0Slot, "RIGHT");
		
		return true;		
	end, function(self, orientation)
		local frames = self.frames;
		
		local num = #frames-1;
		for key, value in ipairs(frames) do
			if ( key > 1 and key < num ) then
				value:superClearAllPoints();
			end
		end
		
		local latencyKeyRing = self.latencyKeyRing;
		local helperFrame = self.helperFrame;
		helperFrame:superClearAllPoints();
		
		if ( orientation == "ACROSS" ) then
			latencyKeyRing:superSetPoint("BOTTOMLEFT", self.frame);
			helperFrame:superSetPoint("TOPLEFT", self.latencyKeyRing);
			helperFrame:superSetPoint("BOTTOMRIGHT", MainMenuBarBackpackButton);
			
			local obj;
			for i = 3, #frames-2, 1 do
				obj = frames[i];
				obj:superSetPoint("LEFT", frames[i-1], "RIGHT");
			end
		else
			latencyKeyRing:superSetPoint("BOTTOM", self.frame);
			MainMenuBarBackpackButton:superSetPoint("TOP", latencyKeyRing, "BOTTOM");
			helperFrame:superSetPoint("TOPLEFT", latencyKeyRing);
			helperFrame:superSetPoint("BOTTOMRIGHT", CharacterBag3Slot);
			
			for i = #frames-3, 3, -1 do
				frames[i]:superSetPoint("TOP", frames[i+1], "BOTTOM");
			end
		end
	end, "B.B.", "helperFrame", "latencyKeyRing", CharacterBag3Slot, CharacterBag2Slot, 
		CharacterBag1Slot, CharacterBag0Slot, MainMenuBarBackpackButton, 
		MainMenuBarPerformanceBarFrame, KeyRingButton);