--
--	LinkHeaven v0.97a
--	by Standil (cpascal@cpascal.net)
--	* Character: [KOR] Prestol server Mony
--
--	GameTooltip codes are from ManyItemTooltips by Freki.
--

LH_VERSION = "0.97";
LH_REVISION = "a";

LH_MAX_TOOLTIP = 20;

LH_HOOKED = false;

LH_CALLER = {
	"ReagentHeaven_ModifyTooltip"
};

local LH_ORG_SetItemRef;
local LH_MENU = nil;
local LH_REAGENTHEAVEN_BUTTON = nil;
local LH_EQUIPCOMPARE_BUTTON = nil;

function LinkHeaven_Chat( msg )
	if( DEFAULT_CHAT_FRAME ) then
		DEFAULT_CHAT_FRAME:AddMessage( msg, 0.0, 1.0, 0.0 );
	end
end

function LinkHeaven_OtherAddonHook()
	if( LH_HOOKED == false ) then
		LH_ORG_SetItemRef = SetItemRef;
		SetItemRef = LinkHeaven_SetItemRef;
		LH_HOOKED = true;
	end
end

function LinkHeaven_OnEvent( event )
	if( event == "VARIABLES_LOADED" ) then
		if( not LH_MAX_USER_TOOLTIP ) then
			LH_MAX_USER_TOOLTIP = LH_MAX_TOOLTIP;
		end
		if( LH_EXTRA_CALLER ) then
			local vIndex, vFunctionName, vFunction;

			for vIndex, vFunctionName in pairs( LH_EXTRA_CALLER ) do
				table.insert( LH_CALLER, vFunctionName );
			end
		else
			LH_EXTRA_CALLER = {};
		end
	elseif( event == "PLAYER_ENTERING_WORLD" ) then
		LinkHeaven_OtherAddonHook();
	end
end

function LinkHeavenOptionSet( varname, value )
	if( not LH_OPTIONS ) then
		LH_OPTIONS = {};
	end
	LH_OPTIONS[varname] = value;
end

function LinkHeavenOptionGet( varname )
	if( not LH_OPTIONS ) then
		return "";
	end
	if( not LH_OPTIONS[varname] ) then
		return "";
	end
	return LH_OPTIONS[varname];
end

function LinkHeaven_DisplayHelpText( frame )
	if ( not frame ) then
		return;
	end

	local info = ChatTypeInfo["SYSTEM"];
	local i = 1;
	local text = TEXT(getglobal("LINKHEAVEN_HELP_TEXT_LINE"..i));
	while text do
		frame:AddMessage(text, info.r, info.g, info.b, info.id);
		i = i + 1;
		text = TEXT(getglobal("LINKHEAVEN_HELP_TEXT_LINE"..i));
	end
end

function LinkHeaven_DeleteCaller( nameTable, functionName )
	local k, v, bFound = false;

	for k, v in pairs( nameTable ) do
		if( v == functionName ) then
			table.remove( nameTable, k );
			bFound = true;
		end
	end
	return bFound;
end

-- LinkHeaven_HandleSlashCmd( msg )
-- This function is called when a user types one of your slash commands
-- the text they enter after the command comes in msg
function LinkHeaven_HandleSlashCmd( msg )
	local cmd = string.gsub( msg, "%s*([^%s]+)%s(.*)", "%1" );
	if( cmd == msg ) then
		msg = nil;
	else
		msg = string.sub( msg, strlen( cmd ) + 2 );
	end
	cmd = string.lower( cmd );
	if( (cmd == nil) or (cmd == "") ) then
		LinkHeaven_DisplayHelpText( this.chatFrame );
	elseif( (cmd == "showicon") or (cmd == LINKHEAVEN_CMD_SHOWICON) ) then
		LinkHeavenOptionSet( "SHOWICON", "1" );
		LinkHeaven_Chat( LINKHEAVEN_DONE );
		LinkHeaven_CloseAllTooltip();
	elseif( (cmd == "hideicon") or (cmd == LINKHEAVEN_CMD_HIDEICON) ) then
		LinkHeavenOptionSet( "SHOWICON", "0" );
		LinkHeaven_Chat( LINKHEAVEN_DONE );
		LinkHeaven_CloseAllTooltip();
	else
		if( not msg ) then
			LinkHeaven_DisplayHelpText( this.chatFrame );
			return;
		end
		local strArgument = gsub( msg, "%s*([^%s]+).*", "%1" );
		if( not strArgument ) then
			LinkHeaven_DisplayHelpText( this.chatFrame );
			return;
		end
		if( (cmd == "setcount") or (cmd == LINKHEAVEN_CMD_SETCOUNT) ) then
			local iValue = tonumber( strArgument );

			if( (iValue > 0) and (iValue < 21) ) then
				LH_MAX_USER_TOOLTIP = iValue;
				LinkHeaven_Chat( LINKHEAVEN_DONE );
				LinkHeaven_CloseAllTooltip();
			end
		elseif( (cmd == "addaddon") or (cmd == LINKHEAVEN_CMD_ADDADDON) ) then
			local vFunction = getglobal( strArgument );
			if( (not vFunction) or (type( vFunction ) ~= "function") ) then
				LinkHeaven_Chat( LINKHEAVEN_FUNCTION_NOTFOUND );
				return;
			end
			table.insert( LH_EXTRA_CALLER, strArgument );
			table.insert( LH_CALLER, strArgument );
			LinkHeaven_Chat( LINKHEAVEN_DONE );
			LinkHeaven_CloseAllTooltip();
		elseif( (cmd == "deleteaddon") or (cmd == LINKHEAVEN_CMD_DELETEADDON) ) then
			local bRet1 = LinkHeaven_DeleteCaller( LH_EXTRA_CALLER, strArgument );
			local bRet2 = LinkHeaven_DeleteCaller( LH_CALLER, strArgument );

			if( (bRet1 == true) or (bRet2 == true) ) then
				LinkHeaven_Chat( LINKHEAVEN_DONE );
				LinkHeaven_CloseAllTooltip();
			end
		else
			LinkHeaven_DisplayHelpText( this.chatFrame );
		end
	end
end

function LinkHeaven_OnLoad()
	-- Events
	this:RegisterEvent( "VARIABLES_LOADED" );
	this:RegisterEvent( "PLAYER_ENTERING_WORLD" );

	-- Slash Commands
	SlashCmdList['LINKHEAVEN'] = LinkHeaven_HandleSlashCmd;
	SLASH_LINKHEAVEN1 = '/linkheaven';
	SLASH_LINKHEAVEN2 = '/lh';
	SLASH_LINKHEAVEN3 = LINKHEAVEN_LOCALIZED_COMMAND1;
	SLASH_LINKHEAVEN4 = LINKHEAVEN_LOCALIZED_COMMAND2;

	for i=1,LH_MAX_TOOLTIP do
		table.insert( UISpecialFrames, "LH_TOOLTIP_"..i );
	end
	table.insert( UIMenus, "LinkHeavenDropDown" );

	LinkHeaven_Chat( "Standil(Mony)'s LinkHeaven(v"..LH_VERSION..LH_REVISION..") AddOn loaded." );
	UIErrorsFrame:AddMessage( "Standil(Mony)'s LinkHeaven(v"..LH_VERSION..LH_REVISION..") AddOn loaded", 1.0, 1.0, 1.0, 1.0, UIERRORS_HOLD_TIME );
end

function LinkHeaven_CloseAllTooltip()
	for i=LH_MAX_USER_TOOLTIP, 1, -1 do
		local frame = getglobal( "LH_TOOLTIP_"..i );
		if ( frame:IsVisible() ) then
			frame:Hide();
		end
	end
end

function LinkHeaven_NameFromHyperLink( hyperLink )
	local name;

	if( not hyperLink ) then
		return nil;
	end
	for name in string.gmatch( hyperLink, "|c%x+|Hitem:%d+:%d+:%d+:%d+|h%[(.-)%]|h|r" ) do
		return name;
	end
	return nil;
end

function LinkHeaven_SellValue_OnShow( frame, itemName )
	if( SellValues and not MerchantFrame:IsVisible() ) then
		local itemShortName = InvList_ShortenItemName( itemName );
		
		-- Don't add a tooltip for hidden items
		if( not InvList_TooltipMode or (InvList_TooltipMode == 1 and InvList_HiddenItems and InvList_HiddenItems[itemName]) ) then
			return;
		end
		local price = SellValues[itemShortName];

		if( price ) then
			local linesAdded = 0;
			if price == 0 then
				frame:AddLine( ITEM_UNSELLABLE, 1.0, 1.0, 0 );
				linesAdded = 1;
			else
				frame:AddLine( SELLVALUE_COST, 1.0, 1.0, 0 );
				SetTooltipMoney( frame, price );
				linesAdded = 2;
                    
				if InvList_TooltipShowStackTotal then
					MoneyFrame_Update( "SellValueMoneyFrame", price * 2 );
					linesAdded = 3;
				end  -- if showstacktotal
			end  -- if price > 0

			-- Adjust width and height to account for new lines
			frame:SetHeight( frame:GetHeight() + (14 * linesAdded) );
			if frame:GetWidth() < 120 then 
				frame:SetWidth(120); 
			end
		end  -- if price
	end
end

function LinkHeaven_SetItemRef( link, text, button )
	if( string.sub( link, 1, string.find( link, ":" ) - 1 ) ~= "item" ) then
		LH_ORG_SetItemRef( link, text, button );
		return;
	end

	if( IsAltKeyDown() ) then
		LH_ORG_SetItemRef( link, text, button );
		return;
	end
	if( IsControlKeyDown() ) then
		DressUpItemLink( text );
		return;
	elseif( IsShiftKeyDown() ) then
		if ( ChatFrameEditBox:IsVisible() ) then
			ChatFrameEditBox:Insert(text);
		end
		return;
	end

	if( not LH_MAX_USER_TOOLTIP ) then
		LH_MAX_USER_TOOLTIP = LH_MAX_TOOLTIP;
	end

	local i;

	for i=LH_MAX_USER_TOOLTIP, 1, -1 do
		local frame = getglobal( "LH_TOOLTIP_"..i );
		if( frame:IsVisible() ) then
			if( frame.LH_link and (frame.LH_link == link) ) then
				frame:Hide();
				return;
			end
		end
	end

	for i=1, LH_MAX_USER_TOOLTIP do
		local frame = getglobal( "LH_TOOLTIP_"..i );
		if ( not frame:IsVisible() ) then
			local itemName,_,quality,_,_,_,_,_,_,texture = GetItemInfo( link );
			if( not itemName ) then
				itemName = LinkHeaven_NameFromHyperLink( text );
			end

			frame.LH_itemName = itemName;
			frame.LH_link = link;
			frame.LH_hyperlink = text;
			frame:Show();
			if ( not frame:IsVisible() ) then
				frame:SetOwner( UIParent, "ANCHOR_PRESERVE" );
			end
			for i=2,30 do
				local textleft = getglobal( frame:GetName().."TextLeft"..i );
				local textright = getglobal( frame:GetName().."TextRight"..i );

				if( textleft ) then
					textleft:SetText("");
				end
				if( textright ) then
					textright:SetText("");
				end
			end
			frame:SetHyperlink( link );
			frame:Show();

			local iconFrame = getglobal( "LH_TOOLTIP_"..i.."Icon" );
			if( iconFrame ) then
				if( LinkHeavenOptionGet( "SHOWICON" ) ~= "0" ) then
					if( texture ) then
						iconFrame:SetTexture( texture );
					else
						iconFrame:SetTexture( "Interface\Icons\INV_Misc_QuestionMark" );
					end
				else
					iconFrame:Hide();
				end
			end

			local vIndex, vFunctionName, vFunction;

			if( LH_CALLER ) then
				for vIndex, vFunctionName in pairs( LH_CALLER ) do
					vFunction = getglobal( vFunctionName );
					if( vFunction ) then
						vFunction( frame, link );
					end
				end
			end

			if( IsAddOnLoaded( "NuguDrop" ) ) then
				NuguDrop_OnShow( "LH_TOOLTIP_"..i );
			end

			if( IsAddOnLoaded( "SellValue" ) ) then
				LinkHeaven_SellValue_OnShow( frame, itemName );
			end

			-- Auctioneer and EnhTooltip compatability
			if( itemName and (TT_Clear or EnhTooltip) ) then
				if( TT_Clear ) then
					TT_Clear();
					TT_TooltipCall( frame, itemName, text, quality, 1, 0 );
					TT_Show( frame );
				elseif( EnhTooltip.TooltipCall ) then
					EnhTooltip.ClearTooltip();
					EnhTooltip.TooltipCall( frame, itemName, text, quality, 1, 0 );
				end
			end

			return;
		end
	end

	LinkHeaven_Chat( LINKHEAVEN_EXCEED_LIMIT );
end

function LinkHeaven_Tooltip_OnHide()
	if( TT_Clear or EnhTooltip ) then
		if( TT_Clear ) then
			TT_Clear();
		elseif( EnhTooltip.ClearTooltip ) then
			EnhTooltip.ClearTooltip();
		end
	end
end

function LinkHeaven_PasteToChatFrame( text )
	if ( not ChatFrameEditBox:IsVisible() ) then
		ChatFrame_OpenChat( text );
	else
		ChatFrameEditBox:SetText( ChatFrameEditBox:GetText()..text );
	end
end

function LinkHeaven_GetCurrentGameTooltipFrame()
	if( not LH_MENU ) then
		return nil;
	end
	return getglobal( LH_MENU );
end

function LinkHeaven_DressUp()
	local frame = LinkHeaven_GetCurrentGameTooltipFrame();

	if( frame and frame.LH_hyperlink ) then
		DressUpItemLink( frame.LH_hyperlink );
	end
end

function LinkHeaven_Relink()
	local frame = LinkHeaven_GetCurrentGameTooltipFrame();

	if( frame and frame.LH_hyperlink ) then
		LinkHeaven_PasteToChatFrame( frame.LH_hyperlink );
	end
end

function LinkHeaven_PasteReagents()
	local frame = LinkHeaven_GetCurrentGameTooltipFrame();

	if( frame and frame.LH_itemName ) then
		local reagentsText = ReagentHeaven_PasteReagents( frame.LH_itemName );
		if( reagentsText ) then
			LinkHeaven_PasteToChatFrame( reagentsText );
		end
	end
end

function LinkHeaven_CompareEquip()
	local frame = LinkHeaven_GetCurrentGameTooltipFrame();

	if( frame ) then
		EquipCompare_ShowCompare( frame );
	end
end

function LinkHeavenDropDown_OnLoad()
	UIMenu_Initialize();
	if( EquipCompare_ShowCompare ) then
		UIMenu_AddButton( TEXT(LH_MENU_COMPAREEQUIP), nil, LinkHeaven_CompareEquip );
		LH_EQUIPCOMPARE_BUTTON = this.numButtons;
	end
	if( ReagentHeaven_PasteReagents ) then
		UIMenu_AddButton( TEXT(LH_MENU_PASTEREAGENTS), nil, LinkHeaven_PasteReagents );
		LH_REAGENTHEAVEN_BUTTON = this.numButtons;
	end
	UIMenu_AddButton( TEXT(LH_MENU_DRESSUP), nil, LinkHeaven_DressUp );
	UIMenu_AddButton( TEXT(LH_MENU_RELINK), nil, LinkHeaven_Relink );
end

function LinkHeavenDropDown_Enable( nID, bEnabled )
	local menuButton = getglobal( "LinkHeavenDropDownButton"..nID );

	if( menuButton ) then
		if( bEnabled == true ) then
			menuButton:Enable();
		else
			menuButton:Disable();
		end
	end
end

function LinkHeavenDropDown_ShowMenu( parentFrame )
	LH_MENU = parentFrame:GetName();
	if( ReagentHeaven_PasteReagents and LH_REAGENTHEAVEN_BUTTON ) then
		local frame = LinkHeaven_GetCurrentGameTooltipFrame();

		if( frame and RH_PRODUCTS[ frame.LH_itemName ] ) then
			LinkHeavenDropDown_Enable( LH_REAGENTHEAVEN_BUTTON, true );
		else
			LinkHeavenDropDown_Enable( LH_REAGENTHEAVEN_BUTTON, false );
		end
	end
	if( EquipCompare_ShowCompare ) then
		local frame = LinkHeaven_GetCurrentGameTooltipFrame();

		local ttext, itype;
		local slotid = nil;
		local i = 2;
		repeat
			ttext = getglobal( frame:GetName().."TextLeft"..i );
			if ( ttext and ttext:IsVisible() ) then
				itype = ttext:GetText();
				if ( itype ) then
					slotid = EquipCompare_ItemTypes[itype];
				end
			end
			i = i + 1;
		until( slotid or i > 5 )
		if( slotid ) then
			LinkHeavenDropDown_Enable( LH_EQUIPCOMPARE_BUTTON, true );
		else
			LinkHeavenDropDown_Enable( LH_EQUIPCOMPARE_BUTTON, false );
		end
	end
	LinkHeavenDropDown:SetPoint("BOTTOMRIGHT", parentFrame, "TOPRIGHT", 0, -2 );
	LinkHeavenDropDown:Show();
end

