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 ipairs    = _G.ipairs;
local type      = _G.type;
local error     = _G.error;
local pcall     = _G.pcall;
local tostring  = _G.tostring;
local tonumber  = _G.tonumber;
local tinsert 	= _G.tinsert;
local string 	= _G.string;
local math 		= _G.math;
local table 	= _G.table;
--[[ STRING METHODS ]]--
local format = string.format;
--[[ MATH METHODS ]]--
local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;
--[[ TABLE METHODS ]]--
local tremove, twipe = table.remove, table.wipe;
--[[
##########################################################
GET ADDON DATA
##########################################################
]]--
local SV = select(2, ...)
local L = SV.L
local LSM = LibStub("LibSharedMedia-3.0")
local MOD = SV:NewPackage("SVQuest", L['Questing']);
--[[
##########################################################
EXTRA QUEST ITEM BUTTON
##########################################################
]]--
local Button = CreateFrame('Button', (...), UIParent, 'SecureActionButtonTemplate, SecureHandlerStateTemplate, SecureHandlerAttributeTemplate')
RegisterStateDriver(Button, 'visible', '[extrabar] hide; show')
Button:SetAttribute('_onattributechanged', [[
	if(name == 'item') then
		if(value and not self:IsShown() and not HasExtraActionBar()) then
			self:Show()
		elseif(not value) then
			self:Hide()
			self:ClearBindings()
		end
	elseif(name == 'state-visible') then
		if(value == 'show') then
			self:CallMethod('Update')
		else
			self:Hide()
			self:ClearBindings()
		end
	end

	if(self:IsShown() and (name == 'item' or name == 'binding')) then
		self:ClearBindings()

		local key = GetBindingKey('EXTRAACTIONBUTTON1')
		if(key) then
			self:SetBindingClick(1, key, self, 'LeftButton')
		end
	end
]])

local function UpdateCooldown(self)
	if(self:IsShown()) then
		local start, duration, enable = GetItemCooldown(self.itemID)
		if(duration > 0) then
			self.Cooldown:SetCooldown(start, duration)
			self.Cooldown:Show()
		else
			self.Cooldown:Hide()
		end
	end
end

Button:RegisterEvent('PLAYER_LOGIN')
Button:SetScript('OnEvent', function(self, event)
	if(event == 'BAG_UPDATE_COOLDOWN') then
		UpdateCooldown(self)
	elseif(event == 'PLAYER_REGEN_ENABLED') then
		self:SetAttribute('item', self.attribute)
		self:UnregisterEvent(event)
		UpdateCooldown(self)
	elseif(event == 'UPDATE_BINDINGS') then
		if(self:IsShown()) then
			self:SetItem()
			self:SetAttribute('binding', GetTime())
		end
	elseif(event == 'PLAYER_LOGIN') then
		self:SetPoint('CENTER', ExtraActionButton1)
		self:SetSize(ExtraActionButton1:GetSize())
		self:SetScale(ExtraActionButton1:GetScale())
		self:SetHighlightTexture([[Interface\Buttons\ButtonHilight-Square]])
		self:SetPushedTexture([[Interface\Buttons\CheckButtonHilight]])
		self:GetPushedTexture():SetBlendMode('ADD')
		self:SetScript('OnLeave', GameTooltip_Hide)
		self:SetAttribute('type', 'item')
		self.updateTimer = 0
		self.rangeTimer = 0
		self:Hide()

		local Icon = self:CreateTexture('$parentIcon', 'BACKGROUND')
		Icon:SetAllPoints()
		self.Icon = Icon

		local HotKey = self:CreateFontString('$parentHotKey', nil, 'NumberFontNormal')
		HotKey:SetPoint('BOTTOMRIGHT', -5, 5)
		self.HotKey = HotKey

		local Cooldown = CreateFrame('Cooldown', '$parentCooldown', self, 'CooldownFrameTemplate')
		Cooldown:ClearAllPoints()
		Cooldown:SetPoint('TOPRIGHT', -2, -3)
		Cooldown:SetPoint('BOTTOMLEFT', 2, 1)
		Cooldown:Hide()
		self.Cooldown = Cooldown

		local Artwork = self:CreateTexture('$parentArtwork', 'OVERLAY')
		Artwork:SetPoint('CENTER', -2, 0)
		Artwork:SetSize(256, 128)
		Artwork:SetTexture([[Interface\ExtraButton\Default]])
		self.Artwork = Artwork

		self:RegisterEvent('UPDATE_BINDINGS')
		self:RegisterEvent('UPDATE_EXTRA_ACTIONBAR')
		self:RegisterEvent('BAG_UPDATE_COOLDOWN')
		self:RegisterEvent('BAG_UPDATE_DELAYED')
		self:RegisterEvent('WORLD_MAP_UPDATE')
		self:RegisterEvent('QUEST_LOG_UPDATE')
		self:RegisterEvent('QUEST_POI_UPDATE')
	else
		self:Update()
	end
end)

Button:SetScript('OnEnter', function(self)
	GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
	GameTooltip:SetHyperlink(self.itemLink)
end)

-- BUG: IsItemInRange() is broken versus friendly npcs (and possibly others)
Button:SetScript('OnUpdate', function(self, elapsed)
	if(self.rangeTimer > TOOLTIP_UPDATE_TIME) then
		local HotKey = self.HotKey
		local inRange = IsItemInRange(self.itemLink, 'target')
		if(HotKey:GetText() == RANGE_INDICATOR) then
			if(inRange == false) then
				HotKey:SetTextColor(1, 0.1, 0.1)
				HotKey:Show()
			elseif(inRange) then
				HotKey:SetTextColor(1, 1, 1)
				HotKey:Show()
			else
				HotKey:Hide()
			end
		else
			if(inRange == false) then
				HotKey:SetTextColor(1, 0.1, 0.1)
			else
				HotKey:SetTextColor(1, 1, 1)
			end
		end

		self.rangeTimer = 0
	else
		self.rangeTimer = self.rangeTimer + elapsed
	end

	if(self.updateTimer > 5) then
		self:Update()
		self.updateTimer = 0
	else
		self.updateTimer = self.updateTimer + elapsed
	end
end)

local zoneWide = {
	[14108] = 541,
	[13998] = 11,
	[25798] = 61, -- quest is bugged, has no zone
	[25799] = 61, -- quest is bugged, has no zone
	[25112] = 161,
	[25111] = 161,
	[24735] = 201,
}

local blacklist = {
	[113191] = true,
	[110799] = true,
	[109164] = true,
}

function Button:SetItem(itemLink, texture)
	if(itemLink) then
		if(itemLink == self.itemLink and self:IsShown()) then
			return
		end

		self.Icon:SetTexture(texture)
		self.itemID, self.itemName = string.match(itemLink, '|Hitem:(.-):.-|h%[(.+)%]|h')
		self.itemLink = itemLink

		if(blacklist[self.itemID]) then
			return
		end
	end

	local HotKey = self.HotKey
	local key = GetBindingKey('EXTRAACTIONBUTTON1')
	if(key) then
		HotKey:SetText(GetBindingText(key, 1))
		HotKey:Show()
	elseif(ItemHasRange(self.itemLink)) then
		HotKey:SetText(RANGE_INDICATOR)
		HotKey:Show()
	else
		HotKey:Hide()
	end

	if(InCombatLockdown()) then
		self.attribute = self.itemName
		self:RegisterEvent('PLAYER_REGEN_ENABLED')
	else
		self:SetAttribute('item', self.itemName)
		UpdateCooldown(self)
	end
end

function Button:RemoveItem()
	if(InCombatLockdown()) then
		self.attribute = nil
		self:RegisterEvent('PLAYER_REGEN_ENABLED')
	else
		self:SetAttribute('item', nil)
	end
end

local ticker
function Button:Update()
	local numItems = 0
	local shortestDistance = 62500 -- 250 yards²
	local closestQuestLink, closestQuestTexture

	for index = 1, GetNumQuestWatches() do
		local questID, _, questIndex, _, _, isComplete = GetQuestWatchInfo(index)
		if(questID and QuestHasPOIInfo(questID)) then
			local link, texture, _, showCompleted = GetQuestLogSpecialItemInfo(questIndex)
			if(link) then
				local areaID = zoneWide[questID]
				if(areaID and areaID == GetCurrentMapAreaID()) then
					closestQuestLink = link
					closestQuestTexture = texture
				elseif(not isComplete or (isComplete and showCompleted)) then
					local distanceSq, onContinent = GetDistanceSqToQuest(questIndex)
					if(onContinent and distanceSq < shortestDistance) then
						shortestDistance = distanceSq
						closestQuestLink = link
						closestQuestTexture = texture
					end
				end

				numItems = numItems + 1
			end
		end
	end

	if(closestQuestLink and not HasExtraActionBar()) then
		self:SetItem(closestQuestLink, closestQuestTexture)
	elseif(self:IsShown()) then
		self:RemoveItem()
	end

	if(numItems > 0 and not ticker) then
		ticker = C_Timer.NewTicker(30, function() -- might want to lower this
			Button:Update()
		end)
	elseif(numItems == 0 and ticker) then
		ticker:Cancel()
		ticker = nil
	end
end
--[[
##########################################################
CORE FUNCTIONS
##########################################################
]]--
function MOD:ReLoad()
	-- DO STUFF
end

function MOD:Load()
	-- DO STUFF
end