local E, L, V, P, G = unpack(ElvUI)
local DT = E:GetModule('DataTexts')

local strjoin = strjoin
local IsFalling = IsFalling
local IsFlying = IsFlying
local IsSwimming = IsSwimming
local GetUnitSpeed = GetUnitSpeed
local C_PlayerInfo_GetGlidingInfo = C_PlayerInfo.GetGlidingInfo

local STAT_CATEGORY_ENHANCEMENTS = STAT_CATEGORY_ENHANCEMENTS
local BASE_MOVEMENT_SPEED = BASE_MOVEMENT_SPEED

local displayString, db = ''
local beforeFalling, wasFlying

local delayed
local function DelayUpdate(panel)
	local _, runSpeed, flightSpeed, swimSpeed = GetUnitSpeed('player')
	local speed, isGliding, forwardSpeed

	if E.Retail then
		isGliding, _, forwardSpeed = C_PlayerInfo_GetGlidingInfo()
	end

	if IsSwimming() then
		speed = swimSpeed
		wasFlying = false
	elseif isGliding then
		speed = forwardSpeed
		wasFlying = true
	elseif IsFlying() then
		speed = flightSpeed
		wasFlying = true
	else
		speed = runSpeed
		wasFlying = false
	end

	if IsFalling() and wasFlying and beforeFalling then
		speed = beforeFalling
	else
		beforeFalling = speed
	end

	local percent = speed / BASE_MOVEMENT_SPEED * 100
	if db.NoLabel then
		panel.text:SetFormattedText(displayString, percent)
	else
		panel.text:SetFormattedText(displayString, db.Label ~= '' and db.Label or L["Mov. Speed"], percent)
	end

	delayed = nil
end

local function OnEvent(panel)
	if not delayed then
		delayed = E:Delay(0.05, DelayUpdate, panel)
	end
end

local function ApplySettings(panel, hex)
	if not db then
		db = E.global.datatexts.settings[panel.name]
	end

	displayString = strjoin('', db.NoLabel and '' or '%s: ', hex, '%.'..db.decimalLength..'f%%|r')
end

DT:RegisterDatatext('MovementSpeed', STAT_CATEGORY_ENHANCEMENTS, { 'UNIT_STATS', 'UNIT_AURA', 'UNIT_SPELL_HASTE' }, OnEvent, nil, nil, nil, nil, _G.STAT_MOVEMENT_SPEED, nil, ApplySettings)
