local lastNotBehindTarget = 0
local lastNotFacingTarget = 0
local lastNotInRange = 0
local isMoving, lastMoved = false, 0
local isTurning, lastTurned = false, 0
local playerX, playerY, lastPlayerX, lastPlayerY
local facing, lastFacing
local events = {}

function events:UI_ERROR_MESSAGE(message)
	if message == "You must be behind your target." then
		lastNotBehindTarget = GetTime()
	elseif message == "You are facing the wrong way!" then
		lastNotFacingTarget = GetTime()
	elseif message == "You are too far away!" then
		lastNotInRange = GetTime()
	end
end	

local function EventFunc(self, event, ...)
	events[event](event, ...)
end
local eventHandler = CreateFrame("Frame", nil, WorldFrame)
eventHandler:SetScript("OnEvent", EventFunc)
for eventname in pairs(events) do eventHandler:RegisterEvent(eventname) end	


eventHandler:SetScript("OnUpdate", function()
	if not WorldMapFrame:IsVisible() then
		lastPlayerX, lastPlayerY = playerX, playerY
		playerX, playerY = GetPlayerMapPosition("player")
		isMoving = playerX ~= lastPlayerX or playerY ~= lastPlayerY
		if isMoving then
			lastMoved = GetTime()
		end
	end
	
	lastFacing = facing
	facing = GetPlayerFacing()
	isTurning = facing ~= lastFacing
	if isTurning then
		lastTurned = GetTime()
	end
end)

WhatsNext:AddConditionalStatement("In Range",{
	category="Position / Rotation",
	test = function(checkTable) 
		return UnitName(tostring(checkTable.unit)) and IsSpellInRange(checkTable.spellName,tostring(checkTable.unit)) == 1
	end,
	text = function(checkTable) 
		return tostring(checkTable.unit) .. " is a valid target for and is within range of " .. tostring(checkTable.spellName) .. "."
	end,
	arguments = {
		spellName = {type = "text", default = ""},
		unit = {type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
	}
})
WhatsNext:AddConditionalStatement("Target In 9.9 Yards",{
	category="Position / Rotation",
	test = function(checkTable) 
		return UnitName(tostring(checkTable.unit)) and CheckInteractDistance(tostring(checkTable.unit), 3)
	end,
	text = function(checkTable) 
		return tostring(checkTable.unit) .. " is within  9.9 yards."
	end,
	arguments = {
		unit = {type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
	}
})
WhatsNext:AddConditionalStatement("Target In 11.11 Yards",{
	category="Position / Rotation",
	test = function(checkTable) 
		return UnitName(tostring(checkTable.unit)) and CheckInteractDistance(tostring(checkTable.unit), 2)
	end,
	text = function(checkTable) 
		return tostring(checkTable.unit) .. " is within 11.11 yards."
	end,
	arguments = {
		unit = {type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
	}
})
WhatsNext:AddConditionalStatement("Target In 28 Yards",{
	category="Position / Rotation",
	test = function(checkTable) 
		return UnitName(tostring(checkTable.unit)) and CheckInteractDistance(tostring(checkTable.unit), 1)
	end,
	text = function(checkTable) 
		return tostring(checkTable.unit) .. " is within 28 yards."
	end,
	arguments = {
		unit = {type = "dropdown", default = "target", possibleValues = WhatsNext.valueLists.unitAny},
	}
})
WhatsNext:AddConditionalStatement("Not Behind Target Detected",{
	category="Position / Rotation",
	test = function(checkTable) 
		return GetTime() - lastNotBehindTarget <= tonumber(checkTable.time)
	end,
	text = function(checkTable) 
		return "has been detected player was not behind their target in the last " .. tostring(checkTable.time) .. " seconds."
	end,
	arguments = {
		time = {type = "integer", default = 0},
	}
})
WhatsNext:AddConditionalStatement("Not Facing Target Detected",{
	category="Position / Rotation",
	test = function(checkTable) 
		return GetTime() - lastNotFacingTarget <= tonumber(checkTable.time)
	end,
	text = function(checkTable) 
		return "has been detected player was not facing their target in the last " .. tostring(checkTable.time) .. " seconds."
	end,
	arguments = {
		time = {type = "integer", default = 0},
	}
})
WhatsNext:AddConditionalStatement("Not In Range Detected",{
	category="Position / Rotation",
	test = function(checkTable) 
		return GetTime() - lastNotInRange <= tonumber(checkTable.time)
	end,
	text = function(checkTable) 
		return "has been detected player was too far away from their target in the last " .. tostring(checkTable.time) .. " seconds."
	end,
	arguments = {
		time = {type = "integer", default = 0},
	}
})
WhatsNext:AddConditionalStatement("Not Behind Target Detected Since Moving/Turning",{
	category="Position / Rotation",
	test = function(checkTable) 
		return  lastNotBehindTarget > lastMoved  and lastNotBehindTarget > lastTurned
	end,
	text = function(checkTable) 
		return "has been detected player was not behind their target since last moving or turning."
	end,
	arguments = {
		time = {type = "integer", default = 0},
	}
})
WhatsNext:AddConditionalStatement("Not Facing Target Detected Since Moving/Turning",{
	category="Position / Rotation",
	test = function(checkTable) 
		return  lastNotFacingTarget > lastMoved and lastNotFacingTarget > lastTurned
	end,
	text = function(checkTable) 
		return "has been detected player was not facing their target since last moving or turning."
	end,
	arguments = {
		time = {type = "integer", default = 0},
	}
})
WhatsNext:AddConditionalStatement("Not In Range Detected Since Moving/Turning",{
	category="Position / Rotation",
	test = function(checkTable) 
		return  lastNotInRange > lastMoved and lastNotInRange > lastTurned
	end,
	text = function(checkTable) 
		return "has been detected player was too far away from their target since last moving or turning."
	end,
	arguments = {
		time = {type = "integer", default = 0},
	}
})
WhatsNext:AddConditionalStatement("Moved",{
	category="Position / Rotation",
	test = function(checkTable) 
		return GetTime() - lastMoved <= tonumber(checkTable.time)
	end,
	text = function(checkTable) 
		return "player has moved in the last " .. tostring(checkTable.time) .. " seconds."
	end,
	arguments = {
		time = {type = "integer", default = 0},
	}
})
WhatsNext:AddConditionalStatement("Turned",{
	category="Position / Rotation",
	test = function(checkTable) 
		return GetTime() - lastTurned <= tonumber(checkTable.time)
	end,
	text = function(checkTable) 
		return "player has turned in the last " .. tostring(checkTable.time) .. " seconds."
	end,
	arguments = {
		time = {type = "integer", default = 0},
	}
})
WhatsNext:AddConditionalStatement("Moving",{
	category="Position / Rotation",
	test = function(checkTable)
		return isMoving
	end,
	text = function(checkTable)
		return "player is moving."
	end,
	arguments = {}
})
WhatsNext:AddConditionalStatement("Turning",{
	category="Position / Rotation",
	test = function(checkTable)
		return isTurning
	end,
	text = function(checkTable)
		return "player is turning."
	end,
	arguments = {}
})