Quantcast
--[[
##############################################################################
_____/\\\\\\\\\\\____/\\\________/\\\__/\\\________/\\\__/\\\\\\\\\\\_       #
 ___/\\\/////////\\\_\/\\\_______\/\\\_\/\\\_______\/\\\_\/////\\\///__      #
	__\//\\\______\///__\//\\\______/\\\__\/\\\_______\/\\\_____\/\\\_____     #
	 ___\////\\\__________\//\\\____/\\\___\/\\\_______\/\\\_____\/\\\_____    #
		______\////\\\________\//\\\__/\\\____\/\\\_______\/\\\_____\/\\\_____   #
		 _________\////\\\______\//\\\/\\\_____\/\\\_______\/\\\_____\/\\\_____  #
			__/\\\______\//\\\______\//\\\\\______\//\\\______/\\\______\/\\\_____ #
			 _\///\\\\\\\\\\\/________\//\\\________\///\\\\\\\\\/____/\\\\\\\\\\\_#
				___\///////////___________\///___________\/////////_____\///////////_#
##############################################################################
S U P E R - V I L L A I N - U I   By: Munglunch                              #
##############################################################################
##########################################################
LOCALIZED LUA FUNCTIONS
##########################################################
]]--
--[[ GLOBALS ]]--
local _G = _G;
local unpack    = _G.unpack;
local select    = _G.select;
local pairs     = _G.pairs;
local type      = _G.type;
local math      = _G.math;
local table 	= _G.table;
--[[ MATH METHODS ]]--
local min = math.min;
local tinsert, twipe, pairs, ipairs, unpack, pcall, select = tinsert, table.wipe, pairs, ipairs, unpack, pcall, select;
local format, gsub, strfind, strmatch, tonumber = format, gsub, strfind, strmatch, tonumber;
--[[
##########################################################
GET ADDON DATA
##########################################################
]]--
local SuperVillain, L = unpack(select(2, ...));
local MOD, DOCKLET_CACHE, TOOL_CACHE, SAFETY_CACHE = {}, {}, {}, {};
local PREV_TOOL, DEFAULT_DOCKLET;
--[[
##########################################################
LOCAL VARS
##########################################################
]]--
local AddOnButton = CreateFrame("Button", "SVUI_AddonDocklet", UIParent);
local SuperDockletMain = CreateFrame('Frame', 'SuperDockletMain', UIParent);
local SuperDockletExtra = CreateFrame('Frame', 'SuperDockletExtra', UIParent);
SuperDockletMain.FrameName = "None";
SuperDockletExtra.FrameName = "None";
local ICONFILE = [[Interface\AddOns\SVUI\assets\artwork\Icons\DOCK-BAG-MICRO]];
local TOOL_DATA = {
	[171] 	= {0,0.25,0,0.25}, 					-- PRO-ALCHEMY
    [794] 	= {0.25,0.5,0,0.25,"Survey"}, 		-- PRO-ARCHAELOGY
    [164] 	= {0.5,0.75,0,0.25}, 				-- PRO-BLACKSMITH
    [184] 	= {0.75,1,0,0.25,"Cooking Fire"}, 	-- PRO-COOKING
    [333] 	= {0,0.25,0.25,0.5,"Disenchant"}, 	-- PRO-ENCHANTING
    [202] 	= {0.25,0.5,0.25,0.5}, 				-- PRO-ENGINEERING
    [129] 	= {0.5,0.75,0.25,0.5}, 				-- PRO-FIRSTAID
    [773] 	= {0,0.25,0.5,0.75,"Milling"}, 		-- PRO-INSCRIPTION
    [755] 	= {0.25,0.5,0.5,0.75,"Prospecting"},-- PRO-JEWELCRAFTING
    [165] 	= {0.5,0.75,0.5,0.75}, 				-- PRO-LEATHERWORKING
    [186] 	= {0.75,1,0.5,0.75}, 				-- PRO-MINING
    [197] 	= {0.25,0.5,0.75,1}, 				-- PRO-TAILORING
}
--[[
##########################################################
PRE VARS/FUNCTIONS
##########################################################
]]--
local AlertActivate = function(self, child)
	local size = MOD.db.buttonSize or 22;
	self:Height(size)
	child:ClearAllPoints()
	child:SetAllPoints(self)
end

local AlertDeactivate = function(self)
	self:Height(1)
end

local leftalert = CreateFrame("Frame", "SuperDockAlertLeft", UIParent)
leftalert.Activate = AlertActivate
leftalert.Deactivate = AlertDeactivate

local rightalert = CreateFrame("Frame", "SuperDockAlertRight", UIParent)
rightalert.Activate = AlertActivate
rightalert.Deactivate = AlertDeactivate

local rightDockSizeHook = function(self,width,height)
	SuperDockWindowRight:Width(width)
	SuperDockWindowRight:Height(height)
	SuperDockWindowRight:SetPoint("BOTTOMLEFT", SuperDockAlertRight, "TOPLEFT", 0, 0)
end

local Dock_OnEnter = function(self, ...)
	if InCombatLockdown() then return end
	self:SetPanelColor("highlight")
	if MOD.SuperDockFaded then
		LeftSuperDock:Show()
		SuperVillain:SecureFadeIn(LeftSuperDock, 0.2, LeftSuperDock:GetAlpha(), 1)
		RightSuperDock:Show()
		SuperVillain:SecureFadeIn(RightSuperDock, 0.2, RightSuperDock:GetAlpha(), 1)
	end
	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
	GameTooltip:ClearLines()
	GameTooltip:AddLine(L["Toggle Docks"], 1, 1, 1)
	GameTooltip:Show()
end

local Dock_OnLeave = function(self, ...)
	if InCombatLockdown() then return end
	self:SetPanelColor("special")
	if MOD.SuperDockFaded then
		SuperVillain:SecureFadeOut(LeftSuperDock, 0.2, LeftSuperDock:GetAlpha(), 0, true)
		SuperVillain:SecureFadeOut(RightSuperDock, 0.2, RightSuperDock:GetAlpha(), 0, true)
	end
	GameTooltip:Hide()
end

local Dock_OnClick = function(self)
	GameTooltip:Hide()
	if MOD.SuperDockFaded then
		MOD.SuperDockFaded = nil;
		SuperVillain:SecureFadeIn(LeftSuperDock, 0.2, LeftSuperDock:GetAlpha(), 1)
		SuperVillain:SecureFadeIn(RightSuperDock, 0.2, RightSuperDock:GetAlpha(), 1)
	else
		MOD.SuperDockFaded = true;
		SuperVillain:SecureFadeOut(LeftSuperDock, 0.2, LeftSuperDock:GetAlpha(), 0, true)
		SuperVillain:SecureFadeOut(RightSuperDock, 0.2, RightSuperDock:GetAlpha(), 0, true)
	end
	SVUI_Cache["Dock"].SuperDockFaded = MOD.SuperDockFaded
end

local Docklet_OnShow = function(self)
	if(_G[SuperDockWindowRight.FrameName]) then
		if(InCombatLockdown() and (_G[SuperDockWindowRight.FrameName].IsProtected and _G[SuperDockWindowRight.FrameName]:IsProtected())) then return end
		_G[SuperDockWindowRight.FrameName]:Show()
	end
	if _G[SuperDockWindowRight.SecondName] then
		if(InCombatLockdown() and (_G[SuperDockWindowRight.SecondName].IsProtected and _G[SuperDockWindowRight.SecondName]:IsProtected())) then return end
		_G[SuperDockWindowRight.SecondName]:Show()
	end
end

local Docklet_OnHide = function(self)
	for i=1, #DOCKLET_CACHE do
		local f = DOCKLET_CACHE[i]
		if(not InCombatLockdown() or (InCombatLockdown() and (f.IsProtected and not f:IsProtected()))) then
			f.IsOpen = false;
			local b = _G[f.ToggleName]
			b:SetPanelColor("special")
			b.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
			if f.Hide then
				f:Hide()
			end
		end
	end
end

local Button_OnEnter = function(self, ...)
	self:SetPanelColor("highlight")
	self.icon:SetGradient(unpack(SuperVillain.Media.gradient.bizzaro))
	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
	GameTooltip:ClearLines()
	GameTooltip:AddLine(self.TText, 1, 1, 1)
	GameTooltip:Show()
end

local Button_OnLeave = function(self, ...)
	self:SetPanelColor("special")
	self.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
	GameTooltip:Hide()
end

local DockletFrame_OnShow = function(self)
	local frameName = self.FrameName;
	if (frameName and _G[frameName]) then
		_G[frameName]:Show()
	end
end

local Addon_OnEnter = function(self)
	if not self.IsOpen then
		self:SetPanelColor("highlight")
		self.icon:SetGradient(unpack(SuperVillain.Media.gradient.bizzaro))
	end
	GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
	GameTooltip:ClearLines()
	GameTooltip:AddLine(self.TText, 1, 1, 1)
	GameTooltip:Show()
end

local Addon_OnLeave = function(self)
	if not self.IsOpen then
		self:SetPanelColor("special")
		self.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
	end
	GameTooltip:Hide()
end

local Addon_OnClick = function(self)
	if SuperDockletMain.FrameName and _G[SuperDockletMain.FrameName] then
		if not _G[SuperDockletMain.FrameName]:IsShown() then
			Docklet_OnHide()
			if not InCombatLockdown() and not SuperDockletMain:IsShown()then
				SuperDockletMain:Show()
			end
			_G[SuperDockletMain.FrameName]:Show()
			self.IsOpen = true;
			self:SetPanelColor("green")
			self.icon:SetGradient(unpack(SuperVillain.Media.gradient.green))
		elseif not SuperDockletMain:IsShown()then
			if not InCombatLockdown() then SuperDockletMain:Show() end
			_G[SuperDockletMain.FrameName]:Show()
			self.IsOpen = true;
			self:SetPanelColor("green")
			self.icon:SetGradient(unpack(SuperVillain.Media.gradient.green))
		end
	else
		SuperDockletMain.FrameName = "None"
		if InCombatLockdown()then return end
		if SuperDockletMain:IsShown()then
			SuperDockletMain:Hide()
		else
			SuperDockletMain:Show()
		end
		self:SetPanelColor("special")
		self.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
	end
	if MOD.db.docklets.enableExtra and SuperDockletExtra.FrameName and _G[SuperDockletExtra.FrameName] then
		if not _G[SuperDockletExtra.FrameName]:IsShown() then
			if not InCombatLockdown() and not SuperDockletExtra:IsShown()then
				SuperDockletExtra:Show()
				SuperDockletMain:Show()
			end
			_G[SuperDockletExtra.FrameName]:Show()
			self.IsOpen = true;
			self:SetPanelColor("green")
			self.icon:SetGradient(unpack(SuperVillain.Media.gradient.green))
		elseif not SuperDockletExtra:IsShown() then
			if not InCombatLockdown() then
				SuperDockletExtra:Show()
				SuperDockletMain:Show()
			end
			_G[SuperDockletExtra.FrameName]:Show()
			self.IsOpen = true;
			self:SetPanelColor("green")
			self.icon:SetGradient(unpack(SuperVillain.Media.gradient.green))
		else
			if not InCombatLockdown() then
				SuperDockletExtra:Hide()
				SuperDockletMain:Hide()
			end
			self:SetPanelColor("special")
			self.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
		end
	else
		SuperDockletExtra.FrameName = "None"
	end
end

local function SetSuperDockStyle(dock)
	if dock.backdrop then return end
	local backdrop = CreateFrame("Frame", nil, dock)
	backdrop:SetAllPoints(dock)
	backdrop:SetFrameStrata("BACKGROUND")
	backdrop.bg = backdrop:CreateTexture(nil, "BORDER")
	backdrop.bg:FillInner(backdrop)
	backdrop.bg:SetTexture(1, 1, 1, 1)
	backdrop.bg:SetGradientAlpha("VERTICAL", 0, 0, 0, 0.8, 0, 0, 0, 0)
	backdrop.left = backdrop:CreateTexture(nil, "OVERLAY")
	backdrop.left:SetTexture(1, 1, 1, 1)
	backdrop.left:Point("TOPLEFT", 1, -1)
	backdrop.left:Point("BOTTOMLEFT", -1, 1)
	backdrop.left:Width(4)
	backdrop.left:SetGradientAlpha("VERTICAL", 0, 0, 0, 1, 0, 0, 0, 0)
	backdrop.right = backdrop:CreateTexture(nil, "OVERLAY")
	backdrop.right:SetTexture(1, 1, 1, 1)
	backdrop.right:Point("TOPRIGHT", -1, -1)
	backdrop.right:Point("BOTTOMRIGHT", -1, 1)
	backdrop.right:Width(4)
	backdrop.right:SetGradientAlpha("VERTICAL", 0, 0, 0, 1, 0, 0, 0, 0)
	backdrop.bottom = backdrop:CreateTexture(nil, "OVERLAY")
	backdrop.bottom:SetTexture(0, 0, 0, 1)
	backdrop.bottom:Point("BOTTOMLEFT", 1, 1)
	backdrop.bottom:Point("BOTTOMRIGHT", -1, 1)
	backdrop.bottom:Height(4)
	backdrop.top = backdrop:CreateTexture(nil, "OVERLAY")
	backdrop.top:SetTexture(0, 0, 0, 0)
	backdrop.top:Point("TOPLEFT", 1, -1)
	backdrop.top:Point("TOPRIGHT", -1, 1)
	backdrop.top:SetAlpha(0)
	backdrop.top:Height(1)
	return backdrop
end
--[[
##########################################################
CORE FUNCTIONS
##########################################################
]]--
function HideSuperDocks()
	Dock_OnClick(LeftDockToggleButton)
end
--[[
##########################################################
DOCKLET HELPERS
##########################################################
]]--
do
	local function GetDefaultWindow()
		local window = DEFAULT_DOCKLET
		if window and _G[window] and not _G[window]:IsShown() then
			SuperDockWindowRight.FrameName = window
			SuperDockWindowRight:Show()
		end
	end

	local Button_OnEnter = function(b)
		if not b.IsOpen then
			b:SetPanelColor("highlight")
	   	b.icon:SetGradient(unpack(SuperVillain.Media.gradient.bizzaro))
		end
		GameTooltip:SetOwner(b, "ANCHOR_TOPLEFT", 0, 4)
		GameTooltip:ClearLines()
		GameTooltip:AddLine(b.TText, 1, 1, 1)
		GameTooltip:Show()
	end

	local Button_OnLeave = function(b)
		if not b.IsOpen then
			b:SetPanelColor("special")
			b.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
		end
		GameTooltip:Hide()
	end

	local Button_OnClick = function(self)
		if InCombatLockdown() then return end
		local linkedFrame = self.FrameName
		if linkedFrame and _G[linkedFrame] then
			SuperDockWindowRight.FrameName = linkedFrame
			if not _G[linkedFrame]:IsShown() then
				if not SuperDockWindowRight:IsShown()then
					SuperDockWindowRight:Show()
				end
				Docklet_OnHide()
				_G[linkedFrame]:Show()
				self.IsOpen = true;
				self:SetPanelColor("green")
				self.icon:SetGradient(unpack(SuperVillain.Media.gradient.green))
			elseif not SuperDockWindowRight:IsShown()then
				SuperDockWindowRight:Show()
				_G[linkedFrame]:Show()
				self.IsOpen = true;
				self:SetPanelColor("green")
				self.icon:SetGradient(unpack(SuperVillain.Media.gradient.green))
			end
		else
			if SuperDockWindowRight:IsShown()then
				SuperDockWindowRight:Hide()
			else
				SuperDockWindowRight:Show()
			end
			self.IsOpen = false;
			self:SetPanelColor("special")
			self.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
			GetDefaultWindow()
		end
	end

	function MOD:CreateBasicToolButton(name,texture,onclick,frameName,isdefault)
		local fName = frameName or name;
		local dockIcon = texture or [[Interface\AddOns\SVUI\assets\artwork\Icons\DOCK-ADDON]];
		local clickFunction = (type(onclick)=="function") and onclick or Button_OnClick;
		local size = SuperDockToolBarRight.currentSize;
		local button = _G[fName .. "_ToolBarButton"] or CreateFrame("Button",("%s_ToolBarButton"):format(fName),SuperDockToolBarRight)
		SuperVillain.AddTool(button)
		button:Size(size,size)
		button:SetFramedButtonTemplate()
		button.icon = button:CreateTexture(nil,"OVERLAY")
		button.icon:FillInner(button,2,2)
		button.icon:SetTexture(dockIcon)
		button.TText = "Open " .. name;
		button.FrameName = fName;
		if isdefault == true then
			DEFAULT_DOCKLET = fName;
		end
		button.IsOpen = isdefault and true or false;
		button:SetScript("OnEnter",Button_OnEnter)
		button:SetScript("OnLeave",Button_OnLeave)
		button:SetScript("OnClick",clickFunction)
		_G[fName].ToggleName = fName.."_ToolBarButton";
		if(isdefault) then
			button:SetPanelColor("green")
			button.icon:SetGradient(unpack(SuperVillain.Media.gradient.green))
		else
			button.icon:SetGradient(unpack(SuperVillain.Media.gradient.light))
		end
	end
end
--[[
##########################################################
DOCKS
##########################################################
]]--
function MOD:CreateSuperBorders()
	local texture = [[Interface\AddOns\SVUI\assets\artwork\Template\BUTTON]];

	local TopPanel = CreateFrame("Frame", "SVUITopPanel", SuperVillain.UIParent)
	TopPanel:Point("TOPLEFT", SuperVillain.UIParent, "TOPLEFT", -1, 1)
	TopPanel:Point("TOPRIGHT", SuperVillain.UIParent, "TOPRIGHT", 1, 1)
	TopPanel:Height(14)
	TopPanel:SetBackdrop({
		bgFile = texture,
		edgeFile = [[Interface\BUTTONS\WHITE8X8]],
		tile = false,
		tileSize = 0,
		edgeSize = 1,
		insets = {left = 0, right = 0, top = 0, bottom = 0}
	})
	TopPanel:SetBackdropColor(unpack(SuperVillain.Media.color.special))
	TopPanel:SetBackdropBorderColor(0,0,0,1)
	TopPanel:SetFrameLevel(0)
	TopPanel:SetFrameStrata('BACKGROUND')
	self.TopPanel = TopPanel;
	self.TopPanel:SetScript("OnShow", function(this)
		this:SetFrameLevel(0)
		this:SetFrameStrata('BACKGROUND')
	end)
	self:TopPanelVisibility()

	local BottomPanel = CreateFrame("Frame", "SVUIBottomPanel", SuperVillain.UIParent)
	BottomPanel:Point("BOTTOMLEFT", SuperVillain.UIParent, "BOTTOMLEFT", -1, -1)
	BottomPanel:Point("BOTTOMRIGHT", SuperVillain.UIParent, "BOTTOMRIGHT", 1, -1)
	BottomPanel:Height(14)
	BottomPanel:SetBackdrop({
		bgFile = texture,
		edgeFile = [[Interface\BUTTONS\WHITE8X8]],
		tile = false,
		tileSize = 0,
		edgeSize = 1,
		insets = {left = 0, right = 0, top = 0, bottom = 0}
	})
	BottomPanel:SetBackdropColor(unpack(SuperVillain.Media.color.special))
	BottomPanel:SetBackdropBorderColor(0,0,0,1)
	BottomPanel:SetFrameLevel(0)
	BottomPanel:SetFrameStrata('BACKGROUND')
	self.BottomPanel = BottomPanel;
	self.BottomPanel:SetScript("OnShow", function(this)
		this:SetFrameLevel(0)
		this:SetFrameStrata('BACKGROUND')
	end)
	MOD:BottomPanelVisibility()
end

local function BorderColorUpdates()
	SVUITopPanel:SetBackdropColor(unpack(SuperVillain.Media.color.special))
	SVUITopPanel:SetBackdropBorderColor(0,0,0,1)
	SVUIBottomPanel:SetBackdropColor(unpack(SuperVillain.Media.color.special))
	SVUIBottomPanel:SetBackdropBorderColor(0,0,0,1)
end

SuperVillain.Registry:SetCallback(BorderColorUpdates)

function MOD:CreateDockPanels()
	self.SuperDockFaded = SVUI_Cache["Dock"].SuperDockFaded

	local leftWidth = self.db.dockLeftWidth or 350;
	local leftHeight = self.db.dockLeftHeight or 180;
	local rightWidth = self.db.dockRightWidth or 350;
	local rightHeight = self.db.dockRightHeight or 180;
	local buttonsize = self.db.buttonSize or 22;
	local spacing = self.db.buttonSpacing or 4;
	local statBarWidth = self.db.dockStatWidth
	local STATS = SuperVillain.SVStats;

	-- [[ CORNER BUTTON ]] --

	local leftbutton = CreateFrame("Button", "LeftSuperDockToggleButton", SuperVillain.UIParent)
	leftbutton:Point("BOTTOMLEFT", SuperVillain.UIParent, "BOTTOMLEFT", 1, 2)
	leftbutton:Size(buttonsize, buttonsize)
	leftbutton:SetFramedButtonTemplate()
	leftbutton.icon = leftbutton:CreateTexture(nil, "OVERLAY", nil, 0)
	leftbutton.icon:FillInner(leftbutton,2,2)
	leftbutton.icon:SetTexture("Interface\\AddOns\\SVUI\\assets\\artwork\\Icons\\SVUI-EMBLEM")
	leftbutton:RegisterForClicks("AnyUp")
	leftbutton:SetScript("OnEnter", Dock_OnEnter)
	leftbutton:SetScript("OnLeave", Dock_OnLeave)
	leftbutton:SetScript("OnClick", Dock_OnClick)

	-- [[ TOOLBARS AND OTHER NONSENSE ]] --

	local toolbarLeft = CreateFrame("Button", "SuperDockToolBarLeft", SuperVillain.UIParent)
	toolbarLeft:Point("LEFT", leftbutton, "RIGHT", spacing, 0)
	toolbarLeft:Width(1)
	toolbarLeft:Height(buttonsize)
	toolbarLeft.currentSize = buttonsize;

	local leftstation = CreateFrame("Frame", "SuperDockChatTabBar", SuperVillain.UIParent)
	leftstation:SetFrameStrata("BACKGROUND")
	leftstation:Size(leftWidth - buttonsize, buttonsize)
	leftstation:Point("LEFT", toolbarLeft, "RIGHT", spacing, 0)
	leftstation:SetFrameLevel(leftstation:GetFrameLevel() + 2)
	leftstation.currentSize = buttonsize;

	local leftdock = CreateFrame("Frame", "LeftSuperDock", SuperVillain.UIParent)
	leftdock:SetFrameStrata("BACKGROUND")
	leftdock:Point("BOTTOMLEFT", SuperVillain.UIParent, "BOTTOMLEFT", 1, buttonsize + 10)
	leftdock:Size(leftWidth, leftHeight)
	SuperVillain:SetSVMovable(leftdock, L["Left Dock"])

	leftalert:SetParent(leftdock)
	leftalert:SetFrameStrata("BACKGROUND")
	leftalert:Size(leftWidth, 1)
	leftalert:Point("BOTTOMRIGHT", leftdock, "BOTTOMRIGHT",0, 0)
	leftalert:SetFrameLevel(leftalert:GetFrameLevel() + 2)
	leftalert.Activate = AlertActivate
	leftalert.Deactivate = AlertDeactivate

	local leftwindow = CreateFrame("Frame", "SuperDockWindowLeft", leftdock)
	leftwindow:SetFrameStrata("BACKGROUND")
	leftwindow:Point("BOTTOMRIGHT", leftalert, "TOPRIGHT", 0, 0)
	leftwindow:Size(leftWidth, leftHeight)
	leftdock.backdrop = SetSuperDockStyle(leftwindow)

	-- [[ CORNER BUTTON ]] --

	local rightbutton = CreateFrame("Button", "RightSuperDockToggleButton", SuperVillain.UIParent)
	rightbutton:Point("BOTTOMRIGHT", SuperVillain.UIParent, "BOTTOMRIGHT", -1, 2)
	rightbutton:Size(buttonsize, buttonsize)
	rightbutton:SetFramedButtonTemplate()
	rightbutton.icon = rightbutton:CreateTexture(nil, "OVERLAY")
	rightbutton.icon:FillInner(rightbutton,2,2)
	rightbutton.icon:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Icons\DOCK-HENCHMAN]])
	rightbutton.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
	rightbutton.TText = "Call Henchman!"
	rightbutton:RegisterForClicks("AnyUp")
	rightbutton:SetScript("OnEnter", Button_OnEnter)
	rightbutton:SetScript("OnLeave", Button_OnLeave)
	rightbutton:SetScript("OnClick", function()SuperVillain:ToggleHenchman()end)

	-- [[ TOOLBARS AND OTHER NONSENSE ]] --

	local toolbarRight = CreateFrame("Button", "SuperDockToolBarRight", SuperVillain.UIParent)
	toolbarRight:Point("RIGHT", rightbutton, "LEFT", -spacing, 0)
	toolbarRight:Size(1, buttonsize)
	toolbarRight.currentSize = buttonsize;

	local macrobar = CreateFrame("Button", "SuperDockMacroBar", SuperVillain.UIParent)
	macrobar:Point("RIGHT", toolbarRight, "LEFT", -spacing, 0)
	macrobar:Size(1, buttonsize)
	macrobar.currentSize = buttonsize;

	local rightdock = CreateFrame("Frame", "RightSuperDock", SuperVillain.UIParent)
	rightdock:SetFrameStrata("BACKGROUND")
	rightdock:Point("BOTTOMRIGHT", SuperVillain.UIParent, "BOTTOMRIGHT", -1, buttonsize + 10)
	rightdock:Size(rightWidth, rightHeight)
	SuperVillain:SetSVMovable(rightdock, L["Right Dock"])

	rightalert:SetParent(rightdock)
	rightalert:SetFrameStrata("BACKGROUND")
	rightalert:Size(rightWidth, 1)
	rightalert:Point("BOTTOMLEFT", rightdock, "BOTTOMLEFT", 0, 0)
	rightalert:SetFrameLevel(rightalert:GetFrameLevel() + 2)
	rightalert.Activate = AlertActivate
	rightalert.Deactivate = AlertDeactivate

	local rightwindow = CreateFrame("Frame", "SuperDockWindowRight", rightdock)
	rightwindow:SetFrameStrata("BACKGROUND")
	rightwindow:Point("BOTTOMLEFT", rightalert, "TOPLEFT", 0, 0)
	rightwindow:Size(rightWidth, rightHeight)
	rightdock.backdrop = SetSuperDockStyle(rightwindow)

	if MOD.SuperDockFaded then LeftSuperDock:Hide()RightSuperDock:Hide() end

	local toolbarTop = CreateFrame("Button", "SuperDockToolBarTop", SuperVillain.UIParent)
	toolbarTop:Point("TOPLEFT", SuperVillain.UIParent, "TOPLEFT", 2, -4)
	toolbarTop:Size(1, buttonsize - 12)
	toolbarTop.openWidth = (leftWidth - 1) / 3;

	--TOP STAT HOLDERS
	local topanchor = CreateFrame("Frame", "SuperDockTopDataAnchor", SuperVillain.UIParent)
	topanchor:Size((leftWidth + rightWidth) - 2, buttonsize - 8)
	topanchor:Point("LEFT", toolbarTop, "RIGHT", spacing, 0)
	SuperVillain:AddToDisplayAudit(topanchor)

	local topleftdata = CreateFrame("Frame", "TopLeftDataPanel", topanchor)
	topleftdata:Size(leftWidth - 1, buttonsize - 8)
	topleftdata:Point("LEFT", topanchor, "LEFT", 0, 0)
	STATS:NewAnchor(topleftdata, 3, "ANCHOR_CURSOR", true)

	local toprightdata = CreateFrame("Frame", "TopRightDataPanel", topanchor)
	toprightdata:Size(leftWidth - 1, buttonsize - 8)
	toprightdata:Point("RIGHT", topanchor, "RIGHT", 0, 0)
	STATS:NewAnchor(toprightdata, 3, "ANCHOR_CURSOR", true)

	--BOTTOM STAT HOLDERS
	local bottomanchor = CreateFrame("Frame", "SuperDockBottomDataAnchor", SuperVillain.UIParent)
	bottomanchor:Size(statBarWidth - 2, buttonsize - 8)
	bottomanchor:Point("BOTTOM", SuperVillain.UIParent, "BOTTOM", 0, 2)
	SuperVillain:AddToDisplayAudit(bottomanchor)

	local bottomleftdata = CreateFrame("Frame", "BottomLeftDataPanel", bottomanchor)
	bottomleftdata:Size((statBarWidth * 0.5) - 1, buttonsize - 8)
	bottomleftdata:Point("LEFT", bottomanchor, "LEFT", 0, 0)
	STATS:NewAnchor(bottomleftdata, 3, "ANCHOR_CURSOR")

	local bottomrightdata = CreateFrame("Frame", "BottomRightDataPanel", bottomanchor)
	bottomrightdata:Size((statBarWidth * 0.5) - 1, buttonsize - 8)
	bottomrightdata:Point("RIGHT", bottomanchor, "RIGHT", 0, 0)
	STATS:NewAnchor(bottomrightdata, 3, "ANCHOR_CURSOR")
end

do
	local LastAddedMacro;
	local MacroCount = 0;

	local function HearthTime()
		local start,duration = GetItemCooldown(6948)
		local expires = duration - (GetTime() - start)
		if expires > 0.05 then
			local timeLeft = 0;
			local calc = 0;
			if expires < 4 then
				return format("|cffff0000%.1f|r", expires)
			elseif expires < 60 then
				return format("|cffffff00%d|r", floor(expires))
			elseif expires < 3600 then
				timeLeft = ceil(expires / 60);
				calc = floor((expires / 60) + .5);
				return format("|cffff9900%dm|r", timeLeft)
			elseif expires < 86400 then
				timeLeft = ceil(expires / 3600);
				calc = floor((expires / 3600) + .5);
				return format("|cff66ffff%dh|r", timeLeft)
			else
				timeLeft = ceil(expires / 86400);
				calc = floor((expires / 86400) + .5);
				return format("|cff6666ff%dd|r", timeLeft)
			end
		else
			return "|cff6666ffReady|r"
		end
	end

	local Hearth_OnEnter = function(self)
		if InCombatLockdown() then return end
		self.glow:Show()
		self:SetPanelColor("highlight")
		GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT", 0, 4)
		GameTooltip:ClearLines()
		GameTooltip:AddLine(L["Hearthstone"], 1, 1, 1)
		local remaining = HearthTime()
		GameTooltip:AddDoubleLine(L["Time Remaining"], remaining, 1, 1, 1, 0, 1, 1)
		if(self.ExtraSpell) then
			GameTooltip:AddLine(" ", 1, 1, 1)
			GameTooltip:AddDoubleLine(self.ExtraSpell, "[Right Click]", 1, 1, 1, 0, 1, 0)
		end
		GameTooltip:Show()
	end

	local Hearth_OnLeave = function(self)
		if InCombatLockdown() then return end
		self.glow:Hide()
		self:SetPanelColor("special")
		GameTooltip:Hide()
	end

	local function AddMacroTool(frame)
		local width;
		local height = SuperDockToolBarRight.currentSize;
		if not LastAddedMacro then
			frame:Point("RIGHT", SuperDockMacroBar, "RIGHT", -6, 0);
		else
			frame:Point("RIGHT", LastAddedMacro, "LEFT", -6, 0);
		end
		LastAddedMacro = frame;
		MacroCount = MacroCount + 1;
		width = MacroCount * (height + 6)
		SuperDockMacroBar:Size(width, height)
	end

	local function CreateMacroToolButton(proName, proID, itemID, size)
		if proName == "Mining" then proName = "Smelting" end
		local data = TOOL_DATA[proID]
		if(not data) then return end
		local button = CreateFrame("Button", ("%s_MacroBarButton"):format(itemID), SuperDockMacroBar, "SecureActionButtonTemplate")
		button:Size(size, size)
		AddMacroTool(button)
		button:SetFramedButtonTemplate()
		button.icon = button:CreateTexture(nil, "OVERLAY")
		button.icon:FillInner(button, 2, 2)
		button.icon:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Icons\PROFESSIONS]])
		button.icon:SetTexCoord(data[1], data[2], data[3], data[4])
		button.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
		button.skillName = proName;
		button.itemId = itemID;
		button.TText = "Open " .. proName;
		button:SetAttribute("type", "macro")
		if(data[5]) then
			local rightClickSpell = data[5]
			button:SetAttribute("macrotext", "/cast [mod:shift]" .. rightClickSpell .. "; " .. proName)
			button.TText2 = "Shift-Click to use " .. rightClickSpell
		else
			button:SetAttribute("macrotext","/cast " .. proName)
		end
		button:SetScript("OnEnter", Macro_OnEnter)
		button:SetScript("OnLeave", Macro_OnLeave)
	end

	function MOD:LoadToolBarProfessions()
		if(MOD.ToolBarLoaded) then return end
		if(InCombatLockdown()) then self:RegisterEvent("PLAYER_REGEN_ENABLED"); return end
		local size = SuperDockMacroBar.currentSize
		local hearth = CreateFrame("Button", "RightSuperDockHearthButton", SuperDockMacroBar, "SecureActionButtonTemplate")
		hearth:Size(size, size)
		AddMacroTool(hearth)
		hearth:SetFramedButtonTemplate()
		hearth.icon = hearth:CreateTexture(nil, "OVERLAY", nil, 0)
		hearth.icon:FillInner(hearth,2,2)
		hearth.icon:SetTexture("Interface\\AddOns\\SVUI\\assets\\artwork\\Icons\\DOCK-HEARTH")
		hearth.icon:SetTexCoord(0,0.5,0,1)
		hearth.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
		hearth.glow = hearth:CreateTexture(nil, "OVERLAY", nil, 2)
		hearth.glow:FillInner(hearth,2,2)
		hearth.glow:SetTexture("Interface\\AddOns\\SVUI\\assets\\artwork\\Icons\\DOCK-HEARTH")
		hearth.glow:SetTexCoord(0.5,1,0,1)
		hearth.glow:Hide()
		hearth:SetScript("OnEnter", Hearth_OnEnter)
		hearth:SetScript("OnLeave", Hearth_OnLeave)

		hearth:RegisterForClicks("AnyUp")
		hearth:SetAttribute("type", "item")
		hearth:SetAttribute("item", "Hearthstone")

		if(SuperVillain.class == "SHAMAN") then
			hearth:SetAttribute("type2", "spell")
			hearth:SetAttribute("spell", "Astral Recall")
			hearth.ExtraSpell = "Astral Recall"
		elseif(SuperVillain.class == "DEATHKNIGHT") then
			hearth:SetAttribute("type2","spell")
			hearth:SetAttribute("spell","Death Gate")
			hearth.ExtraSpell = "Death Gate"
		elseif(SuperVillain.class == "DRUID") then
			hearth:SetAttribute("type2", "spell")
			hearth:SetAttribute("spell", "Teleport: Moonglade")
			hearth.ExtraSpell = "Teleport: Moonglade"
		elseif(SuperVillain.class == "MONK") then
			hearth:SetAttribute("type2", "spell")
			hearth:SetAttribute("spell", "Zen Pilgrimage")
			hearth.ExtraSpell = "Zen Pilgrimage"
		end

		local proName, proID
		local prof1, prof2, archaeology, _, cooking, firstAid = GetProfessions()
		if(firstAid ~= nil) then
			proName, _, _, _, _, _, proID = GetProfessionInfo(firstAid)
			CreateMacroToolButton(proName, proID, firstAid, size)
		end
		if(archaeology ~= nil) then
			proName, _, _, _, _, _, proID = GetProfessionInfo(archaeology)
			CreateMacroToolButton(proName, proID, archaeology, size)
		end
		if(cooking ~= nil) then
			proName, _, _, _, _, _, proID = GetProfessionInfo(cooking)
			CreateMacroToolButton(proName, proID, cooking, size)
		end
		if(prof2 ~= nil) then
			proName, _, _, _, _, _, proID = GetProfessionInfo(prof2)
			if(proID ~= 182 and proID ~= 393) then
				CreateMacroToolButton(proName, proID, prof2, size)
			end
		end
		if(prof1 ~= nil) then
			proName, _, _, _, _, _, proID = GetProfessionInfo(prof1)
			if(proID ~= 182 and proID ~= 393) then
				CreateMacroToolButton(proName, proID, prof1, size)
			end
		end

		MOD.ToolBarLoaded = true
	end
end
--[[
##########################################################
EXTERNALLY ACCESSIBLE METHODS
##########################################################
]]--
SuperVillain.CycleDocklets = Docklet_OnHide
SuperVillain.CurrentlyDocked = {};
function SuperVillain:IsDockletReady(arg)
	local addon = arg;
	if arg == "DockletMain" or arg == "DockletExtra" then
		addon = MOD.db.docklets[arg]
	end
	if addon:find("Skada") then addon = "Skada" end
	if addon == nil or addon == "None" or not IsAddOnLoaded(addon) then
		return false
	end
	return true
end

function SuperVillain:RemoveTool()
	if not self or not self.listIndex then return end
	local name = self:GetName();
	if not SAFETY_CACHE[name] then return end
	SAFETY_CACHE[name] = false;
	local i = self.listIndex;
	tremove(TOOL_CACHE, i)
	local width;
	local height = SuperDockToolBarRight.currentSize;
	PREV_TOOL = TOOL_CACHE[#TOOL_CACHE]
	width = #TOOL_CACHE * (height + 6)
	SuperDockToolBarRight:Size(width, height)
	self:Hide()
end

function SuperVillain:AddTool()
	local name = self:GetName();
	if SAFETY_CACHE[name] then return end
	SAFETY_CACHE[name] = true;
	local width;
	local height = SuperDockToolBarRight.currentSize;
	if not PREV_TOOL or PREV_TOOL == self then
		self:Point("RIGHT", SuperDockToolBarRight, "RIGHT", -6, 0);
	else
		self:Point("RIGHT", PREV_TOOL, "LEFT", -6, 0);
	end
	tinsert(TOOL_CACHE, self)
 	self.listIndex = #TOOL_CACHE;
	PREV_TOOL = self;
	width = #TOOL_CACHE * (height + 6)
	SuperDockToolBarRight:Size(width, height)
	self:Show()
end

do
	local function UnregisterDocklet(name)
		local frame = _G[name];
		if not frame or not frame.listIndex then return end
		local i = frame.listIndex;
		tremove(DOCKLET_CACHE, i)
	end

	local function UnregisterDocklets()
		local frame, i;
		twipe(SuperVillain.CurrentlyDocked);
		if SuperVillain:IsDockletReady("DockletMain") then
			frame = MOD.db.docklets.MainWindow
			if frame ~= nil and frame ~= "None" and _G[frame] then
				UnregisterDocklet(frame)
				MOD.db.docklets.MainWindow = "None"
			end
		elseif AddOnButton.IsRegistered then
			SuperVillain.RemoveTool(AddOnButton)
			AddOnButton.TText = "";
			AddOnButton.IsOpen = false;
			AddOnButton.IsRegistered = false;
		end
		if SuperVillain:IsDockletReady("DockletExtra") then
			frame = MOD.db.docklets.ExtraWindow
			if frame ~= nil and frame ~= "None" and _G[frame] then
				UnregisterDocklet(frame)
				MOD.db.docklets.ExtraWindow = "None"
			end
		end
		SuperDockletMain.FrameName = "None"
		SuperDockletExtra.FrameName = "None"
	end

	function SuperVillain:ReloadDocklets(alert)
		UnregisterDocklets()
		if InCombatLockdown()then return end
		local width = MOD.db.dockRightWidth or 350;
		local height = (MOD.db.dockRightHeight or 180) - 22
		if SuperVillain:IsDockletReady('DockletMain') then
			if SuperVillain:IsDockletReady("DockletExtra") and MOD.db.docklets.enableExtra then
				width = width * 0.5;
			end
			SuperDockletMain:ClearAllPoints()
			SuperDockletMain:Size(width,height)
			SuperDockletMain:Point('BOTTOMLEFT',RightSuperDock,'BOTTOMLEFT',1,1)
			SuperDockletExtra:ClearAllPoints()
			SuperDockletExtra:Size(width,height)
			SuperDockletExtra:Point('BOTTOMLEFT',SuperDockletMain,'BOTTOMRIGHT',0,0)
		end
	end
end

function SuperVillain:RegisterDocklet(name, tooltip, texture, onclick, isdefault)
	local frame = _G[name];
	if frame and (frame.IsObjectType and frame:IsObjectType("Frame")) and (frame.IsProtected and not frame:IsProtected()) then
		frame:ClearAllPoints()
		frame:SetParent(SuperDockWindowRight)
		frame:FillInner(SuperDockWindowRight, 4, 4)
		frame.FrameName = name;
		tinsert(DOCKLET_CACHE, frame);
		frame.listIndex = #DOCKLET_CACHE;
		MOD:CreateBasicToolButton(tooltip, texture, onclick, name, isdefault)
	end
end

function SuperVillain:RegisterMainDocklet(name)
	local frame = _G[name];
	if (frame and (frame.IsObjectType and frame:IsObjectType("Frame")) and (frame.IsProtected and not frame:IsProtected())) then
		SuperDockletMain.FrameName = name;
		MOD.db.docklets.MainWindow = name;
		frame:ClearAllPoints()
		frame:SetParent(SuperDockletMain)
		frame:SetAllPoints(SuperDockletMain)
		frame.ToggleName = "SVUI_AddonDocklet";
		tinsert(DOCKLET_CACHE, frame);
		frame.listIndex = #DOCKLET_CACHE;
		self.AddTool(AddOnButton)
		AddOnButton.TText = "";
		AddOnButton.IsRegistered = true
		self.CurrentlyDocked[name] = true
		if not InCombatLockdown() and frame:IsShown() then frame:Hide() end
	end
end

function SuperVillain:RegisterExtraDocklet(name)
	local frame = _G[name];
	if (frame and (frame.IsObjectType and frame:IsObjectType("Frame")) and (frame.IsProtected and not frame:IsProtected())) then
		SuperDockletExtra.FrameName = name;
		MOD.db.docklets.ExtraWindow = name;
		frame:ClearAllPoints()
		frame:SetParent(SuperDockletExtra)
		frame:SetAllPoints(SuperDockletExtra)
		frame.ToggleName = "SVUI_AddonDocklet";
		tinsert(DOCKLET_CACHE, frame);
		frame.listIndex = #DOCKLET_CACHE;
		AddOnButton.TText = "";
		self.CurrentlyDocked[name] = true;
		if not InCombatLockdown() and frame:IsShown() then frame:Hide() end
	end
end
--[[
##########################################################
BUILD/UPDATE
##########################################################
]]--
function MOD:UpdateSuperDock()
	local leftWidth = self.db.dockLeftWidth or 350;
	local leftHeight = self.db.dockLeftHeight or 180;
	local rightWidth = self.db.dockRightWidth or 350;
	local rightHeight = self.db.dockRightHeight or 180;
	local buttonsize = self.db.buttonSize or 22;
	local spacing = self.db.buttonSpacing or 4;
	local statBarWidth = self.db.dockStatWidth

	_G["LeftSuperDock"]:Size(leftWidth, leftHeight)
	_G["SuperDockAlertLeft"]:Width(leftWidth)
	_G["SuperDockWindowLeft"]:Size(leftWidth, leftHeight)
	_G["RightSuperDock"]:Size(rightWidth, rightHeight)
	_G["SuperDockAlertRight"]:Width(rightWidth)
	_G["SuperDockWindowRight"]:Size(rightWidth, rightHeight)
	_G["SuperDockBottomDataAnchor"]:Size(statBarWidth - 2, buttonsize - 8)
	_G["BottomLeftDataPanel"]:Size((statBarWidth * 0.5) - 1, buttonsize - 8)
	_G["BottomRightDataPanel"]:Size((statBarWidth * 0.5) - 1, buttonsize - 8)

	self:BottomPanelVisibility();
	self:TopPanelVisibility();
	self:UpdateDockBackdrops();
	SuperVillain:ReloadDocklets()
end

function MOD:UpdateDockBackdrops()
	if self.db.rightDockBackdrop then
		RightSuperDock.backdrop:Show()
		RightSuperDock.backdrop:ClearAllPoints()
		RightSuperDock.backdrop:WrapOuter(RightSuperDock, 4, 4)
	else
		RightSuperDock.backdrop:Hide()
	end
	if self.db.leftDockBackdrop then
		LeftSuperDock.backdrop:Show()
		LeftSuperDock.backdrop:ClearAllPoints()
		LeftSuperDock.backdrop:WrapOuter(LeftSuperDock, 4, 4)
	else
		LeftSuperDock.backdrop:Hide()
	end
end

function MOD:BottomPanelVisibility()
	if self.db.bottomPanel then
		self.BottomPanel:Show()
	else
		self.BottomPanel:Hide()
	end
end

function MOD:TopPanelVisibility()
	if self.db.topPanel then
		self.TopPanel:Show()
	else
		self.TopPanel:Hide()
	end
end

function MOD:PLAYER_REGEN_ENABLED()
	self:UnregisterEvent('PLAYER_REGEN_ENABLED')
	self:LoadToolBarProfessions()
end

function MOD:ReLoad()
	self:UpdateSuperDock();
end

function MOD:Load()
	self:CreateSuperBorders()
	self:CreateDockPanels()

	local width = RightSuperDock:GetWidth();
	local height = RightSuperDock:GetHeight() - 22
	SuperDockWindowRight:Size(width, height)
	SuperDockWindowRight:SetPoint("BOTTOMLEFT", SuperDockAlertRight, "TOPLEFT", 0, 0)
	SuperDockWindowRight:SetScript('OnShow', Docklet_OnShow)
	SuperDockWindowRight:SetScript('OnHide', Docklet_OnHide)
	if not InCombatLockdown()then
		Docklet_OnHide()
	end
	hooksecurefunc(RightSuperDock, 'SetSize', rightDockSizeHook)
	self:UpdateDockBackdrops()

	SuperDockletMain:SetFrameLevel(SuperDockWindowRight:GetFrameLevel() + 50)
	SuperDockletExtra:SetFrameLevel(SuperDockWindowRight:GetFrameLevel() + 50)
	local size = SuperDockToolBarRight.currentSize;
	AddOnButton:SetParent(SuperDockToolBarRight)
	AddOnButton:Size(size,size)
	AddOnButton:SetFramedButtonTemplate()
	AddOnButton.icon = AddOnButton:CreateTexture(nil,"OVERLAY")
	AddOnButton.icon:FillInner()
	AddOnButton.icon:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Icons\DOCK-ADDON]])
	AddOnButton.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
	AddOnButton.TText="";
	AddOnButton.IsOpen=false;
	AddOnButton.IsRegistered=false;
	AddOnButton:SetScript("OnEnter",Addon_OnEnter)
	AddOnButton:SetScript("OnLeave",Addon_OnLeave)
	AddOnButton:SetScript("OnClick",Addon_OnClick)
	AddOnButton:Hide()

	SuperDockletMain:SetScript('OnShow', DockletFrame_OnShow)
	SuperDockletExtra:SetScript('OnShow', DockletFrame_OnShow)

	SuperVillain:ReloadDocklets(true)
	SuperVillain:ExecuteTimer(self.LoadToolBarProfessions, 5)
end

SuperVillain.Registry:NewPackage(MOD, "SVDock")