local j=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local f=game:GetService("\080\108\097\121\101\114\115")local a=j.AvatarEditor local m=require(a.Client.GuiLib.LazyLoader)local X=require(a.Shared.Util.Maid)local x=require(a.Shared.Util.Signal)local U=require(a.Shared.Util.Promise)local g=require(a.Client.Theme)local J=f.LocalPlayer local l={}l.__index=l local I={}I.__index=I local function G(j,f,a,m,X)return m+(X-m)*((j-f)/(a-f))end local function W(j,f)local a=J.Character local m=a and a:FindFirstChildWhichIsA("\072\117\109\097\110\111\105\100")local X=(m and m.Health>0)and m:FindFirstChild(j)if X then X.Value=f else warn(j,"\110\111\116 \102\111\117\110\100 \111\114 \100\101\097\100")end end function I.new(j,f,a,U,g)local J=setmetatable({},I)J.Maid=X.new()J.Changed=x.new()J.Min=a J.Max=U J.Frame=j J.Callback=g J.Slider=m.Classes.Slider.new(j.SliderFrame)J.Slider.Interval=.01 J.Slider.TweenClick=false J.Slider:Set(G(f,a,U,0,1))J:Update(G(f,a,U,0,1))J.Maid:GiveTask(J.Slider.Changed:Connect(function(j)j=G(j,0,1,a,U)J:Update(j)end))J.Maid:GiveTask(J.Slider.DragStop:Connect(function()local j=G(J.Slider:Get(),0,1,a,U)J.Changed:Fire(j)end))J.Mask=m.Classes.TextMask.new(j.TextFrame.TextBox)J.Mask:SetMaskType("\073\110\116\101\103\101\114")J.Mask:SetMaxLength(3)J.Maid:GiveTask(J.Mask.Frame.FocusLost:Connect(function()local j=math.clamp(J.Mask:GetValue()/100,a,U)J.Slider:Set(G(j,a,U,0,1))J:Update(j)J.Changed:Fire(j)end))return J end function I.Set(f,j)f.Slider:Set(G(j,f.Min,f.Max,0,1))f.Mask.Frame.Text=string.format("\037\100",G(j,0,1,0,100))end function I.Update(f,j)local a=f.Frame local m=f.Callback a.TextFrame.TextBox.Text=string.format("\037\100",G(j,0,1,0,100))m(j)end function I.Destroy(j)j.Maid:DoCleaning()j.Maid=nil j.Changed:Destroy()j.Changed=nil j.Min=nil j.Max=nil j.Frame=nil j.Callback=nil j.Slider:Destroy()j.Slider=nil j.Mask:Destroy()j.Mask=nil setmetatable(j,nil)end function l.new(j,f)local a=setmetatable({},l)a.Maid=X.new()a.ScaleUpdated=x.new()a.Maid:GiveTask(g:Bind(j,"\083\099\114\111\108\108\066\097\114\073\109\097\103\101\067\111\108\111\114\051","\083\099\114\111\108\108\098\097\114"))for j,f in ipairs(j:GetChildren())do if not f:IsA("\070\114\097\109\101")then continue end a.Maid:GiveTask(g:Bind(f.SliderFrame.Background.Bar,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\068\114\097\103\103\101\114\066\097\114"))a.Maid:GiveTask(g:Bind(f.SliderFrame.Dragger,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\068\114\097\103\103\101\114"))a.Maid:GiveTask(g:Bind(f.TextFrame,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\084\101\114\116\105\097\114\121"))a.Maid:GiveTask(g:Bind(f.TextFrame.TextBox,"\080\108\097\099\101\104\111\108\100\101\114\067\111\108\111\114\051","\080\108\097\099\101\104\111\108\100\101\114\084\101\120\116"))a.Maid:GiveTask(g:Bind(f.TextFrame.TextBox,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"))a.Maid:GiveTask(g:Bind(f.TextLabel,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"))end local m=I.new(j.BodyType,f.BodyTypeScale,0,1,function(j)W("\066\111\100\121\084\121\112\101\083\099\097\108\101",j)end)a.Maid.BodyTypeScale=m a.Maid:GiveTask(m.Changed:Connect(function(j)a.ScaleUpdated:Fire("\066\111\100\121\084\121\112\101\083\099\097\108\101",j)end))local U=I.new(j.Height,f.HeightScale,.9,1.05,function(j)W("\066\111\100\121\072\101\105\103\104\116\083\099\097\108\101",j)end)a.Maid.HeightScale=U a.Maid:GiveTask(U.Changed:Connect(function(j)a.ScaleUpdated:Fire("\072\101\105\103\104\116\083\099\097\108\101",j)end))local J=I.new(j.Width,f.WidthScale,.7,1,function(j)W("\066\111\100\121\087\105\100\116\104\083\099\097\108\101",j)end)a.Maid.WidthScale=J a.Maid:GiveTask(J.Changed:Connect(function(j)a.ScaleUpdated:Fire("\087\105\100\116\104\083\099\097\108\101",j)end))local G=I.new(j.Head,f.HeadScale,.95,1,function(j)W("\072\101\097\100\083\099\097\108\101",j)end)a.Maid.HeadScale=G a.Maid:GiveTask(G.Changed:Connect(function(j)a.ScaleUpdated:Fire("\072\101\097\100\083\099\097\108\101",j)end))local F=I.new(j.Proportion,f.ProportionScale,0,1,function(j)W("\066\111\100\121\080\114\111\112\111\114\116\105\111\110\083\099\097\108\101",j)end)a.Maid.ProportionScale=F a.Maid:GiveTask(F.Changed:Connect(function(j)a.ScaleUpdated:Fire("\080\114\111\112\111\114\116\105\111\110\083\099\097\108\101",j)end))return a end function l.UpdateWearing(a,j,f)local m=a.Maid[j]m:Set(f)end function l.Destroy(j)j.Maid:DoCleaning()j.Maid=nil j.ScaleUpdated:Destroy()j.ScaleUpdated=nil setmetatable(j,nil)end return l
--[[



]]

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local AvatarEditor = ReplicatedStorage.AvatarEditor
local GuiLib = require(AvatarEditor.Client.GuiLib.LazyLoader)
local Maid = require(AvatarEditor.Shared.Util.Maid)
local Signal = require(AvatarEditor.Shared.Util.Signal)
local Promise = require(AvatarEditor.Shared.Util.Promise)
local Theme = require(AvatarEditor.Client.Theme)

local player = Players.LocalPlayer

local Class = {}
Class.__index = Class

local Slider = {}
Slider.__index = Slider

local function map(n, inMin, inMax, outMin, outMax)
	return (outMin + ((outMax - outMin) * ((n - inMin) / (inMax - inMin))))
end

local function setScale(scale, value) -- TODO disable for R6?
	local character = player.Character
	local humanoid = character and character:FindFirstChildWhichIsA("Humanoid")
	local bodyScale = (humanoid and humanoid.Health > 0) and humanoid:FindFirstChild(scale)
	if bodyScale then
		bodyScale.Value = value
	else
		warn(scale, "not found or dead")
	end
end

function Slider.new(frame, x, min, max, callback)
	local self = setmetatable({}, Slider)

	self.Maid = Maid.new()
	self.Changed = Signal.new()
	self.Min = min
	self.Max = max
	self.Frame = frame
	self.Callback = callback

	self.Slider = GuiLib.Classes.Slider.new(frame.SliderFrame)

	self.Slider.Interval = 0.01
	self.Slider.TweenClick = false
	self.Slider:Set(map(x, min, max, 0, 1))

	self:Update(map(x, min, max, 0, 1))

	self.Maid:GiveTask(self.Slider.Changed:Connect(function(value)
		value = map(value, 0, 1, min, max)
		self:Update(value)
	end))

	self.Maid:GiveTask(self.Slider.DragStop:Connect(function()
		local value = map(self.Slider:Get(), 0, 1, min, max)
		self.Changed:Fire(value)
	end))

	self.Mask = GuiLib.Classes.TextMask.new(frame.TextFrame.TextBox)

	self.Mask:SetMaskType("Integer")
	self.Mask:SetMaxLength(3)

	self.Maid:GiveTask(self.Mask.Frame.FocusLost:Connect(function()
		local value = math.clamp(self.Mask:GetValue() / 100, min, max)
		self.Slider:Set(map(value, min, max, 0, 1))
		self:Update(value)
		self.Changed:Fire(value)
	end))

	return self
end

function Slider:Set(value)
	self.Slider:Set(map(value, self.Min, self.Max, 0, 1))
	self.Mask.Frame.Text = string.format("%d", map(value, 0, 1, 0, 100))
end

function Slider:Update(value)
	local frame = self.Frame
	local callback = self.Callback

	frame.TextFrame.TextBox.Text = string.format("%d", map(value, 0, 1, 0, 100))
	callback(value)
end

function Slider:Destroy()
	self.Maid:DoCleaning()
	self.Maid = nil
	self.Changed:Destroy()
	self.Changed = nil
	self.Min = nil
	self.Max = nil
	self.Frame = nil
	self.Callback = nil
	self.Slider:Destroy()
	self.Slider = nil
	self.Mask:Destroy()
	self.Mask = nil
	setmetatable(self, nil)
end

function Class.new(frame, wearingScales)
	local self = setmetatable({}, Class)

	self.Maid = Maid.new()
	self.ScaleUpdated = Signal.new()

	self.Maid:GiveTask(Theme:Bind(frame, "ScrollBarImageColor3", "Scrollbar"))
	for i, v in ipairs(frame:GetChildren()) do
		if not v:IsA("Frame") then
			continue
		end

		self.Maid:GiveTask(Theme:Bind(v.SliderFrame.Background.Bar, "BackgroundColor3", "DraggerBar"))
		self.Maid:GiveTask(Theme:Bind(v.SliderFrame.Dragger, "BackgroundColor3", "Dragger"))
		self.Maid:GiveTask(Theme:Bind(v.TextFrame, "BackgroundColor3", "Tertiary"))
		self.Maid:GiveTask(Theme:Bind(v.TextFrame.TextBox, "PlaceholderColor3", "PlaceholderText"))
		self.Maid:GiveTask(Theme:Bind(v.TextFrame.TextBox, "TextColor3", "Text"))
		self.Maid:GiveTask(Theme:Bind(v.TextLabel, "TextColor3", "Text"))
	end

	local bodyTypeScale = Slider.new(frame.BodyType, wearingScales.BodyTypeScale, 0, 1, function(value)
		setScale("BodyTypeScale", value)
	end)
	self.Maid.BodyTypeScale = bodyTypeScale
	self.Maid:GiveTask(bodyTypeScale.Changed:Connect(function(value)
		self.ScaleUpdated:Fire("BodyTypeScale", value)
	end))

	local heightScale = Slider.new(frame.Height, wearingScales.HeightScale, 0.9, 1.05, function(value)
		setScale("BodyHeightScale", value)
	end)
	self.Maid.HeightScale = heightScale
	self.Maid:GiveTask(heightScale.Changed:Connect(function(value)
		self.ScaleUpdated:Fire("HeightScale", value)
	end))

	local widthScale = Slider.new(frame.Width, wearingScales.WidthScale, 0.7, 1, function(value)
		setScale("BodyWidthScale", value)
	end)
	self.Maid.WidthScale = widthScale
	self.Maid:GiveTask(widthScale.Changed:Connect(function(value)
		self.ScaleUpdated:Fire("WidthScale", value)
	end))

	local headScale = Slider.new(frame.Head, wearingScales.HeadScale, 0.95, 1, function(value)
		setScale("HeadScale", value)
	end)
	self.Maid.HeadScale = headScale
	self.Maid:GiveTask(headScale.Changed:Connect(function(value)
		self.ScaleUpdated:Fire("HeadScale", value)
	end))

	local proportionScale = Slider.new(frame.Proportion, wearingScales.ProportionScale, 0, 1, function(value)
		setScale("BodyProportionScale", value)
	end)
	self.Maid.ProportionScale = proportionScale
	self.Maid:GiveTask(proportionScale.Changed:Connect(function(value)
		self.ScaleUpdated:Fire("ProportionScale", value)
	end))

	return self
end

function Class:UpdateWearing(scale, value)
	local slider = self.Maid[scale]
	slider:Set(value)
end

function Class:Destroy()
	self.Maid:DoCleaning()
	self.Maid = nil
	self.ScaleUpdated:Destroy()
	self.ScaleUpdated = nil
	setmetatable(self, nil)
end

return Class
