local q=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 P=q.AvatarEditor local C=require(P.Shared.Util.Maid)local m=require(P.Shared.Util.Promise)local z=require(P.Shared.Util.Signal)local h=require(P.Shared.Settings)local p=require(P.Client.Theme)local o=f.LocalPlayer local i={}i.__index=i local function S()local q=P.CostumeTemplate:Clone()return q end function i.new(q)local f=setmetatable({},i)f.Maid=C.new()f.Listeners=C.new()f.ScrollingFrame=q.ScrollingFrame f.GridLayout=f.ScrollingFrame.UIGridLayout f.Wear=z.new()f.Delete=z.new()f.Children={}f.Pool={}for q=1,50,1 do f.Pool[q]=S()end f.Maid:GiveTask(p.Changed:Connect(function()f:Render()end))f.Maid:GiveTask(p:Bind(f.ScrollingFrame,"\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"));((m.new(function(q,f)local P=o:WaitForChild("\065\069\095\067\111\115\116\117\109\101\115")q(P)end)):andThen(function(q)f.Folder=q f.Maid:GiveTask(q.ChildAdded:Connect(function()f:Render()end))f.Maid:GiveTask(q.ChildRemoved:Connect(function()f:Render()end))f:Render()end)):catch(warn)return f end function i.GetItem(q)local f=q.Pool local P=table.remove(f,#f)if not P then P=S()end return P end function i.Render(q)if not q.Folder then return end local P=q.Folder local C=q.Listeners local z=q.Children local o=q.ScrollingFrame local i=q.GridLayout local S=q.Pool local j=P:GetChildren()local M={}C:DoCleaning()for P,i in ipairs(j)do local S=z[P]or q:GetItem()M[P]=S S.ItemLabel.Text=i.Name S.More.Visible=false C:GiveTask(p:Bind(S,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\066\117\116\116\111\110"))C:GiveTask(p:Bind(S.ItemLabel,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"))C:GiveTask(p:Bind(S.ItemLabel,"\084\101\120\116\083\116\114\111\107\101\067\111\108\111\114\051","\084\101\120\116\083\116\114\111\107\101"))C:GiveTask(p:Bind(S.More,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\068\101\108\101\116\101"))C:GiveTask(p:Bind(S.More,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"));((m.new(function(q,P)local C,m=pcall(function()return f:CreateHumanoidModelFromDescription(i,Enum.HumanoidRigType.R15,Enum.AssetTypeVerification.ClientOnly)end)if C then q(m)else P(m)end end)):andThen(function(q)C:GiveTask(q)q:SetPrimaryPartCFrame(CFrame.new())local f=q.Humanoid f.DisplayDistanceType=Enum.HumanoidDisplayDistanceType.None f.HealthDisplayType=Enum.HumanoidHealthDisplayType.AlwaysOff q.Animate:Destroy()local P=S.ViewportFrame local m=Instance.new("\067\097\109\101\114\097")C:GiveTask(m)m.CFrame=CFrame.lookAt(Vector3.new(-2,2,-5),q.PrimaryPart.Position)m.Parent=S P.CurrentCamera=m q.Parent=P.WorldModel C:GiveTask(function()P.CurrentCamera=nil end)end)):catch(warn)C:GiveTask(S.More.Activated:Connect(function(f)q.Delete:Fire(i)end))C:GiveTask(S.TouchLongPress:Connect(function(f,P)S.ItemLabel.Visible=false S.More.Visible=false q.Delete:Fire(i)end))C:GiveTask(S.InputBegan:Connect(function(q)if not h.HOVER_INPUTS[q.UserInputType]then return end S.ItemLabel.Visible=true if q.UserInputType==Enum.UserInputType.MouseMovement then S.More.Visible=true end end))C:GiveTask(S.InputEnded:Connect(function(q)if not h.HOVER_INPUTS[q.UserInputType]then return end S.ItemLabel.Visible=false S.More.Visible=false end))C:GiveTask(S.Activated:Connect(function(f)q.Wear:Fire(i)end))S.Parent=o end for q=#j+1,#z,1 do local f=z[q]f.Parent=nil table.insert(S,f)end q.Children=M o.CanvasSize=UDim2.new(0,0,0,i.AbsoluteContentSize.Y)end function i.Destroy(q)q.Maid:DoCleaning()q.Maid=nil q.Listeners:DoCleaning()q.Listeners=nil for q,f in ipairs(q.Children)do f:Destroy()end table.clear(q.Children)for q,f in ipairs(q.Pool)do f:Destroy()end table.clear(q.Pool)setmetatable(q,nil)end return i
--[[



]]

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

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

local player = Players.LocalPlayer

local Class = {}
Class.__index = Class

local function createButton()
	local button = AvatarEditor.CostumeTemplate:Clone()
	return button
end

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

	self.Maid = Maid.new()
	self.Listeners = Maid.new()
	self.ScrollingFrame = frame.ScrollingFrame
	self.GridLayout = self.ScrollingFrame.UIGridLayout
	self.Wear = Signal.new()
	self.Delete = Signal.new()
	self.Children = {}
	self.Pool = {}

	for i = 1, 50 do
		self.Pool[i] = createButton()
	end

	self.Maid:GiveTask(Theme.Changed:Connect(function()
		self:Render()
	end))

	self.Maid:GiveTask(Theme:Bind(self.ScrollingFrame, "ScrollBarImageColor3", "Scrollbar"))

	Promise.new(function(resolve, reject)
		local folder = player:WaitForChild("AE_Costumes")
		resolve(folder)
	end)
		:andThen(function(folder)
			self.Folder = folder
			self.Maid:GiveTask(folder.ChildAdded:Connect(function()
				self:Render()
			end))
			self.Maid:GiveTask(folder.ChildRemoved:Connect(function()
				self:Render()
			end))
			self:Render()
		end)
		:catch(warn)

	return self
end

function Class:GetItem()
	local pool = self.Pool
	local button = table.remove(pool, #pool)
	if not button then
		button = createButton()
	end
	return button
end

function Class:Render()
	if not self.Folder then
		return
	end

	local folder = self.Folder
	local maid = self.Listeners
	local children = self.Children
	local scrollingFrame = self.ScrollingFrame
	local uiGridLayout = self.GridLayout
	local pool = self.Pool

	local list = folder:GetChildren()
	local newChildren = {}

	maid:DoCleaning()

	for i, v in ipairs(list) do
		local button = children[i] or self:GetItem()
		newChildren[i] = button

		button.ItemLabel.Text = v.Name
		button.More.Visible = false

		maid:GiveTask(Theme:Bind(button, "BackgroundColor3", "Button"))
		maid:GiveTask(Theme:Bind(button.ItemLabel, "TextColor3", "Text"))
		maid:GiveTask(Theme:Bind(button.ItemLabel, "TextStrokeColor3", "TextStroke"))
		maid:GiveTask(Theme:Bind(button.More, "BackgroundColor3", "Delete"))
		maid:GiveTask(Theme:Bind(button.More, "TextColor3", "Text"))

		Promise.new(function(resolve, reject)
			local success, result = pcall(function()
				return Players:CreateHumanoidModelFromDescription(
					v,
					Enum.HumanoidRigType.R15,
					Enum.AssetTypeVerification.ClientOnly
				)
			end)
			if success then
				resolve(result)
			else
				reject(result)
			end
		end)
			:andThen(function(result)
				maid:GiveTask(result)
				result:SetPrimaryPartCFrame(CFrame.new())

				local humanoid = result.Humanoid
				humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
				humanoid.HealthDisplayType = Enum.HumanoidHealthDisplayType.AlwaysOff
				result.Animate:Destroy()

				local viewport = button.ViewportFrame
				local camera = Instance.new("Camera")
				maid:GiveTask(camera)
				camera.CFrame = CFrame.lookAt(Vector3.new(-2, 2, -5), result.PrimaryPart.Position)
				camera.Parent = button
				viewport.CurrentCamera = camera
				result.Parent = viewport.WorldModel
				maid:GiveTask(function()
					viewport.CurrentCamera = nil
				end)
			end)
			:catch(warn)

		maid:GiveTask(button.More.Activated:Connect(function(inputObject)
			self.Delete:Fire(v)
		end))

		maid:GiveTask(button.TouchLongPress:Connect(function(touchPositions, inputState)
			button.ItemLabel.Visible = false
			button.More.Visible = false
			self.Delete:Fire(v)
		end))

		maid:GiveTask(button.InputBegan:Connect(function(inputObject)
			if not Settings.HOVER_INPUTS[inputObject.UserInputType] then
				return
			end

			button.ItemLabel.Visible = true
			if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
				button.More.Visible = true
			end
		end))

		maid:GiveTask(button.InputEnded:Connect(function(inputObject)
			if not Settings.HOVER_INPUTS[inputObject.UserInputType] then
				return
			end

			button.ItemLabel.Visible = false
			button.More.Visible = false
		end))

		maid:GiveTask(button.Activated:Connect(function(inputObject)
			self.Wear:Fire(v)
		end))

		button.Parent = scrollingFrame
	end

	for i = #list + 1, #children do
		local button = children[i]
		button.Parent = nil
		table.insert(pool, button)
	end

	self.Children = newChildren
	scrollingFrame.CanvasSize = UDim2.new(0, 0, 0, uiGridLayout.AbsoluteContentSize.Y)
end

function Class:Destroy()
	self.Maid:DoCleaning()
	self.Maid = nil
	self.Listeners:DoCleaning()
	self.Listeners = nil
	for i, v in ipairs(self.Children) do
		v:Destroy()
	end
	table.clear(self.Children)
	for i, v in ipairs(self.Pool) do
		v:Destroy()
	end
	table.clear(self.Pool)
	setmetatable(self, nil)
end

return Class
