local LEVEL_LOWER = 1
local LEVEL_SAME = 2
local LEVEL_HIGHER = 3

local DISTANCE_BESIDE = 1
local DISTANCE_CLOSE = 2
local DISTANCE_FAR = 3
local DISTANCE_VERYFAR = 4

local directions = {
	[DIRECTION_NORTH] = "north",
	[DIRECTION_SOUTH] = "south",
	[DIRECTION_EAST] = "east",
	[DIRECTION_WEST] = "west",
	[DIRECTION_NORTHEAST] = "north-east",
	[DIRECTION_NORTHWEST] = "north-west",
	[DIRECTION_SOUTHEAST] = "south-east",
	[DIRECTION_SOUTHWEST] = "south-west"
}

local descriptions = {
	[DISTANCE_BESIDE] = {[LEVEL_LOWER] = "is below you", [LEVEL_SAME] = "is standing next to you", [LEVEL_HIGHER] = "is above you"},
	[DISTANCE_CLOSE] = {[LEVEL_LOWER] = "is on a lower level to the", [LEVEL_SAME] = "is to the", [LEVEL_HIGHER] = "is on a higher level to the"},
	[DISTANCE_FAR] = "is far to the",
	[DISTANCE_VERYFAR] = "is very far to the"
}

local spell = Spell(SPELL_INSTANT)

function spell.onCastSpell(creature, variant)
	local target = Player(variant:getString())
	if not target or target:getGroup():getAccess() and not creature:getGroup():getAccess() then
		creature:sendCancelMessage(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
		creature:getPosition():sendMagicEffect(CONST_ME_POFF)
		return false
	end

	local targetPosition = target:getPosition()
	local creaturePosition = creature:getPosition()
	local positionDifference = {x = creaturePosition.x - targetPosition.x, y = creaturePosition.y - targetPosition.y, z = creaturePosition.z - targetPosition.z}

	local maxPositionDifference, direction = math.max(math.abs(positionDifference.x), math.abs(positionDifference.y))
	if maxPositionDifference >= 5 then
		local positionTangent = positionDifference.x ~= 0 and positionDifference.y / positionDifference.x or 10
		if math.abs(positionTangent) < 0.4142 then
			direction = positionDifference.x > 0 and DIRECTION_WEST or DIRECTION_EAST
		elseif math.abs(positionTangent) < 2.4142 then
			direction = positionTangent > 0 and (positionDifference.y > 0 and DIRECTION_NORTHWEST or DIRECTION_SOUTHEAST) or positionDifference.x > 0 and DIRECTION_SOUTHWEST or DIRECTION_NORTHEAST
		else
			direction = positionDifference.y > 0 and DIRECTION_NORTH or DIRECTION_SOUTH
		end
	end

	local level = positionDifference.z > 0 and LEVEL_HIGHER or positionDifference.z < 0 and LEVEL_LOWER or LEVEL_SAME
	local distance = maxPositionDifference < 5 and DISTANCE_BESIDE or maxPositionDifference < 101 and DISTANCE_CLOSE or maxPositionDifference < 250 and DISTANCE_FAR or DISTANCE_VERYFAR
	local description = descriptions[distance][level] or descriptions[distance]
	if distance ~= DISTANCE_BESIDE then
		description = description .. " " .. directions[direction]
	end

	creature:sendTextMessage(MESSAGE_INFO_DESCR, target:getName() .. " " .. description .. ".")
	creaturePosition:sendMagicEffect(CONST_ME_MAGIC_BLUE)
	return true
end

spell:group("support")
spell:id(20)
spell:name("Find Person")
spell:words("exiva")
spell:level(8)
spell:mana(20)
spell:isAggressive(false)
spell:hasPlayerNameParam(true)
spell:hasParams(true)
spell:cooldown(2000)
spell:groupCooldown(2000)
spell:vocation("sorcerer;true", "druid;true", "paladin;true", "knight;true", "master sorcerer;true", "elder druid;true", "royal paladin;true", "elite knight;true")
spell:register()
