local W=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local q=game:GetService("\080\108\097\121\101\114\115")local e=W.AvatarEditor local t=require(e.Client.GuiLib.LazyLoader)local V=require(e.Shared.Util.Maid)local d=require(e.Shared.Util.Signal)local E=require(e.Shared.Util.Promise)local L=require(e.Client.Theme)local v=q.LocalPlayer local F={}F.__index=F local U={}U.__index=U local function z(W,q,e,t,V)return t+(V-t)*((W-q)/(e-q))end local function C(W,q)local e=v.Character local t=e and e:FindFirstChildWhichIsA("\072\117\109\097\110\111\105\100")local V=(t and t.Health>0)and t:FindFirstChild(W)if V then V.Value=q else warn(W,"\110\111\116 \102\111\117\110\100 \111\114 \100\101\097\100")end end function U.new(W,q,e,E,L)local v=setmetatable({},U)v.Maid=V.new()v.Changed=d.new()v.Min=e v.Max=E v.Frame=W v.Callback=L v.Slider=t.Classes.Slider.new(W.SliderFrame)v.Slider.Interval=.01 v.Slider.TweenClick=false v.Slider:Set(z(q,e,E,0,1))v:Update(z(q,e,E,0,1))v.Maid:GiveTask(v.Slider.Changed:Connect(function(W)W=z(W,0,1,e,E)v:Update(W)end))v.Maid:GiveTask(v.Slider.DragStop:Connect(function()local W=z(v.Slider:Get(),0,1,e,E)v.Changed:Fire(W)end))v.Mask=t.Classes.TextMask.new(W.TextFrame.TextBox)v.Mask:SetMaskType("\073\110\116\101\103\101\114")v.Mask:SetMaxLength(3)v.Maid:GiveTask(v.Mask.Frame.FocusLost:Connect(function()local W=math.clamp(v.Mask:GetValue()/100,e,E)v.Slider:Set(z(W,e,E,0,1))v:Update(W)v.Changed:Fire(W)end))return v end function U.Set(q,W)q.Slider:Set(z(W,q.Min,q.Max,0,1))q.Mask.Frame.Text=string.format("\037\100",z(W,0,1,0,100))end function U.Update(q,W)local e=q.Frame local t=q.Callback e.TextFrame.TextBox.Text=string.format("\037\100",z(W,0,1,0,100))t(W)end function U.Destroy(W)W.Maid:DoCleaning()W.Maid=nil W.Changed:Destroy()W.Changed=nil W.Min=nil W.Max=nil W.Frame=nil W.Callback=nil W.Slider:Destroy()W.Slider=nil W.Mask:Destroy()W.Mask=nil setmetatable(W,nil)end function F.new(W,q)local e=setmetatable({},F)e.Maid=V.new()e.ScaleUpdated=d.new()e.Maid:GiveTask(L:Bind(W,"\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 W,q in ipairs(W:GetChildren())do if not q:IsA("\070\114\097\109\101")then continue end e.Maid:GiveTask(L:Bind(q.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"))e.Maid:GiveTask(L:Bind(q.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"))e.Maid:GiveTask(L:Bind(q.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"))e.Maid:GiveTask(L:Bind(q.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"))e.Maid:GiveTask(L:Bind(q.TextFrame.TextBox,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"))e.Maid:GiveTask(L:Bind(q.TextLabel,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"))end local t=U.new(W.BodyType,q.BodyTypeScale,0,1,function(W)C("\066\111\100\121\084\121\112\101\083\099\097\108\101",W)end)e.Maid.BodyTypeScale=t e.Maid:GiveTask(t.Changed:Connect(function(W)e.ScaleUpdated:Fire("\066\111\100\121\084\121\112\101\083\099\097\108\101",W)end))local E=U.new(W.Height,q.HeightScale,.9,1.05,function(W)C("\066\111\100\121\072\101\105\103\104\116\083\099\097\108\101",W)end)e.Maid.HeightScale=E e.Maid:GiveTask(E.Changed:Connect(function(W)e.ScaleUpdated:Fire("\072\101\105\103\104\116\083\099\097\108\101",W)end))local v=U.new(W.Width,q.WidthScale,.7,1,function(W)C("\066\111\100\121\087\105\100\116\104\083\099\097\108\101",W)end)e.Maid.WidthScale=v e.Maid:GiveTask(v.Changed:Connect(function(W)e.ScaleUpdated:Fire("\087\105\100\116\104\083\099\097\108\101",W)end))local z=U.new(W.Head,q.HeadScale,.95,1,function(W)C("\072\101\097\100\083\099\097\108\101",W)end)e.Maid.HeadScale=z e.Maid:GiveTask(z.Changed:Connect(function(W)e.ScaleUpdated:Fire("\072\101\097\100\083\099\097\108\101",W)end))local G=U.new(W.Proportion,q.ProportionScale,0,1,function(W)C("\066\111\100\121\080\114\111\112\111\114\116\105\111\110\083\099\097\108\101",W)end)e.Maid.ProportionScale=G e.Maid:GiveTask(G.Changed:Connect(function(W)e.ScaleUpdated:Fire("\080\114\111\112\111\114\116\105\111\110\083\099\097\108\101",W)end))return e end function F.UpdateWearing(e,W,q)local t=e.Maid[W]t:Set(q)end function F.Destroy(W)W.Maid:DoCleaning()W.Maid=nil W.ScaleUpdated:Destroy()W.ScaleUpdated=nil setmetatable(W,nil)end return F
-- Class
-- 0_1195
-- January 10, 2021

--[[



]]

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
