local N=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 C=N("\078\117\109\098\101\114\080\114\111\112\101\114\116\121\084\119\101\101\110\101\114")local F=N("\067\111\108\111\114\051\080\114\111\112\101\114\116\121\084\119\101\101\110\101\114")local h=N("\080\114\111\112\101\114\116\121\084\119\101\101\110\101\114\083\116\097\099\107")local d={FogEnd=500;FogStart=500}local K={}K.ClassName="\079\098\106\101\099\116\084\119\101\101\110\101\114"K.__index=K function K.new(N)local C=setmetatable({},K)C._object=N or error("\078\111 \111\098\106\101\099\116")C._propertyTweeners={}return C end function K.RemoveTween(C,N)local F={}for C,h in pairs(C._propertyTweeners)do h:RemoveTween(N)if not h:HasTweens()then F[C]=true end end for N in pairs(F)do C:_removePropertyTweener(N)end end function K.TweenProperty(d,N,C,F,h)assert(N)assert(C)assert(F)assert(h)local K=d:_getPropertyTweener(F,h)K:TweenProperty(N,C,h)end function K.TweenProperties(h,N,C,F)assert(N)assert(C)assert(F)for F,d in pairs(F)do h:TweenProperty(N,C,F,d)end end function K.Update(N)local C=false for N,F in pairs(N._propertyTweeners)do if F:Update()then C=true end end return C end function K.HasTweens(N)return next(N._propertyTweeners)~=nil end function K._removePropertyTweener(C,N)C._propertyTweeners[N]=nil end function K._getPropertyTweener(a,N,K)if a._propertyTweeners[N]then return a._propertyTweeners[N]end local I=a._object[N]if typeof(I)~=typeof(K)then error(("\066\097\100 \116\121\112\101 \102\111\114 \112\114\111\112\101\114\116\121 \037\113 \112\097\115\115\101\100 \105\110\044 \101\120\112\101\099\116\101\100 \037\113\044 \103\111\116 \037\113"):format(N,typeof(I),typeof(K)))end local b=nil if type(I)=="\110\117\109\098\101\114"then b=C.new(a._object,N)elseif typeof(I)=="\067\111\108\111\114\051"then b=F.new(a._object,N)else error(("\066\097\100 \112\114\111\112\101\114\116\121 \116\121\112\101\033 \037\113"):format(type(K)))end if d[N]then b:SetSpeed(d[N])end local u=h.new(b)a._propertyTweeners[N]=u return u end return K
--- Tweens properties on an object
-- @classmod ObjectTweener

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

local NumberPropertyTweener = require("NumberPropertyTweener")
local Color3PropertyTweener = require("Color3PropertyTweener")
local PropertyTweenerStack = require("PropertyTweenerStack")

local DEFAULT_SPEEDS = {
	["FogEnd"] = 500;
	["FogStart"] = 500;
}

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

function ObjectTweener.new(object)
	local self = setmetatable({}, ObjectTweener)

	self._object = object or error("No object")
	self._propertyTweeners = {}

	return self
end

function ObjectTweener:RemoveTween(key)
	local to_remove = {}
	for property, propertyTweener in pairs(self._propertyTweeners) do
		propertyTweener:RemoveTween(key)
		if not propertyTweener:HasTweens() then
			to_remove[property] = true
		end
	end

	for property in pairs(to_remove) do
		self:_removePropertyTweener(property)
	end
end

function ObjectTweener:TweenProperty(priority, key, property, value)
	assert(priority)
	assert(key)
	assert(property)
	assert(value)

	local tweenerStack = self:_getPropertyTweener(property, value)
	tweenerStack:TweenProperty(priority, key, value)
end

function ObjectTweener:TweenProperties(priority, key, properties)
	assert(priority)
	assert(key)
	assert(properties)

	for property, value in pairs(properties) do
		self:TweenProperty(priority, key, property, value)
	end
end

function ObjectTweener:Update()
	local updating = false
	for _, tweener in pairs(self._propertyTweeners) do
		if tweener:Update() then
			updating = true
		end
	end
	return updating
end

function ObjectTweener:HasTweens()
	return next(self._propertyTweeners) ~= nil
end

function ObjectTweener:_removePropertyTweener(property)
	self._propertyTweeners[property] = nil
end

function ObjectTweener:_getPropertyTweener(property, value)
	if self._propertyTweeners[property] then
		return self._propertyTweeners[property]
	end

	local current_val = self._object[property]
	if typeof(current_val) ~= typeof(value) then
		error(("Bad type for property %q passed in, expected %q, got %q")
			:format(property, typeof(current_val), typeof(value)))
	end

	local base_tweener = nil
	if type(current_val) == "number" then
		base_tweener = NumberPropertyTweener.new(self._object, property)
	elseif typeof(current_val) == "Color3" then
		base_tweener = Color3PropertyTweener.new(self._object, property)
	else
		error(("Bad property type! %q"):format(type(value)))
	end

	if DEFAULT_SPEEDS[property] then
		base_tweener:SetSpeed(DEFAULT_SPEEDS[property])
	end

	local new_tweener = PropertyTweenerStack.new(base_tweener)
	self._propertyTweeners[property] = new_tweener
	return new_tweener
end

return ObjectTweener
