-- definetly not a good idea loading thousands of items at once; use infinite scrolling methods if possible
local function loadAccessories(category)
	local list = Catalog[currentCategory][category]
	if list then
		currentSubCategory = category
		for i, v in ipairs(list) do
			if v ~= nil then
				local button = makeButton(v)
				activeButtons[i] = button
			end
		end
		updateScrollingFrameCanvasSize()
	end
end

local function loadWearing()
	currentSubCategory = nil
	resetScrollingFrame()
	scrollingFrame.Visible = true
	for i, asset in ipairs(wearingAssets.assets) do
		local v = {Id = asset.id, Name = asset.name}
		local button = makeButton(v)
		activeButtons[i] = button
	end
	updateScrollingFrameCanvasSize()
end

local function loadSkinTones()
	local list = Catalog.Appearance.SkinTone
	if list then
		for name, color in next, list do
			local button; button = Button.new({
				Name = name,
				Icon = "rbxasset://textures/whiteCircle.png",
				ActivatedCallback = function(inputObject)
					remoteEvent:FireServer("skintone", name)
				end,
			})
			button.guiButton.Icon.ImageColor3 = color
			button:Parent(scrollingFrame)
			activeButtons[name] = button
		end
		updateScrollingFrameCanvasSize()
	end
end

local function loadScales()
	-- uhh? i forgot what I wanted to do here.
end

local function getCameraOffsetCFrame()
	local ViewSizeX = ScreenSpace.ViewSizeX()
	local ViewSizeY = ScreenSpace.ViewSizeY()
	local offset = ScreenSpace.ScreenToWorld(numberValue.Value * ViewSizeX, ViewSizeY/2, -DEPTH)
	local cameraCFrame = rootPart.CFrame * offset
	local lookCFrame = rootPart.CFrame * Vector3.new(offset.X, offset.Y, DEPTH)
	return CFrame.new(cameraCFrame, lookCFrame)
end

local function updateCamera(delta)
	camera.CFrame = getCameraOffsetCFrame()
end

local function openSequence()
	controlModule:Disable()
	avatarEditorFrame.Visible = true
	catalogFrameOpenTween:Play()
	viewerFrameOpenTween:Play()
	--cameraModule:ActivateOcclusionModule(Enum.DevCameraOcclusionMode.Invisicam)
	originalCamCFrame = camera.CFrame
	local cameraCFrame = getCameraOffsetCFrame()
	local cameraTween = Tween:Create(camera, tweenInfo, {CFrame = cameraCFrame})
	activeConnections[CAMERA_BIND] = cameraTween.Completed:Connect(function(playbackState)
		if playbackState == Enum.PlaybackState.Completed then
			Run:BindToRenderStep(CAMERA_BIND, Enum.RenderPriority.Camera.Value, updateCamera)
		end
	end)
	cameraTween:Play()
	isOpen = true
end

local function closeSequence()
	Run:UnbindFromRenderStep(CAMERA_BIND)
	catalogFrameCloseTween:Play()
	viewerFrameCloseTween:Play()
	local cameraTween = Tween:Create(camera, tweenInfo, {CFrame = originalCamCFrame})
	activeConnections[CAMERA_BIND] = cameraTween.Completed:Connect(function(playbackState)
		if playbackState == Enum.PlaybackState.Completed then
			avatarEditorFrame.Visible = false
			camera.CameraSubject = humanoid
			--cameraModule:ActivateOcclusionModule(Enum.DevCameraOcclusionMode.Zoom)
			controlModule:Enable()
		end
	end)
	cameraTween:Play()
	numberValue.Value = CAMERA_OFFSET
	fullView = false
	isOpen = false
end

local function toggle()
	if isOpen then
		closeSequence()
	else
		openSequence()
	end
end

local function toggleView()
	if fullView then
		catalogFrameOpenTween:Play()
		viewerFrameOpenTween:Play()
		fullViewCloseTween:Play()
	else
		catalogFrameCloseTween:Play()
		viewFramePartialOpenTween:Play()
		fullViewOpenTween:Play()
	end
	fullView = not fullView
end

local function onClientEvent(characterAppearanceInfo)
	wearingAssets = characterAppearanceInfo
	updateSelected()
	--TableUtil.Print(wearingAssets, "avatar", true)
end

for i, button in ipairs(categoryButtons) do
	local function activated(inputObject)
		local subCategoryTabFrame = subCategoryTabsFrame:FindFirstChild(button.Name)
		if subCategoryTabFrame then
			hideAllSubCategoryFrames()
			currentCategory = button.Name
			setSelectedCategory(button)
			subCategoryTabFrame.Visible = true
		elseif button.Name == "Wearing" then
			hideAllSubCategoryFrames()
			currentCategory = button.Name
			setSelectedCategory(button)
			loadWearing()
			setSelectedSubCategory(nil)
			scaleFrame.Visible = false
		end
	end
	local categoryButton = Button.new({
		guiButton = button,
		ActivatedCallback = activated,
	})
	categoryButton:SetSelected(button.Name == currentCategory)
	activeCategoryButtons[button] = categoryButton
end

for i, frame in ipairs(subCategoryFrames) do
	local subCategoryButtons = TableUtil.Filter(frame:GetChildren(), function(item)
		return item:IsA("GuiButton")
	end)
	for ii, button in ipairs(subCategoryButtons) do
		local function activated(inputObject)
			resetScrollingFrame()
			setSelectedSubCategory(button)
			if button.Name == "SkinTone" then
				loadSkinTones()
				scrollingFrame.Visible = true
				scaleFrame.Visible = false
				searchFrame.Visible = true
			elseif button.Name == "Scale" then
				loadScales()
				scrollingFrame.Visible = false
				scaleFrame.Visible = true
				searchFrame.Visible = false
			else
				loadAccessories(button.Name)
				scrollingFrame.Visible = true
				scaleFrame.Visible = false
				searchFrame.Visible = true
			end
		end
		local subCategoryButton = Button.new({
			guiButton = button,
			ActivatedCallback = activated,
		})
		subCategoryButton:SetSelected(button.Name == currentSubCategory)
		activeSubCategoryButtons[button] = subCategoryButton
	end
end