--[[
-- **************************************************************************
-- * TitanLocation.lua
-- *
-- * 2023 Dec : Merged with Classic versions. Classic map does not include
-- * the quest log so the placement of coord on the map, if selected, is a
-- * bit more work.
-- *
-- * By: The Titan Panel Development Team
-- **************************************************************************
--]]
-- ******************************** Constants *******************************
local _G = getfenv(0);
local TITAN_LOCATION_ID = "Location";
local TITAN_BUTTON = "TitanPanel"..TITAN_LOCATION_ID.."Button"
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 = {} -- For AceLocale
local AceTimer = {}
local LocationTimer = nil;

-- Difference in the Blizzard frame for the world map
local MapMinMaxFrame = {}

-- ******************************** Functions *******************************

--[[
-- **************************************************************************
-- NAME : TitanPanelLocationButton_OnLoad()
-- DESC : Registers the plugin upon it loading
-- **************************************************************************
--]]
function TitanPanelLocationButton_OnLoad(self)
	local notes = ""
		.."Adds coordinates and location information to Titan Panel.\n"
--		.."- xxx.\n"
	self.registry = {
		id = TITAN_LOCATION_ID,
		category = "Built-ins",
		version = (TitanUtils_GetAddOnMetadata(TITAN_LOCATION_ID, "Version")) or "",
		menuText = L["TITAN_LOCATION_MENU_TEXT"],
		buttonTextFunction = "TitanPanelLocationButton_GetButtonText",
		tooltipTitle = L["TITAN_LOCATION_TOOLTIP"],
		tooltipTextFunction = "TitanPanelLocationButton_GetTooltipText",
		icon = "Interface\\AddOns\\TitanLocation\\TitanLocation",
		iconWidth = 16,
		notes = notes,
		controlVariables = {
			ShowIcon = true,
			ShowLabelText = true,
			ShowRegularText = false,
			ShowColoredText = true,
			DisplayOnRightSide = true,
		},
		savedVariables = {
			ShowZoneText = 1,
            ShowSubZoneText = true,
			ShowCoordsText = true,
			ShowCoordsOnMap = true,
			ShowCursorOnMap = true,
			ShowLocOnMiniMap = 1,
			ShowIcon = 1,
			ShowLabelText = 1,
			ShowColoredText = 1,
			CoordsFormat = L["TITAN_LOCATION_FORMAT"],
			UpdateWorldmap = false,
			MapLocation = "TOPRIGHT",
			DisplayOnRightSide = false,
		}
	};

	self:RegisterEvent("ZONE_CHANGED");
	self:RegisterEvent("ZONE_CHANGED_INDOORS");
	self:RegisterEvent("ZONE_CHANGED_NEW_AREA");
	self:RegisterEvent("PLAYER_ENTERING_WORLD");

	TitanPanelLocation_CreateMapFrames();
end

--[[
-- **************************************************************************
-- NAME : TitanPanelLocationButton_OnShow()
-- DESC : Display button when plugin is visible
-- **************************************************************************
--]]
function TitanPanelLocationButton_OnShow()
	-- Set the version of the map to use
	if TITAN_ID == "TitanClassic" then
		MapMinMaxFrame = WorldMapFrame.MaximizeMinimizeFrame  

		local mapID = C_Map.GetBestMapForUnit("player");
		if mapID ~= nil and C_Map.MapHasArt(mapID) then
			WorldMapFrame:SetMapID(mapID);
		end
	else
		MapMinMaxFrame = WorldMapFrame.BorderFrame.MaximizeMinimizeFrame 
	end

	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);
	local locationText = ""
	
	-- Coordinates text, if requested
	if (TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsText")) then
		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

		if button.px == 0 and button.py == 0 then
			locationText = "";
		else
		locationText = format(TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat"), 100 * button.px, 100 * button.py)
		end
	else
		locationText = "";
	end

	-- Zone text, if requested
	if (TitanGetVar(TITAN_LOCATION_ID, "ShowZoneText")) then
		if (TitanUtils_ToString(button.subZoneText) == '') then
			if (button.zoneText == '') then
				local Map_unit = C_Map.GetBestMapForUnit -- DF change of API
								or C_Map.GetBestMapUnit
				local _
				_, _, button.zoneText = C_Map.GetMapInfo(Map_unit("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

	-- Color per type of zone (friendly, contested, hostile)
	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 = ""
	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, ...)
-- DF TODO See if we can turn off zone on minimap
--[=[
--]=]
	if TITAN_ID == "TitanClassic" then
		if event == "PLAYER_ENTERING_WORLD" then
			if not TitanGetVar(TITAN_LOCATION_ID, "ShowLocOnMiniMap") 
				and MinimapBorderTop and MinimapBorderTop:IsShown() then
				TitanPanelLocationButton_LocOnMiniMap("PEW")
			end
		end

		if TitanGetVar(TITAN_LOCATION_ID, "ShowLocOnMiniMap") and MinimapBorderTop:IsShown() then
			if not MinimapZoneTextButton:IsShown() then MinimapZoneTextButton:Show() end
--			if not MiniMapWorldMapButton:IsShown() then MiniMapWorldMapButton:Show() end
		end
	else
		-- no work needed
	end

	TitanPanelLocationButton_UpdateZoneInfo(self);
	TitanPanelPluginHandle_OnUpdate(updateTable);
	TitanPanelLocation_HandleUpdater();
--[[
--]]
end

--[[
-- **************************************************************************
-- NAME : TitanPanelLocationButton_CheckForUpdate()
-- DESC : 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
				local message = TitanUtils_ToString(self.zoneText).." "..
					format(TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat"), 100 * self.px, 100 * self.py);
				activeWindow:Insert(message);
			end
		else
			ToggleFrame(WorldMapFrame);
		end
	end
end

--[[
-- **************************************************************************
-- NAME : TitanPanelLocationButton_UpdateZoneInfo()
-- DESC : Update data on button
-- **************************************************************************
--]]
function TitanPanelLocationButton_UpdateZoneInfo(self)
	local _ = nil
	self.zoneText = GetZoneText();
	self.subZoneText = GetSubZoneText();
	self.pvpType, _, self.factionName = GetZonePVPInfo();
end

--[[
-- **************************************************************************
-- NAME : TitanPanelRightClickMenu_PrepareLocationMenu()
-- DESC : Display rightclick menu options
-- **************************************************************************
--]]
local function CoordLoc(loc)
	local res = (TitanGetVar(TITAN_LOCATION_ID, "MapLocation") == loc)
	return res
end
function TitanPanelRightClickMenu_PrepareLocationMenu()
	local info

	-- level 2
	if TitanPanelRightClickMenu_GetDropdownLevel() == 2 then
		if TitanPanelRightClickMenu_GetDropdMenuValue() == "Options" then
			TitanPanelRightClickMenu_AddTitle(L["TITAN_PANEL_OPTIONS"], TitanPanelRightClickMenu_GetDropdownLevel());
			info = {};
			info.text = L["TITAN_LOCATION_MENU_SHOW_ZONE_ON_PANEL_TEXT"];
			info.func = TitanPanelLocationButton_ToggleDisplay;
			info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowZoneText");
			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());

			if TITAN_ID == "TitanClassic" then
				info = {};
				info.text = L["TITAN_LOCATION_MENU_SHOW_SUBZONE_ON_PANEL_TEXT"];
				info.func = function()
					TitanToggleVar(TITAN_LOCATION_ID, "ShowSubZoneText");
					TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
				end
				info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowSubZoneText");
				TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
			else
				-- no work needed
			end

			info = {};
			info.text = L["TITAN_LOCATION_MENU_SHOW_COORDS_ON_PANEL_TEXT"];
			info.func = function()
				TitanToggleVar(TITAN_LOCATION_ID, "ShowCoordsText");
				TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
			end
			info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsText");
			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
			info = {};
			info.text = L["TITAN_LOCATION_MENU_SHOW_COORDS_ON_MAP_TEXT"];
			info.func = TitanPanelLocationButton_ToggleLocationOnMap;
			info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsOnMap");
			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());

			if TITAN_ID == "TitanClassic" then
			info = {};
			info.text = L["TITAN_LOCATION_MENU_SHOW_LOC_ON_MINIMAP_TEXT"];
			info.func = function()
				TitanToggleVar(TITAN_LOCATION_ID, "ShowLocOnMiniMap");
				TitanPanelLocationButton_LocOnMiniMap("config")
			end
			info.checked = TitanGetVar(TITAN_LOCATION_ID, "ShowLocOnMiniMap");
			info.disabled = InCombatLockdown()
			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
			else
				-- no work needed
			end
			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()
			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());

--[=[
			if TITAN_ID == "TitanClassic" then
				info = {};
				TitanPanelRightClickMenu_AddSpacer(TitanPanelRightClickMenu_GetDropdownLevel());
				TitanPanelRightClickMenu_AddTitle(L["TITAN_LOCATION_MENU_MAP_COORDS_TITLE"], TitanPanelRightClickMenu_GetDropdownLevel());
				
				info = {};
				info.text = L["TITAN_LOCATION_MENU_MAP_COORDS_LOC_1"]
				info.func = function()
					TitanSetVar(TITAN_LOCATION_ID, "MapLocation", "TOPLEFT")
				end
				info.checked = CoordLoc("TOPLEFT")
				TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
				info = {};
				info.text = L["TITAN_LOCATION_MENU_MAP_COORDS_LOC_2"]
				info.func = function()
					TitanSetVar(TITAN_LOCATION_ID, "MapLocation", "TOPRIGHT")
				end
				info.checked = CoordLoc("TOPRIGHT")
				TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
				info = {};
				info.text = L["TITAN_LOCATION_MENU_MAP_COORDS_LOC_3"]
				info.func = function()
					TitanSetVar(TITAN_LOCATION_ID, "MapLocation", "BOTTOMLEFT")
				end
				info.checked = CoordLoc("BOTTOMLEFT")
				TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
				info = {};
				info.text = L["TITAN_LOCATION_MENU_MAP_COORDS_LOC_4"]
				info.func = function()
					TitanSetVar(TITAN_LOCATION_ID, "MapLocation", "BOTTOM")
				end
				info.checked = CoordLoc("BOTTOM")
				TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
				info = {};
				info.text = L["TITAN_LOCATION_MENU_MAP_COORDS_LOC_5"]
				info.func = function()
					TitanSetVar(TITAN_LOCATION_ID, "MapLocation", "BOTTOMRIGHT")
				end
				info.checked = CoordLoc("BOTTOMRIGHT")
				TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
			else
				-- no work needed
			end
--]=]
		end
		if TitanPanelRightClickMenu_GetDropdMenuValue() == "CoordFormat" then
			TitanPanelRightClickMenu_AddTitle(L["TITAN_LOCATION_FORMAT_COORD_LABEL"], TitanPanelRightClickMenu_GetDropdownLevel());
			info = {};
			info.text = L["TITAN_LOCATION_FORMAT_LABEL"];
			info.func = function()
				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat", L["TITAN_LOCATION_FORMAT"]);
				TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
			end
			info.checked = (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat") == L["TITAN_LOCATION_FORMAT"])
			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());

			info = {};
			info.text = L["TITAN_LOCATION_FORMAT2_LABEL"];
			info.func = function()
				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat", L["TITAN_LOCATION_FORMAT2"]);
				TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
			end
			info.checked = (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat") == L["TITAN_LOCATION_FORMAT2"])
			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());

			info = {};
			info.text = L["TITAN_LOCATION_FORMAT3_LABEL"];
			info.func = function()
				TitanSetVar(TITAN_LOCATION_ID, "CoordsFormat", L["TITAN_LOCATION_FORMAT3"]);
				TitanPanelButton_UpdateButton(TITAN_LOCATION_ID);
			end
			info.checked = (TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat") == L["TITAN_LOCATION_FORMAT3"])
			TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());
		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;
	TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());

	info = {};
	info.notCheckable = true
	info.text = L["TITAN_LOCATION_FORMAT_COORD_LABEL"];
	info.value = "CoordFormat"
	info.hasArrow = 1;
	TitanPanelRightClickMenu_AddButton(info, TitanPanelRightClickMenu_GetDropdownLevel());

	TitanPanelRightClickMenu_AddControlVars(TITAN_LOCATION_ID)
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

--[[
-- **************************************************************************
-- NAME : TitanPanelLocationButton_LocOnMiniMap()
-- DESC : Show / hide the location above the mini map per user settings
-- **************************************************************************
--]]
function TitanPanelLocationButton_LocOnMiniMap(reason)
	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
	if reason == "config" then
		TitanPanel_AdjustFrames(false);
	else
		-- 2024 Jan - Do not adjust; allow Titan to handle on PEW 
	end
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

	local cursorLocationText = "-C-"
	local playerLocationText = "-P-"

	if (TitanGetVar(TITAN_LOCATION_ID, "ShowCoordsOnMap")) 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
			playerLocationText = format(TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat"), 100 * self.px, 100 * self.py);
		end
		playerLocationText = (format(L["TITAN_LOCATION_MAP_PLAYER_COORDS_TEXT"], TitanUtils_GetHighlightText(playerLocationText)));

		-- Determine the text to show for cursor coords
		local cx, cy = GetCursorPosition();

		-- use the global cursor position to confirm the cursor is over the map, but then use a normalized cursor position to account for map zooming
		local left, bottom, width, height = WorldMapFrame.ScrollContainer:GetScaledRect();
		if (cx > left and cy > bottom and cx < left + width and cy < bottom+ height) then
			cx, cy = WorldMapFrame:GetNormalizedCursorPosition();
			cx, cy = cx or 0, cy or 0;
		else
			cx, cy = 0, 0
		end

		-- per the user requested format
		cursorLocationText = format(TitanGetVar(TITAN_LOCATION_ID, "CoordsFormat"), 100 * cx, 100 * cy)
		cursorLocationText = (format(L["TITAN_LOCATION_MAP_CURSOR_COORDS_TEXT"],
			TitanUtils_GetHighlightText(cursorLocationText)))
	else
		-- use defaults, saving a few cpu cycles
	end
--[==[
print("TLoc"
.." c "..tostring(cursorLocationText).." "
.." p "..tostring(playerLocationText).." "
)
--]==]
		TitanMapPlayerLocation:SetText(cursorLocationText);
		TitanMapCursorLocation:SetText(playerLocationText);

--		local mloc = TitanGetVar(TITAN_LOCATION_ID, "MapLocation") or "TOPRIGHT"
		if TITAN_ID == "TitanClassic" then
			-- Determine where to show the text
			TitanMapPlayerLocation:ClearAllPoints()
			TitanMapCursorLocation:ClearAllPoints()

			TitanMapPlayerLocation:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOM", 0, 10)
			TitanMapCursorLocation:SetPoint("BOTTOMRIGHT", WorldMapFrame, "BOTTOM", -10, 10)
--			TitanMapPlayerLocation:SetPoint("BOTTOMRIGHT", WorldMapFrame, "BOTTOM", -buff, 10)
--			TitanMapCursorLocation:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOM", 0, 10)
--[[			
			if (mloc == "TOPRIGHT") then
				TitanMapPlayerLocation:SetPoint("TOPRIGHT", WorldMapFrame, "TOPRIGHT", -10, -28)
				TitanMapCursorLocation:SetPoint("TOPRIGHT", TitanMapPlayerLocation, "BOTTOMRIGHT", 0, 0)
			elseif (mloc == "TOPLEFT") then
				TitanMapPlayerLocation:SetPoint("TOPLEFT", WorldMapFrame, "TOPLEFT", 10, -28)
				TitanMapCursorLocation:SetPoint("TOPLEFT", TitanMapPlayerLocation, "BOTTOMLEFT", 0, 0)
			elseif (mloc == "BOTTOMLEFT") then
				TitanMapPlayerLocation:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOMLEFT", 10, 10)
				TitanMapCursorLocation:SetPoint("BOTTOMLEFT", TitanMapPlayerLocation, "BOTTOMRIGHT", buff, 0)
			elseif (mloc == "BOTTOMRIGHT") then
				TitanMapPlayerLocation:SetPoint("BOTTOMRIGHT", TitanMapCursorLocation, "BOTTOMLEFT", -buff, 0)
				TitanMapCursorLocation:SetPoint("BOTTOMRIGHT", WorldMapFrame, "BOTTOMRIGHT", -xbuff, 10)
			elseif (mloc == "BOTTOM") then
				TitanMapPlayerLocation:SetPoint("BOTTOMRIGHT", WorldMapFrame, "BOTTOM", -buff, 10)
				TitanMapCursorLocation:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOM", 0, 10)
			end
		elseif Titan_Panel.game_ver == "Classic_Era" then
			-- Determine where to show the text
			TitanMapPlayerLocation:ClearAllPoints()
			TitanMapCursorLocation:ClearAllPoints()

			if (mloc == "TOPRIGHT") then
				TitanMapPlayerLocation:SetPoint("TOPRIGHT", WorldMapFrame, "TOPRIGHT", -10, -28)
				TitanMapCursorLocation:SetPoint("TOPRIGHT", TitanMapPlayerLocation, "BOTTOMRIGHT", 0, 0)
			elseif (mloc == "TOPLEFT") then
				TitanMapPlayerLocation:SetPoint("TOPLEFT", WorldMapFrame, "TOPLEFT", 10, -28)
				TitanMapCursorLocation:SetPoint("TOPLEFT", TitanMapPlayerLocation, "BOTTOMLEFT", 0, 0)
			elseif (mloc == "BOTTOMLEFT") then
				TitanMapPlayerLocation:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOMLEFT", 15, 10)
				TitanMapCursorLocation:SetPoint("BOTTOMLEFT", TitanMapPlayerLocation, "BOTTOMRIGHT", buff, 0)
			elseif (mloc == "BOTTOMRIGHT") then
				TitanMapPlayerLocation:SetPoint("BOTTOMRIGHT", TitanMapCursorLocation, "BOTTOMLEFT", -buff, 0)
				TitanMapCursorLocation:SetPoint("BOTTOMRIGHT", WorldMapFrame, "BOTTOMRIGHT", -xbuff, 10)
			elseif (mloc == "BOTTOM") then
				TitanMapPlayerLocation:SetPoint("BOTTOMRIGHT", WorldMapFrame, "BOTTOM", -buff, 10)
				TitanMapCursorLocation:SetPoint("BOTTOMLEFT", WorldMapFrame, "BOTTOM", 0, 10)
			end
--]]
		else -- current retail
			-- Position the text
			if MapMinMaxFrame.MaximizeButton:IsShown() then
				if WorldMapFrame.TitanSizePrev == "small" then
					-- no change
				else
					TitanMapPlayerLocation:ClearAllPoints();
					TitanMapCursorLocation:ClearAllPoints();
					TitanMapPlayerLocation:SetPoint("RIGHT", MapMinMaxFrame, "LEFT", 0, 0)
					TitanMapCursorLocation:SetPoint("LEFT", WorldMapFrame.BorderFrame.Tutorial, "RIGHT", 0, 0)
					WorldMapFrame.TitanSize = "small"
				end
			else -- map should be 'full' screen
				if WorldMapFrame.TitanSizePrev == "large" then
					-- no change
				else
					TitanMapPlayerLocation:ClearAllPoints();
					TitanMapCursorLocation:ClearAllPoints();
					TitanMapPlayerLocation:SetPoint("RIGHT", MapMinMaxFrame, "LEFT", 0, 0)
					TitanMapCursorLocation:SetPoint("TOP", TitanMapPlayerLocation, "BOTTOM", 0, -5)
					WorldMapFrame.TitanSize = "large"
				end
			end
		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

--[[
-- **************************************************************************
-- NAME : TitanPanelLocation_CreateMapFrames()
-- DESC : Adds player and cursor coords to the WorldMapFrame, unless the player has CT_MapMod
-- VARS : none
-- **************************************************************************
--]]
local TPL_CMF_IsFirstTime = true;
function TitanPanelLocation_CreateMapFrames()
	if (TPL_CMF_IsFirstTime) then
		TPL_CMF_IsFirstTime = false;

		-- avoid an addon conflict
		if (_G["CT_MapMod"]) then
			return;
		end

		-- create the frame to hold the font strings, and simulate an "OnUpdate" script handler using C_Timer for efficiency
--		local frame = CreateFrame("FRAME", "TitanMapFrame", WorldMapFrame.BorderFrame)
		local frame = CreateFrame("FRAME", "TitanMapFrame", WorldMapFrame)
		frame:SetFrameStrata("DIALOG") -- DF need to raise the strata to be seen
		local function updateFunc()
			TitanMapFrame_OnUpdate(frame, 0.07);	-- simulating an OnUpdate call
		end
		frame:HookScript("OnShow", function()
			frame.updateTicker = frame.updateTicker or C_Timer.NewTicker(0.07, updateFunc);
			if MapMinMaxFrame.MaximizeButton:IsShown() then
				WorldMapFrame.TitanSize = "small"
				WorldMapFrame.TitanSizePrev = "none"
			else
				WorldMapFrame.TitanSize = "large"
				WorldMapFrame.TitanSizePrev = "none"
			end
		end);
		frame:HookScript("OnHide", function()
			if (frame.updateTicker) then
				frame.updateTicker:Cancel();
				frame.updateTicker = nil;
			end
		end);

		-- create the font strings and update their position based in minimizing/maximizing the main map
		local playertext = frame:CreateFontString("TitanMapPlayerLocation", "ARTWORK", "GameFontNormal");
		local cursortext = frame:CreateFontString("TitanMapCursorLocation", "ARTWORK", "GameFontNormal");
		playertext:ClearAllPoints();
		cursortext:ClearAllPoints();
		playertext:SetPoint("TOPRIGHT", WorldMapFrameCloseButton, "BOTTOMRIGHT", 0, 0)
		cursortext:SetPoint("TOP", playertext, "BOTTOM", 0, 0)
	end
end


-- ====== Create needed frames
local function Create_Frames()
	if _G[TITAN_BUTTON] then
		return -- if already created
	end
	
	-- general container frame
	local f = CreateFrame("Frame", nil, UIParent)
--	f:Hide()

	-- Titan plugin button
	local window = CreateFrame("Button", TITAN_BUTTON, f, "TitanPanelComboTemplate")
	window:SetFrameStrata("FULLSCREEN")
	-- Using SetScript("OnLoad",   does not work
	TitanPanelLocationButton_OnLoad(window);
--	TitanPanelButton_OnLoad(window); -- Titan XML template calls this...
	
	window:SetScript("OnShow", function(self)
		TitanPanelLocationButton_OnShow(self);
		TitanPanelButton_OnShow(self);
	end)
	window:SetScript("OnHide", function(self)
		TitanPanelLocationButton_OnHide(self) 
	end)
	window:SetScript("OnEvent", function(self, event, ...)
		TitanPanelLocationButton_OnEvent(self, event, ...) 
	end)
	window:SetScript("OnClick", function(self, button)
		TitanPanelLocationButton_OnClick(self, button);
		TitanPanelButton_OnClick(self, button);
	end)
end


if TITAN_ID then -- it exists
	AceTimer = LibStub("AceTimer-3.0")
	L = LibStub("AceLocale-3.0"):GetLocale(TITAN_ID, true)
	Create_Frames() -- do the work
end
