-- Constants
TITAN_ARTWORK_PATH = "Interface\\AddOns\\Titan\\Artwork\\";
TITAN_THRESHOLD_EXCEPTION_COLOR = GRAY_FONT_COLOR;

-- Tables
TITAN_PANEL_NONMOVABLE_PLUGINS = {"Clock", "Volume", "UIScale", "Trans", "AutoHide", "AuxAutoHide"};

TitanPlugins = {};
TitanPluginsIndex = {};

function TitanDebug(debug_message)
	-- Default green color
	DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00" .. TITAN_DEBUG .. " " .. debug_message);
end

function TitanUtils_GetNextButtonOnBar(bar, id, side)
	local index = TitanUtils_GetCurrentIndex(TitanPanelSettings.Buttons, id);
	
	for i, id in pairs(TitanPanelSettings.Buttons) do
		if TitanUtils_GetWhichBar(id) == bar and i > index and TitanPanel_GetPluginSide(id) == side then
			return i;
		end
	end
end

function TitanUtils_GetRealPosition(id)
	local i = TitanPanel_GetButtonNumber(id);
	if TitanPanelSettings.Location[i] == "Bar" and TitanPanelGetVar("BothBars") then
		return TITAN_PANEL_PLACE_TOP;
	elseif TitanPanelSettings.Location[i] == "Bar" then
		return TitanPanelGetVar("Position");
	else
		return TITAN_PANEL_PLACE_BOTTOM;
	end
end

function TitanUtils_GetWhichBar(id)
	local i = TitanPanel_GetButtonNumber(id);
	return TitanPanelSettings.Location[i];
end

function TitanUtils_GetDoubleBar(bothbars, framePosition)
	if framePosition == TITAN_PANEL_PLACE_TOP then
		return TitanPanelGetVar("DoubleBar")
	elseif framePosition == TITAN_PANEL_PLACE_BOTTOM and bothbars == nil then
		return TitanPanelGetVar("DoubleBar")
	elseif framePosition == TITAN_PANEL_PLACE_BOTTOM and bothbars == 1 then
		return TitanPanelGetVar("AuxDoubleBar")
	end
end

function TitanUtils_CheckAutoHideCounting(elapsed)
	local frame = TitanPanelBarButtonHider;
	local auxframe = TitanPanelAuxBarButtonHider;

	if (TitanPanelGetVar("AutoHide")) then
		if (not frame.frameTimer or not frame.isCounting) then
			-- Do nothing
		elseif (frame.frameTimer < 0) then
			TitanPanelBarButton_Hide("TitanPanelBarButton", TitanPanelGetVar("Position"));
			frame.frameTimer = nil;
			frame.isCounting = nil;
		else
			frame.frameTimer = frame.frameTimer - elapsed;
		end
	end
	if (TitanPanelGetVar("AuxAutoHide")) then
		if (not auxframe.frameTimer or not auxframe.isCounting) then
			-- Do nothing
		elseif (auxframe.frameTimer < 0) then
			TitanPanelBarButton_Hide("TitanPanelAuxBarButton", TITAN_PANEL_PLACE_BOTTOM);
			auxframe.frameTimer = nil;
			auxframe.isCounting = nil;
		else
			auxframe.frameTimer = auxframe.frameTimer - elapsed;
		end
	end
end

function TitanUtils_StartAutoHideCounting(frame)
	TITAN_PANEL_SELECTED = TitanUtils_GetButtonID(this:GetName())
	-- Toggle menu

	if TITAN_PANEL_SELECTED == "MoneyButtonGold" or  TITAN_PANEL_SELECTED == "MoneyButtonSilver" or  TITAN_PANEL_SELECTED == "MoneyButtonCopper" then
		TITAN_PANEL_SELECTED = "Money"
	end

	if frame ~= nil then
		local frname = getglobal(frame);
		frname.frameTimer = TITAN_AUTOHIDE_WAIT_TIME;
		frname.isCounting = 1;
	end

end

function TitanUtils_StopAutoHideCounting(frame)
	TITAN_PANEL_SELECTED = TitanUtils_GetButtonID(this:GetName())
	-- Toggle menu
	
	if TITAN_PANEL_SELECTED == "MoneyButtonGold" or  TITAN_PANEL_SELECTED == "MoneyButtonSilver" or  TITAN_PANEL_SELECTED == "MoneyButtonCopper" then
		TITAN_PANEL_SELECTED = "Money"
	end

	if frame == nil then
		frame = "TitanPanel" .. TitanUtils_GetWhichBar(TITAN_PANEL_SELECTED) .. "ButtonHider";
	end

	local frname = getglobal(frame)
	frname.isCounting = nil;
end

function TitanUtils_CheckFrameCounting(frame, elapsed)
	if (frame:IsVisible()) then
		if (not frame.frameTimer or not frame.isCounting) then
			return;
		elseif ( frame.frameTimer < 0 ) then
			frame:Hide();
			frame.frameTimer = nil;
			frame.isCounting = nil;
		else
			frame.frameTimer = frame.frameTimer - elapsed;
		end
	end
end

function TitanUtils_StartFrameCounting(frame, frameShowTime)
	frame.frameTimer = frameShowTime;
	frame.isCounting = 1;
end

function TitanUtils_StopFrameCounting(frame)
	frame.isCounting = nil;
end

function TitanUtils_CloseAllControlFrames()
	for index, value in pairs(TitanPlugins) do
		local frame = getglobal("TitanPanel"..index.."ControlFrame");
		if (frame and frame:IsVisible()) then
			frame:Hide();
		end
	end
end

function TitanUtils_IsAnyControlFrameVisible()
	for index, value in TitanPlugins do
		local frame = getglobal("TitanPanel"..index.."ControlFrame");
		if (frame:IsVisible()) then
			return true;
		end
	end
	return false;
end

function TitanUtils_CloseRightClickMenu()
	if (DropDownList1:IsVisible()) then
		DropDownList1:Hide();
	end
end

function TitanUtils_Ternary(a, b, c)
	if (a) then
		return b;
	else
		return c;
	end
end

function TitanUtils_Toggle(value)
	if (value == 1) then
		return nil;
	else
		return 1;
	end
end

function TitanUtils_Min(a, b)
	if (a and b) then
		return TitanUtils_Ternary((a < b), a, b);
	end
end

function TitanUtils_Max(a, b)
	if (a and b) then
		return TitanUtils_Ternary((a > b), a, b);
	end
end

function TitanUtils_GetEstTimeText(s)
	if (s < 0) then
		return TITAN_NA;
	elseif (s < 60) then
		return format("%d "..TITAN_SECONDS, s);
	elseif (s < 60*60) then
		return format("%.1f "..TITAN_MINUTES, s/60);
	elseif (s < 24*60*60) then
		return format("%.1f "..TITAN_HOURS, s/60/60);
	else
		return format("%.1f "..TITAN_DAYS, s/24/60/60);
	end
end

function TitanUtils_GetFullTimeText(s)
	if (s < 0) then
		return TITAN_NA;
	end
	
	local days = floor(s/24/60/60); s = mod(s, 24*60*60);
	local hours = floor(s/60/60); s = mod(s, 60*60);
	local minutes = floor(s/60); s = mod(s, 60);
	local seconds = s;
	
	return format("%d"..TITAN_DAYS_ABBR..", %2d"..TITAN_HOURS_ABBR..", %2d"..TITAN_MINUTES_ABBR..", %2d"..TITAN_SECONDS_ABBR,
				days, hours, minutes, seconds);
end

function TitanUtils_GetAbbrTimeText(s)
	if (s < 0) then
		return TITAN_NA;
	end
	
	local days = floor(s/24/60/60); s = mod(s, 24*60*60);
	local hours = floor(s/60/60); s = mod(s, 60*60);
	local minutes = floor(s/60); s = mod(s, 60);
	local seconds = s;
	
	local timeText = "";
	if (days ~= 0) then
		timeText = timeText..format("%d"..TITAN_DAYS_ABBR.." ", days);
	end
	if (days ~= 0 or hours ~= 0) then
		timeText = timeText..format("%d"..TITAN_HOURS_ABBR.." ", hours);
	end
	if (days ~= 0 or hours ~= 0 or minutes ~= 0) then
		timeText = timeText..format("%d"..TITAN_MINUTES_ABBR.." ", minutes);
	end	
	timeText = timeText..format("%d"..TITAN_SECONDS_ABBR, seconds);
	
	return timeText;
end

function TitanUtils_GetButton(id, returnThis)
	if (id) then
		return getglobal("TitanPanel"..id.."Button"), id;
	elseif (returnThis) then
		return this, TitanUtils_GetButtonID();
	end
end

function TitanUtils_GetButtonID(name)
	if (name == nil) then
		name = this:GetName();
	end

	if (name ~= nil) then
		local s, e, id = string.find(name, "TitanPanel(.*)Button");
		return id;
	else
		return "not found";
	end
end

function TitanUtils_GetParentButtonID(name)
	local frame = TitanUtils_Ternary(name, getglobal(name), this);

	if ( frame and frame:GetParent() ) then
		return TitanUtils_GetButtonID(frame:GetParent():GetName());
	end
end

function TitanUtils_GetButtonIDFromMenu()
	if ( this:GetParent() ) then
		if ( this:GetParent():GetName() == "TitanPanelBarButton" ) then
			return "Bar";
		elseif ( this:GetParent():GetName() == "TitanPanelAuxBarButton" ) then
			return "Bar";
		elseif ( this:GetParent():GetParent()) then  
			-- TitanPanelChildButton
			return TitanUtils_GetButtonID(this:GetParent():GetParent():GetName());		
		else
			-- TitanPanelButton
			return TitanUtils_GetButtonID(this:GetParent():GetName());		
		end	
	end
end

function TitanUtils_GetControlFrame(id)
	if (id == nil) then
		id = TitanUtils_GetButtonID();
	end

	if (id) then
		return getglobal("TitanPanel"..id.."ControlFrame");
	else
		return;
	end
end

function TitanUtils_GetPlugin(id)
	if (id == nil) then
		id = TitanUtils_GetButtonID();
	end

	if (id) then
		return TitanPlugins[id];
	end
end

function TitanUtils_IsPluginRegistered(id)
	if (id and TitanPlugins[id]) then
		return true;
	else
		return false;
	end
end

function TitanUtils_RegisterPlugin(registry) 
	if (registry and registry.id) then
		local id = registry.id;		
		if TitanUtils_IsPluginRegistered(id) then
			-- We have already registered this plugin we have an issue!
			TitanPanel_LoadError("Plugin " .. id .. TITAN_PANEL_ERROR_DUP_PLUGIN);
		else
			if (not TitanUtils_TableContainsValue(TitanPluginsIndex, id)) then
				TitanPlugins[id] = registry;
	--			if (not TitanUtils_TableContainsValue(TITAN_PANEL_NONMOVABLE_PLUGINS, id)) then
					table.insert(TitanPluginsIndex, registry.id);
					table.sort(TitanPluginsIndex, 
						function(a, b)
							return TitanPlugins[a].menuText < TitanPlugins[b].menuText;
						end
					);
	--			end
			end
		end	
	end
end

function TitanUtils_TableContainsValue(table, value)
	if (table and value) then
		for i, v in pairs(table) do
			if (v == value) then
				return i;
			end
		end
	end
end

function TitanUtils_TableContainsIndex(table, index)
	if (table and index) then
		for i, v in pairs(table) do
			if (i == index) then
				return i;
			end
		end
	end
end

function TitanUtils_GetCurrentIndex(table, value)
	return TitanUtils_TableContainsValue(table, value);
end

function TitanUtils_GetPreviousButton(table, id, isSameType, ignoreClock)	
	local index = TitanUtils_GetCurrentIndex(table, id);
	local isIcon = TitanPanelButton_IsIcon(id);	
	local previousButton, isPreviousIcon;
	
	if ( isSameType ) then
		-- Get the previous button with the same type
		while ( index > 1 ) do
			previousButton = TitanUtils_GetButton(table[index - 1]);
			isPreviousIcon = TitanPanelButton_IsIcon(table[index - 1]);
			
			if ( ( isIcon and isPreviousIcon ) or ( not isIcon and not isPreviousIcon ) ) then
				if ( ( table[index - 1] == TITAN_CLOCK_ID ) and ignoreClock ) then
					-- Do nothing, ignore Clock button
				else
					return previousButton;
				end
			end
			
			index = index - 1;
		end
	else
		-- Simply get the previous button
		if ( index > 1 ) then
			return TitanUtils_GetButton(table[index - 1]);
		end		
	end
end

function TitanUtils_GetNextButton(table, id, isSameType, ignoreClock)	
	local index = TitanUtils_GetCurrentIndex(table, id);
	local isIcon = TitanPanelButton_IsIcon(id);	
	local nextButton, isNextIcon;
	
	if ( isSameType ) then
		-- Get the next button with the same type
		while ( table[index + 1] ) do
			nextButton = TitanUtils_GetButton(table[index + 1]);
			isNextIcon = TitanPanelButton_IsIcon(table[index + 1]);
			
			if ( ( isIcon and isNextIcon ) or ( not isIcon and not isNextIcon ) ) then
				if ( ( table[index + 1] == TITAN_CLOCK_ID ) and ignoreClock ) then
					-- Do nothing, ignore Clock button
				else
					return nextButton;
				end
			end
			
			index = index + 1;
		end
	else
		-- Simply get the next button
		if ( table[index + 1] ) then
			return TitanUtils_GetButton(table[index + 1]);
		end		
	end
end

function TitanUtils_GetFirstButton(array, isSameType, isIcon, ignoreClock)	
	local firstButton, isFirstIcon;
	local size = table.getn(array);
	local index = 1;
	
	if ( isSameType ) then
		-- Get the first button with the same type
		while ( index <= size ) do
			firstButton = TitanUtils_GetButton(array[index]);
			isFirstIcon = TitanPanelButton_IsIcon(array[index]);

			if ( ( isIcon and isFirstIcon ) or ( not isIcon and not isFirstIcon ) ) then
				if ( ( array[index] == TITAN_CLOCK_ID ) and ignoreClock ) then
					-- Do nothing, ignore Clock button
				elseif TitanUtils_GetWhichBar(array[index]) == "AuxBar" then
					-- Do nothing wrong bar
				else
					return firstButton;
				end
			end
			
			index = index + 1;
		end
	else
		-- Simply get the first button
		if ( size > 0 ) then
			return TitanUtils_GetButton(array[1]);
		end		
	end
end

function TitanUtils_GetFirstAuxButton(array, isSameType, isIcon, ignoreClock)	
	local firstButton, isFirstIcon;
	local size = table.getn(array);
	local index = 1;
	
	if ( isSameType ) then
		-- Get the first button with the same type
		while ( index <= size ) do
			firstButton = TitanUtils_GetButton(array[index]);
			isFirstIcon = TitanPanelButton_IsIcon(array[index]);

			if ( ( isIcon and isFirstIcon ) or ( not isIcon and not isFirstIcon ) ) then
				if ( ( array[index] == TITAN_CLOCK_ID ) and ignoreClock ) then
					-- Do nothing, ignore Clock button
				elseif TitanUtils_GetWhichBar(array[index]) == "Bar" then
					-- Do nothing wrong bar
				else
					return firstButton;
				end
			end
						
			index = index + 1;
		end
	else
		-- Simply get the first button
		if ( size > 0 ) then
			return TitanUtils_GetButton(array[1]);
		end		
	end
end

function TitanUtils_GetLastButton(array, isSameType, isIcon, ignoreClock)	
	local lastButton, isLastIcon;
	local size = table.getn(array);
	local index = size;
	
	if ( isSameType ) then
		-- Get the last button with the same type
		while ( index > 0 ) do
			lastButton = TitanUtils_GetButton(array[index]);
			isLastIcon = TitanPanelButton_IsIcon(array[index]);

			if ( ( isIcon and isLastIcon ) or ( not isIcon and not isLastIcon ) ) then
				if ( ( array[index] == TITAN_CLOCK_ID ) and ignoreClock ) then
					-- Do nothing, ignore Clock button
				else
					return lastButton;
				end
			end
			
			index = index - 1;
		end
	else
		-- Simply get the last button
		if ( size > 0 ) then
			return TitanUtils_GetButton(array[size]);
		end		
	end
end

function TitanUtils_GetCPNIndexInArray(array, value)
	if (not array) then
		return;
	end
	
	local currentIndex, previousIndex, nextIndex;
	for i, v in array do
		if (v == value) then
			currentIndex = i;
		end
	end
	
	if (currentIndex > 1) then
		previousIndex = currentIndex - 1;
	end
	
	if (array[currentIndex + 1]) then
		nextIndex = currentIndex + 1;
	end
	
	return currentIndex, previousIndex, nextIndex;
end

function TitanUtils_PrintArray(array) 
	if (not array) then
		TitanDebug("array is nil");
	else
		TitanDebug("{");
		for i, v in array do
			TitanDebug("array[" .. tostring(i) .. "] = " .. tostring(v));
		end
		TitanDebug("}");
	end
	
end

function TitanUtils_GetRedText(text)
	if (text) then
		return RED_FONT_COLOR_CODE..text..FONT_COLOR_CODE_CLOSE;
	end
end

function TitanUtils_GetGreenText(text)
	if (text) then
		return GREEN_FONT_COLOR_CODE..text..FONT_COLOR_CODE_CLOSE;
	end
end

function TitanUtils_GetNormalText(text)
	if (text) then
		return NORMAL_FONT_COLOR_CODE..text..FONT_COLOR_CODE_CLOSE;
	end
end

function TitanUtils_GetHighlightText(text)
	if (text) then
		return HIGHLIGHT_FONT_COLOR_CODE..text..FONT_COLOR_CODE_CLOSE;
	end
end

function TitanUtils_GetColoredText(text, color)
	if (text and color) then
		local redColorCode = format("%02x", color.r * 255);		
		local greenColorCode = format("%02x", color.g * 255);
		local blueColorCode = format("%02x", color.b * 255);		
		local colorCode = "|cff"..redColorCode..greenColorCode..blueColorCode;
		return colorCode..text..FONT_COLOR_CODE_CLOSE;
	end
end

function TitanUtils_GetThresholdColor(ThresholdTable, value)
	if ( not tonumber(value) or type(ThresholdTable) ~= "table" or
			ThresholdTable.Values == nil or ThresholdTable.Colors == nil or
			table.getn(ThresholdTable.Values) >= table.getn(ThresholdTable.Colors) ) then
		return TITAN_THRESHOLD_EXCEPTION_COLOR;
	end

	local n = table.getn(ThresholdTable.Values) + 1;
	for i = 1, n do 
		local low = TitanUtils_Ternary(i == 1, nil, ThresholdTable.Values[i-1]);
		local high = TitanUtils_Ternary(i == n, nil, ThresholdTable.Values[i]);
		
		if ( not low and not high ) then
			-- No threshold values
			return ThresholdTable.Colors[i];
			
		elseif ( not low and high ) then
			-- Value is smaller than the first threshold			
			if ( value < high ) then return ThresholdTable.Colors[i] end
			
		elseif ( low and not high ) then
			-- Value is larger than the last threshold
			if ( low <= value ) then return ThresholdTable.Colors[i] end
			
		else
			-- Value is in between 2 adjacent thresholds
			if ( low <= value and value < high ) then return ThresholdTable.Colors[i] end
		end
	end
	
	-- Should never reach here
	return TITAN_THRESHOLD_EXCEPTION_COLOR;
end

function TitanUtils_ToString(text) 
	return TitanUtils_Ternary(text, text, "");
end

function TitanUtils_GetTotalTime()
	return TitanPanelBarButton.totalTime;
end

function TitanUtils_GetLevelTime()
	return TitanPanelBarButton.levelTime;
end

function TitanUtils_GetSessionTime()
	return TitanPanelBarButton.sessionTime;
end

function TitanUtils_GetOffscreen(frame)
	local offscreenX, offscreenY;

	if ( frame and frame:GetLeft() and frame:GetLeft() * frame:GetEffectiveScale() < UIParent:GetLeft() * UIParent:GetEffectiveScale() ) then
		offscreenX = -1;
	elseif ( frame and frame:GetRight() and frame:GetRight() * frame:GetEffectiveScale() > UIParent:GetRight() * UIParent:GetEffectiveScale() ) then
		offscreenX = 1;
	else
		offscreenX = 0;
	end

	if ( frame and frame:GetTop() and frame:GetTop() * frame:GetEffectiveScale() > UIParent:GetTop() * UIParent:GetEffectiveScale() ) then
		offscreenY = -1;
	elseif ( frame and frame:GetBottom() and frame:GetBottom() * frame:GetEffectiveScale() < UIParent:GetBottom() * UIParent:GetEffectiveScale() ) then
		offscreenY = 1;
	else
		offscreenY = 0;
	end
	
	--[[
	TitanDebug(frame:GetName());
	TitanDebug("frame:GetScale() = "..frame:GetScale());	
	TitanDebug("frame:GetLeft() = "..frame:GetLeft());	
	TitanDebug("frame:GetRight() = "..frame:GetRight());	
	TitanDebug("frame:GetTop() = "..frame:GetTop());	
	TitanDebug("frame:GetBottom() = "..frame:GetBottom());	
	TitanDebug("UIParent:GetScale() = "..UIParent:GetScale());	
	TitanDebug("UIParent:GetLeft() = "..UIParent:GetLeft());	
	TitanDebug("UIParent:GetRight() = "..UIParent:GetRight());	
	TitanDebug("UIParent:GetTop() = "..UIParent:GetTop());	
	TitanDebug("UIParent:GetBottom() = "..UIParent:GetBottom());	
	TitanDebug("offscreenX = "..offscreenX.." | offscreenY = "..offscreenY);
	]]--
	return offscreenX, offscreenY;
end

-- There's obvious bug in Blizzard code to handle the drop down menu offscreen cases.
-- I overwrote this function in order to do it right
function ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset)
	if ( not level ) then
		level = 1;
	end
	UIDROPDOWNMENU_MENU_LEVEL = level;
	UIDROPDOWNMENU_MENU_VALUE = value;
	local listFrame = getglobal("DropDownList"..level);
	local listFrameName = "DropDownList"..level;
	local tempFrame;
	local point, relativePoint, relativeTo;
	if ( not dropDownFrame ) then
		tempFrame = this:GetParent();
	else
		tempFrame = dropDownFrame;
	end
	if ( listFrame:IsVisible() and (UIDROPDOWNMENU_OPEN_MENU == tempFrame:GetName()) ) then
		listFrame:Hide();
	else
		-- Hide the listframe anyways since it is redrawn OnShow() 
		listFrame:Hide();
		
		-- Frame to anchor the dropdown menu to
		local anchorFrame;

		-- Display stuff
		-- Level specific stuff
		if ( level == 1 ) then
			if ( not dropDownFrame ) then
				dropDownFrame = this:GetParent();
			end
			UIDROPDOWNMENU_OPEN_MENU = dropDownFrame:GetName();
			listFrame:ClearAllPoints();
			-- If there's no specified anchorName then use left side of the dropdown menu
			if ( not anchorName ) then
				-- See if the anchor was set manually using setanchor
				if ( dropDownFrame.xOffset ) then
					xOffset = dropDownFrame.xOffset;
				end
				if ( dropDownFrame.yOffset ) then
					yOffset = dropDownFrame.yOffset;
				end
				if ( dropDownFrame.point ) then
					point = dropDownFrame.point;
				end
				if ( dropDownFrame.relativeTo ) then
					relativeTo = dropDownFrame.relativeTo;
				else
					relativeTo = UIDROPDOWNMENU_OPEN_MENU.."Left";
				end
				if ( dropDownFrame.relativePoint ) then
					relativePoint = dropDownFrame.relativePoint;
				end
			elseif ( anchorName == "cursor" ) then
				relativeTo = "UIParent";
				local cursorX, cursorY = GetCursorPosition();
				if ( not xOffset ) then
					xOffset = 0;
				end
				if ( not yOffset ) then
					yOffset = 0;
				end
				xOffset = cursorX + xOffset;
				yOffset = cursorY + yOffset;
			else
				relativeTo = anchorName;
			end
			if ( not xOffset or not yOffset ) then
				xOffset = 8;
				yOffset = 22;
			end
			if ( not point ) then
				point = "TOPLEFT";
			end
			if ( not relativePoint ) then
				relativePoint = "BOTTOMLEFT";
			end
			listFrame:SetPoint(point, relativeTo, relativePoint, xOffset, yOffset);
		else
			if ( not dropDownFrame ) then
				dropDownFrame = getglobal(UIDROPDOWNMENU_OPEN_MENU);
			end
			listFrame:ClearAllPoints();
			-- If this is a dropdown button, not the arrow anchor it to itself
			if ( strsub(this:GetParent():GetName(), 0,12) == "DropDownList" and strlen(this:GetParent():GetName()) == 13 ) then
				anchorFrame = this:GetName();
			else
				anchorFrame = this:GetParent():GetName();
			end
			listFrame:SetPoint("TOPLEFT", anchorFrame, "TOPRIGHT", 0, 0);
		end
		
		-- Change list box appearance depending on display mode
		if ( dropDownFrame and dropDownFrame.displayMode == "MENU" ) then
			getglobal(listFrameName.."Backdrop"):Hide();
			getglobal(listFrameName.."MenuBackdrop"):Show();
		else
			getglobal(listFrameName.."Backdrop"):Show();
			getglobal(listFrameName.."MenuBackdrop"):Hide();
		end

		UIDropDownMenu_Initialize(dropDownFrame, dropDownFrame.initialize, nil, level);
		-- If no items in the drop down don't show it
		if ( listFrame.numButtons == 0 ) then
			return;
		end


		-- Check to see if the dropdownlist is off the screen, if it is anchor it to the top of the dropdown button
		-- I overwrote this part to fix Blizzard's offscreen bug
		listFrame:Show();
		local offscreenX, offscreenY = TitanUtils_GetOffscreen(listFrame);
		offscreenX = TitanUtils_Ternary(offscreenX == 0, nil, 1);
		offscreenY = TitanUtils_Ternary(offscreenY == 0, nil, 1);
		
		--[[
		listFrame:Show();
		-- Hack since GetCenter() is returning coords relative to 1024x768
		local x, y = listFrame:GetCenter();
		-- Hack will fix this in next revision of dropdowns
		if ( not x or not y ) then
			listFrame:Hide();
			return;
		end
		-- Determine whether the menu is off the screen or not
		local offscreenY, offscreenX;
		if ( (y - listFrame:GetHeight()/2) < 0 ) then
			offscreenY = 1;
		end
		if ( x + listFrame:GetWidth()/2 > GetScreenWidth() ) then
			offscreenX = 1;		
		end
		]]--

		
		--  If level 1 can only go off the bottom of the screen
		if ( level == 1 ) then
			if ( offscreenY ) then
				listFrame:ClearAllPoints();
				if ( anchorName == "cursor" ) then
					listFrame:SetPoint("BOTTOMLEFT", relativeTo, "BOTTOMLEFT", xOffset, yOffset);
				else
					listFrame:SetPoint("BOTTOMLEFT", relativeTo, "TOPLEFT", xOffset, -yOffset);
				end
			end

		else
			local anchorPoint, relativePoint, offsetX, offsetY;
			if ( offscreenY ) then
				if ( offscreenX ) then
					anchorPoint = "BOTTOMRIGHT";
					relativePoint = "BOTTOMLEFT";
					offsetX = 0;
					offsetY = -14;
				else
					anchorPoint = "BOTTOMLEFT";
					relativePoint = "BOTTOMRIGHT";
					offsetX = 0;
					offsetY = -14;
				end
			else
				if ( offscreenX ) then
					anchorPoint = "TOPRIGHT";
					relativePoint = "TOPLEFT";
					offsetX = 0;
					offsetY = 14;
				else
					anchorPoint = "TOPLEFT";
					relativePoint = "TOPRIGHT";
					offsetX = 0;
					offsetY = 14;
				end
			end
			listFrame:ClearAllPoints();
			listFrame:SetPoint(anchorPoint, anchorFrame, relativePoint, offsetX, offsetY);
		end
	end
end


function TitanUtils_FindInventoryItemWithText(name, description)
	local bagNum;
	
	TitanPanelTooltip:SetOwner(UIParent, "ANCHOR_NONE");
	for bagNum = 0, 4 do
		local itemInBagNum;
		for itemInBagNum = 1, GetContainerNumSlots (bagNum) do
			local i;
			local text = TitanUtils_GetItemName(bagNum, itemInBagNum);
			--Loop through tooltip
			for i = 1, 15, 1 do
				local field = getglobal("TitanPanelTooltipTextLeft" .. i);
				if (field ~= nil) then
					local text = field:GetText();
					if (i == 1) then
						if ((name ~= nil) and (text ~= name)) then
							break;
						else
							if (description == nil) then
								return bagNum, itemInBagNum;
							end
						end
					else
						if text ~=nil then
							if (string.find(text,description)) then
								return bagNum, itemInBagNum;
							end
						end
					end
				end
			end
		end
	end
	return nil;
end

function TitanUtils_GetItemName(bag, slot)
	local bagNumber = bag;
	local name = "";
	if ( type(bagNumber) ~= "number" ) then
		bagNumber = tonumber(bag);
	end
	TitanPanelTooltip:SetBagItem(bag, slot);
	name = TitanPanelTooltipTextLeft1:GetText();
	if name == nil then
		name = "";
	end
	return name;
end