--[[

Additional function hooks to allow hooks into more tooltips
3.5.0.0908 (Platypus)
$Id: Tooltip.lua 867 2006-05-18 20:46:57Z mentalpower $

You should hook into EnhTooltip using Stubby:
	Stubby.RegisterFunctionHook("EnhTooltip.HOOK", 200, myHookingFunction)
	Where myHooking function is one of your functions (see calling parameters below)
	And HOOK is one of:
		addTooltip
		checkPopup
		merchantHook
		tradeHook
		bankHook
		bagHook
	The number 200 is a number that determines calling order
		A lower number will make your tooltip information display earlier (higher)
		A higher number will call your tooltip later (lower)
		Auctioneer (if installed) gets called at position 100.
		Informant  (if installed) gets called at position 300.
		Enchantrix (if installed) gets called at position 400.

	The appropriate function calls are, respectively:
		tooltip - A tooltip is being displayed, hookFunc will be called as:
		addTooltipHook(frame, name, link, quality, count, price)
		popup - A tooltip may be displayed, unless you want to popup something:
		popped = checkPopupHook(name, link, quality, count, price, hyperlink)
			If your function returns true, then we won't present a tooltip
		merchant - Get called for each of a merchant's items.
		merchantHook(frame, name, link, quality, count, price)
		trade - Get called when a tradeskill window is displayed / item selected
		tradeHook(type, selid)
			valid types: 'trade', 'craft'
			selID will be nil when the window is first displayed
		bank - You are at the bank and are able to scan it's containers
			bankHook()
		bag - One or more of the items in your bags has updated.
			bagHook()


You may use the following methods of the EnhTooltip class:

	EnhTooltip.HideTooltip()
		Causes the enhanced tooltip to vanish.

	EnhTooltip.ClearTooltip()
		Clears the current tooltip of contents and hides it.

	EnhTooltip.GetGSC(money)
		Returns the given money (in copper) amount in gold, silver and copper.

	EnhTooltip.GetTextGSC(money, exact)
		Returns the money (in copper) amount as colored text, suitable for display.
		If exact evaluates to true, then the text will be exact, otherwise rounded.

	EnhTooltip.AddLine(lineText, moneyAmount, embed)
		Adds the lineText to the tooltip.
		If moneyAmount is supplied, the line has a money amount right-aligned after it.
		It embed evaluates to true, then the line is placed at the end of the game tooltip
		and the money amount is converted to a textual form.

	EnhTooltip.AddSeparator()
		Adds an empty line to the tooltip.

	EnhTooltip.LineColor(r, g, b)
		Changes the color of the most recently added line to the given R,G,B value.
		The R,G,B values are floating point values from 0.0 (dark) to 1.0 (bright)

	EnhTooltip.LineSize_Large()
		Changes the size of the font string to 12

	EnhTooltip.LineSize_Small()
		Changes the size of the font string to 10

	EnhTooltip.LineQuality(quality)
		Changes the color of the most recently added line to the quality color of the
		item that is supplied in the quality parameter.

	EnhTooltip.SetIcon(iconPath)
		Adds an icon to the current tooltip, where the texture path is set to that of
		the iconPath parameter.

	EnhTooltip.NameFromLink(link)
		Given a link, returns the embedded item name.

	EnhTooltip.HyperlinkFromLink(link)
		Given a link, returns the blizzard hyperlink (eg: "item:12345:0:321:0")

	EnhTooltip.BaselinkFromLink(link)
		Given a link, returns the first 3 numbers from the item link (eg: "12345:0:321")

	EnhTooltip.QualityFromLink(link)
		Given a link, returns the numerical quality value (0=Poor/Gray ... 4=Epic/Purple)

	EnhTooltip.FakeLink(hyperlink, quality, name)
		Given a hyperlink, a numerical quality and an item name, does it's best to fabricate
		as authentic a link as it can. This link may not be suitable for messaging however.

	EnhTooltip.LinkType(link)
		Given a link, returns the type of link (eg: "item", "enchant")

	EnhTooltip.AddHook(hookType, hookFunc, position)
		Allows dependant addons to register a function for inclusion at key moments.
		Where:
			hookType = The type of event to be notified of. One of:
				tooltip - A tooltip is being displayed, hookFunc will be called as:
				addTooltipHook(frame, name, link, quality, count, price)
				popup - A tooltip may be displayed, unless you want to popup something:
				popped = checkPopupHook(name, link, quality, count, price, hyperlink)
					If your function returns true, then we won't present a tooltip
				merchant - Get called for each of a merchant's items.
				merchantHook(frame, name, link, quality, count, price)
				trade - Get called when a tradeskill window is displayed / item selected
				tradeHook(type, selid)
					valid types: 'trade', 'craft'
					selID will be nil when the window is first displayed
				bank - You are at the bank and are able to scan it's containers
				bankHook()
				bag - One or more of the items in your bags has updated.
					bagHook()
			hookFunction = Your function (prototyped as above) that we will call.
			position = A number that determines calling order
				The default position if not supplied is 100.
				A lower number will make your tooltip information display earlier (higher)
				A higher number will call your tooltip later (lower)
				Auctioneer (if installed) gets called at position 50.
				Enchantrix (if installed) gets called at position 150.

	EnhTooltip.BreakLink(link)
		Given an item link, splits it into it's component parts as follows:
			itemID, randomProperty, enchantment, uniqueID, itemName = EnhTooltip.BreakLink(link)
			Note that the return order is not the same as the order of the items in the link
			(ie: randomProp and enchant are reversed from their link order)

	EnhTooltip.FindItemInBags(findName)
		Searches through your bags to find an item with the given name (exact match)
		It returns the following information about the item:
			bag, slot, itemID, randomProp, enchant, uniqID = EnhTooltip.FindItemInBags(itemName)

	EnhTooltip.SetElapsed(elapsed)
		If a value is given, adds the elapsed interval to our own internal timer.
			Checks to see if it is time to hide the tooltip.
		Returns the total elapsed time that the tooltip has been displayed since startup.

	EnhTooltip.SetMoneySpacing(spacing)
		Sets the amount of padding (if provided) that money should be given in the tooltips.
		Returns the current spacing.

	EnhTooltip.SetPopupKey(key)
		Sets a key (if provided), which if pressed while a tooltip is being displayed, checks
			for hooked functions that may wish to provide popups.
		Returns the current key.

	License:
		This program is free software; you can redistribute it and/or
		modify it under the terms of the GNU General Public License
		as published by the Free Software Foundation; either version 2
		of the License, or (at your option) any later version.

		This program is distributed in the hope that it will be useful,
		but WITHOUT ANY WARRANTY; without even the implied warranty of
		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
		GNU General Public License for more details.

		You should have received a copy of the GNU General Public License
		along with this program(see GLP.txt); if not, write to the Free Software
		Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

]]

-- setting version number
ENHTOOLTIP_VERSION = "3.5.0.0908"
if (ENHTOOLTIP_VERSION == "<".."%version%>") then
	ENHTOOLTIP_VERSION = "3.5.DEV"
end

--[[
---- Initialize a storage space that all our functions can see
--]]
local self = {
	showIgnore = false,
	moneySpacing = 4,
	embedLines = {},
	eventTimer = 0,
	hideTime = 0,
	currentGametip = nil,
	currentItem = nil,
	forcePopupKey = "alt",
	oldChatItem = nil,
	hooks = {},
	notify = { tooltip = {}, popup = {}, merchant = {}, bank = {}, bag = {}, trade = {} },
	notifyFuncs = {},
}

-- =============== LOCAL FUNCTIONS =============== --

-- prototypes for all local functions
local addLine					-- AddLine(lineText,moneyAmount,embed)
local addSeparator				-- AddSeparator(embed)
local addTooltip				-- AddTooltip(frame,name,link,quality,count,price)
local afHookOnEnter				-- AfHookOnEnter(type,index)
local bagHook					-- BagHook()
local bankHook					-- BankHook()
local baselinkFromLink			-- BaselinkFromLink(link)
local breakLink					-- BreakLink(link)
local callBagHook				-- CallBagHook(event,bagNumber)
local callBankHook				-- CallBankHook()
local callCheckPopup			-- CallCheckPopup(name,link,quality,count,price,hyperlink)
local callTradeHook				-- CallTradeHook(type,event,selID)
local cfHookUpdate				-- CfHookUpdate(frame)
local chatHookOnHyperlinkShow	-- ChatHookOnHyperlinkShow(reference,link,button)
local checkHide					-- CheckHide()
local checkPopup				-- CheckPopup(name,link,quality,count,price,hyperlink)
local clearTooltip				-- ClearTooltip()
local debugPrint				-- DebugPrint(...)
local doHyperlink				-- DoHyperlink(reference,link,button)
local embedRender				-- EmbedRender()
local fakeLink					-- FakeLink(hyperlink,quality,name)
local findItemInBags			-- FindItemInBags(findName)
local getglobalIterator			-- GetglobalIterator(format,first,last)
local getGSC					-- GetGSC(money)
local getLootLinkLink			-- GetLootLinkLink(name)
local getLootLinkServer			-- GetLootLinkServer()
local getRect					-- GetRect(object,curRect)
local getTextGSC				-- GetTextGSC(money,exact)
local gtHookOnHide				-- GtHookOnHide()
local gtHookSetAuctionSellItem	-- GtHookSetAuctionSellItem(frame)
local gtHookSetBagItem			-- GtHookSetBagItem(frame,frameID,buttonID,retVal)
local gtHookSetCraftItem		-- GtHookSetCraftItem(frame,skill,slot)
local gtHookSetCraftSpell		-- GtHookSetCraftSpell(frame,skill,slot)
local gtHookSetInboxItem		-- GtHookSetinboxItem(frame,index)
local gtHookSetInventoryItem	-- GtHookSetInventoryItem(frame,unit,slot,retVal)
local gtHookSetLootItem			-- GtHookSetLootItem(frame,slot)
local gtHookSetMerchantItem		-- GtHookSetMerchantItem(frame,slot)
local gtHookSetOwner			-- GtHookSetOwner(frame,owner,anchor)
local gtHookSetQuestItem		-- GtHookSetQuestItem(frame,qtype,slot)
local gtHookSetQuestLogItem		-- GtHookSetQuestLogItem(frame,qtype,slot)
local gtHookSetTradeSkillItem	-- GtHookSetTradeSkillItem(frame,skill,slot)
local gtHookSetText				-- GtHookSetText(funcArgs, retval, frame, text, r, g, b, unknown1, unknown2)
local gtHookAppendText			-- GtHookAppendText(funcArgs, retVal, frame)
local gtHookShow				-- GtHookShow(funcArgs, retVal, frame)
local hideTooltip				-- HideTooltip()
local hyperlinkFromLink			-- HyperlinkFromLink(link)
local imHookOnEnter				-- ImHookOnEnter()
local imiHookOnEnter			-- ImiHookOnEnter()
local lineColor					-- LineColor(r,g,b)
local lineQuality				-- LineQuality(quality)
local lineSize_Large			-- LineSize_Large()
local lineSize_Small			-- LineSize_Small()
local linkType					-- LinkType()
local llHookOnEnter				-- LlHookOnEnter()
local merchantHook				-- MerchantHook(merchant,slot,name,link,quality,count,price,limit)
local merchantScanner			-- MerchantScanner()
local nameFromLink				-- NameFromLink(link)
local qualityFromLink			-- QualityFromLink(link)
local setElapsed				-- SetElapsed(elapsed)
local setIcon					-- SetIcon(iconPath)
local setMoneySpacing			-- SetMoneySpacing(spacing)
local setPopupKey				-- SetPopupKey(key)
local showTooltip				-- ShowTooltip(currentTooltip,skipEmbedRender)
local tooltipCall				-- TooltipCall(frame,name,link,quality,count,price,forcePopup,hyperlink)
local tradeHook					-- TradeHook(type,selID)
local ttInitialize				-- TtInitialize()


------------------------
--  Hookable functions
------------------------

function addTooltip(frame, name, link, quality, count, price)
	-- This is it.
	-- Hook this function when you have something to put into the
	-- tooltip and use the AddLine etc methods to do so.
end

function checkPopup(name, link, quality, count, price, hyperlink)
	-- Hook this function to stop EnhTooltip putting up a tooltip
	-- Return true to stop EnhTooltip's tooltip.
end

function merchantHook(merchant, slot, name, link, quality, count, price, limit)
	-- Hook this function to be notified of an item at a merchant
end

function bankHook()
	-- Hook this function to be alerted to do a bank scan
end

function bagHook()
	-- Hook this function to be alerted to do a bag scan
end

function tradeHook(type,selID)
	-- Hook this function to be notified when a trade window is
	-- displayed or an item therein is selected.
	--   type is one of: "trade", or "craft"
	--   selID can be nil when first opened, or the id of the selected item.
end

------------------------
-- Function definitions
------------------------

function hideTooltip()
	EnhancedTooltip:Hide()
	self.currentItem = ""
	self.hideTime = 0
end

-- Iterate over numbered global objects
function getglobalIterator(fmt, first, last)
	local i = tonumber(first) or 1
	return function()
		if last and (i > last) then
			return
		end
		local obj = getglobal(string.format(fmt, i))
		i = i + 1
		return obj
	end
end

function clearTooltip()
	hideTooltip()
	EnhancedTooltip.hasEmbed = false
	EnhancedTooltip.curEmbed = false
	EnhancedTooltip.hasData = false
	EnhancedTooltip.hasIcon = false
	EnhancedTooltipIcon:Hide()
	EnhancedTooltipIcon:SetTexture("Interface\\Buttons\\UI-Quickslot2")

	for ttText in getglobalIterator("EnhancedTooltipText%d") do
		ttText:Hide()
		ttText:SetTextColor(1.0,1.0,1.0)
		ttText:SetFont(STANDARD_TEXT_FONT, 15);
	end

	for ttMoney in getglobalIterator("EnhancedTooltipMoney%d") do
		ttMoney.myLine = nil
		ttMoney:Hide()
	end

	EnhancedTooltip.lineCount = 0
	EnhancedTooltip.moneyCount = 0
	EnhancedTooltip.minWidth = 0
	for curLine in self.embedLines do
		self.embedLines[curLine] = nil;
	end
	table.setn(self.embedLines, 0);
end

function getRect(object, curRect)
	local rect = curRect
	if (not rect) then
		rect = {}
	end
	rect.t = object:GetTop() or 0
	rect.l = object:GetLeft() or 0
	rect.b = object:GetBottom() or 0
	rect.r = object:GetRight() or 0
	rect.w = object:GetWidth() or 0
	rect.h = object:GetHeight() or 0
	rect.cx = rect.l + (rect.w / 2)
	rect.cy = rect.t - (rect.h / 2)
	return rect
end

function showTooltip(currentTooltip, skipEmbedRender)
	if (self.showIgnore == true) then return end
	if (EnhancedTooltip.hasEmbed and not skipEmbedRender) then
		embedRender()
		self.showIgnore=true;
		currentTooltip:Show()
		self.showIgnore=false;
	end
	if (not EnhancedTooltip.hasData) then
		return
	end

	local width = EnhancedTooltip.minWidth
	if (EnhancedTooltip.hasIcon) then
		width = width + EnhancedTooltipIcon:GetWidth()
	end
	local lineCount = EnhancedTooltip.lineCount
	if (lineCount == 0) then
		if (not EnhancedTooltip.hasEmbed) then
			hideTooltip()
			return
		end
	end

	local height = 0
	for currentLine in getglobalIterator("EnhancedTooltipText%d", 1, lineCount) do
		height = height + currentLine:GetHeight() + 1
	end
	if EnhancedTooltip.hasIcon then
		height = math.max(height, EnhancedTooltipIcon:GetHeight() - 6)
	end
	height = height + 20

	local sWidth = GetScreenWidth()
	local sHeight = GetScreenHeight()

	local cWidth = currentTooltip:GetWidth()
	if (cWidth < width) then
		getglobal(currentTooltip:GetName().."TextLeft1"):SetWidth(width - 20)
		self.showIgnore=true;
		currentTooltip:Show()
		self.showIgnore=false;
	else
		width = cWidth
	end

	local parentObject = currentTooltip.owner
	if (parentObject) then
		local align = currentTooltip.anchor

		enhTooltipParentRect = getRect(currentTooltip.owner, enhTooltipParentRect)

		local xAnchor, yAnchor
		if (enhTooltipParentRect.l - width < sWidth * 0.2) then
			xAnchor = "RIGHT"
		elseif (enhTooltipParentRect.r + width > sWidth * 0.8) then
			xAnchor = "LEFT"
		elseif (align == "ANCHOR_RIGHT") then
			xAnchor = "RIGHT"
		elseif (align == "ANCHOR_LEFT") then
			xAnchor = "LEFT"
		else
			xAnchor = "RIGHT"
		end
		if (enhTooltipParentRect.cy < sHeight/2) then
			yAnchor = "TOP"
		else
			yAnchor = "BOTTOM"
		end

		-- Handle the situation where there isn't enough room on the choosen side of
		-- the parent to display the tooltip. In that case we'll just shift tooltip
		-- enough to the left or right so that it doesn't hang off the screen.
		local xOffset = 0;
		if (xAnchor == "RIGHT" and enhTooltipParentRect.r + width > sWidth - 5) then
			xOffset = -(enhTooltipParentRect.r + width - sWidth + 5);
		elseif (xAnchor == "LEFT" and enhTooltipParentRect.l - width < 5) then
			xOffset = -(enhTooltipParentRect.l - width - 5);
		end

		-- Handle the situation where there isn't enough room on the top or bottom of
		-- the parent to display the tooltip. In that case we'll just shift tooltip
		-- enough up or down so that it doesn't hang off the screen.
		local yOffset = 0;
		local totalHeight = height + currentTooltip:GetHeight();
		if (yAnchor == "TOP" and enhTooltipParentRect.t + totalHeight > sHeight - 5) then
			yOffset = -(enhTooltipParentRect.t + totalHeight - sHeight + 5);
		elseif (yAnchor == "BOTTOM" and enhTooltipParentRect.b - totalHeight < 5) then
			yOffset = -(enhTooltipParentRect.b - totalHeight - 5);
		end

		currentTooltip:ClearAllPoints()
		EnhancedTooltip:ClearAllPoints()
		local anchor = yAnchor..xAnchor

		if (anchor == "TOPLEFT") then
			EnhancedTooltip:SetPoint("BOTTOMRIGHT", parentObject, "TOPLEFT", -5 + xOffset, 5 + yOffset)
			currentTooltip:SetPoint("BOTTOMRIGHT", EnhancedTooltip, "TOPRIGHT", 0,0)
		elseif (anchor == "TOPRIGHT") then
			EnhancedTooltip:SetPoint("BOTTOMLEFT", parentObject, "TOPRIGHT", 5 + xOffset, 5 + yOffset)
			currentTooltip:SetPoint("BOTTOMLEFT", EnhancedTooltip, "TOPLEFT", 0,0)
		elseif (anchor == "BOTTOMLEFT") then
			currentTooltip:SetPoint("TOPRIGHT", parentObject, "BOTTOMLEFT", -5 + xOffset, -5 + yOffset)
			EnhancedTooltip:SetPoint("TOPRIGHT", currentTooltip, "BOTTOMRIGHT", 0,0)
		else -- BOTTOMRIGHT
			currentTooltip:SetPoint("TOPLEFT", parentObject, "BOTTOMRIGHT", 5 + xOffset, -5 + yOffset)
			EnhancedTooltip:SetPoint("TOPLEFT", currentTooltip, "BOTTOMLEFT", 0,0)
		end

	else
		-- No parent
		-- The only option is to tack the object underneath / shuffle it up if there aint enuff room
		self.showIgnore=true;
		currentTooltip:Show()
		self.showIgnore=false;
		enhTooltipTipRect = getRect(currentTooltip, enhTooltipTipRect)

		if (enhTooltipTipRect.b - height < 60) then
			currentTooltip:ClearAllPoints()
			currentTooltip:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", enhTooltipTipRect.l, height+60)
		end
		EnhancedTooltip:ClearAllPoints()
		if (enhTooltipTipRect.cx < 6*sWidth/10) then
			EnhancedTooltip:SetPoint("TOPLEFT", currentTooltip, "BOTTOMLEFT", 0,0)
		else
			EnhancedTooltip:SetPoint("TOPRIGHT", currentTooltip, "BOTTOMRIGHT", 0,0)
		end
	end

	EnhancedTooltip:SetHeight(height)
	EnhancedTooltip:SetWidth(width)
	currentTooltip:SetWidth(width)
	EnhancedTooltip:Show()

	for ttMoney in getglobalIterator("EnhancedTooltipMoney%d") do
		if (ttMoney.myLine ~= nil) then
			local myLine = getglobal(ttMoney.myLine)
			local ttMoneyWidth = ttMoney:GetWidth()
			local ttMoneyLineWidth = myLine:GetWidth()
			ttMoney:ClearAllPoints()
			if ((ttMoney.myLineNumber < 4) and (EnhancedTooltip.hasIcon)) then
				ttMoney:SetPoint("LEFT", myLine, "RIGHT", width - ttMoneyLineWidth - ttMoneyWidth - self.moneySpacing*2 - 34, 0)
			else
				ttMoney:SetPoint("LEFT", myLine, "RIGHT", width - ttMoneyLineWidth - ttMoneyWidth - self.moneySpacing*2, 0)
			end
		end
	end
end

-- calculate the gold, silver, and copper values based the amount of copper
function getGSC(money)
	if (money == nil) then money = 0 end
	local g = math.floor(money / 10000)
	local s = math.floor((money - (g*10000)) / 100)
	local c = math.ceil(money - (g*10000) - (s*100))
	return g,s,c
end

-- formats money text by color for gold, silver, copper
function getTextGSC(money, exact, dontUseColorCodes)
	local TEXT_NONE = "0"

	local GSC_GOLD="ffd100"
	local GSC_SILVER="e6e6e6"
	local GSC_COPPER="c8602c"
	local GSC_START="|cff%s%d|r"
	local GSC_PART=".|cff%s%02d|r"
	local GSC_NONE="|cffa0a0a0"..TEXT_NONE.."|r"

	if (not exact) and (money >= 10000) then
		-- Round to nearest silver
		money = math.floor(money / 100 + 0.5) * 100
	end
	local g, s, c = getGSC(money)

	local gsc = ""
	if (not dontUseColorCodes) then
		local fmt = GSC_START
		if (g > 0) then
			gsc = gsc..string.format(fmt, GSC_GOLD, g)
			fmt = GSC_PART
		end
		if (s > 0) or (c > 0) then
			gsc = gsc..string.format(fmt, GSC_SILVER, s)
			fmt = GSC_PART
		end
		if (c > 0) then
			gsc = gsc..string.format(fmt, GSC_COPPER, c)
		end
		if (gsc == "") then
			gsc = GSC_NONE
		end
	else
		if (g > 0) then
			gsc = gsc .. g .. "g ";
		end;
		if (s > 0) then
			gsc = gsc .. s .. "s ";
		end;
		if (c > 0) then
			gsc = gsc .. c .. "c ";
		end;
		if (gsc == "") then
			gsc = TEXT_NONE
		end
	end
	return gsc
end

function embedRender()
	for pos, lData in self.embedLines do
		self.currentGametip:AddLine(lData.line)
		if (lData.r) then
			local lastLine = getglobal(self.currentGametip:GetName().."TextLeft"..self.currentGametip:NumLines())
			lastLine:SetTextColor(lData.r,lData.g,lData.b)
		end
	end
end

--[[
	@param bExact (boolean) - optional parameter
		if true, then the copper value of the given moneyAmount will always be printed out
		if false (default), then the copper value of the given moneyAmount will not be printed out, if the moneyAmount is too high (see getTextGSC for the exact limit)
		bExact has no meaning, if moneyAmount is nil.
]]
function addLine(lineText, moneyAmount, embed, bExact)
	if (embed) and (self.currentGametip) then
		EnhancedTooltip.hasEmbed = true
		EnhancedTooltip.curEmbed = true
		local line = ""
		if (moneyAmount) then
			line = lineText .. ": " .. getTextGSC(moneyAmount, bExact)
		else
			line = lineText
		end
		table.insert(self.embedLines, {line = line})
		return
	end
	EnhancedTooltip.hasData = true
	EnhancedTooltip.curEmbed = false

	local curLine = EnhancedTooltip.lineCount + 1
	local line = getglobal("EnhancedTooltipText"..curLine)
	line:SetText(lineText)
	line:SetTextColor(1.0, 1.0, 1.0)
	line:Show()
	local lineWidth = line:GetWidth()

	EnhancedTooltip.lineCount = curLine
	if (moneyAmount ~= nil) and (moneyAmount > 0) then
		local curMoney = EnhancedTooltip.moneyCount + 1
		local money = getglobal("EnhancedTooltipMoney"..curMoney)
		money:SetPoint("LEFT", line, "RIGHT", self.moneySpacing, 0)
		TinyMoneyFrame_Update(money:GetName(), math.floor(moneyAmount))
		money.myLine = line:GetName()
		money.myLineNumber = curLine
		money:Show()
		local moneyWidth = money:GetWidth()
		lineWidth = lineWidth + moneyWidth + self.moneySpacing
		getglobal("EnhancedTooltipMoney"..curMoney.."SilverButtonText"):SetTextColor(1.0,1.0,1.0)
		getglobal("EnhancedTooltipMoney"..curMoney.."CopperButtonText"):SetTextColor(0.86,0.42,0.19)
		EnhancedTooltip.moneyCount = curMoney
	end
	lineWidth = lineWidth + 20
	if (lineWidth > EnhancedTooltip.minWidth) then
		EnhancedTooltip.minWidth = lineWidth
	end
end

function addSeparator(embed)
	if (embed) and (self.currentGametip) then
		EnhancedTooltip.hasEmbed = true
		EnhancedTooltip.curEmbed = true
		table.insert(self.embedLines, {line = " "})
		return
	end
	EnhancedTooltip.hasData = true
	EnhancedTooltip.curEmbed = false

	local curLine = EnhancedTooltip.lineCount +1;
	local line = getglobal("EnhancedTooltipText"..curLine)
	line:SetText(" ");
	line:SetTextColor(1.0, 1.0, 1.0);
	line:Show();
	EnhancedTooltip.lineCount = curLine
end

function lineColor(r, g, b)
	if (EnhancedTooltip.curEmbed) and (self.currentGametip) then
		local n = table.getn(self.embedLines)
		self.embedLines[n].r = r
		self.embedLines[n].g = g
		self.embedLines[n].b = b
		return
	end
	local curLine = EnhancedTooltip.lineCount
	if (curLine == 0) then return end
	local line = getglobal("EnhancedTooltipText"..curLine)
	line:SetTextColor(r, g, b)
end

function lineSize_Large()
	if (EnhancedTooltip.curEmbed) and (self.currentGametip) then return end
	local curLine = EnhancedTooltip.lineCount
	if (curLine == 0) then return end
	local line = getglobal("EnhancedTooltipText"..curLine)
	line:SetFont(STANDARD_TEXT_FONT, 15)
end

function lineSize_Small()
	if (EnhancedTooltip.curEmbed) and (self.currentGametip) then return end
	local curLine = EnhancedTooltip.lineCount
	if (curLine == 0) then return end
	local line = getglobal("EnhancedTooltipText"..curLine)
	line:SetFont(STANDARD_TEXT_FONT, 15)
end

function lineQuality(quality)
	if ( quality ) then
		local r, g, b = GetItemQualityColor(quality)
		lineColor(r, g, b)
	else
		lineColor(1.0, 1.0, 1.0)
	end
end

function setIcon(iconPath)
	EnhancedTooltipIcon:SetTexture(iconPath)
	EnhancedTooltipIcon:Show()
	EnhancedTooltip.hasIcon = true
end

function gtHookOnHide()
	local curName = ""
	local hidingName = this:GetName()
	if (self.currentGametip) then curName = self.currentGametip:GetName() end
	if (curName == hidingName) then
		HideObj = hidingName
		self.hideTime = self.eventTimer + 0.1
	end
end

function doHyperlink(reference, link, button)
	if (ItemRefTooltip:IsVisible()) then
		local itemName = ItemRefTooltipTextLeft1:GetText()
		if (itemName and self.currentItem ~= itemName) then
			self.currentItem = itemName

			local testPopup = false
			if (button == "RightButton") then
				testPopup = true
			end
			local callRes = tooltipCall(ItemRefTooltip, itemName, link, -1, 1, 0, testPopup, reference)
			if (callRes == true) then
				self.oldChatItem = {['reference']=reference, ['link']=link, ['button']=button, ['embed']=EnhancedTooltip.hasEmbed}
			elseif (callRes == false) then
				return false;
			end
		end
	end
end

function checkHide()
	if (self.hideTime == 0) then return end

	if (self.eventTimer >= self.hideTime) then
		hideTooltip()
		if (HideObj and HideObj == "ItemRefTooltip") then
			-- closing chatreferenceTT?
			self.oldChatItem = nil -- remove old chatlink data
		elseif self.oldChatItem then
			-- closing another tooltip
			-- redisplay old chatlinkdata, if it was not embeded
			if not self.oldChatItem.embed then
				doHyperlink(self.oldChatItem.reference, self.oldChatItem.link, self.oldChatItem.button)
			end
		end
	end
end

function linkType(link)
	if type(link) ~= "string" then
		return
	end
	local _, _, linktype = string.find(link, "|H(%a+):")
	return linktype
end

function nameFromLink(link)
	local name
	if( not link ) then
		return
	end
	_, _, name = string.find(link, "|c%x+|Hitem:%d+:%d+:%d+:%d+|h%[(.-)%]|h|r");
	if (name) then
		return name;
	end
	return
end

function hyperlinkFromLink(link)
	if( not link ) then
		return
	end
	_, _, hyperlink = string.find(link, "|H([^|]+)|h");
	if (hyperlink) then
		return hyperlink;
	end
end

function baselinkFromLink(link)
	if( not link ) then
		return
	end
	_, _, baselink = string.find(link, "|Hitem:(%d+:%d+:%d+):%d+|h");
	if (baselink) then
		return baselink;
	end
end

function qualityFromLink(link)
	if (not link) then return end
	local _, _, color = string.find(link, "(|c%x+)|Hitem:%d+:%d+:%d+:%d+|h%[.-%]|h|r");
	if color then
		for i = 0, 6 do
			local _, _, _, hex = GetItemQualityColor(i)
			if color == hex then
				return i
			end
		end
	end
	return -1
end

function fakeLink(hyperlink, quality, name)
	-- make this function nilSafe, as it's a global one and might be used by external addons
	if not hyperlink then
		return
	end
	local sName, sLink, iQuality = GetItemInfo(hyperlink)
	if (quality == nil) then quality = iQuality or -1 end
	if (name == nil) then name = sName or "unknown" end
	local _, _, _, color = GetItemQualityColor(quality)
	return color.. "|H"..hyperlink.."|h["..name.."]|h|r"
end

function tooltipCall(frame, name, link, quality, count, price, forcePopup, hyperlink)
	self.currentGametip = frame
	self.hideTime = 0

	local itemSig = frame:GetName()
	if (link) then itemSig = itemSig..link end
	if (count) then itemSig = itemSig..count end
	if (price) then itemSig = itemSig..price end

	if (self.currentItem and self.currentItem == itemSig) then
		-- We are already showing this... No point doing it again.
		showTooltip(self.currentGametip)
		return
	end

	self.currentItem = itemSig

	if (quality==nil or quality==-1) then
		local linkQuality = qualityFromLink(link)
		if (linkQuality and linkQuality > -1) then
			quality = linkQuality
		else
			quality = -1
		end
	end
	if (hyperlink == nil) then hyperlink = link end
	local extract = hyperlinkFromLink(hyperlink)
	if (extract) then hyperlink = extract end

	local showTip = true
	local popupKeyPressed = (
		(self.forcePopupKey == "ctrl" and IsControlKeyDown()) or
		(self.forcePopupKey == "alt" and IsAltKeyDown()) or
		(self.forcePopupKey == "shift" and IsShiftKeyDown())
	)

	if ((forcePopup == true) or ((forcePopup == nil) and (popupKeyPressed))) then
		local popupTest = checkPopup(name, link, quality, count, price, hyperlink)
		if (popupTest) then
			showTip = false
		end
	end

	if (showTip) then
		clearTooltip()
		self.showIgnore = true
		EnhTooltip.AddTooltip(frame, name, link, quality, count, price)
		self.showIgnore = false
		showTooltip(frame)
		self.currentItem = itemSig
		return true
	else
		frame:Hide()
		hideTooltip()
		return false
	end
end



------------------------
-- Hook calling functions
------------------------

function callCheckPopup(name, link, quality, count, price, hyperlink)
	if (EnhTooltip.CheckPopup(name, link, quality, count, price, hyperlink)) then
		return true;
	end
	return false
end

function merchantScanner()
	local npcName = UnitName("NPC")
	local numMerchantItems = GetMerchantNumItems()
	local link, quality, name, texture, price, quantity, numAvailable, isUsable
	for i=1, numMerchantItems, 1 do
		link = GetMerchantItemLink(i)
		quality = qualityFromLink(link)
		name, texture, price, quantity, numAvailable, isUsable = GetMerchantItemInfo(i)
		EnhTooltip.MerchantHook(npcName, i, name, link, quality, quantity, price, numAvailable)
	end
end

function callBankHook()
	if not (BankFrame and BankFrame:IsVisible()) then return end
	EnhTooltip.BankHook(0)
end

function callBagHook(funcVars, event, bagNumber)
	if (bagNumber >= 5) and (bagNumber < 10) then
		if not (BankFrame and BankFrame:IsVisible()) then return end
		EnhTooltip.BankHook(bagNumber)
	else
		EnhTooltip.BagHook(bagNumber)
	end
end

function callTradeHook(funcVars, event, selID)
	EnhTooltip.TradeHook(funcVars[1], selID)
end



------------------------
-- Tooltip functions that we have hooked
------------------------

function chatHookOnHyperlinkShow(funcArgs, retVal, reference, link, button)
	if (IsAltKeyDown()) and AuctionFrame and (AuctionFrame:IsVisible()) then
		AuctionFrameTab_OnClick(1)
		local itemID = breakLink(link)
		if (itemID) then
			local itemName = GetItemInfo(tostring(itemID))
			if (itemName) then
				BrowseName:SetText(itemName)
				BrowseMinLevel:SetText("")
				BrowseMaxLevel:SetText("")
				AuctionFrameBrowse.selectedInvtype = nil
				AuctionFrameBrowse.selectedInvtypeIndex = nil
				AuctionFrameBrowse.selectedClass = nil
				AuctionFrameBrowse.selectedClassIndex = nil
				AuctionFrameBrowse.selectedSubclass = nil
				AuctionFrameBrowse.selectedSubclassIndex = nil
				AuctionFrameFilters_Update()
				IsUsableCheckButton:SetChecked(0)
				UIDropDownMenu_SetSelectedValue(BrowseDropDown, -1)
				AuctionFrameBrowse_Search()
				BrowseNoResultsText:SetText(BROWSE_NO_RESULTS)
				ItemRefTooltip:Hide()
			end
		end
		return
	end

	doHyperlink(reference, link, button)
end

function afHookOnEnter(funcArgs, retVal, type, index)
	local link = GetAuctionItemLink(type, index)
	if (link) then
		local name = nameFromLink(link)
		if (name) then
			local aiName, aiTexture, aiCount, aiQuality, aiCanUse, aiLevel, aiMinBid, aiMinIncrement, aiBuyoutPrice, aiBidAmount, aiHighBidder, aiOwner = GetAuctionItemInfo(type, index)
			tooltipCall(GameTooltip, name, link, aiQuality, aiCount)
		end
	end
end

function cfHookUpdate(funcArgs, retVal, frame)
	local frameID = frame:GetID()
	local frameName = frame:GetName()
	local iButton
	for iButton = 1, frame.size do
		local button = getglobal(frameName.."Item"..iButton)
		if (GameTooltip:IsOwned(button)) then
			local buttonID = button:GetID()
			local link = GetContainerItemLink(frameID, buttonID)
			local name = nameFromLink(link)

			if (name) then
				local texture, itemCount, locked, quality, readable = GetContainerItemInfo(frameID, buttonID)
				if (quality == nil) then quality = qualityFromLink(link) end

				tooltipCall(GameTooltip, name, link, quality, itemCount)
			end
		end
	end
end

function gtHookSetLootItem(funcArgs, retVal, frame, slot)
	local link = GetLootSlotLink(slot)
	local name = nameFromLink(link)
	if (name) then
		local texture, item, quantity, quality = GetLootSlotInfo(slot)
		if (quality == nil) then quality = qualityFromLink(link) end
		tooltipCall(GameTooltip, name, link, quality, quantity)
	end
end

function gtHookSetQuestItem(funcArgs, retVal, frame, qtype, slot)
	local link = GetQuestItemLink(qtype, slot)
	if (link) then
		local name, texture, quantity, quality, usable = GetQuestItemInfo(qtype, slot)
		tooltipCall(GameTooltip, name, link, quality, quantity)
	end
end

function gtHookSetQuestLogItem(funcArgs, retVal, frame, qtype, slot)
	local link = GetQuestLogItemLink(qtype, slot)
	if (link) then
		local name, texture, quantity, quality, usable = GetQuestLogRewardInfo(slot)
		if (name == nil) then name = nameFromLink(link) end
		quality = qualityFromLink(link) -- I don't trust the quality returned from the above function.

		tooltipCall(GameTooltip, name, link, quality, quantity)
	end
end

function gtHookSetBagItem(funcArgs, retVal, frame, frameID, buttonID)
	local link = GetContainerItemLink(frameID, buttonID)
	local name = nameFromLink(link)

	if (name) then
		local texture, itemCount, locked, quality, readable = GetContainerItemInfo(frameID, buttonID)
		if (quality==nil or quality==-1) then quality = qualityFromLink(link) end

		tooltipCall(GameTooltip, name, link, quality, itemCount)
	end
end

function gtHookSetInboxItem(funcArgs, retVal, frame, index)
	local inboxItemName, itemTexture, inboxItemCount, inboxItemQuality = GetInboxItem(index)
	local itemName, hyperLink, itemQuality, itemLink

	for itemID = 1, 30000 do
		itemName, hyperLink, itemQuality = GetItemInfo(itemID)
		if (itemName and itemName == inboxItemName) then
			local _, _, _, hex = GetItemQualityColor(tonumber(itemQuality))
			itemLink = hex.. "|H"..hyperLink.."|h["..itemName.."]|h|r"
			tooltipCall(GameTooltip, inboxItemName, itemLink, inboxItemQuality, inboxItemCount)
			break
		end
	end
	
end

function gtHookSetInventoryItem(funcArgs, retVal, frame, unit, slot)
	local link = GetInventoryItemLink(unit, slot)
	if (link) then
		local name = nameFromLink(link)
		local quantity
		if (slot >= 20 and slot <= 23) then
			-- Workaround for bag slots. Quiver slots report the number of
			-- arrows in there instead of 1 for the actual bag.
			-- And well, bags aren't stackable anyway, so here you go:
			quantity = 1
		else
			-- Should be 1 for anything but quivers, because even empty slots
			-- return 1.. but who knows what crazy stuff Blizzard will add ;)
			quantity = GetInventoryItemCount(unit, slot)
		end
		local quality = GetInventoryItemQuality(unit, slot)
		if (quality == nil) then quality = qualityFromLink(link) end

		tooltipCall(GameTooltip, name, link, quality, quantity)
	end
end

function gtHookSetMerchantItem(funcArgs, retVal, frame, slot)
	local link = GetMerchantItemLink(slot)
	if (link) then
		local name, texture, price, quantity, numAvailable, isUsable = GetMerchantItemInfo(slot)
		local quality = qualityFromLink(link)
		tooltipCall(GameTooltip, name, link, quality, quantity, price)
	end
end

function gtHookSetCraftItem(funcArgs, retVal, frame, skill, slot)
	local link
	if (slot) then
		link = GetCraftReagentItemLink(skill, slot)
		if (link) then
			local name, texture, quantity, quantityHave = GetCraftReagentInfo(skill, slot)
			local quality = qualityFromLink(link)
			tooltipCall(GameTooltip, name, link, quality, quantity, 0)
		end
	else
		link = GetCraftItemLink(skill)
		if (link) then
			local name = nameFromLink(link)
			local quality = qualityFromLink(link)
			tooltipCall(GameTooltip, name, link, quality, 1, 0)
		end
	end
end

function gtHookSetCraftSpell(funcArgs, retVal, frame, slot)
	local name = GetCraftInfo(slot)
	local link = GetCraftItemLink(slot)
	if name and link then
		tooltipCall(GameTooltip, name, link)
	end
end

function gtHookSetTradeSkillItem(funcArgs, retVal, frame, skill, slot)
	local link
	if (slot) then
		link = GetTradeSkillReagentItemLink(skill, slot)
		if (link) then
			local name, texture, quantity, quantityHave = GetTradeSkillReagentInfo(skill, slot)
			local quality = qualityFromLink(link)
			tooltipCall(GameTooltip, name, link, quality, quantity, 0)
		end
	else
		link = GetTradeSkillItemLink(skill)
		if (link) then
			local name = nameFromLink(link)
			local quality = qualityFromLink(link)
			tooltipCall(GameTooltip, name, link, quality, 1, 0)
		end
	end
end

-- Given a Blizzard item link, breaks it into it's itemID, randomProperty, enchantProperty, uniqueness and name
function breakLink(link)
	if (type(link) ~= 'string') then return end
	local i,j, itemID, enchant, randomProp, uniqID, name = string.find(link, "|Hitem:(%d+):(%d+):(%d+):(%d+)|h[[]([^]]+)[]]|h")
	return tonumber(itemID or 0), tonumber(randomProp or 0), tonumber(enchant or 0), tonumber(uniqID or 0), name
end


function findItemInBags(findName)
	for bag = 0, 4, 1 do
		size = GetContainerNumSlots(bag)
		if (size) then
			for slot = size, 1, -1 do
				local link = GetContainerItemLink(bag, slot)
				if (link) then
					local itemID, randomProp, enchant, uniqID, itemName = breakLink(link)
					if (itemName == findName) then
						return bag, slot, itemID, randomProp, enchant, uniqID
					end
				end
			end
		end
	end
end

function gtHookSetAuctionSellItem(funcArgs, retVal, frame)
	local name, texture, quantity, quality, canUse, price = GetAuctionSellItemInfo()
	if (name) then
		local bag, slot = findItemInBags(name)
		if (bag) then
			local link = GetContainerItemLink(bag, slot)
			if (link) then
				tooltipCall(GameTooltip, name, link, quality, quantity, price)
			end
		end
	end
end

function gtHookSetText(funcArgs, retval, frame, text, r, g, b, a, textWrap)
	-- Nothing to do for plain text
	if (self.currentGametip == frame) then
		clearTooltip()
	end
end

function gtHookAppendText(funcArgs, retVal, frame)
	if (self.currentGametip and self.currentItem and self.currentItem ~= "") then
		showTooltip(self.currentGametip, true)
	end
end

function gtHookShow(funcArgs, retVal, frame)
	if (self.hookRecursion) then
		return;
	end
	if (self.currentGametip and self.currentItem and self.currentItem ~= "") then
		self.hookRecursion = true;
		showTooltip(self.currentGametip, true)
		self.hookRecursion = nil;
	end
end

function imiHookOnEnter()
	if(not IM_InvList) then return end
	local id = this:GetID()

	if(id == 0) then
		id = this:GetParent():GetID()
	end
	local offset = FauxScrollFrame_GetOffset(ItemsMatrix_IC_ScrollFrame)
	local item = IM_InvList[id + offset]

	if (not item) then return end
	local imlink = ItemsMatrix_GetHyperlink(item.name)
	local link = fakeLink(imlink, item.quality, item.name)
	if (link) then
		tooltipCall(GameTooltip, item.name, link, item.quality, item.count, 0)
	end
end

function imHookOnEnter()
	local imlink = ItemsMatrix_GetHyperlink(this:GetText())
	if (imlink) then
		local name = this:GetText()
		local link = fakeLink(imlink, -1, name)
		tooltipCall(GameTooltip, name, link, -1, 1, 0)
	end
end

function getLootLinkServer()
	return LootLinkState.ServerNamesToIndices[GetCVar("realmName")]
end

function getLootLinkLink(name)
	local itemLink = ItemLinks[name]
	if (itemLink and itemLink.c and itemLink.i and LootLink_CheckItemServer(itemLink, getLootLinkServer())) then
		local item = string.gsub(itemLink.i, "(%d+):(%d+):(%d+):(%d+)", "%1:0:%3:%4")
		local link = "|c"..itemLink.c.."|Hitem:"..item.."|h["..name.."]|h|r"
		return link
	end
	return
end

function llHookOnEnter()
	local name = this:GetText()
	local link = getLootLinkLink(name)
	if (link) then
		local quality = qualityFromLink(link)
		tooltipCall(LootLinkTooltip, name, link, quality, 1, 0)
	end
end

function gtHookSetOwner(funcArgs, retVal, frame, owner, anchor)
	frame.owner = owner
	frame.anchor = anchor
end

------------------------
-- Operation functions
------------------------

function setElapsed(elapsed)
	if (elapsed) then
		self.eventTimer = self.eventTimer + elapsed
	end
	checkHide()
	return self.eventTimer
end

function setMoneySpacing(spacing)
	if (spacing ~= nil) then self.moneySpacing = spacing end
	return self.moneySpacing
end

function setPopupKey(key)
	if (key ~= nil) then self.forcePopupKey = key end
	return self.forcePopupKey
end


------------------------
-- Debug functions
------------------------

local function dump(...)
	local out = "";
	for i = 1, arg.n, 1 do
		local d = arg[i];
		local t = type(d);
		if (t == "table") then
			out = out .. "{";
			local first = true;
			if (d) then
				for k, v in pairs(d) do
					if (not first) then out = out .. ", "; end
					first = false;
					out = out .. dump(k);
					out = out .. " = ";
					out = out .. dump(v);
				end
			end
			out = out .. "}";
		elseif (t == "nil") then
			out = out .. "NIL";
		elseif (t == "number") then
			out = out .. d;
		elseif (t == "string") then
			out = out .. "\"" .. d .. "\"";
		elseif (t == "boolean") then
			if (d) then
				out = out .. "true";
			else
				out = out .. "false";
			end
		else
			out = out .. string.upper(t) .. "??";
		end

		if (i < arg.n) then out = out .. ", "; end
	end
	return out;
end

function debugPrint(...)
	local debugWin = 0;
	local name, shown;
	for i=1, NUM_CHAT_WINDOWS do
		name,_,_,_,_,_,shown = GetChatWindowInfo(i);
		if (string.lower(name) == "ettdebug") then debugWin = i; break; end
	end
	if (debugWin == 0) then return end

	local out = "";
	for i = 1, arg.n, 1 do
		if (i > 1) then out = out .. ", "; end
		local t = type(arg[i]);
		if (t == "string") then
			out = out .. '"'..arg[i]..'"';
		elseif (t == "number") then
			out = out .. arg[i];
		else
			out = out .. dump(arg[i]);
		end
	end
	getglobal("ChatFrame"..debugWin):AddMessage(out, 1.0, 1.0, 0.3);
end


------------------------
-- Load and initialization functions
------------------------

--The new blizzard addons are called:
--	Blizzard_TrainerUI,		Blizzard_MacroUI,		Blizzard_RaidUI,		Blizzard_TradeSkillUI,
--	Blizzard_InspectUI,		Blizzard_BattlefieldMinimap,	Blizzard_TalentUI,
--	Blizzard_AuctionUI,		Blizzard_BindingUI,		Blizzard_CraftUI


-- Hook in alternative Auctionhouse tooltip code
local function hookAuctionHouse()
	Stubby.RegisterFunctionHook("AuctionFrameItem_OnEnter", 200, afHookOnEnter)
end

-- Hook the ItemsMatrix tooltip functions
local function hookItemsMatrix()
	Stubby.RegisterFunctionHook("IMInv_ItemButton_OnEnter", 200, imiHookOnEnter)
	Stubby.RegisterFunctionHook("ItemsMatrixItemButton_OnEnter", 200, imHookOnEnter)
end

-- Hook the LootLink tooltip function
local function hookLootLink()
	Stubby.RegisterFunctionHook("LootLinkItemButton_OnEnter", 200, llHookOnEnter)
end

-- Hook tradeskill functions
local function hookTradeskill()
	Stubby.RegisterFunctionHook("TradeSkillFrame_Update", 200, callTradeHook, "trade", "")
	Stubby.RegisterFunctionHook("TradeSkillFrame_SetSelection", 200, callTradeHook, "trade", "")
end

-- Hook craft functions
local function hookCraft()
	Stubby.RegisterFunctionHook("CraftFrame_Update", 200, callTradeHook, "craft", "");
	Stubby.RegisterFunctionHook("CraftFrame_SetSelection", 200, callTradeHook, "craft", "");
end

function ttInitialize()
	----  Establish hooks to all the game tooltips.

	-- Hook in alternative Chat/Hyperlinking code
	Stubby.RegisterFunctionHook("ChatFrame_OnHyperlinkShow", 200, chatHookOnHyperlinkShow)

	-- Container frame linking
	Stubby.RegisterFunctionHook("ContainerFrame_Update", 200, cfHookUpdate)

	-- Game tooltips
	Stubby.RegisterFunctionHook("GameTooltip.SetLootItem", 200, gtHookSetLootItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetQuestItem", 200, gtHookSetQuestItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetQuestLogItem", 200, gtHookSetQuestLogItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetInboxItem", 200, gtHookSetInboxItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetInventoryItem", 200, gtHookSetInventoryItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetBagItem", 200, gtHookSetBagItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetMerchantItem", 200, gtHookSetMerchantItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetCraftItem", 200, gtHookSetCraftItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetCraftSpell", 200, gtHookSetCraftSpell);
	Stubby.RegisterFunctionHook("GameTooltip.SetTradeSkillItem", 200, gtHookSetTradeSkillItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetAuctionSellItem", 200, gtHookSetAuctionSellItem);
	Stubby.RegisterFunctionHook("GameTooltip.SetText", 200, gtHookSetText);
	Stubby.RegisterFunctionHook("GameTooltip.AppendText", 200, gtHookAppendText);
	Stubby.RegisterFunctionHook("GameTooltip.SetOwner", 200, gtHookSetOwner);
	Stubby.RegisterFunctionHook("GameTooltip.Show", 200, gtHookShow);
	Stubby.RegisterFunctionHook("GameTooltip_OnHide", 200, gtHookOnHide);

	-- Establish hooks for us to use.
	Stubby.RegisterAddOnHook("Blizzard_AuctionUI", "EnhTooltip", hookAuctionHouse)
	Stubby.RegisterAddOnHook("ItemsMatrix", "EnhTooltip", hookItemsMatrix)
	Stubby.RegisterAddOnHook("LootLink", "EnhTooltip", hookLootLink)
	Stubby.RegisterAddOnHook("Blizzard_TradeSkillUI", "EnhTooltip", hookTradeskill)
	Stubby.RegisterAddOnHook("Blizzard_CraftUI", "EnhTooltip", hookCraft)

	-- Register event notification
	Stubby.RegisterEventHook("MERCHANT_SHOW", "EnhTooltip", merchantScanner);
	Stubby.RegisterEventHook("TRADE_SKILL_SHOW", "EnhTooltip", callTradeHook, 'trade');
	Stubby.RegisterEventHook("TRADE_SKILL_CLOSE", "EnhTooltip", callTradeHook, 'trade');
	Stubby.RegisterEventHook("CRAFT_SHOW", "EnhTooltip", callTradeHook, 'craft');
	Stubby.RegisterEventHook("CRAFT_CLOSE", "EnhTooltip", callTradeHook, 'craft');
	Stubby.RegisterEventHook("BANKFRAME_OPENED", "EnhTooltip", callBankHook);
	Stubby.RegisterEventHook("PLAYERBANKSLOTS_CHANGED", "EnhTooltip", callBankHook);
	Stubby.RegisterEventHook("BAG_UPDATE", "EnhTooltip", callBagHook);
end


-- =============== EVENT HANDLERS =============== --

function TT_OnLoad()
	EnhancedTooltip:SetBackdropColor(0,0,0)
	clearTooltip()
	ttInitialize()
end

function TT_OnUpdate(elapsed)
	setElapsed(elapsed)
end

-- =============== DEFINE ACCESS OBJECT =============== --

-- Global object
EnhTooltip = {
	AddTooltip			= addTooltip,
	CheckPopup			= checkPopup,
	MerchantHook		= merchantHook,
	TradeHook			= tradeHook,
	BankHook			= bankHook,
	BagHook				= bagHook,

	AddLine				= addLine,
	AddSeparator		= addSeparator,
	LineColor			= lineColor,
	LineQuality			= lineQuality,
	LineSize_Large		= lineSize_Large,
	LineSize_Small		= lineSize_Small,
	SetIcon				= setIcon,

	ClearTooltip		= clearTooltip,
	HideTooltip			= hideTooltip,
	ShowTooltip			= showTooltip,

	GetglobalIterator	= getglobalIterator,
	GetGSC				= getGSC,
	GetTextGSC			= getTextGSC,
	BaselinkFromLink	= baselinkFromLink,
	BreakLink			= breakLink,
	FindItemInBags		= findItemInBags,

	FakeLink			= fakeLink,
	HyperlinkFromLink	= hyperlinkFromLink,
	NameFromLink		= nameFromLink,
	QualityFromLink		= qualityFromLink,
	LinkType			= linkType,

	SetMoneySpacing		= setMoneySpacing,
	SetPopupKey			= setPopupKey,
	TooltipCall			= tooltipCall,

	SetElapsed			= setElapsed,
	DebugPrint			= debugPrint,
}
