local D=script.Parent local E=D.Parent local s=require(E.Roact)local d=require(E.Sift)local V=require(D.strict)local B={Provider=require(script.StyleProvider),Consumer=require(script.StyleConsumer),ApplyDescription=require(script.ApplyDescription),RegisterStateAction=require(script.RegisterStateAction)}B.ColorThemes={DarkTheme=require(script.Themes["\067\111\108\111\114\046\068\097\114\107\084\104\101\109\101"]),LightTheme=require(script.Themes["\067\111\108\111\114\046\076\105\103\104\116\084\104\101\109\101"])}B.FontThemes={SourceSans=require(script.Themes["\070\111\110\116\046\083\111\117\114\099\101\083\097\110\115\084\104\101\109\101"]),Gotham=require(script.Themes["\070\111\110\116\046\071\111\116\104\097\109\084\104\101\109\101"])}B.StyleThemes={Default=require(script.Themes["\083\116\121\108\101\046\068\101\102\097\117\108\116"])}B.ImageThemes={Default=require(script.Themes["\073\109\097\103\101\046\068\101\102\097\117\108\116"]);RobloxImages=require(script.Themes["\073\109\097\103\101\046\082\111\098\108\111\120\073\109\097\103\101\115\046\108\117\097"])}for D,E in pairs(script.Themes:GetChildren())do local s,d=unpack(E.Name:split("\046"))if not(s and d)or s~="\067\111\108\111\114"and(s~="\070\111\110\116"and s~="\083\116\121\108\101")then continue end xpcall(function()B[s.."\084\104\101\109\101\115"][d]=require(E)end,function(D)warn("\070\097\105\108\101\100 \116\111 \114\101\103\105\115\116\101\114 \116\104\101\109\101\046 \084\104\101\109\101\058",E,"\069\114\114\111\114\058",D)end)end local v={colors=function(D)if typeof(D)=="\067\111\108\111\114\051"then return{Color=D;Transparency=0}end warn("\065 \109\105\115\115\105\110\103 \099\111\108\111\114 \115\116\121\108\101 \119\097\115 \102\111\117\110\100 \102\111\114",D,"\105\110 \087\105\110\114\111 \116\104\101\109\101 \102\105\108\101\115")local E=nil local s=math.random(0,2)if s==0 then E=Color3.new(0,1,1)elseif s==1 then E=Color3.new(1,0,1)elseif s==2 then E=Color3.new(1,1,0)end return{Color=E,Transparency=.25}end,images=function(D)if(tostring(D)):find("\114\098\120\097\115\115\101\116\105\100\058\047\047")then return{Image=D,ImageRectOffset=Vector2.new(),ImageRectSize=Vector2.new()}end warn("\065 \109\105\115\115\105\110\103 \105\109\097\103\101 \115\116\121\108\101 \119\097\115 \102\111\117\110\100 \102\111\114",D,"\105\110 \087\105\110\114\111 \105\109\097\103\101 \102\105\108\101\115")return{Image="\114\098\120\097\115\115\101\116\105\100\058\047\047\057\050\053\056\049\048\053\050\054",ImageTransparency=.75,ImageRectOffset=Vector2.new(),ImageRectSize=Vector2.new(),ScaleType=Enum.ScaleType.Tile,ResampleMode=Enum.ResamplerMode.Pixelated;TileSize=UDim2.fromOffset(25,25)}end;styles=function(D)error(("\099\111\117\108\100 \110\111\116 \102\105\110\100 \097 \115\116\121\108\101 \119\105\116\104 \116\104\101 \112\097\116\104 \111\102 \096\037\115\096"):format(D))end;fonts=function(D)if typeof(D)=="\069\110\117\109\073\116\101\109"then return{Font=Font.fromEnum(D);Size=20;LineHeight=20,ParagraphSpacing=.0}end warn("\065 \109\105\115\115\105\110\103 \102\111\110\116 \115\116\121\108\101 \119\097\115 \102\111\117\110\100 \102\111\114",D,"\105\110 \087\105\110\114\111 \116\104\101\109\101 \102\105\108\101\115")return{Font=Font.fromEnum(Enum.Font.RobotoMono);Size=14,LineHeight=.74,ParagraphSpacing=.0}end}function B.new(D)local E=d.Dictionary.join({},unpack(D))return setmetatable({},{__newindex=function()error("\084\104\101\109\101 \105\115 \114\101\097\100 \111\110\108\121\046")end;__index=function(D,s)local d=rawget(E,s)if d~=nil then return d end local V=((tostring(s)):split("\047"))[1]local B=v[V]if B then return B(s)elseif s~=nil then return s else warn(("\096\037\115\096 \105\115 \110\111\116 \097 \118\097\108\105\100 \109\101\109\098\101\114 \111\102 \084\104\101\109\101\046"):format(tostring(s)))return function()error(("\096\037\115\096 \105\115 \110\111\116 \097 \118\097\108\105\100 \109\101\109\098\101\114 \111\102 \084\104\101\109\101\046"):format(tostring(s)))end end end})end B.Themes={DarkTheme=B.new({B.ImageThemes.Default,B.ImageThemes.RobloxImages,B.StyleThemes.Default,B.FontThemes.SourceSans;B.ColorThemes.DarkTheme}),LightTheme=B.new({B.ImageThemes.Default,B.ImageThemes.RobloxImages,B.StyleThemes.Default;B.FontThemes.SourceSans;B.ColorThemes.LightTheme})}function B.WithTheme(D)return s.createElement(B.Consumer,{render=function(E)if not E then return D(B.Themes.LightTheme)end return D(E.Theme)end})end return V(B,"\087\105\110\114\111\046\084\104\101\109\101")
-- Theme: The theming utility used all throught Winro

local Winro = script.Parent
local Packages = Winro.Parent

local Roact = require(Packages.Roact)
local Sift = require(Packages.Sift)
local strict = require(Winro.strict)

-- Theme
local Theme = {
	Provider = require(script.StyleProvider),
	Consumer = require(script.StyleConsumer),
	ApplyDescription = require(script.ApplyDescription),
	RegisterStateAction = require(script.RegisterStateAction),
}

-- Theme Containers
Theme.ColorThemes = {
	DarkTheme = require(script.Themes["Color.DarkTheme"]),
	LightTheme = require(script.Themes["Color.LightTheme"]),
}
Theme.FontThemes = {
	SourceSans = require(script.Themes["Font.SourceSansTheme"]),
	Gotham = require(script.Themes["Font.GothamTheme"]),
}
Theme.StyleThemes = {
	Default = require(script.Themes["Style.Default"]),
}
Theme.ImageThemes = {
	Default = require(script.Themes["Image.Default"]),
	RobloxImages = require(script.Themes["Image.RobloxImages.lua"])
}

-- Register Themes
for _, CustomTheme in pairs(script.Themes:GetChildren()) do

	-- Extract Theme info
	local Type, Name = unpack(CustomTheme.Name:split('.'))

	-- Validate
	if (not (Type and Name)) or (Type ~= 'Color' and Type ~= 'Font' and Type ~= 'Style') then
		continue
	end

	-- Register
	xpcall(function()
		Theme[Type .. 'Themes'][Name] = require(CustomTheme)
	end, function(Error)
		warn('Failed to register theme. Theme:', CustomTheme, 'Error:', Error)
	end)
end

-- Custom fallback handlers
local Fallbacks = {
	colors = function(index)

		-- If the index is a color, use it
		if typeof(index) == 'Color3' then
			return {
				Color = index,
				Transparency = 0
			}
		end

		-- Warn of missing color style
		warn('A missing color style was found for', index, 'in Winro theme files')

		local Color = nil
		local RandomNumber = math.random(0, 2)

		if RandomNumber == 0 then
			Color = Color3.new(0, 1, 1)
		elseif RandomNumber == 1 then
			Color = Color3.new(1, 0, 1)
		elseif RandomNumber == 2 then
			Color = Color3.new(1, 1, 0)
		end

		return {
			Color = Color,
			Transparency = 0.25,
		}
	end,
	images = function(index)
		
		-- If the index is an image, use it
		if tostring(index):find('rbxassetid://') then
			return {
				Image = index,
				ImageRectOffset = Vector2.new(),
				ImageRectSize = Vector2.new()
			}
		end

		-- Warn of missing image
		warn('A missing image style was found for', index, 'in Winro image files')

		return {
			Image = 'rbxassetid://925810526',--'rbxasset://textures/ui/GuiImagePlaceholder.png',
			ImageTransparency = 0.75,
			ImageRectOffset = Vector2.new(),
			ImageRectSize = Vector2.new(),
			ScaleType = Enum.ScaleType.Tile,
			ResampleMode = Enum.ResamplerMode.Pixelated,
			TileSize = UDim2.fromOffset(25, 25)
		}
	end,
	styles = function(index)
		error(('could not find a style with the path of `%s`'):format(index))
	end,
	fonts = function(index)
		-- If the index is a FontEnum, use it
		if typeof(index) == 'EnumItem' then
			return {
				Font = Font.fromEnum(index),
				Size = 20,
				LineHeight = 20,
				ParagraphSpacing = 0.0,
			}
		end

		-- Warn of missing font style
		warn('A missing font style was found for', index, 'in Winro theme files')

		return {
			Font = Font.fromEnum(Enum.Font.RobotoMono),
			Size = 14,
			LineHeight = 0.74,
			ParagraphSpacing = 0.0,
		}
	end
}

-- Creates a new theme by combining all the provided theme components
function Theme.new(Themes)

	-- Merge the themes
	local Theme = Sift.Dictionary.join({}, unpack(Themes))

	-- Attach metatable
	return setmetatable({}, {
		__newindex = function()
			error('Theme is read only.')
		end,
		__index = function(_, index)

			-- Fetch an existing value
			local Existing = rawget(Theme, index)
			if Existing ~= nil then--and (typeof(Existing) ~= 'table' or math.random(0, 6) ~= 0) then
				return Existing
			end

			-- Extract the path's root
			local PathRoot = tostring(index):split('/')[1]

			-- Get the last-resort fallback
			local Fallback = Fallbacks[PathRoot]
			if Fallback then
				return Fallback(index)
			elseif index ~= nil then
				return index
			else
				warn(('`%s` is not a valid member of Theme.'):format(tostring(index)))

				-- Return something that should throw an error at the source of the index as it cannot be used as a theme
				return function ()
					error(('`%s` is not a valid member of Theme.'):format(tostring(index)))
				end
			end
		end
	})
end

-- Prebuilt themes
Theme.Themes = {
	DarkTheme = Theme.new({
		Theme.ImageThemes.Default,
		Theme.ImageThemes.RobloxImages,
		Theme.StyleThemes.Default,
		Theme.FontThemes.SourceSans,
		Theme.ColorThemes.DarkTheme,
	}),
	LightTheme = Theme.new({
		Theme.ImageThemes.Default,
		Theme.ImageThemes.RobloxImages,
		Theme.StyleThemes.Default,
		Theme.FontThemes.SourceSans,
		Theme.ColorThemes.LightTheme,
	}),
}

-- Theme Provider
function Theme.WithTheme(RenderFunction)

	return Roact.createElement(Theme.Consumer, {
		render = function(ThemeContainer)
			
			-- Fallback
			if not ThemeContainer then
				return RenderFunction(Theme.Themes.LightTheme)
			end

			return RenderFunction(ThemeContainer.Theme)
		end
	})
end

return strict(Theme, 'Winro.Theme')
