-- 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.Name)
	end

	if not readOnly then
		box.FocusLost:connect(function(enterPressed)
			Set(object, propertyData, ToValue(box.Text,propertyType.Name))
			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.Name)]: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.Name)
	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 propertyType.Category == "Enum" and RbxApi.Enums[propertyType.Name] then
		control = Controls["Enum"](object, propertyData, readOnly)
	elseif propertyType.Category == "Class" and RbxApi.Classes[propertyType.Name] then
		control = Controls["Object"](object, propertyData, readOnly)
	elseif Controls[propertyType.Name] then
		control = Controls[propertyType.Name](object, propertyData, readOnly)
	else
		control = Controls["default"](object, propertyData, readOnly)
	end
	return control
end