-- alas poor coupler.ClickDetector.MouseClick:connect(function() ... end), I knew thee well

remote.OnServerEvent:connect(function(player)
	if IsCoupled.Value then
		IsCoupled.Value = false
	else
		Allow.Value = not Allow.Value
		Recolor()
	end
end)

IsCoupled.Changed:connect(function()
	if IsCoupled.Value == false then
		Decouple()
	end
	Recolor()
end)

function rotate(a,b)
	local weld = Instance.new("Rotate")
	weld.Part0 = a
	weld.Part1 = b
	weld.C0 = CFrame.new()
	weld.C1 = b.CFrame:inverse() * a.CFrame--use this because you get less floating point errors
	weld.Name = "CouplerRotate"
	return weld
end

function rotateSpecial(a,b)
	local weld = Instance.new("Rotate")
	weld.Part0 = a
	weld.Part1 = b
	weld.C0 = CFrame.new(0,0,-0.6)
	weld.C1 = CFrame.new(0,0,-0.6)*CFrame.Angles(0,math.pi,0)
	weld.Name = "CouplerRotate"
	return weld
end

function PGSRotates(coupler1,coupler2)
	local R1 = Instance.new("Part")
	R1.CanCollide = false
	R1.Transparency = 1
	R1.FormFactor = "Plate"
	R1.Size = Vector3.new()
	--R1.CanCollide = false
	R1.TopSurface = "Smooth"
	R1.BottomSurface = "Smooth"
	local R2 = R1:Clone()
	R1.CFrame = coupler1.CFrame
	R2.CFrame = coupler2.CFrame
	rotate(coupler1,R1).Parent = coupler1
	rotate(coupler2,R2).Parent = coupler2
	rotateSpecial(R1,R2).Parent = R1
	R1.Parent = coupler.Parent
	R2.Parent = coupler.Parent
	return R1,R2
end

function Couple(coupler,otherCoupler)
	if PGS then
		coupler.CanCollide = false
		otherCoupler.CanCollide = false
		R1,R2 = PGSRotates(coupler,otherCoupler)
	else
		MyWeld = weld(coupler,otherCoupler)
		MyWeld.Parent = model
	end
	coupler.SoundClose:Play()
end

CoupledTo.Changed:connect(function()
	if CoupledTo.Value then
		--the network ownership means the couplers won't freak out when you couple
		local otherCoupler = CoupledTo.Value:FindFirstChild("Coupler")
		if otherCoupler
		and CoupledTo.Value:FindFirstChild("IsCoupled")
		and CoupledTo.Value.IsCoupled:IsA("BoolValue")
		and CoupledTo.Value.IsCoupled.Value
		then
			--continue
		else
			return
		end
		local owner = coupler:GetNetworkOwner()
		local otherOwner = otherCoupler:GetNetworkOwner()
		local ownerAuto = coupler:GetNetworkOwnershipAuto()
		local otherOwnerAuto = otherCoupler:GetNetworkOwnershipAuto()
		if coupler:CanSetNetworkOwnership() then
			coupler:SetNetworkOwner(nil)
		end
		if CoupledTo.Value.Coupler:CanSetNetworkOwnership() then
			coupler:SetNetworkOwner(nil)
		end
		Couple(coupler,otherCoupler)
		if coupler:CanSetNetworkOwnership() then
			if ownerAuto and otherOwnerAuto then
				coupler:SetNetworkOwnershipAuto()
			elseif ownerAuto then
				coupler:SetNetworkOwner(otherOwner)
			elseif otherOwnerAuto then
				coupler:SetNetworkOwner(owner)
			else
				coupler:SetNetworkOwner(owner)
			end
		end
		wait()
		if PGS then
			WeldDisappear = coupler.ChildRemoved:connect(function(it)
				if it.Name == "CouplerRotate" then
					Decouple()
					WeldDisappear:disconnect()
				end
			end)
		else
			WeldDisappear = MyWeld.AncestryChanged:connect(function()
				Decouple()
				WeldDisappear:disconnect()
			end)
		end
	else
		coupler.CanCollide = true
	end
end)

coupler.Touched:connect(function(TouchedPart)
	if TouchedPart.Parent and TouchedPart.Name == "Coupler" then--make sure the part still exists and that it is called "Coupler" (a good indicator)
		local OtherCoupler = TouchedPart.Parent
		local OtherAllow = OtherCoupler:FindFirstChild("Allow")--make sure this is a coupler by looking for the value that says we can couple
		local OtherIsCoupled = OtherCoupler:FindFirstChild("IsCoupled")--make sure this is a coupler by looking for the value that says it is coupled
		if OtherAllow and OtherIsCoupled then
			if OtherAllow.Value == true
			and Allow.Value == true
			and OtherIsCoupled.Value == false
			and IsCoupled.Value == false
			then
				IsCoupled.Value = true
				OtherIsCoupled.Value = true
				CoupledTo.Value = OtherCoupler
				if OtherCoupler:FindFirstChild("CoupledTo") then
					OtherCoupler.CoupledTo.Value = model
				end
			end
		end
	end
end)