local v=require((game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")):WaitForChild("\078\101\118\101\114\109\111\114\101"))local E=v("\083\105\103\110\097\108")local F={}F.__index=F F.ClassName="\065\110\105\109\097\116\105\111\110\080\108\097\121\101\114"function F.new(v)local N=setmetatable({},F)N._humanoid=v or error("\078\111 \104\117\109\097\110\111\105\100")N._tracks={}N._fadeTime=.4 N.TrackPlayed=E.new()return N end function F.WithAnimation(E,v)E._tracks[v.Name]=E._humanoid:LoadAnimation(v)return E end function F.AddAnimation(F,v,E)local N=Instance.new("\065\110\105\109\097\116\105\111\110")if tonumber(E)then N.AnimationId="\104\116\116\112\058\047\047\119\119\119\046\114\111\098\108\111\120\046\099\111\109\047\065\115\115\101\116\063\073\068\061"..tonumber(E)or error("\078\111 \097\110\105\109\097\116\105\111\110\073\100")else N.AnimationId=E end N.Name=v or error("\078\111 \110\097\109\101")return F:WithAnimation(N)end function F.GetTrack(E,v)return E._tracks[v]or error("\084\114\097\099\107 \100\111\101\115 \110\111\116 \101\120\105\115\116")end function F.PlayTrack(c,v,E,F,N,Q)E=E or c._fadeTime local l=c:GetTrack(v)if not l.IsPlaying then c.TrackPlayed:Fire(v,E,F,N,Q)c:StopAllTracks(Q or E)l:Play(E,F,N)end return l end function F.StopTrack(F,v,E)E=E or F._fadeTime local N=F:GetTrack(v)if N.IsPlaying then N:Stop(E)end return N end function F.StopAllTracks(E,v)for F,N in pairs(E._tracks)do E:StopTrack(F,v)end end function F.Destroy(v)v:StopAllTracks()setmetatable(v,nil)end return F
--- The AnimationPlayer makes playing and loading tracks into a humanoid easy, providing an interface to
-- playback animations by name instead of resolving a reference to the actual animation.
-- @classmod AnimationPlayer

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Nevermore"))

local Signal = require("Signal")

local AnimationPlayer = {}
AnimationPlayer.__index = AnimationPlayer
AnimationPlayer.ClassName = "AnimationPlayer"

--- Constructs a new animation player for the given humanoid.
-- @constructor
-- @tparam Humanoid humanoid The humanoid to construct the animation player with. The humanoid will have animations
-- loaded in on them.
function AnimationPlayer.new(humanoid)
	local self = setmetatable({}, AnimationPlayer)

	self._humanoid = humanoid or error("No humanoid")
	self._tracks = {}
	self._fadeTime = 0.4 -- Default

	self.TrackPlayed = Signal.new()

	return self
end

--- Adds an animation to use, storing the animation by the name property. The animation will be loaded
-- into the humanoids.
-- @param animation The animation to add.
function AnimationPlayer:WithAnimation(animation)
	self._tracks[animation.Name] = self._humanoid:LoadAnimation(animation)

	return self
end

--- Adds an animation to play
function AnimationPlayer:AddAnimation(name, animationId)
	local animation = Instance.new("Animation")

	if tonumber(animationId) then
		animation.AnimationId = "http://www.roblox.com/Asset?ID=" .. tonumber(animationId) or error("No animationId")
	else
		animation.AnimationId = animationId
	end

	animation.Name = name or error("No name")

	return self:WithAnimation(animation)
end

--- Returns a track in the player
function AnimationPlayer:GetTrack(trackName)
	return self._tracks[trackName] or error("Track does not exist")
end

--- Plays a track
-- @tparam string trackName Name of the track to play
-- @tparam[opt=0.4] number fadeTime How much time it will take to transition into the animation.
-- @tparam[opt=1] number weight Acts as a multiplier for the offsets and rotations of the playing animation
	-- This parameter is extremely unstable.
	-- Any parameter higher than 1.5 will result in very shaky motion, and any parameter higher '
	-- than 2 will almost always result in NAN errors. Use with caution.
-- @tparam[opt=1] number speed The time scale of the animation.
	-- Setting this to 2 will make the animation 2x faster, and setting it to 0.5 will make it
	-- run 2x slower.
-- @tparam[opt=0.4] number stopFadeTime
function AnimationPlayer:PlayTrack(trackName, fadeTime, weight, speed, stopFadeTime)
	fadeTime = fadeTime or self._fadeTime
	local track = self:GetTrack(trackName)

	if not track.IsPlaying then
		self.TrackPlayed:Fire(trackName, fadeTime, weight, speed, stopFadeTime)

		self:StopAllTracks(stopFadeTime or fadeTime)
		track:Play(fadeTime, weight, speed)
	end

	return track
end

--- Stops a track from being played
-- @tparam string trackName
-- @tparam[opt=0.4] number fadeTime
-- @treturn AnimationTrack
function AnimationPlayer:StopTrack(trackName, fadeTime)
	fadeTime = fadeTime or self._fadeTime

	local track = self:GetTrack(trackName)

	if track.IsPlaying then
		track:Stop(fadeTime)
	end

	return track
end

--- Stops all tracks playing
function AnimationPlayer:StopAllTracks(fadeTime)
	for trackName, _ in pairs(self._tracks) do
		self:StopTrack(trackName, fadeTime)
	end
end

--- Deconstructs the animation player, stopping all tracks
function AnimationPlayer:Destroy()
	self:StopAllTracks()
	setmetatable(self, nil)
end

return AnimationPlayer