Quantcast
--[[
##############################################################################
_____/\\\\\\\\\\\____/\\\________/\\\__/\\\________/\\\__/\\\\\\\\\\\_       #
 ___/\\\/////////\\\_\/\\\_______\/\\\_\/\\\_______\/\\\_\/////\\\///__      #
  __\//\\\______\///__\//\\\______/\\\__\/\\\_______\/\\\_____\/\\\_____     #
   ___\////\\\__________\//\\\____/\\\___\/\\\_______\/\\\_____\/\\\_____    #
    ______\////\\\________\//\\\__/\\\____\/\\\_______\/\\\_____\/\\\_____   #
     _________\////\\\______\//\\\/\\\_____\/\\\_______\/\\\_____\/\\\_____  #
      __/\\\______\//\\\______\//\\\\\______\//\\\______/\\\______\/\\\_____ #
       _\///\\\\\\\\\\\/________\//\\\________\///\\\\\\\\\/____/\\\\\\\\\\\_#
        ___\///////////___________\///___________\/////////_____\///////////_#
##############################################################################
S U P E R - V I L L A I N - U I   By: Munglunch                              #
##############################################################################
--]]
local SVUI_ADDON_NAME, SV = ...
local SVLib = LibStub("LibSuperVillain-1.0")
local L = SVLib:Lang()
local MOD = {}
--[[
##########################################################
LOCAL VARS
##########################################################
]]--
local HenchmenFrame = CreateFrame("Frame", "HenchmenFrame", UIParent);
local STANDARD_TEXT_FONT = _G.STANDARD_TEXT_FONT
local OPTION_LEFT = [[Interface\Addons\SVUI\assets\artwork\Doodads\HENCHMEN-OPTION-LEFT]];
local OPTION_RIGHT = [[Interface\Addons\SVUI\assets\artwork\Doodads\HENCHMEN-OPTION-RIGHT]];
local OPTION_SUB = [[Interface\Addons\SVUI\assets\artwork\Doodads\HENCHMEN-SUBOPTION]];
local SWITCH = [[Interface\Addons\SVUI\assets\artwork\Doodads\HENCHMEN-MINION-SWITCH]];
local BUBBLE = [[Interface\Addons\SVUI\assets\artwork\Doodads\HENCHMEN-SPEECH]];
local SUBOPTIONS = {};
local HENCHMEN_DATA = {
	{
		{0,"Adjust My Colors!","Color Themes","Click here to change your current color theme to one of the default sets."},
		{20,"Adjust My Frames!","Frame Styles","Click here to change your current frame styles to one of the default sets."},
		{40,"Adjust My Bars!","Bar Layouts","Click here to change your current actionbar layout to one of the default sets."},
		{-40,"Adjust My Auras!","Aura Layouts","Click here to change your buff/debuff layout to one of the default sets."},
		{-20,"Show Me All Options!","Config Screen","Click here to access the entire SVUI configuration."}
	},
	{
		{0,"Accept Quests","Your minions will automatically accept quests for you", "autoquestaccept"},
		{20,"Complete Quests","Your minions will automatically complete quests for you", "autoquestcomplete"},
		{40,"Select Rewards","Your minions will automatically select quest rewards for you", "autoquestreward"},
		{-40,"Greed Roll","Your minions will automatically roll greed (or disenchant if available) on green quality items for you", "autoRoll"},
		{-20,"Watch Factions","Your minions will automatically change your tracked reputation to the last faction you were awarded points for", "autorepchange"}
	},
	{
		{49084,67,113,69,70,73,75}, --Rascal Bot
		{29404,67,113,69,70,73,75}, --Macabre Marionette
		{45613,0,5,10,69,10,69}, 	--Bishibosh
		{34770,70,82,70,82,70,82}, 	--Gilgoblin
		{45562,69,69,69,69,69,69}, 	--Burgle
		{37339,60,60,60,60,60,60}, 	--Augh
		{2323,67,113,69,70,73,75}, 	--Defias Henchman
	}
}

local takingOnlyCash,deletedelay,mailElapsed,childCount=false,0.5,0,-1;
local GetAllMail, GetAllMailCash, OpenMailItem, WaitForMail, StopOpeningMail, FancifyMoneys, lastopened, needsToWait, total_cash, baseInboxFrame_OnClick;
local incpat 	  = gsub(gsub(FACTION_STANDING_INCREASED, "(%%s)", "(.+)"), "(%%d)", "(.+)");
local changedpat  = gsub(gsub(FACTION_STANDING_CHANGED, "(%%s)", "(.+)"), "(%%d)", "(.+)");
local decpat	  = gsub(gsub(FACTION_STANDING_DECREASED, "(%%s)", "(.+)"), "(%%d)", "(.+)");
local standing    = ('%s:'):format(STANDING);
local reputation  = ('%s:'):format(REPUTATION);
local hideStatic = false;
local AutomatedEvents = {
	"CHAT_MSG_COMBAT_FACTION_CHANGE",
	"MERCHANT_SHOW",
	"QUEST_COMPLETE",
	"QUEST_GREETING",
	"GOSSIP_SHOW",
	"QUEST_DETAIL",
	"QUEST_ACCEPT_CONFIRM",
	"QUEST_PROGRESS"
}
--[[
##########################################################
SCRIPT HANDLERS
##########################################################
]]--
local ColorFunc = function(self) SV.Setup.SetColorTheme(self.value, true); SV:ToggleHenchman() end
local UnitFunc = function(self) SV.Setup.SetUnitframeLayout(self.value, true); SV:ToggleHenchman() end
local BarFunc = function(self) SV.Setup.SetupBarLayout(self.value, true); SV:ToggleHenchman() end
local AuraFunc = function(self) SV.Setup.SetupAuralayout(self.value, true); SV:ToggleHenchman() end
local ConfigFunc = function() SV:ToggleConfig(); SV:ToggleHenchman() end
local speechTimer;

local Tooltip_Show = function(self)
	GameTooltip:SetOwner(HenchmenFrame,"ANCHOR_TOP",0,12)
	GameTooltip:ClearLines()
	GameTooltip:AddLine(self.ttText)
	GameTooltip:Show()
end

local Tooltip_Hide = function(self)
	GameTooltip:Hide()
end

local Minion_OnMouseUp = function(self)
	if(not self.setting()) then
		self.indicator:SetTexCoord(0,1,0.5,1)
		self.setting(true)
	else
		self.indicator:SetTexCoord(0,1,0,0.5)
		self.setting(false)
	end
end

local Option_OnMouseUp = function(self)
	if(type(self.callback) == "function") then
		self:callback(param)
	end
end

local SubOption_OnMouseUp = function(self)
	if not InCombatLockdown()then
		local name=self:GetName()
		for _,frame in pairs(SUBOPTIONS) do
			frame.anim:Finish()
			frame:Hide()
		end
		if not self.isopen then
			for i=1, self.suboptions do
				_G[name.."Sub"..i]:Show()
				_G[name.."Sub"..i].anim:Play()
				_G[name.."Sub"..i].anim:Finish()
			end
			self.isopen=true
		else
			self.isopen=false
		end
	end
end

local Speech_OnTimeout = function()
	HenchmenSpeechBubble:Hide()
	speechTimer = nil
end

local Speech_OnEnter = function(self)
	SV:SecureFadeOut(self, 0.5, 1, 0)
	local newTimer = SV.Timers:ExecuteTimer(Speech_OnTimeout, 0.5, speechTimer)
	speechTimer = newTimer
	self:SetScript("OnEnter", nil)
end

local Speech_OnShow = function(self)
	if self.message then
		self.txt:SetText(self.message)
		local newTimer = SV.Timers:ExecuteTimer(Speech_OnTimeout, 5, speechTimer)
		speechTimer = newTimer
		self.message = nil
		self:SetScript("OnEnter", Speech_OnEnter)
	else
		self:Hide()
	end
end
--[[
##########################################################
LOCAL FUNCTIONS
##########################################################
]]--
local function UpdateHenchmanModel(hide)
	if(not hide and not HenchmenFrameModel:IsShown()) then
		local models = HENCHMEN_DATA[3]
		local mod = random(1,#models)
		local emod = random(2,7)
		local id = models[mod][1]
		local emote = models[mod][emod]
		HenchmenFrameModel:ClearModel()
		HenchmenFrameModel:SetDisplayInfo(id)
		HenchmenFrameModel:SetAnimation(emote)
		HenchmenFrameModel:Show()
	else
		HenchmenFrameModel:Hide()
	end
end

function GetAllMail()
	if GetInboxNumItems()==0 then return end
	SVUI_GetMailButton:SetScript("OnClick",nil)
	SVUI_GetGoldButton:SetScript("OnClick",nil)
	baseInboxFrame_OnClick=InboxFrame_OnClick;
	InboxFrame_OnClick = SV.fubar
	SVUI_GetMailButton:RegisterEvent("UI_ERROR_MESSAGE")
	OpenMailItem(GetInboxNumItems())
end

function GetAllMailCash()
	takingOnlyCash = true;
	GetAllMail()
end

function OpenMailItem(mail)
	if not InboxFrame:IsVisible()then return StopOpeningMail("Mailbox Minion Needs a Mailbox!")end
	if mail==0 then
		MiniMapMailFrame:Hide()
		return StopOpeningMail("Finished getting your mail!")
	end
	local _, _, _, _, money, CODAmount, _, itemCount = GetInboxHeaderInfo(mail)
	if not takingOnlyCash then
		if money > 0 or itemCount and itemCount > 0 and CODAmount <= 0 then
			AutoLootMailItem(mail)
			needsToWait=true
		end
	elseif money > 0 then
		TakeInboxMoney(mail)
		needsToWait=true;
		if total_cash then total_cash = total_cash - money end
	end
	local numMail = GetInboxNumItems()
	if itemCount and itemCount > 0 or numMail > 1 and mail <= numMail then
		lastopened = mail;
		SVUI_GetMailButton:SetScript("OnUpdate",WaitForMail)
	else
		MiniMapMailFrame:Hide()
		StopOpeningMail()
	end
end

function WaitForMail(_, elapsed)
	mailElapsed = mailElapsed + elapsed;
	if not needsToWait or mailElapsed > deletedelay then
		if not InboxFrame:IsVisible() then return StopOpeningMail("The Mailbox Minion Needs a Mailbox!") end
		mailElapsed = 0;
		needsToWait = false;
		SVUI_GetMailButton:SetScript("OnUpdate", nil)
		local _, _, _, _, money, CODAmount, _, itemCount = GetInboxHeaderInfo(lastopened)
		if money > 0 or not takingOnlyCash and CODAmount <= 0 and itemCount and itemCount > 0 then
			OpenMailItem(lastopened)
		else
			OpenMailItem(lastopened - 1)
		end
	end
end

function StopOpeningMail(msg, ...)
	SVUI_GetMailButton:SetScript("OnUpdate", nil)
	SVUI_GetMailButton:SetScript("OnClick", GetAllMail)
	SVUI_GetGoldButton:SetScript("OnClick", GetAllMailCash)
	if baseInboxFrame_OnClick then
		InboxFrame_OnClick = baseInboxFrame_OnClick
	end
	SVUI_GetMailButton:UnregisterEvent("UI_ERROR_MESSAGE")
	takingOnlyCash = false;
	total_cash = nil;
	needsToWait = false;
	if msg then
		SV:HenchmanSays(msg)
	end
end

function FancifyMoneys(cash)
	if cash > 10000 then
		return("%d|cffffd700g|r%d|cffc7c7cfs|r%d|cffeda55fc|r"):format((cash / 10000), ((cash / 100) % 100), (cash % 100))
	elseif cash > 100 then
		return("%d|cffc7c7cfs|r%d|cffeda55fc|r"):format(((cash / 100) % 100), (cash % 100))
	else
		return("%d|cffeda55fc|r"):format(cash%100)
	end
end
--[[
##########################################################
CORE FUNCTIONS
##########################################################
]]--
local function CreateMinionOptions(i)
	local lastIndex = i - 1;
	local options = HENCHMEN_DATA[2][i]
	local offsetX = options[1] * -1
	local option = CreateFrame("Frame", "MinionOptionButton"..i, HenchmenFrame)
	option:SetSize(148,50)

	if i==1 then
		option:Point("TOPRIGHT",HenchmenFrame,"TOPLEFT",-32,-32)
	else
		option:Point("TOP",_G["MinionOptionButton"..lastIndex],"BOTTOM",offsetX,-32)
	end

	local setting = options[4];
	local dbSet = MOD.db[setting];
	option.setting = function(toggle)
		if(toggle == nil) then
			return MOD.db[setting]
		else
			MOD.db[setting] = toggle;
		end
	end
	SV.Animate:Slide(option,-500,-500)
	option:SetFrameStrata("DIALOG")
	option:SetFrameLevel(24)
	option:EnableMouse(true)
	option.bg = option:CreateTexture(nil,"BORDER")
	option.bg:SetPoint("TOPLEFT",option,"TOPLEFT",-4,4)
	option.bg:SetPoint("BOTTOMRIGHT",option,"BOTTOMRIGHT",4,-24)
	option.bg:SetTexture(OPTION_LEFT)
	option.bg:SetVertexColor(1,1,1,0.6)
	option.txt = option:CreateFontString(nil,"DIALOG")
	option.txt:FillInner(option)
	option.txt:SetFont(SV.Media.font.dialog,12,"NONE")
	option.txt:SetJustifyH("CENTER")
	option.txt:SetJustifyV("MIDDLE")
	option.txt:SetText(options[2])
	option.txt:SetTextColor(0,0,0)
	option.txthigh = option:CreateFontString(nil,"HIGHLIGHT")
	option.txthigh:FillInner(option)
	option.txthigh:SetFont(SV.Media.font.dialog,12,"OUTLINE")
	option.txthigh:SetJustifyH("CENTER")
	option.txthigh:SetJustifyV("MIDDLE")
	option.txthigh:SetText(options[2])
	option.txthigh:SetTextColor(0,1,1)
	option.ttText = options[3]
	option.indicator = option:CreateTexture(nil,"OVERLAY")
	option.indicator:SetSize(100,32)
	option.indicator:Point("RIGHT", option , "LEFT", -5, 0)
	option.indicator:SetTexture(SWITCH)
	if(not dbSet) then
		option.indicator:SetTexCoord(0,1,0,0.5)
	else
		option.indicator:SetTexCoord(0,1,0.5,1)
	end

	option:SetScript("OnEnter", Tooltip_Show)
	option:SetScript("OnLeave", Tooltip_Hide)
	option:SetScript("OnMouseUp", Minion_OnMouseUp)
end

local function CreateHenchmenOptions(i)
	local lastIndex = i - 1;
	local options = HENCHMEN_DATA[1][i]
	local offsetX = options[1]
	local option = CreateFrame("Frame", "HenchmenOptionButton"..i, HenchmenFrame)
	option:SetSize(148,50)
	if i==1 then
		option:Point("TOPLEFT",HenchmenFrame,"TOPRIGHT",32,-32)
	else
		option:Point("TOP",_G["HenchmenOptionButton"..lastIndex],"BOTTOM",offsetX,-32)
	end
	SV.Animate:Slide(option,500,-500)
	option:SetFrameStrata("DIALOG")
	option:SetFrameLevel(24)
	option:EnableMouse(true)
	option.bg = option:CreateTexture(nil,"BORDER")
	option.bg:SetPoint("TOPLEFT",option,"TOPLEFT",-4,4)
	option.bg:SetPoint("BOTTOMRIGHT",option,"BOTTOMRIGHT",4,-24)
	option.bg:SetTexture(OPTION_RIGHT)
	option.bg:SetVertexColor(1,1,1,0.6)
	option.txt = option:CreateFontString(nil,"DIALOG")
	option.txt:FillInner(option)
	option.txt:SetFont(SV.Media.font.dialog,12,"NONE")
	option.txt:SetJustifyH("CENTER")
	option.txt:SetJustifyV("MIDDLE")
	option.txt:SetText(options[2])
	option.txt:SetTextColor(0,0,0)
	option.txthigh = option:CreateFontString(nil,"HIGHLIGHT")
	option.txthigh:FillInner(option)
	option.txthigh:SetFont(SV.Media.font.dialog,12,"OUTLINE")
	option.txthigh:SetJustifyH("CENTER")
	option.txthigh:SetJustifyV("MIDDLE")
	option.txthigh:SetText(options[2])
	option.txthigh:SetTextColor(0,1,1)
	option.ttText = options[3]
	option:SetScript("OnEnter", Tooltip_Show)
	option:SetScript("OnLeave", Tooltip_Hide)
end

local function CreateHenchmenSubOptions(buttonIndex,optionIndex)
	local parent = _G["HenchmenOptionButton"..buttonIndex]
	local name = format("HenchmenOptionButton%dSub%d", buttonIndex, optionIndex);
	local calc = 90 * optionIndex;
	local yOffset = 180 - calc;
	local frame = CreateFrame("Frame",name,HenchmenFrame)
	frame:SetSize(122,50)
	frame:Point("BOTTOMLEFT", parent, "TOPRIGHT", 75, yOffset)
	frame:SetFrameStrata("DIALOG")
	frame:SetFrameLevel(24)
	frame:EnableMouse(true)
	frame.bg = frame:CreateTexture(nil,"BORDER")
	frame.bg:SetPoint("TOPLEFT",frame,"TOPLEFT",-12,12)
	frame.bg:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",12,-18)
	frame.bg:SetTexture(OPTION_SUB)
	frame.bg:SetVertexColor(1,1,1,0.6)
	frame.txt = frame:CreateFontString(nil,"DIALOG")
	frame.txt:FillInner(frame)
	frame.txt:SetFont(STANDARD_TEXT_FONT,12,"OUTLINE")
	frame.txt:SetJustifyH("CENTER")
	frame.txt:SetJustifyV("MIDDLE")
	frame.txt:SetTextColor(1,1,1)
	frame.txthigh = frame:CreateFontString(nil,"HIGHLIGHT")
	frame.txthigh:FillInner(frame)
	frame.txthigh:SetFontTemplate(false,12,"OUTLINE","CENTER","MIDDLE")
	frame.txthigh:SetTextColor(1,1,0)
	SV.Animate:Slide(frame,500,0)

	tinsert(SUBOPTIONS,frame)
end

local function CreateHenchmenFrame()
	HenchmenFrame:SetParent(SV.UIParent)
	HenchmenFrame:SetPoint("CENTER",UIParent,"CENTER",0,0)
	HenchmenFrame:SetWidth(500)
	HenchmenFrame:SetHeight(500)
	HenchmenFrame:SetFrameStrata("DIALOG")
	HenchmenFrame:SetFrameLevel(24)
	SV.Animate:Slide(HenchmenFrame,0,-500)

	local model = CreateFrame("PlayerModel", "HenchmenFrameModel", HenchmenFrame)
	model:SetPoint("TOPLEFT",HenchmenFrame,25,-25)
	model:SetPoint("BOTTOMRIGHT",HenchmenFrame,-25,25)
	model:SetFrameStrata("DIALOG")
	model:SetPosition(0,0,0)
	model:Hide()

	HenchmenFrame:Hide()

	local HenchmenCalloutFrame = CreateFrame("Frame","HenchmenCalloutFrame",SV.UIParent)
	HenchmenCalloutFrame:SetPoint("BOTTOM",UIParent,"BOTTOM",100,150)
	HenchmenCalloutFrame:SetWidth(256)
	HenchmenCalloutFrame:SetHeight(128)
	HenchmenCalloutFrame:SetFrameStrata("DIALOG")
	HenchmenCalloutFrame:SetFrameLevel(24)
	SV.Animate:Slide(HenchmenCalloutFrame,-356,-278)
	HenchmenCalloutFramePic = HenchmenCalloutFrame:CreateTexture("HenchmenCalloutFramePic","ARTWORK")
	HenchmenCalloutFramePic:SetTexture([[Interface\Addons\SVUI\assets\artwork\Doodads\HENCHMEN-CALLOUT]])
	HenchmenCalloutFramePic:SetAllPoints(HenchmenCalloutFrame)
	HenchmenCalloutFrame:Hide()

	local HenchmenFrameBG = CreateFrame("Frame","HenchmenFrameBG",SV.UIParent)
	HenchmenFrameBG:SetAllPoints(WorldFrame)
	HenchmenFrameBG:SetBackdrop({bgFile = [[Interface\BUTTONS\WHITE8X8]]})
	HenchmenFrameBG:SetBackdropColor(0,0,0,0.9)
	HenchmenFrameBG:SetFrameStrata("DIALOG")
	HenchmenFrameBG:SetFrameLevel(22)
	HenchmenFrameBG:Hide()
	HenchmenFrameBG:SetScript("OnMouseUp", SV.ToggleHenchman)

	for i=1, 5 do
		CreateHenchmenOptions(i)
		CreateMinionOptions(i)
	end
	------------------------------------------------------------------------
	CreateHenchmenSubOptions(1,1)
	HenchmenOptionButton1Sub1.txt:SetText("KABOOM!")
	HenchmenOptionButton1Sub1.txthigh:SetText("KABOOM!")
	HenchmenOptionButton1Sub1.value = "kaboom"
	HenchmenOptionButton1Sub1.callback = ColorFunc
	HenchmenOptionButton1Sub1:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(1,2)
	HenchmenOptionButton1Sub2.txt:SetText("Darkness")
	HenchmenOptionButton1Sub2.txthigh:SetText("Darkness")
	HenchmenOptionButton1Sub2.value = "dark"
	HenchmenOptionButton1Sub2.callback = ColorFunc
	HenchmenOptionButton1Sub2:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(1,3)
	HenchmenOptionButton1Sub3.txt:SetText("Classy")
	HenchmenOptionButton1Sub3.txthigh:SetText("Classy")
	HenchmenOptionButton1Sub3.value = "classy"
	HenchmenOptionButton1Sub3.callback = ColorFunc
	HenchmenOptionButton1Sub3:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(1,4)
	HenchmenOptionButton1Sub4.txt:SetText("Vintage")
	HenchmenOptionButton1Sub4.txthigh:SetText("Vintage")
	HenchmenOptionButton1Sub4.value = "default"
	HenchmenOptionButton1Sub4.callback = ColorFunc
	HenchmenOptionButton1Sub4:SetScript("OnMouseUp", Option_OnMouseUp)

	HenchmenOptionButton1.suboptions = 4;
	HenchmenOptionButton1.isopen = false;
	HenchmenOptionButton1:SetScript("OnMouseUp",SubOption_OnMouseUp)
	------------------------------------------------------------------------
	CreateHenchmenSubOptions(2,1)
	HenchmenOptionButton2Sub1.txt:SetText("SUPER: Elaborate Frames")
	HenchmenOptionButton2Sub1.txthigh:SetText("SUPER: Elaborate Frames")
	HenchmenOptionButton2Sub1.value = "super"
	HenchmenOptionButton2Sub1.callback = UnitFunc
	HenchmenOptionButton2Sub1:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(2,2)
	HenchmenOptionButton2Sub2.txt:SetText("Simple: Basic Frames")
	HenchmenOptionButton2Sub2.txthigh:SetText("Simple: Basic Frames")
	HenchmenOptionButton2Sub2.value = "simple"
	HenchmenOptionButton2Sub2.callback = UnitFunc
	HenchmenOptionButton2Sub2:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(2,3)
	HenchmenOptionButton2Sub3.txt:SetText("Compact: Minimal Frames")
	HenchmenOptionButton2Sub3.txthigh:SetText("Compact: Minimal Frames")
	HenchmenOptionButton2Sub3.value = "compact"
	HenchmenOptionButton2Sub3.callback = UnitFunc
	HenchmenOptionButton2Sub3:SetScript("OnMouseUp", Option_OnMouseUp)

	HenchmenOptionButton2.suboptions = 3;
	HenchmenOptionButton2.isopen = false;
	HenchmenOptionButton2:SetScript("OnMouseUp",SubOption_OnMouseUp)
	------------------------------------------------------------------------
	CreateHenchmenSubOptions(3,1)
	HenchmenOptionButton3Sub1.txt:SetText("One Row: Small Buttons")
	HenchmenOptionButton3Sub1.txthigh:SetText("One Row: Small Buttons")
	HenchmenOptionButton3Sub1.value = "default"
	HenchmenOptionButton3Sub1.callback = BarFunc
	HenchmenOptionButton3Sub1:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(3,2)
	HenchmenOptionButton3Sub2.txt:SetText("Two Rows: Small Buttons")
	HenchmenOptionButton3Sub2.txthigh:SetText("Two Rows: Small Buttons")
	HenchmenOptionButton3Sub2.value = "twosmall"
	HenchmenOptionButton3Sub2.callback = BarFunc
	HenchmenOptionButton3Sub2:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(3,3)
	HenchmenOptionButton3Sub3.txt:SetText("One Row: Large Buttons")
	HenchmenOptionButton3Sub3.txthigh:SetText("One Row: Large Buttons")
	HenchmenOptionButton3Sub3.value = "onebig"
	HenchmenOptionButton3Sub3.callback = BarFunc
	HenchmenOptionButton3Sub3:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(3,4)
	HenchmenOptionButton3Sub4.txt:SetText("Two Rows: Large Buttons")
	HenchmenOptionButton3Sub4.txthigh:SetText("Two Rows: Large Buttons")
	HenchmenOptionButton3Sub4.value = "twobig"
	HenchmenOptionButton3Sub4.callback = BarFunc
	HenchmenOptionButton3Sub4:SetScript("OnMouseUp", Option_OnMouseUp)

	HenchmenOptionButton3.suboptions = 4;
	HenchmenOptionButton3.isopen = false;
	HenchmenOptionButton3:SetScript("OnMouseUp",SubOption_OnMouseUp)
	------------------------------------------------------------------------
	CreateHenchmenSubOptions(4,1)
	HenchmenOptionButton4Sub1.txt:SetText("Icons Only")
	HenchmenOptionButton4Sub1.txthigh:SetText("Icons Only")
	HenchmenOptionButton4Sub1.value = "icons"
	HenchmenOptionButton4Sub1.callback = AuraFunc
	HenchmenOptionButton4Sub1:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(4,2)
	HenchmenOptionButton4Sub2.txt:SetText("Bars Only")
	HenchmenOptionButton4Sub2.txthigh:SetText("Bars Only")
	HenchmenOptionButton4Sub2.value = "bars"
	HenchmenOptionButton4Sub2.callback = AuraFunc
	HenchmenOptionButton4Sub2:SetScript("OnMouseUp", Option_OnMouseUp)

	CreateHenchmenSubOptions(4,3)
	HenchmenOptionButton4Sub3.txt:SetText("The Works: Bars and Icons")
	HenchmenOptionButton4Sub3.txthigh:SetText("The Works: Bars and Icons")
	HenchmenOptionButton4Sub3.value = "theworks"
	HenchmenOptionButton4Sub3.callback = AuraFunc
	HenchmenOptionButton4Sub3:SetScript("OnMouseUp", Option_OnMouseUp)

	HenchmenOptionButton4.suboptions = 3;
	HenchmenOptionButton4.isopen = false;
	HenchmenOptionButton4:SetScript("OnMouseUp",SubOption_OnMouseUp)
	------------------------------------------------------------------------
	HenchmenOptionButton5:SetScript("OnMouseUp", ConfigFunc)
	------------------------------------------------------------------------
	for _,frame in pairs(SUBOPTIONS) do
		frame.anim:Finish()
		frame:Hide()
	end

	MOD.PostLoaded = true
end

function SV:ToggleHenchman()
	if InCombatLockdown()then return end
	if(not MOD.PostLoaded) then
		CreateHenchmenFrame()
	end
	if not HenchmenFrame:IsShown()then
		HenchmenFrameBG:Show()

		UpdateHenchmanModel()

		HenchmenFrame.anim:Finish()
		HenchmenFrame:Show()
		HenchmenFrame.anim:Play()
		HenchmenCalloutFrame.anim:Finish()
		HenchmenCalloutFrame:Show()
		HenchmenCalloutFrame:SetAlpha(1)
		HenchmenCalloutFrame.anim:Play()
		UIFrameFadeOut(HenchmenCalloutFrame,5)
		for i=1,5 do
			local option=_G["HenchmenOptionButton"..i]
			option.anim:Finish()
			option:Show()
			option.anim:Play()

			local minion=_G["MinionOptionButton"..i]
			minion.anim:Finish()
			minion:Show()
			minion.anim:Play()
		end
		RightSuperDockToggleButton.icon:SetGradient(unpack(SV.Media.gradient.green))
	else
		UpdateHenchmanModel(true)
		for _,frame in pairs(SUBOPTIONS)do
			frame.anim:Finish()
			frame:Hide()
		end
		HenchmenOptionButton1.isopen=false;
		HenchmenOptionButton2.isopen=false;
		HenchmenOptionButton3.isopen=false;
		HenchmenCalloutFrame.anim:Finish()
		HenchmenCalloutFrame:Hide()
		HenchmenFrame.anim:Finish()
		HenchmenFrame:Hide()
		HenchmenFrameBG:Hide()
		for i=1,5 do
			local option=_G["HenchmenOptionButton"..i]
			option.anim:Finish()
			option:Hide()

			local minion=_G["MinionOptionButton"..i]
			minion.anim:Finish()
			minion:Hide()
		end
		RightSuperDockToggleButton.icon:SetGradient("VERTICAL", 0.5, 0.53, 0.55, 0.8, 0.8, 1)
	end
end

function SV:HenchmanSays(msg)
	HenchmenSpeechBubble.message = msg;
	HenchmenSpeechBubble:Show();
end
--[[
##########################################################
MAIL HELPER
##########################################################
]]--
function MOD:ToggleMailMinions()
	if not MOD.db.mailOpener then
		SVUI_MailMinion:Hide()
	else
		SVUI_MailMinion:Show()
	end
end

function MOD:LoadMailMinions()
	local SVUI_MailMinion = CreateFrame("Frame","SVUI_MailMinion",InboxFrame);
	SVUI_MailMinion:SetWidth(150)
	SVUI_MailMinion:SetHeight(25)
	SVUI_MailMinion:SetPoint("CENTER",InboxFrame,"TOP",-22,-400)

	local SVUI_GetMailButton=CreateFrame("Button","SVUI_GetMailButton",SVUI_MailMinion,"UIPanelButtonTemplate")
	SVUI_GetMailButton:SetWidth(70)
	SVUI_GetMailButton:SetHeight(25)
	SVUI_GetMailButton:SetButtonTemplate()
	SVUI_GetMailButton:SetPoint("LEFT",SVUI_MailMinion,"LEFT",0,0)
	SVUI_GetMailButton:SetText("Get All")
	SVUI_GetMailButton:SetScript("OnClick",GetAllMail)
	SVUI_GetMailButton:SetScript("OnEnter",function()
		GameTooltip:SetOwner(SVUI_GetMailButton,"ANCHOR_RIGHT")
		GameTooltip:AddLine(string.format("%d messages",GetInboxNumItems()),1,1,1)
		GameTooltip:Show()
	end)
	SVUI_GetMailButton:SetScript("OnLeave",function()GameTooltip:Hide()end)
	SVUI_GetMailButton:SetScript("OnEvent",function(l,m,h,n,o,p)
		if m=="UI_ERROR_MESSAGE"then
			if h==ERR_INV_FULL or h==ERR_ITEM_MAX_COUNT then
				StopOpeningMail("Your bags are too full!")
			end
		end
	end)

	local SVUI_GetGoldButton=CreateFrame("Button","SVUI_GetGoldButton",SVUI_MailMinion,"UIPanelButtonTemplate")
	SVUI_GetGoldButton:SetWidth(70)
	SVUI_GetGoldButton:SetHeight(25)
	SVUI_GetGoldButton:SetButtonTemplate()
	SVUI_GetGoldButton:SetPoint("RIGHT",SVUI_MailMinion,"RIGHT",0,0)
	SVUI_GetGoldButton:SetText("Get Gold")
	SVUI_GetGoldButton:SetScript("OnClick",GetAllMailCash)
	SVUI_GetGoldButton:SetScript("OnEnter",function()
		if not total_cash then
			total_cash=0;
			for a=0,GetInboxNumItems()do
				total_cash=total_cash + select(5,GetInboxHeaderInfo(a))
			end
		end
		GameTooltip:SetOwner(SVUI_GetGoldButton,"ANCHOR_RIGHT")
		GameTooltip:AddLine(FancifyMoneys(total_cash),1,1,1)
		GameTooltip:Show()
	end)
	SVUI_GetGoldButton:SetScript("OnLeave",function()GameTooltip:Hide()end)
end
--[[
##########################################################
INVITE AUTOMATONS
##########################################################
]]--
function MOD:PARTY_INVITE_REQUEST(event, arg)
	if not self.db.autoAcceptInvite then return end

	if IsInGroup() or QueueStatusMinimapButton:IsShown() then return end

	if GetNumFriends() > 0 then ShowFriends() end
	if IsInGuild() then GuildRoster() end

	hideStatic = true;
	local invited = false;
	for i = 1, GetNumFriends()do
		local friend = GetFriendInfo(i)
		if friend == arg then
			AcceptGroup()
			invited = true;
			SV:AddonMessage("Accepted an Invite From Your Friends!")
			break
		end
	end
	if not invited then
		for i = 1, BNGetNumFriends()do
			local _, _, _, friend = BNGetFriendInfo(i)
			arg = arg:match("(.+)%-.+") or arg;
			if friend == arg then
				AcceptGroup()
				invited = true;
				SV:AddonMessage("Accepted an Invite!")
				break
			end
		end
	end
	if not invited then
		for i = 1, GetNumGuildMembers(true)do
			local guildMate = GetGuildRosterInfo(i)
			if guildMate == arg then
				AcceptGroup()
				invited = true;
				SV:AddonMessage("Accepted an Invite From Your Guild!")
				break
			end
		end
	end
	if invited then
		local popup = StaticPopup_FindVisible("PARTY_INVITE")
		if(popup) then
			popup.inviteAccepted = 1
			StaticPopup_Hide("PARTY_INVITE")
		else
			popup = StaticPopup_FindVisible("PARTY_INVITE_XREALM")
			if(popup) then
				popup.inviteAccepted = 1
				StaticPopup_Hide("PARTY_INVITE_XREALM")
			end
		end
	end
end
--[[
##########################################################
REPAIR AUTOMATONS
##########################################################
]]--
function MOD:MERCHANT_SHOW()
	if self.db.vendorGrays then SV.SVBag:VendorGrays(nil,true) end
	local autoRepair = self.db.autoRepair;
	if IsShiftKeyDown() or autoRepair == "NONE" or not CanMerchantRepair() then return end
	local repairCost,canRepair=GetRepairAllCost()
	local loan=GetGuildBankWithdrawMoney()
	if autoRepair == "GUILD" and (not CanGuildBankRepair() or (repairCost > loan)) then autoRepair = "PLAYER" end
	if repairCost > 0 then
		if canRepair then
			RepairAllItems(autoRepair=='GUILD')
			local x,y,z= repairCost % 100,floor((repairCost % 10000)/100), floor(repairCost / 10000)
			if autoRepair=='GUILD' then
				SV:HenchmanSays("Repairs Complete! ...Using Guild Money!\n"..GetCoinTextureString(repairCost,12))
			else
				SV:HenchmanSays("Repairs Complete!\n"..GetCoinTextureString(repairCost,12))
			end
		else
			SV:HenchmanSays("The Minions Say You Are Too Broke To Repair! They Are Laughing..")
		end
	end
end
--[[
##########################################################
REP AUTOMATONS
##########################################################
]]--
function MOD:CHAT_MSG_COMBAT_FACTION_CHANGE(event, msg)
	if not self.db.autorepchange then return end
	local _, _, faction, amount = msg:find(incpat)
	if not faction then
		_, _, faction, amount = msg:find(changedpat) or msg:find(decpat)
	end
	if faction and faction ~= GUILD_REPUTATION then
		local active = GetWatchedFactionInfo()
		for factionIndex = 1, GetNumFactions() do
			local name = GetFactionInfo(factionIndex)
			if name == faction and name ~= active then
				-- local inactive = IsFactionInactive(factionIndex) or SetWatchedFactionIndex(factionIndex)
				local strMsg = ("Watching Faction: %s"):format(name)
				SV:AddonMessage(strMsg)
				break
			end
		end
	end
end
--[[
##########################################################
QUEST AUTOMATONS
##########################################################
]]--
function MOD:AutoQuestProxy()
	if(IsShiftKeyDown()) then return false; end
    if((not QuestIsDaily() or not QuestIsWeekly()) and (self.db.autodailyquests)) then return false; end
    if(QuestFlagsPVP() and (not self.db.autopvpquests)) then return false; end
    return true
end

function MOD:QUEST_GREETING()
    if(self.db.autoquestaccept == true and self:AutoQuestProxy()) then
        local active,available = GetNumActiveQuests(), GetNumAvailableQuests()
        if(active + available == 0) then return end
        if(available > 0) then
            SelectAvailableQuest(1)
        end
        if(active > 0) then
            SelectActiveQuest(1)
        end
    end
end

function MOD:GOSSIP_SHOW()
    if(self.db.autoquestaccept == true and self:AutoQuestProxy()) then
        if GetGossipAvailableQuests() then
            SelectGossipAvailableQuest(1)
        elseif GetGossipActiveQuests() then
            SelectGossipActiveQuest(1)
        end
    end
end

function MOD:QUEST_DETAIL()
    if(self.db.autoquestaccept == true and self:AutoQuestProxy()) then
        if not QuestGetAutoAccept() then
			AcceptQuest()
		else
			CloseQuest()
		end
    end
end

function MOD:QUEST_ACCEPT_CONFIRM()
    if(self.db.autoquestaccept == true and self:AutoQuestProxy()) then
        ConfirmAcceptQuest()
        StaticPopup_Hide("QUEST_ACCEPT_CONFIRM")
    end
end

function MOD:QUEST_PROGRESS()
	if(IsShiftKeyDown()) then return false; end
    if(self.db.autoquestcomplete == true and IsQuestCompletable()) then
        CompleteQuest()
    end
end

function MOD:QUEST_COMPLETE()
	if(not self.db.autoquestcomplete and (not self.db.autoquestreward)) then return end
	if(IsShiftKeyDown()) then return false; end
	local rewards = GetNumQuestChoices()
	if rewards > 1 then
		local auto_select = QuestFrameRewardPanel.itemChoice or QuestInfoFrame.itemChoice;
		local selection, value = 1, 0;
		if self.db.autoquestreward == true then
			for i = 1, rewards do
				local iLink = GetQuestItemLink("choice", i)
				if iLink then
					local iValue = select(11,GetItemInfo(iLink))
					if iValue and iValue > value then
						value = iValue;
						selection = i
					end
				end
			end
			local chosenItem = _G[("QuestInfoItem%d"):format(selection)]
			if chosenItem.type == "choice" then
				QuestInfoItemHighlight:ClearAllPoints()
				QuestInfoItemHighlight:SetAllPoints(chosenItem)
				QuestInfoItemHighlight:Show()
				QuestInfoFrame.itemChoice = chosenItem:GetID()
				SV:HenchmanSays("A Minion Has Chosen Your Reward!")
			end
		end
		auto_select = selection
		if self.db.autoquestcomplete == true then
			GetQuestReward(auto_select)
		end
	else
		if(self.db.autoquestcomplete == true) then
			GetQuestReward(GetNumQuestChoices())
		end
	end
end
--[[
##########################################################
BUILD FUNCTION / UPDATE
##########################################################
]]--
function MOD:Load()
	local bubble = CreateFrame("Frame", "HenchmenSpeechBubble", SV.UIParent)
	bubble:SetSize(256,128)
	bubble:Point("BOTTOMRIGHT", RightSuperDockToggleButton, "TOPLEFT", 0, 0)
	bubble:SetFrameStrata("DIALOG")
	bubble:SetFrameLevel(24)
	bubble.bg = bubble:CreateTexture(nil,"BORDER")
	bubble.bg:SetAllPoints(bubble)
	bubble.bg:SetTexture(BUBBLE)
	bubble.bg:SetVertexColor(1,1,1)
	bubble.txt = bubble:CreateFontString(nil,"DIALOG")
	bubble.txt:Point("TOPLEFT", bubble, "TOPLEFT", 5, -5)
	bubble.txt:Point("BOTTOMRIGHT", bubble, "BOTTOMRIGHT", -5, 20)
	bubble.txt:SetFont(SV.Media.font.dialog,12,"NONE")
	bubble.txt:SetText("")
	bubble.txt:SetTextColor(0,0,0)
	bubble.txt:SetWordWrap(true)
	bubble:Hide()
	bubble:SetScript('OnShow', Speech_OnShow)

	if IsAddOnLoaded("Postal") then
		self.db.mailOpener = false
	else
		self:LoadMailMinions()
		self:ToggleMailMinions()
	end

	self:RegisterEvent('PARTY_INVITE_REQUEST')

	for _,event in pairs(AutomatedEvents) do
		self:RegisterEvent(event)
	end

	if self.db.pvpautorelease then
		local autoReleaseHandler = CreateFrame("frame")
		autoReleaseHandler:RegisterEvent("PLAYER_DEAD")
		autoReleaseHandler:SetScript("OnEvent",function(self,event)
			local isInstance, instanceType = IsInInstance()
			if(isInstance and instanceType == "pvp") then
				local spell = GetSpellInfo(20707)
				if(SV.class ~= "SHAMAN" and not(spell and UnitBuff("player",spell))) then
					RepopMe()
				end
			end
			for i=1,GetNumWorldPVPAreas() do
				local _,localizedName, isActive = GetWorldPVPAreaInfo(i)
				if(GetRealZoneText() == localizedName and isActive) then RepopMe() end
			end
		end)
	end

	local skippy = CreateFrame("Frame")
	skippy:RegisterEvent("CINEMATIC_START")
	skippy:SetScript("OnEvent", function(_, event)
		if event == "CINEMATIC_START" then
			if(MOD.db.skipcinematics) then
				CinematicFrame_CancelCinematic()
			end
		end
	end)
	local PlayMovie_hook = MovieFrame_PlayMovie
	MovieFrame_PlayMovie = function(...)
		if(MOD.db.skipcinematics) then
			GameMovieFinished()
		else
			PlayMovie_hook(...)
		end
	end
end
--[[
##########################################################
DEFINE CONFIG AND REGISTER
##########################################################
]]--
SVLib:NewPackage(MOD, "SVHenchmen")