Quantcast

- Fixing git mistake.

HonorGoG [08-09-18 - 23:32]
- Fixing git mistake.
Filename
Titan/TitanMovable.lua
TitanLocation/TitanLocation.lua
TitanPerformance/TitanPerformance.lua
diff --git a/Titan/TitanMovable.lua b/Titan/TitanMovable.lua
new file mode 100755
index 0000000..6cce7b1
--- /dev/null
+++ b/Titan/TitanMovable.lua
@@ -0,0 +1,775 @@
+--[[ File
+NAME: TitanMovable.lua
+DESC: Contains the routines to adjust the Blizzard frames to make room for the Titan bars the user has selected.
+There are a select set of Blizzard frames at the top of screen and at the bottom of the screen that Titan will move.
+Each frame adjusted has an entry in TitanMovableData. TitanMovableData is local and not directly accessible via addons.
+However addons can tell Titan to not adjust some or all frames using TitanUtils_AddonAdjust(frame, bool). Addons that replace all or parts of the Blizzard UI use this.
+
+The user can turn turn on / off the adjusting of all top frames or all bottom frames.
+In addition the user can select to turn off / on adjusting of select top frames (minimap or ticket frame) or select bottom frames (chat / log or bags)
+:DESC
+--]]
+-- Globals
+
+-- Locals
+local _G = getfenv(0);
+local InCombatLockdown = _G.InCombatLockdown;
+
+--[[ Titan
+Declare the Ace routines
+ local AceTimer = LibStub("AceTimer-3.0")
+ i.e. TitanPanelAce.ScheduleTimer("LDBToTitanSetText", TitanLDBRefreshButton, 2);
+ or
+ i.e. TitanPanelAce:ScheduleTimer(TitanLDBRefreshButton, 2);
+
+ Be careful that the 'self' is proper to cancel timers!!!
+--]]
+local TitanPanelAce = LibStub("AceAddon-3.0"):NewAddon("TitanPanel", "AceHook-3.0", "AceTimer-3.0")
+
+--Determines the optimal magic number based on resolution
+--local menuBarTop = 55;
+--local width, height = string.match((({GetScreenResolutions()})[GetCurrentResolution()] or ""), "(%d+).-(%d+)");
+--if ( tonumber(width) / tonumber(height ) > 4/3 ) then
+	--Widescreen resolution
+--	menuBarTop = 75;
+--end
+
+--[[From Resike to prevent tainting stuff to override the SetPoint calls securely.
+hooksecurefunc(FrameRef, "SetPoint", function(self)
+	if self.moving then
+		return
+	end
+	self.moving = true
+	self:SetMovable(true)
+	self:SetUserPlaced(true)
+	self:ClearAllPoints()
+	self:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
+	self:SetMovable(false)
+	self.moving = nil
+end)
+--]]
+
+--[[ Titan
+TitanMovable is a local table that is cleared then filled with the frames Titan needs to check and adjust, if necessary, with each 'adjust frame' check.
+--]]
+local TitanMovable = {};
+--[[ Titan
+NAME: TitanMovableData table
+DESC: TitanMovableData is a local table that holds each frame Titan may need to adjust. It also has the anchor points and offsets needed to make room for the Titan bar(s)
+
+The index is the frame name. Each record contains:
+frameName - frame name (string) to adjust
+frameArchor - the frame anchor point
+xArchor - anchor relative to the frameName
+y - any additional adjustment in the y axis
+position - top or bottom
+addonAdj - true if another addon is taking responsibility of adjusting this frame, if false Titan will use the user setttings to adjust or not
+:DESC
+--]]
+local TitanMovableData = {
+	PlayerFrame = {frameName = "PlayerFrame", frameArchor = "TOPLEFT", xArchor = "LEFT", y = -4,
+		position = TITAN_PANEL_PLACE_TOP, addonAdj = false},
+	TargetFrame = {frameName = "TargetFrame", frameArchor = "TOPLEFT", xArchor = "LEFT", y = -4,
+		position = TITAN_PANEL_PLACE_TOP, addonAdj = false},
+	PartyMemberFrame1 = {frameName = "PartyMemberFrame1", frameArchor = "TOPLEFT", xArchor = "LEFT", y = -128,
+		position = TITAN_PANEL_PLACE_TOP, addonAdj = false},
+	TicketStatusFrame = {frameName = "TicketStatusFrame", frameArchor = "TOPRIGHT", xArchor = "RIGHT", y = 0,
+		position = TITAN_PANEL_PLACE_TOP, addonAdj = false},
+	BuffFrame = {frameName = "BuffFrame", frameArchor = "TOPRIGHT", xArchor = "RIGHT", y = -13,
+		position = TITAN_PANEL_PLACE_TOP, addonAdj = false},
+	MinimapCluster = {frameName = "MinimapCluster", frameArchor = "TOPRIGHT", xArchor = "RIGHT", y = 0,
+		position = TITAN_PANEL_PLACE_TOP, addonAdj = false},
+--	WorldStateAlwaysUpFrame = {frameName = "WorldStateAlwaysUpFrame", frameArchor = "TOP", xArchor = "CENTER", y = -15,
+--		position = TITAN_PANEL_PLACE_TOP, addonAdj = false},
+	MainMenuBar = {frameName = "MainMenuBar", frameArchor = "BOTTOM", xArchor = "CENTER", y = 0,
+		position = TITAN_PANEL_PLACE_BOTTOM, addonAdj = false},
+	MultiBarRight = {frameName = "MultiBarRight", frameArchor = "BOTTOMRIGHT", xArchor = "RIGHT", y = 98,
+		position = TITAN_PANEL_PLACE_BOTTOM, addonAdj = false},
+	OverrideActionBar = {frameName = "OverrideActionBar", frameArchor = "BOTTOM", xArchor = "CENTER", y = 0,
+		position = TITAN_PANEL_PLACE_BOTTOM, addonAdj = false},
+	MicroButtonAndBagsBar = {frameName = "MicroButtonAndBagsBar", frameArchor = "BOTTOMRIGHT", xArchor = "RIGHT", y = 0,
+		position = TITAN_PANEL_PLACE_BOTTOM, addonAdj = false},
+}
+
+--[[ local
+NAME: TitanMovableFrame_CheckThisFrame
+DESC: Add the given frame to the list so it will be checked. Once 'full' the table will be looped through to see if the frame must be moved or not.
+VAR: frameName - frame to check
+OUT: None
+NOTE:
+-  The frame is added to TitanMovable.
+:NOTE
+--]]
+local function TitanMovableFrame_CheckThisFrame(frameName)
+	-- For safety check if the frame is in the table to adjust
+	if TitanMovableData[frameName] then
+		table.insert(TitanMovable, frameName)
+	end
+end
+
+--[[ Titan
+NAME: TitanMovable_AdjustTimer
+DESC: Cancel then add the given timer. The timer must be in TitanTimers.
+VAR: ttype - The timer type (string) as defined in TitanTimers
+OUT:  None
+--]]
+function TitanMovable_AdjustTimer(ttype)
+	local timer = TitanTimers[ttype]
+	if timer then
+		TitanPanelAce.CancelAllTimers(timer.obj)
+		TitanPanelAce.ScheduleTimer(timer.obj, timer.callback, timer.delay)
+	end
+end
+
+--[[ Titan
+NAME: TitanMovable_AddonAdjust
+DESC: Set the given frame to be adjusted or not by another addon. This is called from TitanUtils for a developer API.
+VAR: frame - frame name (string)
+VAR: bool - true (addon will adjust) or false (Titan will use its settings)
+OUT:  None
+--]]
+function TitanMovable_AddonAdjust(frame, bool)
+	for index, value in pairs(TitanMovableData) do
+		frameData = value
+		if frameData then
+			frameName = frameData.frameName;
+		end
+
+		if (frame == frameName) then
+			frameData.addonAdj = bool
+		end
+	end
+end
+
+--[[ API
+NAME: TitanMovable_GetPanelYOffset
+DESC: Get the Y axis offset Titan needs (1 or 2 bars) at the given position - top or bottom.
+VAR: framePosition - TITAN_PANEL_PLACE_TOP or TITAN_PANEL_PLACE_BOTTOM
+OUT: Y axis offset, in pixels
+NOTE:
+- The prefered method to determine the Y offset needed by using TitanUtils_GetBarAnchors().
+:NOTE
+--]]
+function TitanMovable_GetPanelYOffset(framePosition) -- used by other addons
+	-- Both top & bottom are figured out but only the
+	-- requested postion is returned
+	local barnum_top = 0;
+	local barnum_bot = 0
+
+	-- If user has the top adjust set then determine the
+	-- top offset
+	if not TitanPanelGetVar("ScreenAdjust") then
+		if TitanPanelGetVar("Bar_Show") then
+			barnum_top = 1
+		end
+		if TitanPanelGetVar("Bar2_Show") then
+			barnum_top = 2
+		end
+	end
+	-- If user has the top adjust set then determine the
+	-- bottom offset
+	if not TitanPanelGetVar("AuxScreenAdjust") then
+		if TitanPanelGetVar("AuxBar_Show") then
+			barnum_bot = 1
+		end
+		if TitanPanelGetVar("AuxBar2_Show") then
+			barnum_bot = 2
+		end
+	end
+
+	local scale = TitanPanelGetVar("Scale")
+	-- return the requested offset
+	-- 0 will be returned if the user has not bars showing
+	-- or the scale is not valid
+	if scale and framePosition then
+		if framePosition == TITAN_PANEL_PLACE_TOP then
+			return (-TITAN_PANEL_BAR_HEIGHT * scale)*(barnum_top);
+		elseif framePosition == TITAN_PANEL_PLACE_BOTTOM then
+			return (TITAN_PANEL_BAR_HEIGHT * scale)*(barnum_bot)-1;
+			-- no idea why -1 is needed... seems anchoring to bottom is off a pixel
+		end
+	end
+	return 0
+end
+
+--[[ local
+NAME: TitanMovableFrame_GetXOffset
+DESC: Get the x axis offset Titan needs to adjust the given frame.
+VAR: frame - frame object
+VAR: point - "LEFT" / "RIGHT" / "TOP" / "BOTTOM" / "CENTER"
+OUT: int - X axis offset, in pixels
+--]]
+local function TitanMovableFrame_GetXOffset(frame, point)
+	-- A valid frame and point is required
+	-- Determine a proper X offset using the given point (position)
+	local ret = 0 -- In case the inputs were invalid or the point was not relevant to the frame then return 0
+	if frame and point then
+		if point == "LEFT" and frame:GetLeft() and UIParent:GetLeft() then
+			ret = frame:GetLeft() - UIParent:GetLeft();
+		elseif point == "RIGHT" and frame:GetRight() and UIParent:GetRight() then
+			ret = frame:GetRight() - UIParent:GetRight();
+		elseif point == "TOP" and frame:GetTop() and UIParent:GetTop() then
+			ret = frame:GetTop() - UIParent:GetTop();
+		elseif point == "BOTTOM" and frame:GetBottom() and UIParent:GetBottom() then
+			ret = frame:GetBottom() - UIParent:GetBottom();
+		elseif point == "CENTER" and frame:GetLeft() and frame:GetRight()
+				and UIParent:GetLeft() and UIParent:GetRight() then
+			local framescale = frame.GetScale and frame:GetScale() or 1;
+			ret = (frame:GetLeft()* framescale + frame:GetRight()
+				* framescale - UIParent:GetLeft() - UIParent:GetRight()) / 2;
+		end
+	end
+
+	return ret
+end
+
+--[[ Titan
+NAME: TitanMovableFrame_CheckFrames
+DESC: Determine the frames that may need to be moved at the given position.
+VAR: position - TITAN_PANEL_PLACE_TOP / TITAN_PANEL_PLACE_BOTTOM / TITAN_PANEL_PLACE_BOTH
+OUT: None
+--]]
+function TitanMovableFrame_CheckFrames(position)
+	-- reset the frames to move
+	TitanMovable = {};
+
+	-- check top as requested
+	if (position == TITAN_PANEL_PLACE_TOP)
+	or position == TITAN_PANEL_PLACE_BOTH then
+		-- Move PlayerFrame
+		TitanMovableFrame_CheckThisFrame(PlayerFrame:GetName())
+
+		-- Move TargetFrame
+		TitanMovableFrame_CheckThisFrame(TargetFrame:GetName())
+
+		-- Move PartyMemberFrame
+		TitanMovableFrame_CheckThisFrame(PartyMemberFrame1:GetName())
+
+		-- Move TicketStatusFrame
+		if TitanPanelGetVar("TicketAdjust") then
+			TitanMovableFrame_CheckThisFrame(TicketStatusFrame:GetName())
+		end
+
+		-- Move MinimapCluster
+		if not CleanMinimap then
+			if not TitanPanelGetVar("MinimapAdjust") then
+				TitanMovableFrame_CheckThisFrame(MinimapCluster:GetName())
+			end
+		end
+		-- Move BuffFrame
+		TitanMovableFrame_CheckThisFrame(BuffFrame:GetName())
+
+		-- Move UIWidgetTopCenterContainerFrame
+		TitanMovableFrame_CheckThisFrame(UIWidgetTopCenterContainerFrame:GetName());
+
+--[[		-- Move OrderHallCommandBar
+		if OrderHallCommandBar then
+			TitanMovableFrame_CheckThisFrame(OrderHallCommandBar:GetName());
+		end]]--
+	end
+
+	-- check bottom as requested
+	if (position == TITAN_PANEL_PLACE_BOTTOM)
+	or position == TITAN_PANEL_PLACE_BOTH then
+
+		-- Move MainMenuBar
+		TitanMovableFrame_CheckThisFrame(MainMenuBar:GetName());
+
+		-- Move OverrideActionBar
+		TitanMovableFrame_CheckThisFrame(OverrideActionBar:GetName());
+
+		-- Move MicroButtonAndBagsBar
+		TitanMovableFrame_CheckThisFrame(MicroButtonAndBagsBar:GetName());
+	end
+end
+
+--[[ Titan
+NAME: TitanMovableFrame_MoveFrames
+DESC: Actually adjust the frames at the given position.
+VAR: position - TITAN_PANEL_PLACE_TOP / TITAN_PANEL_PLACE_BOTTOM / TITAN_PANEL_PLACE_BOTH
+OUT: None
+--]]
+function TitanMovableFrame_MoveFrames(position)
+	-- Once the frames to check have been collected,
+	-- move them as needed.
+	local frameData, frame, frameName, frameArchor, xArchor, y, xOffset, yOffset, panelYOffset;
+
+	-- Collect the frames we need to move
+	TitanMovableFrame_CheckFrames(position);
+
+	-- move them...
+	if not InCombatLockdown() then
+		local adj_frame = true
+		for index, value in pairs(TitanMovable) do
+			adj_frame = true -- assume the frame is to be adjusted
+			frameData = TitanMovableData[value];
+			if frameData then
+				frame = _G[frameData.frameName];
+				frameName = frameData.frameName;
+				frameArchor = frameData.frameArchor;
+			end
+
+			if (frame and (frame:IsUserPlaced()))
+			then
+				-- The user has positioned the frame
+				adj_frame = false
+			end
+			if frameData.addonAdj then
+				-- An addon has taken control of the frame
+				adj_frame = false
+			end
+
+			if adj_frame then
+				xArchor = frameData.xArchor;
+				y = frameData.y;
+
+				panelYOffset = TitanMovable_GetPanelYOffset(frameData.position);
+				xOffset = TitanMovableFrame_GetXOffset(frame, xArchor);
+
+				-- properly adjust buff frame(s) if GM Ticket is visible
+
+				-- Use IsShown rather than IsVisible. In some cases (after closing
+				-- full screen map) the ticket may not yet be visible.
+				if (frameName == "BuffFrame")
+				and TicketStatusFrame:IsShown()
+				and TitanPanelGetVar("TicketAdjust") then
+					yOffset = (-TicketStatusFrame:GetHeight())
+								+ panelYOffset
+				else
+					yOffset = y + panelYOffset;
+				end
+
+				-- properly adjust MinimapCluster if its border is hidden
+				if frameName == "MinimapCluster"
+				and MinimapBorderTop
+				and not MinimapBorderTop:IsShown() then
+					yOffset = yOffset + (MinimapBorderTop:GetHeight() * 3/5) - 5
+				end
+
+				-- adjust the MainMenuBar according to its scale
+				if frameName == "MainMenuBar" and MainMenuBar:IsVisible() then
+					local framescale = MainMenuBar:GetScale() or 1;
+					yOffset =  yOffset / framescale;
+					if ( StatusTrackingBarManager:GetNumberVisibleBars() == 2 ) then
+						yOffset = yOffset + 17;
+					elseif ( StatusTrackingBarManager:GetNumberVisibleBars() == 1 ) then
+						yOffset = yOffset + 14;
+					end
+				end
+
+				-- account for Reputation Status Bar (doh)
+				local playerlevel = UnitLevel("player");
+				if frameName == "MultiBarRight"
+				and ReputationWatchStatusBar:IsVisible()
+				and playerlevel < _G["MAX_PLAYER_LEVEL"] then
+					yOffset = yOffset + 8;
+				end
+
+				frame:ClearAllPoints();
+				frame:SetPoint(frameArchor, "UIParent", frameArchor,
+					xOffset, yOffset);
+			else
+				--Leave frame where it is as it has been moved by a user
+			end
+			-- Move bags as needed
+			UpdateContainerFrameAnchors();
+		end
+	else
+		-- nothing to do
+	end
+end
+
+--[[ Titan
+NAME: TitanAdjustBottomFrames
+DESC: Adjust the frames at TITAN_PANEL_PLACE_BOTTOM.
+VAR:  None
+OUT:  None
+--]]
+function TitanAdjustBottomFrames()
+	TitanPanel_AdjustFrames(TITAN_PANEL_PLACE_BOTTOM, true)
+end
+
+--[[ Titan
+NAME: Titan_FCF_UpdateDockPosition
+DESC: Secure post hook to help adjust the chat / log frame.
+VAR:  None
+OUT:  None
+NOTE:
+- This is required because Blizz adjusts the chat frame relative to other frames so some of the Blizz code is copied.
+- If in combat or if the user has moved the chat frame then no action is taken.
+- The frame is adjusted in the Y axis only.
+:NOTE
+--]]
+local function Titan_FCF_UpdateDockPosition()
+	if not Titan__InitializedPEW
+	or not TitanPanelGetVar("LogAdjust")
+	or TitanPanelGetVar("AuxScreenAdjust") then
+		return
+	end
+
+	if not InCombatLockdown() or (InCombatLockdown()
+	and not _G["DEFAULT_CHAT_FRAME"]:IsProtected()) then
+		local panelYOffset = TitanMovable_GetPanelYOffset(TITAN_PANEL_PLACE_BOTTOM);
+		local scale = TitanPanelGetVar("Scale");
+		if scale then
+			panelYOffset = panelYOffset + (24 * scale) -- after 3.3.5 an additional adjust was needed. why? idk
+		end
+
+--[[ Blizz code
+		if _G["DEFAULT_CHAT_FRAME"]:IsUserPlaced() then
+			if _G["SIMPLE_CHAT"] ~= "1" then return end
+		end
+
+		local chatOffset = 85 + panelYOffset;
+		if GetNumShapeshiftForms() > 0 or HasPetUI() or PetHasActionBar() then
+			if MultiBarBottomLeft:IsVisible() then
+				chatOffset = chatOffset + 55;
+			else
+				chatOffset = chatOffset + 15;
+			end
+		elseif MultiBarBottomLeft:IsVisible() then
+			chatOffset = chatOffset + 15;
+		end
+		_G["DEFAULT_CHAT_FRAME"]:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", 32, chatOffset);
+		FCF_DockUpdate();
+--]]
+		if ( DEFAULT_CHAT_FRAME:IsUserPlaced() ) then
+			return;
+		end
+
+		local chatOffset = 85 + panelYOffset; -- Titan change to adjust Y offset
+		if ( GetNumShapeshiftForms() > 0 or HasPetUI() or PetHasActionBar() ) then
+			if ( MultiBarBottomLeft:IsShown() ) then
+				chatOffset = chatOffset + 55;
+			else
+				chatOffset = chatOffset + 15;
+			end
+		elseif ( MultiBarBottomLeft:IsShown() ) then
+			chatOffset = chatOffset + 15;
+		end
+		DEFAULT_CHAT_FRAME:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT",
+			32, chatOffset);
+		FCF_DockUpdate();
+	end
+end
+
+--[[ Titan
+NAME: Titan_ContainerFrames_Relocate
+DESC: Secure post hook to help adjust the bag frames.
+VAR:  None
+OUT:  None
+NOTE:
+- The frame is adjusted in the Y axis only.
+- The Blizz routine "ContainerFrames_Relocate" should be examined for any conditions it checks and any changes to the SetPoint.
+If Blizz changes the anchor points the SetPoint here must change as well!!
+The Blizz routine calculates X & Y offsets to UIParent (screen) so there is not need to store the prior offsets.
+Like the Blizz routine we search through the visible bags. Unlike the Blizz routine we only care about the first of each column to adjust for Titan.
+This way the Blizz code does not need to be copied here.
+:NOTE
+--]]
+local function Titan_ContainerFrames_Relocate()
+	if not TitanPanelGetVar("BagAdjust") then
+		return
+	end
+
+	local panelYOffset = TitanMovable_GetPanelYOffset(TITAN_PANEL_PLACE_BOTTOM)
+	local off_y = 10000 -- something ridiculously high
+	local bottom_y = 0
+	local right_x = 0
+
+	for index, frameName in ipairs(ContainerFrame1.bags) do
+		frame = _G[frameName];
+		if frame:GetBottom() then bottom_y = frame:GetBottom() end
+		if ( bottom_y < off_y ) then
+			-- Start a new column
+			right_x = frame:GetRight()
+			frame:ClearAllPoints();
+			frame:SetPoint("BOTTOMRIGHT", frame:GetParent(),
+				"BOTTOMLEFT", -- changed because we are taking the current x value
+				right_x, -- x is not adjusted
+				bottom_y + panelYOffset -- y
+			)
+		end
+		off_y = bottom_y
+	end
+end
+
+--[[ Titan
+NAME: TitanMovableFrame_AdjustBlizzardFrames
+DESC: Calls the helper routines to adjust the chat / log frame and bag frames.
+VAR:  None
+OUT:  None
+NOTE:
+- This is required because Blizz (or addons) could adjust the chat frame outside the events that Titan registers for.
+- If in combat or if the user has moved the chat frame then no action is taken.
+- The frame is adjusted in the Y axis only.
+:NOTE
+--]]
+local function TitanMovableFrame_AdjustBlizzardFrames()
+	if not InCombatLockdown() then
+		Titan_FCF_UpdateDockPosition();
+		Titan_ContainerFrames_Relocate();
+	end
+end
+
+--[[ Titan
+NAME: Titan_AdjustUIScale
+DESC: Adjust the scale of Titan bars and plugins to the user selected scaling. This is called by the secure post hooks to the 'Video Options Frame'.
+VAR:  None
+OUT:  None
+--]]
+local function Titan_AdjustUIScale()
+	Titan_AdjustScale()
+end
+
+--[[ Titan
+NAME: Titan_Hook_Adjust_Both
+DESC: Adjust top and bottom frames. This is called by the secure post hooks.
+VAR:  None
+OUT:  None
+NOTE:
+- Starts a timer () which is a callback to Titan_ManageFramesNew.
+- These could arrive quickly. To prevent many adjusts from stacking, cancel any pending then queue this one.
+:NOTE
+--]]
+local function Titan_Hook_Adjust_Both()
+	TitanMovable_AdjustTimer("Adjust")
+end
+
+--[[ Titan
+NAME: TitanPanel_AdjustFrames
+DESC: Adjust the frames at the given position.
+VAR: position - TITAN_PANEL_PLACE_TOP / TITAN_PANEL_PLACE_BOTTOM / TITAN_PANEL_PLACE_BOTH
+VAR: blizz - true or false
+OUT:  None
+NOTE:
+- if blizz is true then the post hook code for chat / log frame and the bag frames is run
+:NOTE
+--]]
+function TitanPanel_AdjustFrames(position, blizz)
+	-- Adjust frame positions top only, bottom only, or both
+	TitanMovableFrame_MoveFrames(position)
+
+	-- move the Blizzard frames if requested
+	if blizz and position == (TITAN_PANEL_PLACE_BOTTOM or TITAN_PANEL_PLACE_TOP) then
+		TitanMovableFrame_AdjustBlizzardFrames()
+	end
+end
+
+--[[ Titan
+NAME: Titan_ManageFramesNew
+DESC: Adjust the frames at TITAN_PANEL_PLACE_BOTH.
+VAR:  None
+OUT:  None
+--]]
+function Titan_ManageFramesNew()
+	TitanPanel_AdjustFrames(TITAN_PANEL_PLACE_BOTH, false)
+	return
+end
+
+--[[ Titan
+NAME: Titan_AdjustScale
+DESC: Update the bars and plugins to the user selected scale.
+VAR:  None
+OUT:  None
+NOTE:
+- Ensure Titan has done its initialization before this is run.
+:NOTE
+--]]
+function Titan_AdjustScale()
+	-- Only adjust if Titan is fully initialized
+	if Titan__InitializedPEW then
+		TitanPanel_SetScale();
+
+		TitanPanel_ClearAllBarTextures()
+		TitanPanel_CreateBarTextures()
+
+		for idx,v in pairs (TitanBarData) do
+			TitanPanel_SetTexture(TITAN_PANEL_DISPLAY_PREFIX..TitanBarData[idx].name
+				, TITAN_PANEL_PLACE_TOP);
+		end
+
+		TitanPanelBarButton_DisplayBarsWanted()
+		TitanPanel_RefreshPanelButtons();
+	end
+end
+
+function Titan_ManageFramesTest1()
+	if Titan__InitializedPEW then
+		-- We know the desired bars are now drawn so we can adjust
+		if InCombatLockdown() then
+		else
+--TitanDebug ("Titan_ManageFramesTest1 ")
+	left = floor(OverrideActionBar:GetLeft() + 0.5)
+	left = GetScreenWidth() / 2
+	bot = floor(OverrideActionBar:GetBottom() + 0.5)
+TitanDebug("... OverrideActionBar "
+..(bot or "?").." "
+..(left or "?").." "
+)
+	point, relFrame, relPoint, xOff, yOff = OverrideActionBar:GetPoint(OverrideActionBar:GetNumPoints())
+	OverrideActionBar:ClearAllPoints()
+	OverrideActionBar:SetPoint("BOTTOM", TitanPanelBottomAnchor, "TOP", left, 0)
+	OverrideActionBar:SetPoint(point, relFrame, relPoint, xOff, TitanPanelBottomAnchor:GetTop()+0)
+	left = OverrideActionBar:GetCenter()
+	bot = OverrideActionBar:GetBottom()
+TitanDebug("... OverrideActionBar "
+..(bot or "?").." "
+..(left or "?").." "
+)
+
+		end
+	end
+-- There is a chance the person stays in combat so this could
+-- keep looping...
+end
+
+function Titan_GetFrameOrigPositions()
+	local orig = {}
+	local frameData
+	local point, relTo, relPoint, xOff, yOff = "", {}, "", 0, 0
+	local relFrame = ""
+	for index, value in pairs(TitanMovableData) do
+		frameData = TitanMovableData[index];
+		if frameData then
+			point, relTo, relPoint, xOff, yOff = "", {}, "", 0, 0
+			frame = _G[frameData.frameName];
+			point, relTo, relPoint, xOff, yOff = frame:GetPoint(frame:GetNumPoints())
+TitanDebug("Orig: "
+..frameData.frameName.." "
+..relTo:GetName() or "?".." "
+)
+			orig = {
+				point = point,
+				relTo = relTo,
+				relPoint = relPoint,
+				xOff = xOff,
+				yOff = yOff,
+			}
+			TitanMovableOrig[frameData.frameName] = orig
+		end
+	end
+end
+
+function Titan_SetFrameOrigPositions()
+	local left = 0
+	local bot = 0
+	-- TESTING!!!
+TitanDebug("TESTING!!: Setting frames to Titan anchor "
+..(TitanPanelBottomAnchor:GetTop() or "?").." "
+)
+	left = MainMenuBar:GetLeft()
+	left = GetScreenWidth() / 2
+	bot = MainMenuBar:GetBottom()
+TitanDebug("... MainMenuBar "
+..(bot or "?").." "
+..(left or "?").." "
+)
+--	local point, relFrame, relPoint, xOff, yOff = MainMenuBar:GetPoint(MainMenuBar:GetNumPoints())
+	MainMenuBar:ClearAllPoints()
+	MainMenuBar:SetPoint("BOTTOM", TitanPanelBottomAnchor, "TOP", left, 0)
+--	MainMenuBar:SetPoint(point, relFrame, relPoint, xOff, TitanPanelBottomAnchor:GetTop()+0)
+	left = MainMenuBar:GetLeft()
+	bot = MainMenuBar:GetBottom()
+TitanDebug("... MainMenuBar "
+..(bot or "?").." "
+..(left or "?").." "
+)
+
+	left = floor(OverrideActionBar:GetLeft() + 0.5)
+	left = GetScreenWidth() / 2
+	bot = floor(OverrideActionBar:GetBottom() + 0.5)
+TitanDebug("... OverrideActionBar "
+..(bot or "?").." "
+..(left or "?").." "
+)
+--	point, relFrame, relPoint, xOff, yOff = OverrideActionBar:GetPoint(OverrideActionBar:GetNumPoints())
+	OverrideActionBar:ClearAllPoints()
+	OverrideActionBar:SetPoint("BOTTOM", TitanPanelBottomAnchor, "TOP", left, 0)
+--	OverrideActionBar:SetPoint(point, relFrame, relPoint, xOff, TitanPanelBottomAnchor:GetTop()+0)
+	left = OverrideActionBar:GetCenter()
+	bot = OverrideActionBar:GetBottom()
+TitanDebug("... OverrideActionBar "
+..(bot or "?").." "
+..(left or "?").." "
+)
+
+	if false then
+		left = MultiBarRight:GetLeft()
+		MultiBarRight:ClearAllPoints()
+		MultiBarRight:SetPoint("BOTTOMLEFT", TitanPanelBottomAnchor, "TOP", left, 98)
+
+		left = TargetFrame:GetLeft()
+		TargetFrame:ClearAllPoints()
+		TargetFrame:SetPoint("TOPLEFT", TitanPanelTopAnchor, "BOTTOM", left, -4)
+
+		left = PlayerFrame:GetLeft()
+		PlayerFrame:ClearAllPoints()
+		PlayerFrame:SetPoint("TOPLEFT", TitanPanelTopAnchor, "BOTTOM", left, -4)
+
+		left = PartyMemberFrame1:GetLeft()
+		PartyMemberFrame1:ClearAllPoints()
+		PartyMemberFrame1:SetPoint("TOPLEFT", TitanPanelTopAnchor, "BOTTOM", left, -128)
+
+		left = TicketStatusFrame:GetLeft()
+		TicketStatusFrame:ClearAllPoints()
+		TicketStatusFrame:SetPoint("TOPLEFT", TitanPanelTopAnchor, "BOTTOM", left, 0)
+
+		left = BuffFrame:GetLeft()
+		BuffFrame:ClearAllPoints()
+		BuffFrame:SetPoint("TOPLEFT", TitanPanelTopAnchor, "BOTTOM", left, -13)
+
+		left = MinimapCluster:GetLeft()
+		MinimapCluster:ClearAllPoints()
+		MinimapCluster:SetPoint("TOPLEFT", TitanPanelTopAnchor, "BOTTOM", left, 0)
+	end
+end
+
+--[[ Titan
+NAME: TitanMovable_SecureFrames
+DESC: Once Titan is initialized create the post hooks we need to help adjust frames properly.
+VAR:  None
+OUT:  None
+NOTE:
+- The secure post hooks are required because Blizz adjusts frames Titan is interested in at times other than the events Titan registers for.
+- This used to be inline code but was moved to a routine to avoid errors as Titan loaded.
+:NOTE
+--]]
+function TitanMovable_SecureFrames()
+	if not TitanPanelAce:IsHooked("FCF_UpdateDockPosition", Titan_FCF_UpdateDockPosition) then
+		TitanPanelAce:SecureHook("FCF_UpdateDockPosition", Titan_FCF_UpdateDockPosition) -- FloatingChatFrame
+	end
+	if not TitanPanelAce:IsHooked("UIParent_ManageFramePositions", Titan_Hook_Adjust_Both) then
+		TitanPanelAce:SecureHook("UIParent_ManageFramePositions", Titan_Hook_Adjust_Both) -- UIParent.lua
+		TitanPanel_AdjustFrames(TITAN_PANEL_PLACE_BOTTOM, false)
+	end
+
+	if not TitanPanelAce:IsHooked(TicketStatusFrame, "Show", Titan_Hook_Adjust_Both) then
+		-- Titan Hooks to Blizzard Frame positioning functions
+		--TitanPanelAce:SecureHook("TicketStatusFrame_OnShow", Titan_Hook_Adjust_Both) -- HelpFrame.xml
+		--TitanPanelAce:SecureHook("TicketStatusFrame_OnHide", Titan_Hook_Adjust_Both) -- HelpFrame.xml
+		TitanPanelAce:SecureHook(TicketStatusFrame, "Show", Titan_Hook_Adjust_Both) -- HelpFrame.xml
+		TitanPanelAce:SecureHook(TicketStatusFrame, "Hide", Titan_Hook_Adjust_Both) -- HelpFrame.xml
+		TitanPanelAce:SecureHook(MainMenuBar, "Show", Titan_Hook_Adjust_Both) -- HelpFrame.xml
+		TitanPanelAce:SecureHook(MainMenuBar, "Hide", Titan_Hook_Adjust_Both) -- HelpFrame.xml
+		TitanPanelAce:SecureHook(OverrideActionBar, "Show", Titan_Hook_Adjust_Both) -- HelpFrame.xml
+		TitanPanelAce:SecureHook(OverrideActionBar, "Hide", Titan_Hook_Adjust_Both) -- HelpFrame.xml
+--		TitanPanelAce:SecureHook(OverrideActionBar, "Show", Titan_ManageFramesTest1) -- HelpFrame.xml
+--		TitanPanelAce:SecureHook(OverrideActionBar, "Hide", Titan_ManageFramesTest1) -- HelpFrame.xml
+		TitanPanelAce:SecureHook("UpdateContainerFrameAnchors", Titan_ContainerFrames_Relocate) -- ContainerFrame.lua
+		TitanPanelAce:SecureHook(WorldMapFrame, "Hide", Titan_Hook_Adjust_Both) -- WorldMapFrame.lua
+		TitanPanelAce:SecureHook("BuffFrame_Update", Titan_Hook_Adjust_Both) -- BuffFrame.lua
+	end
+
+	if not TitanPanelAce:IsHooked("VideoOptionsFrameOkay_OnClick", Titan_AdjustUIScale) then
+		-- Properly Adjust UI Scale if set
+		-- Note: These are the least intrusive hooks we could think of, to properly adjust the Titan Bar(s)
+		-- without having to resort to a SetCvar secure hook. Any addon using SetCvar should make sure to use the 3rd
+		-- argument in the API call and trigger the CVAR_UPDATE event with an appropriate argument so that other addons
+		-- can detect this behavior and fire their own functions (where applicable).
+		TitanPanelAce:SecureHook("VideoOptionsFrameOkay_OnClick", Titan_AdjustUIScale) -- VideoOptionsFrame.lua
+		TitanPanelAce:SecureHook(VideoOptionsFrame, "Hide", Titan_AdjustUIScale) -- VideoOptionsFrame.xml
+	end
+
+--	TitanPanelAce:SecureHook(OverrideActionBar, "SetPoint", Titan_ManageFramesTest1) --
+end
diff --git a/TitanLocation/TitanLocation.lua b/TitanLocation/TitanLocation.lua
new file mode 100644
index 0000000..b55df87
--- /dev/null
+++ b/TitanLocation/TitanLocation.lua
@@ -0,0 +1,577 @@
+-- **************************************************************************
+-- * TitanLocation.lua
+-- *
+-- * By: TitanMod, Dark Imakuni, Adsertor and the Titan Development Team
+-- **************************************************************************
+
+-- ******************************** Constants *******************************
+local _G = getfenv(0);
+local TITAN_LOCATION_ID = "Location";
+local OFFSET_X = 0.0022  --  0.0022;
+local OFFSET_Y = -0.0262  --  -0.0262;
+local cachedX = 0
+local cachedY = 0
+local updateTable = {TITAN_LOCATION_ID, TITAN_PANEL_UPDATE_BUTTON};
+-- ******************************** Variables *******************************
+local L = LibStub("AceLocale-3.0"):GetLocale("Titan", true)
+local AceTimer = LibStub("AceTimer-3.0")
+local LocationTimer = nil;
+-- ******************************** Functions *******************************
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_OnLoad()
+-- DESC : Registers the plugin upon it loading
+-- **************************************************************************
+function TitanPanelLocationButton_OnLoad(self)
+	self.registry = {
+		id = TITAN_LOCATION_ID,
+		category = "Built-ins",
+		version = TITAN_VERSION,
+		menuText = L["TITAN_LOCATION_MENU_TEXT"],
+		buttonTextFunction = "TitanPanelLocationButton_GetButtonText",
+		tooltipTitle = L["TITAN_LOCATION_TOOLTIP"],
+		tooltipTextFunction = "TitanPanelLocationButton_GetTooltipText",
+		icon = "Interface\\AddOns\\TitanLocation\\TitanLocation",
+		iconWidth = 16,
+		controlVariables = {
+			ShowIcon = true,
+			ShowLabelText = true,
+			ShowRegularText = false,
+			ShowColoredText = true,
+			DisplayOnRightSide = false
+		},
+		savedVariables = {
+			ShowZoneText = 1,
+			ShowCoordsOnMap = true,
+			ShowCursorOnMap = true,
+			ShowLocOnMiniMap = 1,
+			ShowIcon = 1,
+			ShowLabelText = 1,
+			ShowColoredText = 1,
+			CoordsFormat1 = 1,
+			CoordsFormat2 = false,
+			CoordsFormat3 = false,
+			UpdateWorldmap = false,
+		}
+	};
+
+	self:RegisterEvent("ZONE_CHANGED");
+	self:RegisterEvent("ZONE_CHANGED_INDOORS");
+	self:RegisterEvent("ZONE_CHANGED_NEW_AREA");
+	self:RegisterEvent("PLAYER_ENTERING_WORLD");
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_OnShow()
+-- DESC : Display button when plugin is visible
+-- **************************************************************************
+function TitanPanelLocationButton_OnShow()
+	local mapID = C_Map.GetBestMapForUnit("player");
+<<<<<<< HEAD
+	if mapID ~= nil then
+    	WorldMapFrame:SetMapID(mapID);
+	end
+=======
+	WorldMapFrame:SetMapID(mapID);
+>>>>>>> parent of b7802a1... Throw away...
+	TitanPanelLocation_HandleUpdater();
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_OnHide()
+-- DESC : Destroy repeating timer when plugin is hidden
+-- **************************************************************************
+function TitanPanelLocationButton_OnHide()
+	AceTimer.CancelTimer("TitanPanelLocation", LocationTimer, true)
+	LocationTimer = nil;
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_GetButtonText(id)
+-- DESC : Calculate coordinates and then display data on button
+-- VARS : id = button ID
+-- **************************************************************************
+function TitanPanelLocationButton_GetButtonText(id)
+	local button, id = TitanUtils_GetButton(id, true);
+
+	button.px, button.py = TitanPanelGetPlayerMapPosition();
+	-- cache coordinates for update checking later on
+	cachedX = button.px;
+	cachedY = button.py;
+	if button.px == nil then button.px = 0 end
+	if button.py == nil then button.py = 0 end
+	local locationText = "";
+	if (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat1")) then
+		locationText = format(L["TITAN_LOCATION_FORMAT"], 100 * button.px, 100 * button.py);
+	elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat2")) then
+		locationText = format(L["TITAN_LOCATION_FORMAT2"], 100 * button.px, 100 * button.py);
+	elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat3")) then
+		locationText = format(L["TITAN_LOCATION_FORMAT3"], 100 * button.px, 100 * button.py);
+	end
+
+	if button.px == 0 and button.py == 0 then
+		locationText = "";
+	end
+
+	if (TitanGetVar(TITAN_LOCATION_ID, "ShowZoneText")) then
+		if (TitanUtils_ToString(button.subZoneText) == '') then
+			if (button.zoneText == '') then
+				_, _, button.zoneText = C_Map.GetMapInfo(C_Map.GetBestMapUnit("player"));
+			end
+			locationText = TitanUtils_ToString(button.zoneText)..' '..locationText;
+		else
+			locationText = TitanUtils_ToString(button.subZoneText)..' '..locationText;
+		end
+	else
+		if button.px == 0 and button.py == 0 then
+			locationText = L["TITAN_LOCATION_NO_COORDS"];
+		end
+	end
+
+	local locationRichText;
+	if (TitanGetVar(TITAN_LOCATION_ID, "ShowColoredText")) then
+		if (TitanPanelLocationButton.isArena) then
+			locationRichText = TitanUtils_GetRedText(locationText);
+		elseif (TitanPanelLocationButton.pvpType == "friendly") then
+			locationRichText = TitanUtils_GetGreenText(locationText);
+		elseif (TitanPanelLocationButton.pvpType == "hostile") then
+			locationRichText = TitanUtils_GetRedText(locationText);
+		elseif (TitanPanelLocationButton.pvpType == "contested") then
+			locationRichText = TitanUtils_GetNormalText(locationText);
+		else
+			locationRichText = TitanUtils_GetNormalText(locationText);
+		end
+	else
+		locationRichText = TitanUtils_GetHighlightText(locationText);
+	end
+
+	return L["TITAN_LOCATION_BUTTON_LABEL"], locationRichText;
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_GetTooltipText()
+-- DESC : Display tooltip text
+-- **************************************************************************
+function TitanPanelLocationButton_GetTooltipText()
+	local pvpInfoRichText;
+
+	pvpInfoRichText = "";
+	if (TitanPanelLocationButton.pvpType == "sanctuary") then
+		pvpInfoRichText = TitanUtils_GetGreenText(SANCTUARY_TERRITORY);
+	elseif (TitanPanelLocationButton.pvpType == "arena") then
+		TitanPanelLocationButton.subZoneText = TitanUtils_GetRedText(TitanPanelLocationButton.subZoneText);
+		pvpInfoRichText = TitanUtils_GetRedText(CONTESTED_TERRITORY);
+		elseif (TitanPanelLocationButton.pvpType == "friendly") then
+		pvpInfoRichText = TitanUtils_GetGreenText(format(FACTION_CONTROLLED_TERRITORY, TitanPanelLocationButton.factionName));
+	elseif (TitanPanelLocationButton.pvpType == "hostile") then
+		pvpInfoRichText = TitanUtils_GetRedText(format(FACTION_CONTROLLED_TERRITORY, TitanPanelLocationButton.factionName));
+	elseif (TitanPanelLocationButton.pvpType == "contested") then
+		pvpInfoRichText = TitanUtils_GetRedText(CONTESTED_TERRITORY);
+	else
+		--pvpInfoRichText = TitanUtils_GetNormalText(CONTESTED_TERRITORY);
+	end
+
+	return ""..
+		L["TITAN_LOCATION_TOOLTIP_ZONE"].."\t"..TitanUtils_GetHighlightText(TitanPanelLocationButton.zoneText).."\n"..
+		TitanUtils_Ternary((TitanPanelLocationButton.subZoneText == ""), "", L["TITAN_LOCATION_TOOLTIP_SUBZONE"].."\t"..TitanUtils_GetHighlightText(TitanPanelLocationButton.subZoneText).."\n")..
+		TitanUtils_Ternary((pvpInfoRichText == ""), "", L["TITAN_LOCATION_TOOLTIP_PVPINFO"].."\t"..pvpInfoRichText.."\n")..
+		"\n"..
+		TitanUtils_GetHighlightText(L["TITAN_LOCATION_TOOLTIP_HOMELOCATION"]).."\n"..
+		L["TITAN_LOCATION_TOOLTIP_INN"].."\t"..TitanUtils_GetHighlightText(GetBindLocation()).."\n"..
+		TitanUtils_GetGreenText(L["TITAN_LOCATION_TOOLTIP_HINTS_1"]).."\n"..
+		TitanUtils_GetGreenText(L["TITAN_LOCATION_TOOLTIP_HINTS_2"]);
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_OnEvent()
+-- DESC : Parse events registered to plugin and act on them
+-- **************************************************************************
+function TitanPanelLocationButton_OnEvent(self, event, ...)
+	if event == "PLAYER_ENTERING_WORLD" then
+		if not TitanGetVar(TITAN_LOCATION_ID, "ShowLocOnMiniMap") and MinimapBorderTop and MinimapBorderTop:IsShown() then
+			TitanPanelLocationButton_LocOnMiniMap()
+		end
+	end
+	if TitanGetVar(TITAN_LOCATION_ID, "UpdateWorldmap") then
+		local mapID = C_Map.GetBestMapForUnit("player")
+<<<<<<< HEAD
+		if mapID ~= nil then
+    		WorldMapFrame:SetMapID(mapID);
+		end
+=======
+		WorldMapFrame:SetMapID(mapID)
+>>>>>>> parent of b7802a1... Throw away...
+	end
+	TitanPanelLocationButton_UpdateZoneInfo(self);
+	TitanPanelPluginHandle_OnUpdate(updateTable);
+	TitanPanelLocation_HandleUpdater();
+end
+
+-- function to throttle down unnecessary updates
+function TitanPanelLocationButton_CheckForUpdate()
+	local mapID = C_Map.GetBestMapForUnit("player")
+	local tempx, tempy = TitanPanelGetPlayerMapPosition();
+	if tempx ~= cachedX or tempy ~= cachedY then
+		TitanPanelPluginHandle_OnUpdate(updateTable);
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocation_HandleUpdater()
+-- DESC : Check to see if you are inside an instance
+-- **************************************************************************
+function TitanPanelLocation_HandleUpdater()
+	if TitanPanelLocationButton:IsVisible() and not LocationTimer then
+		LocationTimer = AceTimer.ScheduleRepeatingTimer("TitanPanelLocation", TitanPanelLocationButton_CheckForUpdate, 0.5)
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_OnClick(button)
+-- DESC : Copies coordinates to chat line for shift-LeftClick
+-- VARS : button = value of action
+-- **************************************************************************
+function TitanPanelLocationButton_OnClick(self, button)
+	if (button == "LeftButton") then
+		if (IsShiftKeyDown()) then
+			local activeWindow = ChatEdit_GetActiveWindow();
+			if ( activeWindow ) then
+				if (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat1")) then
+					message = TitanUtils_ToString(self.zoneText).." "..
+					format(L["TITAN_LOCATION_FORMAT"], 100 * self.px, 100 * self.py);
+				elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat2")) then
+					message = TitanUtils_ToString(self.zoneText).." "..
+					format(L["TITAN_LOCATION_FORMAT2"], 100 * self.px, 100 * self.py);
+				elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat3")) then
+					message = TitanUtils_ToString(self.zoneText).." "..
+					format(L["TITAN_LOCATION_FORMAT3"], 100 * self.px, 100 * self.py);
+				end
+				activeWindow:Insert(message);
+			end
+		else
+			--WorldMap_ToggleSizeUp();
+			if (not GetCVarBool("miniWorldMap")) then
+				--/; # Deprecated in WoW 8.0.1
+			end
+			ToggleFrame(WorldMapFrame);
+		end
+	end
+--[[
+-- Works great when map is small. When map is large, Titan stays on top.
+-- Sometimes other buttons stay on top of map.
+-- Think we'd have to adjust strata of anything touched by TitanMovable
+	if (button == "LeftButton") then
+		if ( WORLDMAP_SETTINGS.size == WORLDMAP_WINDOWED_SIZE ) then
+			if ( WorldMapFrame:IsVisible() ) then
+				WorldMapFrame:Hide()
+			else
+				WorldMapFrame:Show()
+			end
+		end
+	end
+--]]
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_UpdateZoneInfo()
+-- DESC : Update data on button
+-- **************************************************************************
+function TitanPanelLocationButton_UpdateZoneInfo(self)
+	local _ = nil
+	self.zoneText = GetZoneText();
+	self.subZoneText = GetSubZoneText();
+	--self.minimapZoneText = GetMinimapZoneText();
+	self.pvpType, _, self.factionName = GetZonePVPInfo();
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelRightClickMenu_PrepareLocationMenu()
+-- DESC : Display rightclick menu options
+-- **************************************************************************
+function TitanPanelRightClickMenu_PrepareLocationMenu()
+	local info
+
+	-- level 2
+	if _G["L_UIDROPDOWNMENU_MENU_LEVEL"] == 2 then
+		if _G["L_UIDROPDOWNMENU_MENU_VALUE"] == "Options" then
+			TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_OPTIONS"], _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+			info = {};
+			info.text = L["TITAN_LOCATION_MENU_SHOW_ZONE_ON_PANEL_TEXT"];
+			info.func = TitanPanelLocationButton_ToggleDisplay;
+			info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowZoneText");
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			info = {};
+			info.text = L["TITAN_LOCATION_MENU_SHOW_COORDS_ON_MAP_TEXT"];
+			info.func = TitanPanelLocationButton_ToggleLocationOnMap;
+			info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsOnMap");
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			info = {};
+			info.text = L["TITAN_LOCATION_MENU_SHOW_LOC_ON_MINIMAP_TEXT"];
+			info.func = TitanPanelLocationButton_ToggleLocOnMiniMap;
+			info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowLocOnMiniMap");
+			info.disabled = InCombatLockdown()
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			info = {};
+			info.text = L["TITAN_LOCATION_MENU_UPDATE_WORLD_MAP"];
+			info.func = function()
+				TitanToggleVar(TITAN_LOCATION_ID, "UpdateWorldmap");
+			end
+			info.checked = TitanGetVar(TITAN_LOCATION_ID, "UpdateWorldmap");
+			info.disabled = InCombatLockdown()
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+		end
+		if _G["L_UIDROPDOWNMENU_MENU_VALUE"] == "CoordFormat" then
+			TitanPanelRightClickMenu_AddTitle(L["TITAN_LOCATION_FORMAT_COORD_LABEL"], _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+			info = {};
+			info.text = L["TITAN_LOCATION_FORMAT_LABEL"];
+			info.func = function()
+				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat1", 1);
+				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat2", nil);
+				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat3", nil);
+				TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
+			end
+			info.checked = TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat1");
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			info = {};
+			info.text = L["TITAN_LOCATION_FORMAT2_LABEL"];
+			info.func = function()
+				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat1", nil);
+				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat2", 1);
+				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat3", nil);
+				TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
+			end
+			info.checked = TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat2");
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			info = {};
+			info.text = L["TITAN_LOCATION_FORMAT3_LABEL"];
+			info.func = function()
+				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat1", nil);
+				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat2", nil);
+				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat3", 1);
+				TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
+			end
+			info.checked = TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat3");
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+		end
+		return
+	end
+
+	-- level 1
+	TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_LOCATION_ID].menuText);
+
+	info = {};
+	info.notCheckable = true
+	info.text = L["TITAN_PANEL_OPTIONS"];
+	info.value = "Options"
+	info.hasArrow = 1;
+	L_UIDropDownMenu_AddButton(info);
+
+	info = {};
+	info.notCheckable = true
+	info.text = L["TITAN_LOCATION_FORMAT_COORD_LABEL"];
+	info.value = "CoordFormat"
+	info.hasArrow = 1;
+	L_UIDropDownMenu_AddButton(info);
+
+	TitanPanelRightClickMenu_AddSpacer();
+	TitanPanelRightClickMenu_AddToggleIcon(TITAN_LOCATION_ID);
+	TitanPanelRightClickMenu_AddToggleLabelText(TITAN_LOCATION_ID);
+	TitanPanelRightClickMenu_AddToggleColoredText(TITAN_LOCATION_ID);
+	TitanPanelRightClickMenu_AddSpacer();
+	TitanPanelRightClickMenu_AddCommand(L["TITAN_PANEL_MENU_HIDE"], TITAN_LOCATION_ID, TITAN_PANEL_MENU_FUNC_HIDE);
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_ToggleDisplay()
+-- DESC : Set option to show zone text
+-- **************************************************************************
+function TitanPanelLocationButton_ToggleDisplay()
+	TitanToggleVar(TITAN_LOCATION_ID, "ShowZoneText");
+	TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_ToggleLocationOnMap()
+-- DESC : Set option to show player coordinates on map
+-- **************************************************************************
+function TitanPanelLocationButton_ToggleLocationOnMap()
+	TitanToggleVar(TITAN_LOCATION_ID, "ShowCoordsOnMap");
+	if (TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsOnMap")) then
+		TitanMapPlayerLocation:Show();
+	else
+		TitanMapPlayerLocation:Hide();
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_ToggleCursorLocationOnMap()
+-- DESC : Set option to show cursor coordinates on map
+-- **************************************************************************
+function TitanPanelLocationButton_ToggleCursorLocationOnMap()
+	TitanToggleVar(TITAN_LOCATION_ID, "ShowCursorOnMap");
+	if (TitanGetVar(TITAN_LOCATION_ID, "ShowCursorOnMap")) then
+		TitanMapCursorLocation:Show();
+	else
+		TitanMapCursorLocation:Hide();
+	end
+end
+
+function TitanPanelLocationButton_ToggleLocOnMiniMap()
+	TitanToggleVar(TITAN_LOCATION_ID, "ShowLocOnMiniMap");
+	TitanPanelLocationButton_LocOnMiniMap()
+end
+
+function TitanPanelLocationButton_LocOnMiniMap()
+	if TitanGetVar(TITAN_LOCATION_ID, "ShowLocOnMiniMap") then
+		MinimapBorderTop:Show()
+		MinimapZoneTextButton:Show()
+		MiniMapWorldMapButton:Show()
+	else
+		MinimapBorderTop:Hide()
+		MinimapZoneTextButton:Hide()
+		MiniMapWorldMapButton:Hide()
+	end
+	-- adjust MiniMap frame if needed
+	TitanMovableFrame_CheckFrames(1);
+	TitanMovableFrame_MoveFrames(1, TitanPanelGetVar("ScreenAdjust"));
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelLocationButton_ToggleColor()
+-- DESC : Set option to show colored text
+-- **************************************************************************
+function TitanPanelLocationButton_ToggleColor()
+	TitanToggleVar(TITAN_LOCATION_ID, "ShowColoredText");
+	TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
+end
+
+-- **************************************************************************
+-- NAME : TitanMapFrame_OnUpdate()
+-- DESC : Update coordinates on map
+-- **************************************************************************
+function TitanMapFrame_OnUpdate(self, elapsed)
+	-- using :Hide / :Show prevents coords from running
+	-- TitanMapFrame:Hide() -- hide parent
+
+	-- Determine the text to show for player coords
+
+--[[
+	if WorldMapFrame:IsVisible() then
+		TitanMapPlayerLocation:SetText("");
+	else
+		self.px, self.py = TitanPanelGetPlayerMapPosition();
+		if self.px == nil then self.px = 0 end
+		if self.py == nil then self.py = 0 end
+		if self.px == 0 and self.py == 0 then
+			playerLocationText = L["TITAN_LOCATION_NO_COORDS"]
+		else
+			if (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat1")) then
+				playerLocationText = format(L["TITAN_LOCATION_FORMAT"], 100 * self.px, 100 * self.py);
+			elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat2")) then
+				playerLocationText = format(L["TITAN_LOCATION_FORMAT2"], 100 * self.px, 100 * self.py);
+			elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat3")) then
+				playerLocationText = format(L["TITAN_LOCATION_FORMAT3"], 100 * self.px, 100 * self.py);
+			end
+		end
+		TitanMapPlayerLocation:SetText(format(L["TITAN_LOCATION_MAP_PLAYER_COORDS_TEXT"], TitanUtils_GetHighlightText(playerLocationText)));
+	end
+]]
+	if WorldMapFrame:IsMaximized() then
+		self.px, self.py = TitanPanelGetPlayerMapPosition();
+		if self.px == nil then self.px = 0 end
+		if self.py == nil then self.py = 0 end
+		if self.px == 0 and self.py == 0 then
+			playerLocationText = L["TITAN_LOCATION_NO_COORDS"]
+		else
+			if (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat1")) then
+				playerLocationText = format(L["TITAN_LOCATION_FORMAT"], 100 * self.px, 100 * self.py);
+			elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat2")) then
+				playerLocationText = format(L["TITAN_LOCATION_FORMAT2"], 100 * self.px, 100 * self.py);
+			elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat3")) then
+				playerLocationText = format(L["TITAN_LOCATION_FORMAT3"], 100 * self.px, 100 * self.py);
+			end
+		end
+		TitanMapPlayerLocation:SetText(format(L["TITAN_LOCATION_MAP_PLAYER_COORDS_TEXT"], TitanUtils_GetHighlightText(playerLocationText)));
+	else
+		TitanMapPlayerLocation:SetText("");
+	end
+
+	-- Determine the text to show for cursor coords
+
+		-- calc cursor position on the map
+		local cursorLocationText, playerLocationText;
+		local x, y = GetCursorPosition();
+		x = x / WorldMapFrame:GetEffectiveScale();
+		y = y / WorldMapFrame:GetEffectiveScale();
+
+		local centerX, centerY = WorldMapFrame:GetCenter();
+		local width = WorldMapFrame:GetWidth();
+		local height = WorldMapFrame:GetHeight();
+		local cx = ((x - (centerX - (width/2))) / width) -- OFFSET_X
+		local cy = ((centerY + (height/2) - y ) / height) --  OFFSET_Y
+		-- cut off if the cursor coords are beyond the map, show 0,0
+		if cx < 0 or cx > 1 or cy < 0 or cy > 1 then
+			cx = 0
+			cy = 0
+		end
+		-- per the user requested format
+		if (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat1")) then
+			cursorLocationText = format(L["TITAN_LOCATION_FORMAT"], 100 * cx, 100 * cy);
+		elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat2")) then
+			cursorLocationText = format(L["TITAN_LOCATION_FORMAT2"], 100 * cx, 100 * cy);
+		elseif (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat3")) then
+			cursorLocationText = format(L["TITAN_LOCATION_FORMAT3"], 100 * cx, 100 * cy);
+		end
+		if (TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsOnMap")) then
+			TitanMapCursorLocation:SetText(format(L["TITAN_LOCATION_MAP_CURSOR_COORDS_TEXT"],
+				TitanUtils_GetHighlightText(cursorLocationText)));
+		else
+			TitanMapCursorLocation:SetText("");
+		end
+
+	-- Determine where to show the text
+
+	-- *
+	TitanMapPlayerLocation:ClearAllPoints()
+--[[
+	if ( WorldMapFrame:IsVisible() ) then
+		-- **
+		TitanMapPlayerLocation:SetPoint("TOPLEFT", WorldMapFrame, "TOPLEFT", 75, -12)
+	else
+		x_offset = (WorldMapFrame:GetWidth() / 1.6) -- left fifth of map
+			- (TitanMapPlayerLocation:GetWidth() / 1.8) -- center of coords
+		TitanMapPlayerLocation:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOMLEFT", x_offset, 10)
+	end
+]]
+	if WorldMapFrame:IsMaximized() then
+		x_offset = (WorldMapFrame:GetWidth() / 1.6) -- left fifth of map
+			- (TitanMapPlayerLocation:GetWidth() / 1.8) -- center of coords
+		TitanMapPlayerLocation:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOMLEFT", x_offset, 10)
+	else
+		TitanMapPlayerLocation:SetPoint("TOPLEFT", WorldMapFrame, "TOPLEFT", 75, -12)
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelGetPlayerMapPosition()
+-- DESC : Get the player coordinates
+-- VARS : x = location on x axis, y = location on y axis
+-- **************************************************************************
+function TitanPanelGetPlayerMapPosition()
+    local mapID = C_Map.GetBestMapForUnit("player")
+    if mapID == nil then
+        return nil, nil
+    end
+
+    local position = C_Map.GetPlayerMapPosition(mapID, "player")
+    if position == nil then
+        return nil, nil
+    else
+    	return position:GetXY()
+	end
+end
diff --git a/TitanPerformance/TitanPerformance.lua b/TitanPerformance/TitanPerformance.lua
new file mode 100644
index 0000000..1754d8e
--- /dev/null
+++ b/TitanPerformance/TitanPerformance.lua
@@ -0,0 +1,796 @@
+-- **************************************************************************
+-- * TitanPerformance.lua
+-- *
+-- * By: TitanMod, Dark Imakuni, Adsertor and the Titan Development Team
+-- **************************************************************************
+
+-- ******************************** Constants *******************************
+local TITAN_PERFORMANCE_ID = "Performance";
+local TITAN_PERF_FRAME_SHOW_TIME = 0.5;
+local updateTable = {TITAN_PERFORMANCE_ID, TITAN_PANEL_UPDATE_ALL};
+
+local TITAN_FPS_THRESHOLD_TABLE = {
+	Values = { 20, 30 },
+	Colors = { RED_FONT_COLOR, NORMAL_FONT_COLOR, GREEN_FONT_COLOR },
+}
+local TITAN_LATENCY_THRESHOLD_TABLE = {
+	Values = { PERFORMANCEBAR_LOW_LATENCY, PERFORMANCEBAR_MEDIUM_LATENCY },
+	Colors = { GREEN_FONT_COLOR, NORMAL_FONT_COLOR, RED_FONT_COLOR },
+}
+local TITAN_MEMORY_RATE_THRESHOLD_TABLE = {
+	Values = { 1, 2 },
+	Colors = { GREEN_FONT_COLOR, NORMAL_FONT_COLOR, RED_FONT_COLOR },
+}
+
+-- ******************************** Variables *******************************
+local _G = getfenv(0);
+local topAddOns;
+local memUsageSinceGC = {};
+local counter = 1; --counter for active addons
+local L = LibStub("AceLocale-3.0"):GetLocale("Titan", true)
+local AceTimer = LibStub("AceTimer-3.0")
+local PerfTimer = nil;
+-- ******************************** Functions *******************************
+
+-- **************************************************************************
+-- NAME : TitanPanelPerformanceButton_OnLoad()
+-- DESC : Registers the plugin upon it loading
+-- **************************************************************************
+function TitanPanelPerformanceButton_OnLoad(self)
+	self.registry = {
+		id = TITAN_PERFORMANCE_ID,
+		category = "Built-ins",
+		version = TITAN_VERSION,
+		menuText = L["TITAN_PERFORMANCE_MENU_TEXT"],
+		buttonTextFunction = "TitanPanelPerformanceButton_GetButtonText";
+		tooltipCustomFunction = TitanPanelPerformanceButton_SetTooltip;
+		icon = "Interface\\AddOns\\TitanPerformance\\TitanPerformance",
+		iconWidth = 16,
+		controlVariables = {
+			ShowIcon = true,
+			ShowLabelText = true,
+			ShowRegularText = false,
+			ShowColoredText = true,
+			DisplayOnRightSide = false,
+		},
+		savedVariables = {
+			ShowFPS = 1,
+			ShowLatency = 1,
+			ShowWorldLatency = 1,
+			ShowMemory = 1,
+			ShowAddonMemory = false,
+			ShowAddonIncRate = false,
+			NumOfAddons = 5,
+			AddonMemoryType = 1,
+			ShowIcon = 1,
+			ShowLabelText = false,
+			ShowColoredText = 1,
+		}
+	};
+
+	self.fpsSampleCount = 0;
+	self:RegisterEvent("PLAYER_ENTERING_WORLD");
+end
+
+function TitanPanelPerformanceButton_OnShow()
+	if not PerfTimer then
+		PerfTimer = AceTimer.ScheduleRepeatingTimer("TitanPanelPerformance", TitanPanelPerformanceButtonHandle_OnUpdate, 1.5 )
+	end
+end
+
+function TitanPanelPerformanceButton_OnHide()
+	AceTimer.CancelTimer("TitanPanelPerformance", PerfTimer, true)
+	PerfTimer = nil;
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerformanceButton_OnUpdate(elapsed)
+-- DESC : Update button data
+-- VARS : elapsed = <research>
+-- **************************************************************************
+function TitanPanelPerformanceButtonHandle_OnUpdate()
+	TitanPanelPluginHandle_OnUpdate(updateTable);
+	if not (TitanPanelRightClickMenu_IsVisible()) and _G["TitanPanelPerfControlFrame"]:IsVisible() and not (MouseIsOver(_G["TitanPanelPerfControlFrame"])) then
+		_G["TitanPanelPerfControlFrame"]:Hide();
+	end
+end
+
+function TitanPanelPerformanceButton_OnEvent(self, event, ...)
+	if event == "PLAYER_ENTERING_WORLD" then
+		local i;
+		topAddOns = {}
+		-- scan how many addons are active
+		local count = GetNumAddOns();
+		local ActiveAddons = 0;
+<<<<<<< HEAD
+		local NumOfAddons = TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons");
+		if NumOfAddons == nil then
+			NumOfAddons = 5;
+			TitanSetVar(TITAN_PERFORMANCE_ID, "NumOfAddons", 5);
+		end
+=======
+>>>>>>> parent of b7802a1... Throw away...
+		for i=1, count do
+			if IsAddOnLoaded(i) then
+				ActiveAddons = ActiveAddons + 1;
+			end
+		end
+<<<<<<< HEAD
+--TitanDebug("NumOfAddons: " .. TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons"));
+		if ActiveAddons < NumOfAddons then
+			counter = ActiveAddons;
+		else
+			counter = NumOfAddons;
+=======
+
+--TitanDebug("NumOfAddons: " .. TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons"));
+--TitanDebug("ActiveAddons: " .. ActiveAddons);
+
+		if ActiveAddons < TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons") then
+			counter = ActiveAddons;
+		else
+			counter = TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons");
+>>>>>>> parent of b7802a1... Throw away...
+		end
+		--set the counter to the proper number of active addons that are being monitored
+		for i=1, counter do
+			topAddOns[i] = {name = '', value = 0}
+		end
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerformanceButton_GetButtonText(id)
+-- DESC : Calculate performance based logic for button text
+-- VARS : id = button ID
+-- **************************************************************************
+function TitanPanelPerformanceButton_GetButtonText(id)
+	local button = _G["TitanPanelPerformanceButton"];
+	local color, fpsRichText, latencyRichText, memoryRichText;
+	local showFPS = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowFPS");
+	local showLatency = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowLatency");
+	local showWorldLatency = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowWorldLatency")
+	local showMemory = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowMemory");
+
+	-- Update real time data
+	TitanPanelPerformanceButton_UpdateData()
+
+	-- FPS text
+	if ( showFPS ) then
+		local fpsText = format(L["TITAN_FPS_FORMAT"], button.fps);
+		if ( TitanGetVar(TITAN_PERFORMANCE_ID, "ShowColoredText") ) then
+			color = TitanUtils_GetThresholdColor(TITAN_FPS_THRESHOLD_TABLE, button.fps);
+			fpsRichText = TitanUtils_GetColoredText(fpsText, color);
+		else
+			fpsRichText = TitanUtils_GetHighlightText(fpsText);
+		end
+	end
+
+	-- Latency text
+	latencyRichText = ""
+	if ( showLatency ) then
+		local latencyText = format(L["TITAN_LATENCY_FORMAT"], button.latencyHome);
+		if ( TitanGetVar(TITAN_PERFORMANCE_ID, "ShowColoredText") ) then
+			color = TitanUtils_GetThresholdColor(TITAN_LATENCY_THRESHOLD_TABLE, button.latencyHome);
+			latencyRichText = TitanUtils_GetColoredText(latencyText, color);
+		else
+			latencyRichText = TitanUtils_GetHighlightText(latencyText)
+		end
+	end
+
+	if ( showWorldLatency  ) then
+		local latencyWorldText = format(L["TITAN_LATENCY_FORMAT"], button.latencyWorld);
+		if ( showLatency ) then
+			latencyRichText = latencyRichText.."/"
+		end
+		if ( TitanGetVar(TITAN_PERFORMANCE_ID, "ShowColoredText") ) then
+			color = TitanUtils_GetThresholdColor(TITAN_LATENCY_THRESHOLD_TABLE, button.latencyWorld);
+			latencyRichText = latencyRichText..TitanUtils_GetColoredText(latencyWorldText, color);
+		else
+			latencyRichText = latencyRichText..TitanUtils_GetHighlightText(latencyWorldText);
+		end
+	end
+
+	-- Memory text
+	if ( showMemory ) then
+		local memoryText = format(L["TITAN_MEMORY_FORMAT"], button.memory/1024);
+		memoryRichText = TitanUtils_GetHighlightText(memoryText);
+	end
+
+	if ( showFPS ) then
+		if ( showLatency or showWorldLatency ) then
+			if ( showMemory ) then
+				return L["TITAN_FPS_BUTTON_LABEL"], fpsRichText, L["TITAN_LATENCY_BUTTON_LABEL"], latencyRichText, L["TITAN_MEMORY_BUTTON_LABEL"], memoryRichText;
+			else
+				return L["TITAN_FPS_BUTTON_LABEL"], fpsRichText, L["TITAN_LATENCY_BUTTON_LABEL"], latencyRichText;
+			end
+		else
+			if ( showMemory ) then
+				return L["TITAN_FPS_BUTTON_LABEL"], fpsRichText, L["TITAN_MEMORY_BUTTON_LABEL"], memoryRichText;
+			else
+				return L["TITAN_FPS_BUTTON_LABEL"], fpsRichText;
+			end
+		end
+	else
+		if ( showLatency or showWorldLatency ) then
+			if ( showMemory ) then
+				return L["TITAN_LATENCY_BUTTON_LABEL"], latencyRichText, L["TITAN_MEMORY_BUTTON_LABEL"], memoryRichText;
+			else
+				return L["TITAN_LATENCY_BUTTON_LABEL"], latencyRichText;
+			end
+		else
+			if ( showMemory ) then
+				return L["TITAN_MEMORY_BUTTON_LABEL"], memoryRichText;
+			else
+				return;
+			end
+		end
+	end
+end
+
+-- **************************************************************************
+-- NAME : Stats_UpdateAddonsList(self, watchingCPU)
+-- DESC : Execute garbage collection for Leftclick on button
+-- **************************************************************************
+local function Stats_UpdateAddonsList(self, watchingCPU)
+	if(watchingCPU) then
+		UpdateAddOnCPUUsage()
+	else
+		UpdateAddOnMemoryUsage()
+	end
+
+	local total = 0
+	local i,j,k;
+	local showAddonRate = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowAddonIncRate");
+	for i=1, GetNumAddOns() do
+		local value = (watchingCPU and GetAddOnCPUUsage(i)) or GetAddOnMemoryUsage(i)
+		local name = GetAddOnInfo(i)
+		total = total + value
+
+		for j,addon in ipairs(topAddOns) do
+			if(value > addon.value) then
+				for k = counter, 1, -1 do
+					if(k == j) then
+						topAddOns[k].value = value
+						topAddOns[k].name = GetAddOnInfo(i)
+						break
+					elseif(k ~= 1) then
+						topAddOns[k].value = topAddOns[k-1].value
+						topAddOns[k].name = topAddOns[k-1].name
+					end
+				end
+				break
+			end
+		end
+	end
+
+	GameTooltip:AddLine(' ')
+
+	if (total > 0) then
+		if(watchingCPU) then
+			GameTooltip:AddLine('|cffffffff'..L["TITAN_PERFORMANCE_ADDON_CPU_USAGE_LABEL"])
+		else
+			GameTooltip:AddLine('|cffffffff'..L["TITAN_PERFORMANCE_ADDON_MEM_USAGE_LABEL"])
+		end
+
+		if not watchingCPU then
+			if (showAddonRate == 1) then
+				GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_NAME_LABEL"],LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_USAGE_LABEL"].."/"..L["TITAN_PERFORMANCE_ADDON_RATE_LABEL"]..":")
+			else
+				GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_NAME_LABEL"],LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_USAGE_LABEL"]..":")
+			end
+		end
+
+		if watchingCPU then
+			GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_NAME_LABEL"],LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_USAGE_LABEL"]..":")
+		end
+
+		for _,addon in ipairs(topAddOns) do
+			if(watchingCPU) then
+				local diff = addon.value/total * 100;
+				local incrate = "";
+				incrate = format("(%.2f%%)", diff);
+				if (showAddonRate == 1) then
+					GameTooltip:AddDoubleLine(NORMAL_FONT_COLOR_CODE..addon.name," |cffffffff"..format("%.3f",addon.value)..L["TITAN_MILLISECOND"].." "..GREEN_FONT_COLOR_CODE..incrate);
+				else
+					GameTooltip:AddDoubleLine(NORMAL_FONT_COLOR_CODE..addon.name," |cffffffff"..format("%.3f",addon.value)..L["TITAN_MILLISECOND"]);
+				end
+			else
+				local diff = addon.value - (memUsageSinceGC[addon.name])
+				if diff < 0 or memUsageSinceGC[addon.name]== 0 then
+					memUsageSinceGC[addon.name] = addon.value;
+				end
+				local incrate = "";
+				if diff > 0 then
+					incrate = format("(+%.2f) "..L["TITAN_KILOBYTES_PER_SECOND"], diff);
+				end
+				if (showAddonRate == 1) then
+					if TitanGetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType") == 1 then
+					GameTooltip:AddDoubleLine(NORMAL_FONT_COLOR_CODE..addon.name," |cffffffff"..format(L["TITAN_MEMORY_FORMAT"], addon.value/1000).." "..GREEN_FONT_COLOR_CODE..incrate)
+					else
+						if addon.value > 1000 then
+							GameTooltip:AddDoubleLine(NORMAL_FONT_COLOR_CODE..addon.name," |cffffffff"..format(L["TITAN_MEMORY_FORMAT"], addon.value/1000).." "..GREEN_FONT_COLOR_CODE..incrate)
+						else
+							GameTooltip:AddDoubleLine(NORMAL_FONT_COLOR_CODE..addon.name," |cffffffff"..format(L["TITAN_MEMORY_FORMAT_KB"], addon.value).." "..GREEN_FONT_COLOR_CODE..incrate)
+						end
+					end
+				else
+					if TitanGetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType") == 1 then
+					GameTooltip:AddDoubleLine(NORMAL_FONT_COLOR_CODE..addon.name," |cffffffff"..format(L["TITAN_MEMORY_FORMAT"], addon.value/1000))
+					else
+						if addon.value > 1000 then
+							GameTooltip:AddDoubleLine(NORMAL_FONT_COLOR_CODE..addon.name," |cffffffff"..format(L["TITAN_MEMORY_FORMAT"], addon.value/1000))
+						else
+							GameTooltip:AddDoubleLine(NORMAL_FONT_COLOR_CODE..addon.name," |cffffffff"..format(L["TITAN_MEMORY_FORMAT_KB"], addon.value))
+						end
+					end
+				end
+			end
+		end
+
+		GameTooltip:AddLine(' ')
+
+		if(watchingCPU) then
+			GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_TOTAL_CPU_USAGE_LABEL"], format("%.3f",total)..L["TITAN_MILLISECOND"])
+		else
+			if TitanGetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType") == 1 then
+			GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_TOTAL_MEM_USAGE_LABEL"],format(L["TITAN_MEMORY_FORMAT"], total/1000))
+			else
+				if total > 1000 then
+					GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_TOTAL_MEM_USAGE_LABEL"], format(L["TITAN_MEMORY_FORMAT"], total/1000))
+				else
+					GameTooltip:AddDoubleLine(LIGHTYELLOW_FONT_COLOR_CODE..L["TITAN_PERFORMANCE_ADDON_TOTAL_MEM_USAGE_LABEL"], format(L["TITAN_MEMORY_FORMAT_KB"], total))
+				end
+			end
+		end
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerformanceButton_SetTooltip()
+-- DESC : Display tooltip text
+-- **************************************************************************
+function TitanPanelPerformanceButton_SetTooltip()
+	local button = _G["TitanPanelPerformanceButton"];
+	local showFPS = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowFPS");
+	local showLatency = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowLatency");
+	local showWorldLatency = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowWorldLatency")
+	local showMemory = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowMemory");
+	local showAddonMemory = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowAddonMemory");
+
+	-- Tooltip title
+	GameTooltip:SetText(L["TITAN_PERFORMANCE_TOOLTIP"], HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
+
+	-- FPS tooltip
+	if ( showFPS ) then
+		local fpsText = format(L["TITAN_FPS_FORMAT"], button.fps);
+		local avgFPSText = format(L["TITAN_FPS_FORMAT"], button.avgFPS);
+		local minFPSText = format(L["TITAN_FPS_FORMAT"], button.minFPS);
+		local maxFPSText = format(L["TITAN_FPS_FORMAT"], button.maxFPS);
+
+		GameTooltip:AddLine("\n");
+		GameTooltip:AddLine(TitanUtils_GetHighlightText(L["TITAN_FPS_TOOLTIP"]));
+		GameTooltip:AddDoubleLine(L["TITAN_FPS_TOOLTIP_CURRENT_FPS"], TitanUtils_GetHighlightText(fpsText));
+		GameTooltip:AddDoubleLine(L["TITAN_FPS_TOOLTIP_AVG_FPS"], TitanUtils_GetHighlightText(avgFPSText));
+		GameTooltip:AddDoubleLine(L["TITAN_FPS_TOOLTIP_MIN_FPS"], TitanUtils_GetHighlightText(minFPSText));
+		GameTooltip:AddDoubleLine(L["TITAN_FPS_TOOLTIP_MAX_FPS"], TitanUtils_GetHighlightText(maxFPSText));
+	end
+
+	-- Latency tooltip
+	if ( showLatency or showWorldLatency ) then
+		local latencyText = format(L["TITAN_LATENCY_FORMAT"], button.latencyHome);
+		local latencyWorldText = format(L["TITAN_LATENCY_FORMAT"], button.latencyWorld);
+		local bandwidthInText = format(L["TITAN_LATENCY_BANDWIDTH_FORMAT"], button.bandwidthIn);
+		local bandwidthOutText = format(L["TITAN_LATENCY_BANDWIDTH_FORMAT"], button.bandwidthOut);
+
+		GameTooltip:AddLine("\n");
+		GameTooltip:AddLine(TitanUtils_GetHighlightText(L["TITAN_LATENCY_TOOLTIP"]));
+		if showLatency then GameTooltip:AddDoubleLine(L["TITAN_LATENCY_TOOLTIP_LATENCY_HOME"], TitanUtils_GetHighlightText(latencyText)); end
+		if showWorldLatency then GameTooltip:AddDoubleLine(L["TITAN_LATENCY_TOOLTIP_LATENCY_WORLD"], TitanUtils_GetHighlightText(latencyWorldText)); end
+		GameTooltip:AddDoubleLine(L["TITAN_LATENCY_TOOLTIP_BANDWIDTH_IN"], TitanUtils_GetHighlightText(bandwidthInText));
+		GameTooltip:AddDoubleLine(L["TITAN_LATENCY_TOOLTIP_BANDWIDTH_OUT"], TitanUtils_GetHighlightText(bandwidthOutText));
+	end
+
+	-- Memory tooltip
+	if ( showMemory ) then
+		local memoryText = format(L["TITAN_MEMORY_FORMAT"], button.memory/1024);
+		local initialMemoryText = format(L["TITAN_MEMORY_FORMAT"], button.initialMemory/1024);
+		local sessionTime = time() - button.startSessionTime;
+		local rateRichText, timeToGCRichText, rate, timeToGC, color;
+		if ( sessionTime == 0 ) then
+			rateRichText = TitanUtils_GetHighlightText("N/A");
+		else
+			rate = (button.memory - button.initialMemory) / sessionTime;
+			color = TitanUtils_GetThresholdColor(TITAN_MEMORY_RATE_THRESHOLD_TABLE, rate);
+			rateRichText = TitanUtils_GetColoredText(format(L["TITAN_MEMORY_RATE_FORMAT"], rate), color);
+		end
+		if ( button.memory == button.initialMemory ) then
+			timeToGCRichText = TitanUtils_GetHighlightText("N/A");
+		end
+
+		GameTooltip:AddLine("\n");
+		GameTooltip:AddLine(TitanUtils_GetHighlightText(L["TITAN_MEMORY_TOOLTIP"]));
+		GameTooltip:AddDoubleLine(L["TITAN_MEMORY_TOOLTIP_CURRENT_MEMORY"], TitanUtils_GetHighlightText(memoryText));
+		GameTooltip:AddDoubleLine(L["TITAN_MEMORY_TOOLTIP_INITIAL_MEMORY"], TitanUtils_GetHighlightText(initialMemoryText));
+		GameTooltip:AddDoubleLine(L["TITAN_MEMORY_TOOLTIP_INCREASING_RATE"], rateRichText);
+	end
+
+	if ( showAddonMemory == 1 ) then
+		for _,i in pairs(topAddOns) do
+			i.name = '';
+			i.value = 0;
+		end
+		Stats_UpdateAddonsList(self, GetCVar('scriptProfile') == '1' and not IsModifierKeyDown())
+	end
+
+	GameTooltip:AddLine(TitanUtils_GetGreenText(L["TITAN_PERFORMANCE_TOOLTIP_HINT"]));
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelRightClickMenu_PreparePerformanceMenu()
+-- DESC : Display rightclick menu options
+-- **************************************************************************
+function TitanPanelRightClickMenu_PreparePerformanceMenu()
+	local info
+
+	-- level 3
+	if _G["L_UIDROPDOWNMENU_MENU_LEVEL"] == 3 and _G["L_UIDROPDOWNMENU_MENU_VALUE"]== "AddonControlFrame" then
+		TitanPanelPerfControlFrame:Show()
+		return
+	end
+
+	-- level 2
+	if _G["L_UIDROPDOWNMENU_MENU_LEVEL"] == 2 then
+		if _G["L_UIDROPDOWNMENU_MENU_VALUE"] == "Options" then
+			TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_OPTIONS"], _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			local temptable = {TITAN_PERFORMANCE_ID, "ShowFPS"};
+			info = {};
+			info.text = L["TITAN_PERFORMANCE_MENU_SHOW_FPS"];
+			info.value = temptable;
+			info.func = function()
+				TitanPanelRightClickMenu_ToggleVar(temptable)
+			end
+			info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowFPS");
+			info.keepShownOnClick = 1;
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			local temptable = {TITAN_PERFORMANCE_ID, "ShowLatency"};
+			info = {};
+			info.text = L["TITAN_PERFORMANCE_MENU_SHOW_LATENCY"];
+			info.value = temptable;
+			info.func = function()
+				TitanPanelRightClickMenu_ToggleVar(temptable)
+			end
+			info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowLatency");
+			info.keepShownOnClick = 1;
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			local temptable = {TITAN_PERFORMANCE_ID, "ShowWorldLatency"};
+			info = {};
+			info.text = L["TITAN_PERFORMANCE_MENU_SHOW_LATENCY_WORLD"];
+			info.value = temptable;
+			info.func = function()
+				TitanPanelRightClickMenu_ToggleVar(temptable)
+			end
+			info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowWorldLatency");
+			info.keepShownOnClick = 1;
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			local temptable = {TITAN_PERFORMANCE_ID, "ShowMemory"};
+			info = {};
+			info.text = L["TITAN_PERFORMANCE_MENU_SHOW_MEMORY"];
+			info.value = temptable;
+			info.func = function()
+				TitanPanelRightClickMenu_ToggleVar(temptable)
+			end
+			info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowMemory");
+			info.keepShownOnClick = 1;
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+		end
+
+		if _G["L_UIDROPDOWNMENU_MENU_VALUE"] == "AddonUsage" then
+			TitanPanelRightClickMenu_AddTitle(L["TITAN_PERFORMANCE_ADDONS"], _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			local temptable = {TITAN_PERFORMANCE_ID, "ShowAddonMemory"};
+			info = {};
+			info.text = L["TITAN_PERFORMANCE_MENU_SHOW_ADDONS"];
+			info.value = temptable;
+			info.func = function()
+				TitanPanelRightClickMenu_ToggleVar(temptable)
+			end
+			info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowAddonMemory");
+			info.keepShownOnClick = 1;
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			local temptable = {TITAN_PERFORMANCE_ID, "ShowAddonIncRate"};
+			info = {};
+			info.text = L["TITAN_PERFORMANCE_MENU_SHOW_ADDON_RATE"];
+			info.value = temptable;
+			info.func = function()
+				TitanPanelRightClickMenu_ToggleVar(temptable)
+			end
+			info.checked = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowAddonIncRate");
+			info.keepShownOnClick = 1;
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+
+			info = {};
+			info.notCheckable = true
+			info.text = L["TITAN_PERFORMANCE_CONTROL_TOOLTIP"]..LIGHTYELLOW_FONT_COLOR_CODE..tostring(TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons"));
+			info.value = "AddonControlFrame"
+			info.hasArrow = 1;
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+		end
+
+		if _G["L_UIDROPDOWNMENU_MENU_VALUE"] == "AddonMemoryFormat" then
+			TitanPanelRightClickMenu_AddTitle(L["TITAN_PERFORMANCE_ADDON_MEM_FORMAT_LABEL"], _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+			info = {};
+			info.text = L["TITAN_MEGABYTE"];
+			info.checked = function() if TitanGetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType") == 1 then return true else return nil end
+			end
+			info.func = function() TitanSetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType", 1) end
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+			info = {};
+			info.text = L["TITAN_MEMORY_KBMB_LABEL"];
+			info.checked = function() if TitanGetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType") == 2 then return true else return nil end
+			end
+			info.func = function() TitanSetVar(TITAN_PERFORMANCE_ID, "AddonMemoryType", 2) end
+			L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+		end
+
+		if _G["L_UIDROPDOWNMENU_MENU_VALUE"] == "CPUProfiling" then
+			if ( GetCVar("scriptProfile") == "1" ) then
+				TitanPanelRightClickMenu_AddTitle(L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL"]..": "..GREEN_FONT_COLOR_CODE..L["TITAN_PANEL_MENU_ENABLED"], _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+				info = {};
+				info.text = L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL_OFF"]..GREEN_FONT_COLOR_CODE..L["TITAN_PANEL_MENU_RELOADUI"];
+				info.func = function() SetCVar("scriptProfile", "0", 1) ReloadUI() end
+				L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+			else
+				TitanPanelRightClickMenu_AddTitle(L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL"]..": "..RED_FONT_COLOR_CODE..L["TITAN_PANEL_MENU_DISABLED"], _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+				info = {};
+				info.text = L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL_ON"]..GREEN_FONT_COLOR_CODE..L["TITAN_PANEL_MENU_RELOADUI"];
+				info.func = function() SetCVar("scriptProfile", "1", 1) ReloadUI() end
+				L_UIDropDownMenu_AddButton(info, _G["L_UIDROPDOWNMENU_MENU_LEVEL"]);
+			end
+		end
+		return
+	end
+
+	-- level 1
+	TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_PERFORMANCE_ID].menuText);
+
+	info = {};
+	info.notCheckable = true
+	info.text = L["TITAN_PANEL_OPTIONS"];
+	info.value = "Options"
+	info.hasArrow = 1;
+	L_UIDropDownMenu_AddButton(info);
+
+	info = {};
+	info.notCheckable = true
+	info.text = L["TITAN_PERFORMANCE_ADDONS"];
+	info.value = "AddonUsage"
+	info.hasArrow = 1;
+	L_UIDropDownMenu_AddButton(info);
+
+	info = {};
+	info.notCheckable = true
+	info.text = L["TITAN_PERFORMANCE_ADDON_MEM_FORMAT_LABEL"];
+	info.value = "AddonMemoryFormat"
+	info.hasArrow = 1;
+	L_UIDropDownMenu_AddButton(info);
+
+	info = {};
+	info.notCheckable = true
+	info.text = L["TITAN_PERFORMANCE_MENU_CPUPROF_LABEL"];
+	info.value = "CPUProfiling"
+	info.hasArrow = 1;
+	L_UIDropDownMenu_AddButton(info);
+
+	TitanPanelRightClickMenu_AddSpacer();
+	TitanPanelRightClickMenu_AddToggleIcon(TITAN_PERFORMANCE_ID);
+	TitanPanelRightClickMenu_AddToggleLabelText(TITAN_PERFORMANCE_ID);
+	TitanPanelRightClickMenu_AddToggleColoredText(TITAN_PERFORMANCE_ID);
+	TitanPanelRightClickMenu_AddSpacer();
+	TitanPanelRightClickMenu_AddCommand(L["TITAN_PANEL_MENU_HIDE"], TITAN_PERFORMANCE_ID, TITAN_PANEL_MENU_FUNC_HIDE);
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerformanceButton_UpdateData()
+-- DESC : Update button data
+-- **************************************************************************
+function TitanPanelPerformanceButton_UpdateData()
+	local button = _G["TitanPanelPerformanceButton"];
+	local showFPS = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowFPS");
+	local showLatency = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowLatency");
+	local showWorldLatency = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowWorldLatency")
+	local showMemory = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowMemory");
+	local showAddonMemory = TitanGetVar(TITAN_PERFORMANCE_ID, "ShowAddonMemory");
+
+	-- FPS Data
+	if ( showFPS ) then
+		button.fps = GetFramerate();
+		button.fpsSampleCount = button.fpsSampleCount + 1;
+		if (button.fpsSampleCount == 1) then
+			button.minFPS = button.fps;
+			button.maxFPS = button.fps;
+			button.avgFPS = button.fps;
+		else
+			if (button.fps < button.minFPS) then
+				button.minFPS = button.fps;
+			elseif (button.fps > button.maxFPS) then
+				button.maxFPS = button.fps;
+			end
+			button.avgFPS = (button.avgFPS * (button.fpsSampleCount - 1) + button.fps) / button.fpsSampleCount;
+		end
+	end
+
+	-- Latency Data
+	if ( showLatency or showWorldLatency ) then
+		-- bandwidthIn, bandwidthOut, latencyHome, latencyWorld = GetNetStats();
+		button.bandwidthIn, button.bandwidthOut, button.latencyHome, button.latencyWorld = GetNetStats();
+	end
+
+	-- Memory data
+	if ( showMemory ) or (showAddonMemory == 1) then
+		local previousMemory = button.memory;
+		button.memory, button.gcThreshold = gcinfo();
+		if ( not button.startSessionTime ) then
+			-- Initial data
+			local i;
+			button.startSessionTime = time();
+			button.initialMemory = button.memory;
+
+			for i = 1, GetNumAddOns() do
+				memUsageSinceGC[GetAddOnInfo(i)] = GetAddOnMemoryUsage(i)
+			end
+		elseif (previousMemory and button.memory and previousMemory > button.memory) then
+			-- Reset data after garbage collection
+			local k,i;
+			button.startSessionTime = time();
+			button.initialMemory = button.memory;
+
+			for k in pairs(memUsageSinceGC) do
+				memUsageSinceGC[k] = nil
+			end
+
+			for i = 1, GetNumAddOns() do
+				memUsageSinceGC[GetAddOnInfo(i)] = GetAddOnMemoryUsage(i)
+			end
+		end
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerformanceButton_ResetMemory()
+-- DESC : Reset the memory monitoring values
+-- **************************************************************************
+--function TitanPanelPerformanceButton_ResetMemory()
+	-- local button = _G["TitanPanelPerformanceButton"];
+	--button.memory, button.gcThreshold = gcinfo();
+	--button.initialMemory = button.memory;
+	--button.startSessionTime = time();
+--end
+
+
+-- **************************************************************************
+-- NAME : TitanPanelPerformanceButton_OnClick()
+-- DESC : Execute garbage collection for Leftclick on button
+-- **************************************************************************
+function TitanPanelPerformanceButton_OnClick(self, button)
+	if button == "LeftButton" then
+		collectgarbage('collect');
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerfControlSlider_OnEnter()
+-- DESC : Display tooltip on entering slider
+-- **************************************************************************
+function TitanPanelPerfControlSlider_OnEnter(self)
+	self.tooltipText = TitanOptionSlider_TooltipText(L["TITAN_PERFORMANCE_CONTROL_TOOLTIP"], TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons"));
+	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT");
+	GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, 1);
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerfControlSlider_OnLeave()
+-- DESC : Hide tooltip after leaving slider
+-- **************************************************************************
+function TitanPanelPerfControlSlider_OnLeave(self)
+	self.tooltipText = nil;
+	GameTooltip:Hide();
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerfControlSlider_OnShow()
+-- DESC : Display slider tooltip
+-- **************************************************************************
+function TitanPanelPerfControlSlider_OnShow(self)
+	_G[self:GetName().."Text"]:SetText(TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons"));
+	_G[self:GetName().."High"]:SetText(L["TITAN_PERFORMANCE_CONTROL_LOW"]);
+	_G[self:GetName().."Low"]:SetText(L["TITAN_PERFORMANCE_CONTROL_HIGH"]);
+	self:SetMinMaxValues(1, 40);
+	self:SetValueStep(1);
+	self:SetValue(41 - TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons"));
+	TitanPanelPerfControlFrame:SetBackdropColor(0, 0, 0, 1)
+
+	TitanPanelPerfControlFrame:ClearAllPoints();
+	TitanPanelPerfControlFrame:SetPoint("LEFT", "DropDownList2Button4ExpandArrow","RIGHT", 9/DropDownList2Button4ExpandArrow:GetScale(),0);
+	local offscreenX, offscreenY = TitanUtils_GetOffscreen(TitanPanelPerfControlFrame);
+	if offscreenX == -1 or offscreenX == 0 then
+		TitanPanelPerfControlFrame:ClearAllPoints();
+		TitanPanelPerfControlFrame:SetPoint("LEFT", "DropDownList2Button4ExpandArrow","RIGHT", 9/DropDownList2Button4ExpandArrow:GetScale(),0);
+	else
+		TitanPanelPerfControlFrame:ClearAllPoints();
+		TitanPanelPerfControlFrame:SetPoint("RIGHT", "DropDownList2","LEFT", 3/DropDownList2Button4ExpandArrow:GetScale(),0);
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerfControlSlider_OnValueChanged(arg1)
+-- DESC : Display slider tooltip text
+-- VARS : arg1 = positive or negative change to apply
+-- **************************************************************************
+function TitanPanelPerfControlSlider_OnValueChanged(self, a1)
+	_G[self:GetName().."Text"]:SetText(41 - self:GetValue());
+
+	if a1 == -1 then
+		self:SetValue(self:GetValue() + 1);
+	end
+
+	if a1 == 1 then
+		self:SetValue(self:GetValue() - 1);
+	end
+
+	TitanSetVar(TITAN_PERFORMANCE_ID, "NumOfAddons", 41 - self:GetValue());
+
+	local i;
+	topAddOns = {};
+	-- scan how many addons are active
+	local count = GetNumAddOns();
+	local ActiveAddons = 0;
+	for i=1, count do
+		if IsAddOnLoaded(i) then
+			ActiveAddons = ActiveAddons + 1;
+		end
+	end
+
+	if ActiveAddons < TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons") then
+		counter = ActiveAddons;
+	else
+		counter = TitanGetVar(TITAN_PERFORMANCE_ID, "NumOfAddons");
+	end
+
+	--set the counter to the proper number of active addons that are being monitored
+	for i=1, counter do
+		topAddOns[i] = {name = '', value = 0}
+	end
+
+	-- Update GameTooltip
+	if (self.tooltipText) then
+		self.tooltipText = TitanOptionSlider_TooltipText(L["TITAN_PERFORMANCE_CONTROL_TOOLTIP"], 41 - self:GetValue());
+		GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, 1);
+	end
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerfControlFrame_OnLoad()
+-- DESC : Create performance option frame
+-- **************************************************************************
+function TitanPanelPerfControlFrame_OnLoad(self)
+	_G[self:GetName().."Title"]:SetText(L["TITAN_PERFORMANCE_CONTROL_TITLE"]);
+	self:SetBackdropBorderColor(1, 1, 1);
+	self:SetBackdropColor(0, 0, 0, 1);
+end
+
+-- **************************************************************************
+-- NAME : TitanPanelPerfControlFrame_OnUpdate(elapsed)
+-- DESC : If dropdown is visible, see if its timer has expired.  If so, hide frame
+-- VARS : elapsed = <research>
+-- **************************************************************************
+function TitanPanelPerfControlFrame_OnUpdate(self, elapsed)
+	if not MouseIsOver(_G["TitanPanelPerfControlFrame"]) and not MouseIsOver (_G["DropDownList2Button4"]) and not MouseIsOver (_G["DropDownList2Button4ExpandArrow"]) then
+		TitanUtils_CheckFrameCounting(self, elapsed);
+	end
+end
\ No newline at end of file