local D=script.Parent.Parent.Parent local E=require(D.Flipper)local function s(D)if typeof(D)=="\067\111\108\111\114\083\101\113\117\101\110\099\101"then local E={}for D,s in pairs(D.Keypoints)do local d=s.Value E[D]={T=s.Time,V={R=d.R,G=d.G,B=d.B}}end return E else local E={}for D,s in pairs(D.Keypoints)do E[D]={T=s.Time;V=s.Value}end return E end end local function d(D,s)local d={}for D,V in pairs(D)do d[D]={T=E.Spring.new(V.T,s)}if typeof(V.V)=="\116\097\098\108\101"then local B=V.V d[D].V={R=E.Spring.new(B.R,s),G=E.Spring.new(B.G,s);B=E.Spring.new(B.B,s)}else d[D].V=E.Spring.new(V.V,s)end end return d end return function(D,d,V,B,v)for w,I in pairs(D.StyleBindings)do local A=d[I]local R=V[A]local p=D[I]:getValue()if not(p and p.Color)then D["\083\101\116"..I](R)continue end local o=p.Color local q,e,S=o.R,o.G,o.B local k=D[I.."\077\111\116\111\114"]if k then pcall(k.destroy,k)end local K={R=q;G=e;B=S;T=p.Transparency}if p.ColorSequence then K.CS=s(p.ColorSequence)end if p.TransparencySequence then K.TS=s(p.TransparencySequence)end local N=E.GroupMotor.new(K)D[I.."\077\111\116\111\114"]=N N:onStep(function(E)local s,d=nil,nil if E.CS then local D={}for E,s in pairs(E.CS)do local d=s.V D[E]=ColorSequenceKeypoint.new(s.T,Color3.new(d.R,d.G,d.B))end s=ColorSequence.new(D)end if E.TS then local D={}for E,s in pairs(E.TS)do D[E]=NumberSequenceKeypoint.new(s.T,s.V)end d=NumberSequence.new(D)end D["\083\101\116"..I]({Color=Color3.new(E.R,E.G,E.B),Transparency=E.T,ColorSequence=R.ColorSequence,TransparencySequence=R.TransparencySequence})end)N:onComplete(function()N:destroy()D[I.."\077\111\116\111\114"]=nil end)local Q=R.Color local L,f,W=Q.R,Q.G,Q.B local H={R=E.Spring.new(L,B);G=E.Spring.new(f,B),B=E.Spring.new(W,B),T=E.Spring.new(R.Transparency,v)}if R.ColorSequence then end if R.TransparencySequence then end N:setGoal(H)end end
local Packages = script.Parent.Parent.Parent
local Flipper = require(Packages.Flipper)

local function CollectKeypoints(Sequence)

	if typeof(Sequence) == 'ColorSequence' then

		-- Extract each keypoint
		local Keypoints = {}

		for Index, Keypoint in pairs(Sequence.Keypoints) do
			local Color = Keypoint.Value
			Keypoints[Index] = {
				T = Keypoint.Time,
				V = {
					R = Color.R,
					G = Color.G,
					B = Color.B,
				}
			}
		end

		return Keypoints
	else

		-- Extract each keypoint
		local Keypoints = {}

		for Index, Keypoint in pairs(Sequence.Keypoints) do
			Keypoints[Index] = {
				T = Keypoint.Time,
				V = Keypoint.Value
			}
		end

		return Keypoints
	end
end

local function SpringKeypoints(Keypoints, SpringOptions)

	-- Get springed keypoints
	local SpringedKeypoints = {}

	for Index, Keypoint in pairs(Keypoints) do
		
		SpringedKeypoints[Index] = {
			T = Flipper.Spring.new(Keypoint.T, SpringOptions)
		}

		-- Color keypoints
		if typeof(Keypoint.V) == 'table' then
			local Color = Keypoint.V

			SpringedKeypoints[Index].V = {
				R = Flipper.Spring.new(Color.R, SpringOptions),
				G = Flipper.Spring.new(Color.G, SpringOptions),
				B = Flipper.Spring.new(Color.B, SpringOptions)
			}

		-- Number keypoints
		else
			SpringedKeypoints[Index].V = Flipper.Spring.new(Keypoint.V, SpringOptions)
		end
	end

	return SpringedKeypoints
end

return function (self, Description, Theme, ColorAnimationSettings, TransparencyAnimationSettings)

	--- todo: Add a way to determine if the theme wash changed
	-- -- Skip if our current description is the same
	-- if self.Description and (Description.Name == self.Description.Name) then
	-- 	return
	-- end

	-- -- Register
	-- self.Description = Description

	-- Update each style binding
	for _, StyleBinding in pairs(self.StyleBindings) do
		
		-- Get the style key
		local StyleKey = Description[StyleBinding]

		-- Get the style
		local Style = Theme[StyleKey]

		-- Extract initial style, for animation
		local InitialStyle = self[StyleBinding]:getValue()

		-- If no initial, animation isn't noticeable
		if not (InitialStyle and InitialStyle.Color) then
			self['Set' .. StyleBinding](Style)
			continue
		end

		local InitialColor = InitialStyle.Color
		local R, G, B = InitialColor.R, InitialColor.G, InitialColor.B

		-- Remove existing motor, if found
		local ExistingMotor = self[StyleBinding .. 'Motor']
		if ExistingMotor then
			pcall(ExistingMotor.destroy, ExistingMotor)
		end

		-- Extract initial values for motor
		local InitialValues = {
			R = R,
			G = G,
			B = B,
			T = InitialStyle.Transparency,
		}

		-- Color and Transparency sequences
		if InitialStyle.ColorSequence then
			InitialValues.CS = CollectKeypoints(InitialStyle.ColorSequence)
		end

		if InitialStyle.TransparencySequence then
			InitialValues.TS = CollectKeypoints(InitialStyle.TransparencySequence)
		end

		-- Create animation motor
		local Motor = Flipper.GroupMotor.new(InitialValues)

		self[StyleBinding .. 'Motor'] = Motor

		-- Bind motor
		Motor:onStep(function(Values)
			local CS, TS = nil, nil

			-- Build ColorSequence
			if Values.CS then

				-- Build keypoints
				local Keypoints = {}

				for Index, KeypointData in pairs(Values.CS) do
					local Color = KeypointData.V

					Keypoints[Index] = ColorSequenceKeypoint.new(KeypointData.T, Color3.new(Color.R, Color.G, Color.B))
				end

				-- Create sequence
				CS = ColorSequence.new(Keypoints)
			end

			-- Build TransparencySequence
			if Values.TS then
				
				-- Build keypoints
				local Keypoints = {}

				for Index, KeypointData in pairs(Values.TS) do
					Keypoints[Index] = NumberSequenceKeypoint.new(KeypointData.T, KeypointData.V)
				end

				-- Create sequence
				TS = NumberSequence.new(Keypoints)
			end

			-- Update style
			self['Set' .. StyleBinding]({
				Color = Color3.new(Values.R, Values.G, Values.B),
				Transparency = Values.T,
				ColorSequence = Style.ColorSequence, -- todo: fix CS
				TransparencySequence = Style.TransparencySequence, -- todo: fix TS
			})
		end)

		Motor:onComplete(function()
			Motor:destroy()
			self[StyleBinding .. 'Motor'] = nil
		end)

		-- Gather goals
		local Color = Style.Color
		local R, G, B = Color.R, Color.G, Color.B
		local Goals = {
			R = Flipper.Spring.new(R, ColorAnimationSettings),
			G = Flipper.Spring.new(G, ColorAnimationSettings),
			B = Flipper.Spring.new(B, ColorAnimationSettings),
			T = Flipper.Spring.new(Style.Transparency, TransparencyAnimationSettings),
		}

		-- Color and Transparency sequences
		if Style.ColorSequence then
			--Goals.CS = SpringKeypoints(CollectKeypoints(Style.ColorSequence), ColorAnimationSettings)
		end

		if Style.TransparencySequence then
			--Goals.TS = SpringKeypoints(CollectKeypoints(Style.TransparencySequence), TransparencyAnimationSettings)
		end

		-- Play animation
		Motor:setGoal(Goals)
	end
end
