--===================================================
--									
--								GHI Position
--								GHI_Position.lua
--
--			Information about position of the user
--	
-- 						(c)2012 The Gryphonheart Team
--								All rights reserved
--===================================================

local class
function GHI_Position()
	if class then
		return class
	end
	class = GHClass("GHI_Position")

	--local variables
	local continent
	local currentContinent
	local x
	local y
	local zoneIndex
	local areaID
	local floorLevel;
	local dungeonLevel;
	local dungeonLevelDropDownShown;

	GHI_Event("GHP_LOADED",function()
		if GHP_FloorLevelDetermination then
			floorLevel = GHP_FloorLevelDetermination();
		end
	end);


	local Round = function(num,decimals)
		if decimals then
			return tonumber(string.format("%."..decimals.."f",num));
		end
		return num;
	end

	local ConvertMopToCata = function(x_mop,y_mop)
		local x_cata = 1.243338591 * x_mop - 2822.734638;
		local y_cata = 1.243339374 * y_mop - 409.9540594;
		return x_cata,y_cata;
	end

	local IsMopClient = function()
		local _, _, _, tocVersion = GetBuildInfo()
		return tocVersion >= 50000;
	end

	local ResetMap = function()
		SetMapToCurrentZone();
		if GetCurrentMapAreaID() == areaID then
			SetDungeonMapLevel(dungeonLevel);
		else
			SetMapByID(areaID)
		end
		if dungeonLevelDropDownShown then
			DropDownList1:Show();
		end
	end
	--Class functions
	class.GetCoor = function(unit,decimals)
		if not (unit) then unit = "player" end

		zoneIndex = GetCurrentMapZone()
		continent = GetCurrentMapContinent()
		areaID = GetCurrentMapAreaID()
		dungeonLevel = GetCurrentMapDungeonLevel();

		-- check if drop down is shown
		if DropDownList1:IsShown() and ({DropDownList1:GetPoint(1)})[2] == WorldMapLevelDropDownLeft then
			dungeonLevelDropDownShown = true;
		else
			dungeonLevelDropDownShown = false;
		end

		-- Move map
		SetMapToCurrentZone()
		currentContinent = GetCurrentMapContinent()
		if currentContinent < 0 or currentContinent > 4 then
			ResetMap()
			return 0.0, 0.0, 0
		end

		if currentContinent == 3 then
			SetMapZoom(3)
		else
			SetMapZoom(0)
		end

		local x, y = GetPlayerMapPosition(unit)
		local level;
		if floorLevel then
			level = floorLevel.GetCurrentFloorLevel();
		end

		if currentContinent == 3 then
			x = x * 2228.61382 -- scale for Outland
			y = y * 1485.74255
			ResetMap();
			return Round(x,decimals), Round(y,decimals), 2, level
		else
			x = x * 11698.9534 -- scale for Azeroth
			y = y * 7799.30229
			ResetMap();

			if IsMopClient() then
				x,y = ConvertMopToCata(x,y);
			end

			return Round(x,decimals), Round(y,decimals), 1, level
		end
	end

	class.GetPlayerPos = function(decimals)
		local x, y, world, level = class.GetCoor("player",decimals);
		return {
			x = x,
			y = y,
			world = world,
			level = level,
		};
	end

	class.IsPosWithinRange = function(position, range)
		GHCheck("GHI_Position.IsPosWithinRange", { "Table", "Number" }, { position, range })
		local playerPos = class.GetPlayerPos();
		position.world = position.world or position.continent;

		if not (playerPos.world == position.world) then
			return false;
		end

		local xDiff = position.x - playerPos.x;
		local yDiff = position.y - playerPos.y;
		return math.abs(math.sqrt(xDiff * xDiff + yDiff * yDiff)) <= range
	end

	class.OnNextMoveCallback = function(range,func,_repeat)
		local pos = class.GetPlayerPos(3);
		GHI_Timer(function()
			if pos then
				if not(class.IsPosWithinRange(pos,range)) then
					func();
					if _repeat then
						pos = class.GetPlayerPos(3);
					else
						pos = nil;
					end
				end
			end
		end,1);
	end

	return class
end
