local p=require(script.Parent.Parent.Configuration)local m=p.Roact local O=p.RoactAnimate local j="\114\098\120\097\115\115\101\116\105\100\058\047\047\049\051\049\054\048\052\053\050\049\055"local q=UDim2.fromScale(.5,.5)local f=UDim2.new()local Y={[0]={Umbra={Transparency=1,Blur=0},Penumbra={Transparency=1;Blur=0},Ambient={Transparency=1;Blur=0}},[1]={Umbra={Transparency=.86,Blur=2};Penumbra={Transparency=.88;Blur=2,Offset=UDim2.fromOffset(0,2)};Ambient={Transparency=.8,Blur=3,Offset=UDim2.fromOffset(0,1)}},[2]={Umbra={Transparency=.86,Blur=4},Penumbra={Transparency=.88;Blur=4,Offset=UDim2.fromOffset(0,3)},Ambient={Transparency=.8,Blur=5,Offset=UDim2.fromOffset(0,1)}},[3]={Umbra={Transparency=.86;Blur=3,Offset=UDim2.fromOffset(0,3)},Penumbra={Transparency=.88,Blur=4,Offset=UDim2.fromOffset(0,3)};Ambient={Transparency=.8,Blur=8,Offset=UDim2.fromOffset(0,1)}};[4]={Umbra={Transparency=.86;Blur=4;Offset=UDim2.fromOffset(0,2)},Penumbra={Transparency=.88;Blur=5;Offset=UDim2.fromOffset(0,4)};Ambient={Transparency=.8;Blur=10,Offset=UDim2.fromOffset(0,1)}};[6]={Umbra={Transparency=.86;Blur=10,Offset=UDim2.fromOffset(0,6)},Penumbra={Transparency=.88;Blur=18,Offset=UDim2.fromOffset(0,1)},Ambient={Transparency=.8,Blur=5;Offset=UDim2.fromOffset(0,3)}},[8]={Umbra={Transparency=.86,Blur=10,Offset=UDim2.fromOffset(0,8)},Penumbra={Transparency=.88,Blur=14;Offset=UDim2.fromOffset(0,3)},Ambient={Transparency=.8;Blur=15,Offset=UDim2.fromOffset(0,4)}};[9]={Umbra={Transparency=.86;Blur=12;Offset=UDim2.fromOffset(0,9)},Penumbra={Transparency=.88,Blur=16;Offset=UDim2.fromOffset(0,3)},Ambient={Transparency=.8;Blur=6;Offset=UDim2.fromOffset(0,5)}},[12]={Umbra={Transparency=.86,Blur=17,Offset=UDim2.fromOffset(0,12)};Penumbra={Transparency=.88;Blur=22,Offset=UDim2.fromOffset(0,5)},Ambient={Transparency=.8;Blur=8,Offset=UDim2.fromOffset(0,7)}};[16]={Umbra={Transparency=.86;Blur=24,Offset=UDim2.fromOffset(0,16)};Penumbra={Transparency=.88,Blur=30,Offset=UDim2.fromOffset(0,6)};Ambient={Transparency=.8,Blur=10,Offset=UDim2.fromOffset(0,8)}}}local S=TweenInfo.new(.1,Enum.EasingStyle.Linear)local X=m.PureComponent:extend("\077\097\116\101\114\105\097\108\083\104\097\100\111\119")X.defaultProps={ZIndex=1}function X.init(m,p)assert(p.Elevation and Y[p.Elevation],"\112\114\111\112\115\046\069\108\101\118\097\116\105\111\110 \105\115 \105\110\118\097\108\105\100")local j=Y[p.Elevation]m:setState({_umbraTransparency=O.Value.new(j.Umbra.Transparency);_umbraSize=O.Value.new(UDim2.new(1,j.Umbra.Blur,1,j.Umbra.Blur)),_umbraPosition=O.Value.new(q+(j.Umbra.Offset or f));_penumbraTransparency=O.Value.new(j.Penumbra.Transparency);_penumbraSize=O.Value.new(UDim2.new(1,j.Penumbra.Blur,1,j.Penumbra.Blur)),_penumbraPosition=O.Value.new(q+(j.Penumbra.Offset or f));_ambientTransparency=O.Value.new(j.Ambient.Transparency),_ambientSize=O.Value.new(UDim2.new(1,j.Ambient.Blur,1,j.Ambient.Blur));_ambientPosition=O.Value.new(q+(j.Ambient.Offset or f))})end function X.willUpdate(m,p)local j=Y[p.Elevation]local X=table.create(9)X[1]=O(m.state._umbraTransparency,S,j.Umbra.Transparency)X[2]=O(m.state._umbraSize,S,UDim2.new(1,j.Umbra.Blur,1,j.Umbra.Blur))X[3]=O(m.state._umbraPosition,S,q+(j.Umbra.Offset or f))X[4]=O(m.state._penumbraTransparency,S,j.Penumbra.Transparency)X[5]=O(m.state._penumbraSize,S,UDim2.new(1,j.Penumbra.Blur,1,j.Penumbra.Blur))X[6]=O(m.state._penumbraPosition,S,q+(j.Penumbra.Offset or f))X[7]=O(m.state._ambientTransparency,S,j.Ambient.Transparency)X[8]=O(m.state._ambientSize,S,UDim2.new(1,j.Ambient.Blur,1,j.Ambient.Blur))X[9]=O(m.state._ambientPosition,S,q+(j.Ambient.Offset or f));(O.Parallel(X)):Start()end function X.render(p)return m.createElement("\070\114\097\109\101",{Name="\083\104\097\100\111\119\082\111\111\116",ZIndex=p.props.ZIndex,BackgroundTransparency=1;Size=UDim2.fromScale(1,1);[m.Ref]=function(m)p._rbx=m end},{Umbra=m.createElement(O.ImageLabel,{BackgroundTransparency=1,Image=j;ImageColor3=Color3.new();ImageTransparency=p.state._umbraTransparency;Size=p.state._umbraSize,AnchorPoint=Vector2.new(.5,.5),Position=p.state._umbraPosition,ScaleType=Enum.ScaleType.Slice,SliceCenter=Rect.new(10,10,118,118)});Penumbra=m.createElement(O.ImageLabel,{BackgroundTransparency=1,Image=j;ImageColor3=Color3.new();ImageTransparency=p.state._penumbraTransparency,Size=p.state._penumbraSize;AnchorPoint=Vector2.new(.5,.5);Position=p.state._penumbraPosition,ScaleType=Enum.ScaleType.Slice;SliceCenter=Rect.new(10,10,118,118)});Ambient=m.createElement(O.ImageLabel,{BackgroundTransparency=1,Image=j,ImageColor3=Color3.new(),ImageTransparency=p.state._ambientTransparency;Size=p.state._ambientSize;AnchorPoint=Vector2.new(.5,.5);Position=p.state._ambientPosition;ScaleType=Enum.ScaleType.Slice,SliceCenter=Rect.new(10,10,118,118)})})end return X
local Configuration = require(script.Parent.Parent.Configuration)
local Roact = Configuration.Roact
local RoactAnimate = Configuration.RoactAnimate

local SHADOW_IMAGE = "rbxassetid://1316045217"
local CENTER_UDIM2 = UDim2.fromScale(0.5, 0.5)
local EMPTY_UDIM2 = UDim2.new()

local SHADOW_SETTINGS = {
	[0] = {
		Umbra = {
			Transparency = 1,
			Blur = 0,
		},
		Penumbra = {
			Transparency = 1,
			Blur = 0,
		},
		Ambient = {
			Transparency = 1,
			Blur = 0,
		},
	},
	[1] = {
		Umbra = {
			Transparency = 1 - 0.14,
			Blur = 2,
		},
		Penumbra = {
			Transparency = 1 - 0.12,
			Blur = 2,
			Offset = UDim2.fromOffset(0, 2),
		},
		Ambient = {
			Transparency = 0.8,
			Blur = 3,
			Offset = UDim2.fromOffset(0, 1),
		},
	},
	[2] = {
		Umbra = {
			Transparency = 1 - 0.14,
			Blur = 4,
		},
		Penumbra = {
			Transparency = 1 - 0.12,
			Blur = 4,
			Offset = UDim2.fromOffset(0, 3),
		},
		Ambient = {
			Transparency = 0.8,
			Blur = 5,
			Offset = UDim2.fromOffset(0, 1),
		},
	},
	[3] = {
		Umbra = {
			Transparency = 1 - 0.14,
			Blur = 3,
			Offset = UDim2.fromOffset(0, 3),
		},
		Penumbra = {
			Transparency = 1 - 0.12,
			Blur = 4,
			Offset = UDim2.fromOffset(0, 3),
		},
		Ambient = {
			Transparency = 0.8,
			Blur = 8,
			Offset = UDim2.fromOffset(0, 1),
		},
	},
	[4] = {
		Umbra = {
			Transparency = 1 - 0.14,
			Blur = 4,
			Offset = UDim2.fromOffset(0, 2),
		},
		Penumbra = {
			Transparency = 1 - 0.12,
			Blur = 5,
			Offset = UDim2.fromOffset(0, 4),
		},
		Ambient = {
			Transparency = 0.8,
			Blur = 10,
			Offset = UDim2.fromOffset(0, 1),
		},
	},
	[6] = {
		Umbra = {
			Transparency = 1 - 0.14,
			Blur = 10,
			Offset = UDim2.fromOffset(0, 6),
		},
		Penumbra = {
			Transparency = 1 - 0.12,
			Blur = 18,
			Offset = UDim2.fromOffset(0, 1),
		},
		Ambient = {
			Transparency = 0.8,
			Blur = 5,
			Offset = UDim2.fromOffset(0, 3),
		},
	},
	[8] = {
		Umbra = {
			Transparency = 1 - 0.14,
			Blur = 10,
			Offset = UDim2.fromOffset(0, 8),
		},
		Penumbra = {
			Transparency = 1 - 0.12,
			Blur = 14,
			Offset = UDim2.fromOffset(0, 3),
		},
		Ambient = {
			Transparency = 0.8,
			Blur = 15,
			Offset = UDim2.fromOffset(0, 4),
		},
	},
	[9] = {
		Umbra = {
			Transparency = 1 - 0.14,
			Blur = 12,
			Offset = UDim2.fromOffset(0, 9),
		},
		Penumbra = {
			Transparency = 1 - 0.12,
			Blur = 16,
			Offset = UDim2.fromOffset(0, 3),
		},
		Ambient = {
			Transparency = 0.8,
			Blur = 6,
			Offset = UDim2.fromOffset(0, 5),
		},
	},
	[12] = {
		Umbra = {
			Transparency = 1 - 0.14,
			Blur = 17,
			Offset = UDim2.fromOffset(0, 12),
		},
		Penumbra = {
			Transparency = 1 - 0.12,
			Blur = 22,
			Offset = UDim2.fromOffset(0, 5),
		},
		Ambient = {
			Transparency = 0.8,
			Blur = 8,
			Offset = UDim2.fromOffset(0, 7),
		},
	},
	[16] = {
		Umbra = {
			Transparency = 1 - 0.14,
			Blur = 24,
			Offset = UDim2.fromOffset(0, 16),
		},
		Penumbra = {
			Transparency = 1 - 0.12,
			Blur = 30,
			Offset = UDim2.fromOffset(0, 6),
		},
		Ambient = {
			Transparency = 0.8,
			Blur = 10,
			Offset = UDim2.fromOffset(0, 8),
		},
	},
}

local SHADOW_TWEEN_INFO = TweenInfo.new(
	0.1,
	Enum.EasingStyle.Linear
)

local Shadow = Roact.PureComponent:extend("MaterialShadow")
Shadow.defaultProps = {
	ZIndex = 1,
}

function Shadow:init(props)
	assert(props.Elevation and SHADOW_SETTINGS[props.Elevation], "props.Elevation is invalid")
	local shadowProps = SHADOW_SETTINGS[props.Elevation]

	self:setState({
		_umbraTransparency = RoactAnimate.Value.new(shadowProps.Umbra.Transparency),
		_umbraSize = RoactAnimate.Value.new(UDim2.new(1, shadowProps.Umbra.Blur, 1, shadowProps.Umbra.Blur)),
		_umbraPosition = RoactAnimate.Value.new(CENTER_UDIM2 + (shadowProps.Umbra.Offset or EMPTY_UDIM2)),
		_penumbraTransparency = RoactAnimate.Value.new(shadowProps.Penumbra.Transparency),
		_penumbraSize = RoactAnimate.Value.new(UDim2.new(1, shadowProps.Penumbra.Blur, 1, shadowProps.Penumbra.Blur)),
		_penumbraPosition = RoactAnimate.Value.new(CENTER_UDIM2 + (shadowProps.Penumbra.Offset or EMPTY_UDIM2)),
		_ambientTransparency = RoactAnimate.Value.new(shadowProps.Ambient.Transparency),
		_ambientSize = RoactAnimate.Value.new(UDim2.new(1, shadowProps.Ambient.Blur, 1, shadowProps.Ambient.Blur)),
		_ambientPosition = RoactAnimate.Value.new(CENTER_UDIM2 + (shadowProps.Ambient.Offset or EMPTY_UDIM2)),
	})
end

function Shadow:willUpdate(nextProps)
	local shadowProps = SHADOW_SETTINGS[nextProps.Elevation]
	local animation = table.create(9)
	animation[1] = RoactAnimate(self.state._umbraTransparency, SHADOW_TWEEN_INFO, shadowProps.Umbra.Transparency)
	animation[2] = RoactAnimate(self.state._umbraSize, SHADOW_TWEEN_INFO, UDim2.new(1, shadowProps.Umbra.Blur, 1, shadowProps.Umbra.Blur))
	animation[3] = RoactAnimate(self.state._umbraPosition, SHADOW_TWEEN_INFO, CENTER_UDIM2 + (shadowProps.Umbra.Offset or EMPTY_UDIM2))
	animation[4] = RoactAnimate(self.state._penumbraTransparency, SHADOW_TWEEN_INFO, shadowProps.Penumbra.Transparency)
	animation[5] = RoactAnimate(self.state._penumbraSize, SHADOW_TWEEN_INFO, UDim2.new(1, shadowProps.Penumbra.Blur, 1, shadowProps.Penumbra.Blur))
	animation[6] = RoactAnimate(self.state._penumbraPosition, SHADOW_TWEEN_INFO, CENTER_UDIM2 + (shadowProps.Penumbra.Offset or EMPTY_UDIM2))
	animation[7] = RoactAnimate(self.state._ambientTransparency, SHADOW_TWEEN_INFO, shadowProps.Ambient.Transparency)
	animation[8] = RoactAnimate(self.state._ambientSize, SHADOW_TWEEN_INFO, UDim2.new(1, shadowProps.Ambient.Blur, 1, shadowProps.Ambient.Blur))
	animation[9] = RoactAnimate(self.state._ambientPosition, SHADOW_TWEEN_INFO, CENTER_UDIM2 + (shadowProps.Ambient.Offset or EMPTY_UDIM2))

	RoactAnimate.Parallel(animation):Start()
end

function Shadow:render()
	return Roact.createElement("Frame", {
		Name = "ShadowRoot",
		ZIndex = self.props.ZIndex,
		BackgroundTransparency = 1,
		Size = UDim2.fromScale(1, 1),
		[Roact.Ref] = function(rbx)
			self._rbx = rbx
		end,
	}, {
		Umbra = Roact.createElement(RoactAnimate.ImageLabel, {
			BackgroundTransparency = 1,
			Image = SHADOW_IMAGE,
			ImageColor3 = Color3.new(),
			ImageTransparency = self.state._umbraTransparency,
			Size = self.state._umbraSize,
			AnchorPoint = Vector2.new(0.5, 0.5),
			Position = self.state._umbraPosition,
			ScaleType = Enum.ScaleType.Slice,
			SliceCenter = Rect.new(10, 10, 118, 118),
		}),

		Penumbra = Roact.createElement(RoactAnimate.ImageLabel, {
			BackgroundTransparency = 1,
			Image = SHADOW_IMAGE,
			ImageColor3 = Color3.new(),
			ImageTransparency = self.state._penumbraTransparency,
			Size = self.state._penumbraSize,
			AnchorPoint = Vector2.new(0.5, 0.5),
			Position = self.state._penumbraPosition,
			ScaleType = Enum.ScaleType.Slice,
			SliceCenter = Rect.new(10, 10, 118, 118),
		}),

		Ambient = Roact.createElement(RoactAnimate.ImageLabel, {
			BackgroundTransparency = 1,
			Image = SHADOW_IMAGE,
			ImageColor3 = Color3.new(),
			ImageTransparency = self.state._ambientTransparency,
			Size = self.state._ambientSize,
			AnchorPoint = Vector2.new(0.5, 0.5),
			Position = self.state._ambientPosition,
			ScaleType = Enum.ScaleType.Slice,
			SliceCenter = Rect.new(10, 10, 118, 118),
		}),
	})
end

return Shadow
