local q={}q.default=function(q,U,j)local Z=U.Name local K=U.ValueType local m=CreateTextBox(j)m.Size=UDim2.new(1,-2*Styles.Margin,1,0)m.Position=UDim2.new(0,Styles.Margin,0,0)local function H()local U=q[Z]m.Text=ToString(U,K)end if not j then m.FocusLost:connect(function(j)Set(q,U,ToValue(m.Text,K))H()end)end H()q.Changed:connect(function(q)if q==Z then H()end end)return m end q.bool=function(q,U,j)local Z=U.Name local K=q[Z]local m,H=CreateCheckbox(K,j,function(j)Set(q,U,not K)end)m.Position=UDim2.new(0,Styles.Margin,0,Styles.Margin)H(K)local function t()K=q[Z]H(K)end q.Changed:connect(function(q)if q==Z then t()end end)if q:IsA("\066\111\111\108\086\097\108\117\101")then q.Changed:connect(function(q)t()end)end t()return m end q.BrickColor=function(q,U,j)local Z=U.Name local K,m,H=CreateBrickColor(j,function(j)Set(q,U,j)end)local function t()local U=q[Z]H.BackgroundColor3=U.Color m.Text=tostring(U)end t()q.Changed:connect(function(q)if q==Z then t()end end)return K end q.Color3=function(q,U,j)local Z=U.Name local K,m,H=CreateColor3Control(j)m.FocusLost:connect(function(j)Set(q,U,ToValue(m.Text,"\067\111\108\111\114\051"))local K=q[Z]H.BackgroundColor3=K m.Text=ToString(K,"\067\111\108\111\114\051")end)local function t()local U=q[Z]H.BackgroundColor3=U m.Text=ToString(U,"\067\111\108\111\114\051")end t()q.Changed:connect(function(q)if q==Z then t()end end)return K end q.Enum=function(q,U,j)local Z=U.Name local K=U.ValueType local m=q[Z].Name local H={}for q,U in pairs(Enum[tostring(K)]:GetEnumItems())do table.insert(H,U.Name)end local t,A=CreateDropDown(H,m,j,function(j)Set(q,U,j)end)local function N()local U=q[Z].Name A.Text=tostring(U)end N()q.Changed:connect(function(q)if q==Z then N()end end)return t end q.Object=function(q,U,j)local Z=U.Name local K=U.ValueType local m=CreateObject(j,function() end)m.Size=UDim2.new(1,-2*Styles.Margin,1,0)m.Position=UDim2.new(0,Styles.Margin,0,0)local function H()if AwaitingObjectObj==q then if AwaitingObjectValue==true then m.Text="\083\101\108\101\099\116 \097\110 \079\098\106\101\099\116"return end end local U=q[Z]m.Text=ToString(U,K)end if not j then m.MouseButton1Click:connect(function()if AwaitingObjectValue then AwaitingObjectValue=false H()return end AwaitingObjectValue=true AwaitingObjectObj=q AwaitingObjectProp=U m.Text="\083\101\108\101\099\116 \097\110 \079\098\106\101\099\116"end)m.Cancel.Visible=true m.Cancel.MouseButton1Click:connect(function()q[Z]=nil end)end H()q.Changed:connect(function(q)if q==Z then H()end end)if q:IsA("\079\098\106\101\099\116\086\097\108\117\101")then q.Changed:connect(function(q)H()end)end return m end function GetControl(U,j,Z)local K=j.ValueType local m=nil if q[K]then m=q[K](U,j,Z)elseif RbxApi.IsEnum(K)then m=q.Enum(U,j,Z)else m=q.default(U,j,Z)end return m end
-- Code for handling controls of various data types --

local Controls = {}

Controls["default"] = function(object, propertyData, readOnly)
	local propertyName = propertyData["Name"]
	local propertyType = propertyData["ValueType"]

	local box = CreateTextBox(readOnly)
	box.Size = UDim2.new(1, -2 * Styles.Margin, 1, 0)
	box.Position = UDim2.new(0, Styles.Margin, 0, 0)

	local function update()
		local value = object[propertyName]
		box.Text = ToString(value, propertyType)
	end

	if not readOnly then
		box.FocusLost:connect(function(enterPressed)
			Set(object, propertyData, ToValue(box.Text, propertyType))
			update()
		end)
	end

	update()

	object.Changed:connect(function(property)
		if property == propertyName then
			update()
		end
	end)

	return box
end

Controls["bool"] = function(object, propertyData, readOnly)
	local propertyName = propertyData["Name"]
	local checked = object[propertyName]

	local checkbox, setValue = CreateCheckbox(checked, readOnly, function(value)
		Set(object, propertyData, not checked)
	end)
	checkbox.Position = UDim2.new(0, Styles.Margin, 0, Styles.Margin)

	setValue(checked)

	local function update()
		checked = object[propertyName]
		setValue(checked)
	end

	object.Changed:connect(function(property)
		if property == propertyName then
			update()
		end
	end)

	if object:IsA("BoolValue") then
		object.Changed:connect(function(val)
			update()
		end)
	end

	update()

	return checkbox
end

Controls["BrickColor"] = function(object, propertyData, readOnly)
	local propertyName = propertyData["Name"]

	local frame, label, brickColorBox = CreateBrickColor(readOnly, function(brickColor)
		Set(object, propertyData, brickColor)
	end)

	local function update()
		local value = object[propertyName]
		brickColorBox.BackgroundColor3 = value.Color
		label.Text = tostring(value)
	end

	update()

	object.Changed:connect(function(property)
		if property == propertyName then
			update()
		end
	end)

	return frame
end

Controls["Color3"] = function(object, propertyData, readOnly)
	local propertyName = propertyData["Name"]

	local frame, textBox, colorBox = CreateColor3Control(readOnly)

	textBox.FocusLost:connect(function(enterPressed)
		Set(object, propertyData, ToValue(textBox.Text, "Color3"))
		local value = object[propertyName]
		colorBox.BackgroundColor3 = value
		textBox.Text = ToString(value, "Color3")
	end)

	local function update()
		local value = object[propertyName]
		colorBox.BackgroundColor3 = value
		textBox.Text = ToString(value, "Color3")
	end

	update()

	object.Changed:connect(function(property)
		if property == propertyName then
			update()
		end
	end)

	return frame
end

Controls["Enum"] = function(object, propertyData, readOnly)
	local propertyName = propertyData["Name"]
	local propertyType = propertyData["ValueType"]

	local enumName = object[propertyName].Name

	local enumNames = {}
	for _, enum in pairs(Enum[tostring(propertyType)]:GetEnumItems()) do
		table.insert(enumNames, enum.Name)
	end

	local dropdown, propertyLabel = CreateDropDown(enumNames, enumName, readOnly, function(value)
		Set(object, propertyData, value)
	end)
	--dropdown.Parent = frame

	local function update()
		local value = object[propertyName].Name
		propertyLabel.Text = tostring(value)
	end

	update()

	object.Changed:connect(function(property)
		if property == propertyName then
			update()
		end
	end)

	return dropdown
end

Controls["Object"] = function(object, propertyData, readOnly)
	local propertyName = propertyData["Name"]
	local propertyType = propertyData["ValueType"]

	local box = CreateObject(readOnly, function() end)
	box.Size = UDim2.new(1, -2 * Styles.Margin, 1, 0)
	box.Position = UDim2.new(0, Styles.Margin, 0, 0)

	local function update()
		if AwaitingObjectObj == object then
			if AwaitingObjectValue == true then
				box.Text = "Select an Object"
				return
			end
		end
		local value = object[propertyName]
		box.Text = ToString(value, propertyType)
	end

	if not readOnly then
		box.MouseButton1Click:connect(function()
			if AwaitingObjectValue then
				AwaitingObjectValue = false
				update()
				return
			end
			AwaitingObjectValue = true
			AwaitingObjectObj = object
			AwaitingObjectProp = propertyData
			box.Text = "Select an Object"
		end)

		box.Cancel.Visible = true
		box.Cancel.MouseButton1Click:connect(function()
			object[propertyName] = nil
		end)
	end

	update()

	object.Changed:connect(function(property)
		if property == propertyName then
			update()
		end
	end)

	if object:IsA("ObjectValue") then
		object.Changed:connect(function(val)
			update()
		end)
	end

	return box
end

function GetControl(object, propertyData, readOnly)
	local propertyType = propertyData["ValueType"]
	local control = nil

	if Controls[propertyType] then
		control = Controls[propertyType](object, propertyData, readOnly)
	elseif RbxApi.IsEnum(propertyType) then
		control = Controls["Enum"](object, propertyData, readOnly)
	else
		control = Controls["default"](object, propertyData, readOnly)
	end
	return control
end
