Quantcast
local T, C, L = unpack(Tukui)
if not C.actionbar.enable == true then return end

local function KillTukuiButtons()
	local buttons = {
		TukuiBar2Button,
		TukuiBar3Button,
		TukuiBar4Button,
		TukuiBar5ButtonTop,
		TukuiBar5ButtonBottom,
	}

	for _,b in pairs(buttons) do
		if b then b:Kill() end
	end
end

local TukuiConfigBackup = C.actionbar

function T.GetActionButtons(query)
	local Buttons = {}

	if not query then query = "12345" end --if no parameters given, return all normal action bars

	query = strlower(tostring(query))

	for i = 1, 12 do
		if strfind(query,"1") then
			tinsert(Buttons, _G["ActionButton"..i])
		end
		if strfind(query,"2") then
			tinsert(Buttons, _G["MultiBarBottomLeftButton"..i])
		end
		if strfind(query,"3") then
			tinsert(Buttons, _G["MultiBarBottomRightButton"..i])
		end
		if strfind(query,"4") then
			tinsert(Buttons, _G["MultiBarLeftButton"..i])
		end
		if strfind(query,"5") then
			tinsert(Buttons, _G["MultiBarRightButton"..i])
		end
	end

	if query and strfind(query,"pet") then
		for i=1, 10 do
			tinsert(Buttons, _G["PetActionButton"..i])
		end
	end
	if query and strfind(query, "shapeshift") then
		for i=1, 10 do
			tinsert(Buttons , _G["ShapeshiftButton"..i])
		end
	end

	return Buttons
end



local function style(self)
	local name = self:GetName()

	local Count = _G[name.."Count"]
	local HotKey = _G[name.."HotKey"]
	local Border = _G[name.."Panel"]

	Count:SetFont(T.GetPixelFont())
	Count.SetFont = T.dummy
	HotKey:SetFont(T.GetPixelFont())
	HotKey.SetFont = T.dummy

	Border:ThickBorder()
	Border:AllPoints(self)
	Border:SetTemplate("Transparent")
end

function T.UpdateAllActionBars()
	if InCombatLockdown() then return end
	KillTukuiButtons()
	local buttonSuffix = { "ActionButton", "MultiBarBottomLeftButton", "MultiBarBottomRightButton", "MultiBarLeftButton", "MultiBarRightButton" }
	local previousBar

	local bSize = C.actionbar.buttonsize
	local bSpacing = C.actionbar.buttonspacing

	for i=1, 5 do
		local bar = _G["TukuiBar"..i]
		bar:SetBackdrop(nil)

		local bSuffix = buttonSuffix[i]

		local enabled  = C.actionbar.barspecific[i].enabled
		local numButtons = C.actionbar.barspecific[i].numButtons
		local perRow = C.actionbar.barspecific[i].perRow
		local userPlaced = C.actionbar.barspecific[i].userPlaced

		if C.actionbar.barspecific[i].enabled then bar:Show() else bar:Hide() end
		for j=1, 12 do
			local b = _G[bSuffix..j]

			b:SetSize(bSize, bSize)

			style(b)

			if not C.actionbar.barspecific[i].enabled then
				b:Hide()
			else
				b:Show()
				if i == 1 then b:SetParent(bar) end

				local bLast = _G[bSuffix..(j-1)]
				local bAbove = _G[bSuffix..(j-perRow)]
				b:ClearAllPoints()
				if j==1 then
					b:SetPoint("TOPLEFT", bar , "TOPLEFT", 0, 0)
				elseif j > numButtons then
					b:SetPoint("TOPLEFT", UIParent, "BOTTOMRIGHT", 5, -5)
				elseif (j-1)%perRow == 0 then
					b:SetPoint("TOP", bAbove, "BOTTOM", 0, -bSpacing)
				else
					b:SetPoint("LEFT", bLast, "RIGHT", bSpacing, 0)
				end
			end
		end

		if perRow > numButtons then perRow = numButtons end
		local perCol = ceil(numButtons/perRow)
		bar:SetWidth((perRow*bSize) + ((perRow-1)*bSpacing))
		bar:SetHeight((perCol*bSize) + ((perCol-1)*bSpacing))
		if not bar:IsUserPlaced() then
			bar:ClearAllPoints()
			if i == 1 then
				bar:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, 10)
			else
				bar:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, 10+((i-1)*bSize)+bSpacing*(i-1))
			end
			previousBar = bar
		end
	end

	do

		local perRow = 10
		local bar = _G["TukuiPetBar"]
		bar:SetBackdrop(nil)
		bar:SetHeight(bSize)
		bar:SetWidth((bSize*10)+(bSpacing*9))
		for j=1, 10 do
			local b = _G["PetActionButton"..j]
			local bLast = _G["PetActionButton"..(j-1)]
			b:ClearAllPoints()
			b:SetSize(bSize, bSize)
			style(b)
			if j == 1 then
				b:SetPoint("LEFT", bar, "LEFT", 0, 0)
			else
				if C.actionbar.verticalpet then
					b:SetPoint("TOP", bLast, "BOTTOM", 0, -bSpacing)
				else
					b:SetPoint("LEFT", bLast, "RIGHT", bSpacing, 0)
				end
			end
		end

		if not bar:IsUserPlaced() then
			bar:ClearAllPoints()
			bar:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, 10+((5)*bSize)+bSpacing*(5))
		end
	end

	for _,button in pairs(T.GetActionButtons()) do
		if C.actionbar.hotkey then
			_G[button:GetName().."HotKey"]:Show()
		else
			_G[button:GetName().."HotKey"]:Hide()
		end


		if C.actionbar.showgrid then
			button:SetAttribute("showgrid", 1)
			ActionButton_ShowGrid(button)
		else
			button:SetAttribute("showgrid", 0)
			ActionButton_HideGrid(button)
		end
	end
end

local function LoadVariables()
	if SaftUISaved and SaftUISaved.ActionBars then
		local ab = SaftUISaved.ActionBars
		C.actionbar.buttonsize = ab.buttonsize
		C.actionbar.buttonspacing = ab.buttonspacing
		C.actionbar.hotkey = ab.showhotkey
		C.actionbar.showgrid = ab.showgrid
		C.actionbar.barspecific = ab.barspecific or {
			[1] = { enabled = true, numButtons = 12, perRow = 12 },
			[2] = { enabled = true, numButtons = 12, perRow = 12  },
			[3] = { enabled = true, numButtons = 12, perRow = 12  },
			[4] = { enabled = true, numButtons = 12, perRow = 12  },
			[5] = { enabled = true, numButtons = 12, perRow = 12  },
		}
		C.actionbar.verticalpet = ab.verticalpet or false
	else
		C.actionbar.verticalpet = false
		C.actionbar.barspecific = {
			[1] = { enabled = true, numButtons = 12, perRow = 12 },
			[2] = { enabled = true, numButtons = 12, perRow = 12  },
			[3] = { enabled = true, numButtons = 12, perRow = 12  },
			[4] = { enabled = true, numButtons = 12, perRow = 12  },
			[5] = { enabled = true, numButtons = 12, perRow = 12  },
		}
	end
	--Update to reflect changes from saved variables
	T.UpdateAllActionBars()
end

local LoadFrame = CreateFrame("Frame")
LoadFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
LoadFrame:RegisterEvent("PLAYER_LOGOUT")
LoadFrame:SetScript("OnEvent", function(self, event, addon)
	if event == "PLAYER_ENTERING_WORLD" then
		--If saved variables exist, load them into Tukui's action bar config
		LoadVariables()
		hooksecurefunc(T, "StyleActionBarButton", style)
	elseif event == "PLAYER_LOGOUT" then
		--If saved variables don't exist, create then
		if not SaftUISaved then SaftUISaved = {} end
		if not SaftUISaved["ActionBars"] then SaftUISaved["ActionBars"] = {} end

		--Update Saved Variables when logging out
		local ab = SaftUISaved.ActionBars
		ab.buttonsize = C.actionbar.buttonsize
		ab.buttonspacing = C.actionbar.buttonspacing
		ab.showhotkey = C.actionbar.hotkey
		ab.showgrid = C.actionbar.showgrid
		ab.barspecific = C.actionbar.barspecific
		ab.verticalpet = C.actionbar.verticalpet
	end
end)

--Create config
local function CreateMenuButton(parent, width, height, text, ...)
	local button = CreateFrame("Button", nil, parent)
	button:SetFrameLevel(parent:GetFrameLevel()+1)
	button:SetSize(width, height)
	button:SetTemplate("Thin")
	if ... then button:SetPoint(...) end

	button.text = button:CreateFontString(nil, "OVERLAY")
	button.text:SetFont(unpack(C.pFont))
	button.text:SetPoint("CENTER", 1, 0)
	if text then button.text:SetText(text) end

	button:SetScript("OnEnter", function(self)
		self.text:SetTextColor(0/255, 170/255, 255/255)
		self:SetBackdropColor(.1, .1, .1)
	end)
	button:SetScript("OnLeave", function(self)
		self.text:SetTextColor(255/255, 255/255, 255/255)
		self:SetBackdropColor(unpack(C.media.backdropcolor))
	end)

	return button
end

local function CreateEditBox(self, width, height)
	local editbox = CreateFrame("EditBox", nil, self)
	editbox:SetSize(width, height)
	editbox:SetTemplate("Thin")
	editbox:SetFont(unpack(C.pFont))
	editbox:SetTextInsets(3, 0, 0, 0)
	editbox:SetAutoFocus(false)
	editbox:ClearFocus()
	editbox:SetScript("OnEditFocusGained", function(self) self:HighlightText() end)
	editbox:SetScript("OnEditFocusLost", function(self) self:HighlightText(0,0) end)

	return editbox
end

local window = CreateFrame("Frame", "TukuiActionBarMenu", UIParent)
window:SetFrameStrata("HIGH")

function T.LoadActionBarMenu()
	if InCombatLockdown() then print("Cannot configure action bars in combat.") return end
	if TukuiActionBarMenu.Loaded then ToggleFrame(TukuiActionBarMenu) return end --Only continue if the config is not loaded

	window:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
	window:SetSize(250, 20)
	window:SetTemplate()
	window:CreateBackdrop()

	window:EnableMouse(true)
	window:SetMovable(true)
	window:SetScript("OnMouseDown", function(self) self:StartMoving() end)
	window:SetScript("OnMouseUp", function(self) self:StopMovingOrSizing() end)

	local title = window:CreateFontString(nil, "OVERLAY")
	title:SetFont(unpack(C.pFont))
	title:SetPoint("CENTER")
	title:SetText("Action Bar Config")
	window.title = title

	local close = CreateMenuButton(window, 20, 20, "X", "RIGHT", window, "RIGHT", 0, 0)
	close:SetBackdrop(nil)
	close:HookScript("OnEnter", function(self) self:SetBackdrop(nil) end)
	close:HookScript("OnLeave", function(self) self:SetBackdrop(nil) end)
	close:SetScript("OnClick", function() window:Hide() end)
	window.close = close


	local panels = {}

	do
		local panel = CreateFrame("Frame", nil, window)

		panel:SetTemplate()
		panel:SetWidth(window:GetWidth()-10)
		panel:SetHeight(72)

		local buttonSize = CreateFrame("Frame", nil, panel)
		buttonSize:EnableMouse(true)
		buttonSize:SetSize(panel:GetWidth(), 18)
		buttonSize:SetFrameLevel(panel:GetFrameLevel()+1)
		buttonSize:SetPoint("TOP", panel, "TOP", 0, -3)
		buttonSize:AddText("text", "Button Size",  "LEFT", buttonSize, "LEFT", 4, 1)
		buttonSize.editbox = CreateEditBox(buttonSize, 30, 14)
		buttonSize.editbox:SetTextInsets(3, 0, 0, 1)
		buttonSize.editbox:SetPoint("RIGHT", buttonSize, "RIGHT", -4, 0)
		buttonSize.editbox:SetText(C.actionbar.buttonsize)
		buttonSize.editbox:SetScript("OnEscapePressed", function(self)
			self:ClearFocus()
			self:SetText(C.actionbar.buttonsize)
		end)
		buttonSize.editbox:SetScript("OnEnterPressed", function(self)
			self:ClearFocus()
			if not tonumber(self:GetText()) then self:SetText(C.actionbar.buttonsize) return end

			local newbuttonSize = tonumber(self:GetText())
			if newbuttonSize > 40 then newbuttonSize = 40; self:SetText("40") end
			if newbuttonSize < 10 then newbuttonSize = 10; self:SetText("10") end
			C.actionbar.buttonsize = newbuttonSize
			T.UpdateAllActionBars()
		end)

		local buttonSpacing = CreateFrame("Frame", nil, panel)
		buttonSpacing:EnableMouse(true)
		buttonSpacing:SetSize(panel:GetWidth(), 18)
		buttonSpacing:SetFrameLevel(panel:GetFrameLevel()+1)
		buttonSpacing:SetPoint("TOP", buttonSize, "BOTTOM", 0, 1)
		buttonSpacing:AddText("text", "Button Spacing", "LEFT", buttonSpacing, "LEFT", 4, 1)
		buttonSpacing.editbox = CreateEditBox(buttonSpacing, 30, 14)
		buttonSpacing.editbox:SetTextInsets(3, 0, 0, 1)
		buttonSpacing.editbox:SetPoint("RIGHT", buttonSpacing, "RIGHT", -4, 0)
		buttonSpacing.editbox:SetText(C.actionbar.buttonspacing)
		buttonSpacing.editbox:SetScript("OnEscapePressed", function(self)
			self:ClearFocus()
			self:SetText(C.actionbar.buttonspacing)
		end)
		buttonSpacing.editbox:SetScript("OnEnterPressed", function(self)
			self:ClearFocus()
			if not tonumber(self:GetText()) then self:SetText(C.actionbar.buttonspacing) return end

			local newButtonSpacing = tonumber(self:GetText())
			if newButtonSpacing > 10 then newButtonSpacing = 10; self:SetText("10") end
			if newButtonSpacing < -5 then newButtonSpacing = -5; self:SetText("-5") end
			C.actionbar.buttonspacing = newButtonSpacing
			T.UpdateAllActionBars()
		end)

		local hotKey = CreateFrame("Frame", nil, panel)
		hotKey:EnableMouse(true)
		hotKey:SetSize(panel:GetWidth(), 18)
		hotKey:SetFrameLevel(panel:GetFrameLevel()+1)
		hotKey:SetPoint("TOP", buttonSpacing, "BOTTOM", 0, 1)
		hotKey:AddText("text", "Show Hotkey", "LEFT", hotKey, "LEFT", 4, 1)
		hotKey.checkbox = CreateFrame("CheckButton", nil, hotKey, "UICheckButtonTemplate")
		T.SkinCheckBox(hotKey.checkbox)
		hotKey.checkbox:SetChecked(C.actionbar.hotkey)
		hotKey.checkbox:SetPoint("RIGHT", hotKey, "RIGHT", -4, 0)
		hotKey.checkbox:SetSize(16,16)
		hotKey.checkbox:HookScript("OnClick", function(self)
			C.actionbar.hotkey = (self:GetChecked() and true) or false
			T.UpdateAllActionBars()
		end)

		local verticalPet = CreateFrame("Frame", nil, panel)
		verticalPet:EnableMouse(true)
		verticalPet:SetSize(panel:GetWidth(), 18)
		verticalPet:SetFrameLevel(panel:GetFrameLevel()+1)
		verticalPet:SetPoint("TOP", hotKey, "BOTTOM", 0, 1)
		verticalPet:AddText("text", "Vertical Pet Bar", "LEFT", verticalPet, "LEFT", 4, 1)
		verticalPet.checkbox = CreateFrame("CheckButton", nil, verticalPet, "UICheckButtonTemplate")
		T.SkinCheckBox(verticalPet.checkbox)
		verticalPet.checkbox:SetChecked(C.actionbar.verticalpet)
		verticalPet.checkbox:SetPoint("RIGHT", verticalPet, "RIGHT", -4, 0)
		verticalPet.checkbox:SetSize(16,16)
		verticalPet.checkbox:HookScript("OnClick", function(self)
			C.actionbar.verticalpet = (self:GetChecked() and true) or false
			T.UpdateAllActionBars()
		end)

		-- local showGrid = CreateFrame("Frame", nil, panel)
		-- showGrid:EnableMouse(true)
		-- showGrid:SetSize(panel:GetWidth(), 16)
		-- showGrid:SetFrameLevel(panel:GetFrameLevel()+1)
		-- showGrid:SetPoint("TOP", hotKey, "BOTTOM", 0, 1)
		-- showGrid:AddText("text", "Show Grid", "LEFT", showGrid, "LEFT", 4, 0)
		-- showGrid.checkbox = CreateFrame("CheckButton", nil, showGrid, "UICheckButtonTemplate")
		-- T.SkinCheckBox(showGrid.checkbox)
		-- showGrid.checkbox:SetChecked(C.actionbar.showgrid)
		-- showGrid.checkbox:SetPoint("RIGHT", showGrid, "RIGHT", -4, 0)
		-- showGrid.checkbox:SetSize(16,16)
		-- showGrid.checkbox:HookScript("OnClick", function(self)
			-- C.actionbar.showgrid = (self:GetChecked() and true) or false
			-- T.UpdateAllActionBars()
		-- end)

		panels[1] = panel
	end

	do
		local panel = CreateFrame("Frame", nil, window)

		panel:SetTemplate()
		panel:SetWidth(window:GetWidth()-10)
		panel:SetHeight(20)

		panel:AddText("enable", "Bar", "LEFT", panel, "LEFT", 9, 0)
		panel:AddText("enable", "Enabled", "CENTER", panel, "CENTER", -32, 0)
		panel:AddText("enable", "Total", "CENTER", panel, "CENTER", 31, 0)
		panel:AddText("enable", "Per Row", "RIGHT", panel, "RIGHT", -8, 0)

		panels[2] = panel
	end

	for i=1, 5 do
		local panel = CreateFrame("Frame", nil, window)
		panel:SetTemplate()
		panel:SetWidth(window:GetWidth()-10)
		panel:SetHeight(20)

		panel:AddText("label", "Bar "..i, "LEFT", panel, "LEFT", 9, 0)

		panel.enable = CreateFrame("CheckButton", nil, panel, "UICheckButtonTemplate")
		T.SkinCheckBox(panel.enable)
		panel.enable:SetChecked(C.actionbar.barspecific[i].enabled)
		panel.enable:SetPoint("CENTER", panel, "CENTER", -33, 0)
		panel.enable:SetSize(16,16)
		panel.enable:HookScript("OnClick", function(self)
			C.actionbar.barspecific[i].enabled = (self:GetChecked() and true) or false
			T.UpdateAllActionBars()
		end)

		panel.numButtons = CreateEditBox(panel, 20, 14)
		panel.numButtons:SetTextInsets(3, 0, 0, 1)
		panel.numButtons:SetJustifyH("CENTER")
		panel.numButtons:SetPoint("CENTER", panel, "CENTER", 30, 0)
		panel.numButtons:SetText(C.actionbar.barspecific[i].numButtons)
		panel.numButtons:SetScript("OnEscapePressed", function(self)
			self:ClearFocus()
			self:SetText(C.actionbar.barspecific[i].numButtons)
		end)
		panel.numButtons:SetScript("OnEnterPressed", function(self)
			self:ClearFocus()
			if not tonumber(self:GetText()) then self:SetText(C.actionbar.barspecific[i].numButtons) return end

			local newNumButtons = tonumber(self:GetText())
			if newNumButtons > 12 then newNumButtons = 12; self:SetText("12") end
			if newNumButtons < 1 then newNumButtons = 1; self:SetText("1") end
			C.actionbar.barspecific[i].numButtons = newNumButtons
			T.UpdateAllActionBars()
		end)

		panel.perRow = CreateEditBox(panel, 20, 14)
		panel.perRow:SetTextInsets(3, 0, 0, 1)
		panel.perRow:SetJustifyH("CENTER")
		panel.perRow:SetPoint("CENTER", panel, "RIGHT", -27, 0)
		panel.perRow:SetText(C.actionbar.barspecific[i].perRow)
		panel.perRow:SetScript("OnEscapePressed", function(self)
			self:ClearFocus()
			self:SetText(C.actionbar.barspecific[i].perRow)
		end)
		panel.perRow:SetScript("OnEnterPressed", function(self)
			self:ClearFocus()
			if not tonumber(self:GetText()) then self:SetText(C.actionbar.barspecific[i].perRow) return end

			local newPerRow = tonumber(self:GetText())
			if newPerRow > 12 then newPerRow = 12; self:SetText("12") end
			if newPerRow < 1 then newPerRow = 1; self:SetText("1") end
			C.actionbar.barspecific[i].perRow = newPerRow
			T.UpdateAllActionBars()
		end)

		function panel.UpdateVisibility()
			if panel.enable:GetChecked() then
				panel.perRow:SetAlpha(1)
				panel.perRow:EnableMouse(true)
				panel.numButtons:SetAlpha(1)
				panel.numButtons:EnableMouse(true)
				panel.label:SetTextColor(1, 1, 1, 1)
			else
				panel.perRow:SetAlpha(0.2)
				panel.perRow:EnableMouse(false)
				panel.numButtons:SetAlpha(0.2)
				panel.numButtons:EnableMouse(false)
				panel.label:SetTextColor(1, 1, 1, 0.2)
			end
		end
		panel.UpdateVisibility()
		panel.enable:HookScript("OnClick", panel.UpdateVisibility)

		panels[#panels+1] = panel
	end

	local prevPanel
	for i,panel in pairs(panels) do
		if i == 1 then
			panel:SetPoint("TOP", window, "BOTTOM", 0, -6)
		else
			panel:SetPoint("TOP", prevPanel, "BOTTOM", 0, -4)
		end
		prevPanel = panel
	end

	window.backdrop:ClearAllPoints()
	window.backdrop:SetPoint("TOPLEFT", window, "BOTTOMLEFT", 0, -1)
	window.backdrop:SetPoint("TOPRIGHT", window, "BOTTOMRIGHT", 0, -1)
	window.backdrop:SetPoint("BOTTOM", prevPanel, "BOTTOM", 0, -5)

	window.Loaded = true
end

SLASH_ACTIONBARCONFIG1, SLASH_ACTIONBARCONFIG2, SLASH_ACTIONBARCONFIG3 = '/actionbar', '/abar', '/ab'
SlashCmdList["ACTIONBARCONFIG"] = function() T.LoadActionBarMenu() end

StaticPopupDialogs["ACTIONBARRESET"] = {
	text = "Are you sure you want to reset your actionbars?",
	button1 = "Yes",
	button2 = "No",
	OnAccept = function()
		C.actionbar = TukuiConfigBackup
		if SaftUISaved then SaftUISaved.ActionBars = nil end
		LoadVariables()
	end,
	timeout = 0,
	whileDead = true,
	hideOnEscape = true,
}

SLASH_ACTIONBARRESET1 = '/resetab'
SlashCmdList["ACTIONBARRESET"] = function() StaticPopup_Show("ACTIONBARRESET") end

local bars = {}
for i=1, 6 do
	local bar
	if i==6 then
		bar = _G["TukuiPetBar"]
	else
		bar = _G["TukuiBar"..i]
	end
	bar:SetMovable(true)
	bar:AddText("moveText", "", "CENTER", 0, 1)

	tinsert(T.AllowFrameMoving, bar)
end