-- Other
local IsGettingOff = false
local IsOnSegway = false
local Vector3new, CFramenew, Mathrad, Mathpi, CFrameangles, Raynew = Vector3.new, CFrame.new, math.rad, math.pi, CFrame.Angles, Ray.new


function Hopoff()
	if SegwayObject.Value ~= nil and IsGettingOff == false and SegwayObject.Value.PrimaryPart and SeaterObject.Value ~= nil then
		IsGettingOff = true
		IsOnSegway = false
		local PrimaryPart = SegwayObject.Value.PrimaryPart 
		local px,py,pz,xx,yx,zx,xy,yy,zy,xz,yz,zz=PrimaryPart.CFrame:components()
		
		ContextService:UnbindAction("segInputAction")
			
		-- Delete welds
		if SeaterObject.Value ~= nil then
			repeat wait() until DeleteWelds:InvokeServer(SeaterObject.Value.Parent) == true or SeaterObject.Value == nil
		end
		
		-- Resets camera's behavior
		Camera.CameraType = "Custom"
		
		-- Set gyro to have power
		if Thruster.Value then
			Thruster.Value.BodyGyro.MaxTorque = Vector3new(400000, 0, 400000)
		end
		
		-- Stops sounds
		if SeaterObject.Value and SeaterObject.Value.Parent:FindFirstChild("Run") then
			StopSound:FireServer(SeaterObject.Value.Parent.Run,0)
			PlaySound:FireServer(SeaterObject.Value.Parent.Off,SeaterObject.Value.Parent.Off.Pitch,SeaterObject.Value.Parent.Off.Volume)
		end
		
		-- Flips segway if fell over
		if SegwayObject.Value then
			SegwayObject.Value:SetPrimaryPartCFrame(CFramenew(px,py+0.1,pz,1,yx,zx,xy,1,zy,xz,yz,1))
		end	
		
		-- Turn off lights
		ConfigLights:FireServer(0.3,"Bright bluish green",false,"SmoothPlastic",Lights,Notifiers)
		
		-- Re-parents mobile gui and reshows mobile controls
		GuiControls.Parent = script.Parent
		UserInputService.ModalEnabled = false
		OffButton.ImageColor3 = LiftedColor
		
		-- Shows tool UI via use with VR
		if UserInputService.VREnabled then
			if PlayerGui and PlayerGui:FindFirstChild("DisplayGui") and PlayerGui:FindFirstChild("ColorGui") then
				PlayerGui:FindFirstChild("DisplayGui").Enabled = true
				PlayerGui:FindFirstChild("ColorGui").Enabled = true
			end
			
			UpdateCharTrans(0,0)
		end
		
		-- Disconnect events
		SitListener:disconnect()
		JumpListener:disconnect()
		
		-- Resets the tilt motor angle
		if TiltMotor.Value then
			TiltMotor.Value.DesiredAngle = 0
		end
		
		-- Makes the thruster's velocity still
		PrimaryPart.Anchored = true
			
		-- Makes object values nil
		UndoTags:FireServer()
		
		-- Configures humanoid
		ConfigHumanoid:InvokeServer(false,true,true)
		
		-- Unanchors segway
		PrimaryPart.Anchored = false
		PrimaryPart.Velocity = Vector3.new()
			
		-- Reset direction and steer tags
		Direction = 0
		Steer = 0
			
		wait(1)
		UndoHasWelded:FireServer(SeaterObject)
		
		IsGettingOff = false
	end
end

function UpdateCharTrans(BodyTrans,SegwayTrans)	
	-- Changes character's body while VR
	for _,d in pairs(Character:GetDescendants()) do
		if d and d:IsA("BasePart") then
			if (d.Parent:FindFirstChild("Humanoid") or d.Parent:IsA("Accessory")) then
				d.LocalTransparencyModifier = BodyTrans
			else 
				d.LocalTransparencyModifier = SegwayTrans
			end
		elseif d and d:IsA("Decal") and d.Name == "face" then
			d.Transparency = BodyTrans
		end
	end
end

function UpdateVRPos()
	if UserInputService.VREnabled and Character and Character.Parent and Character:FindFirstChild("Head") then
		local hpx,hpy,hpz,hxx,hxy,hxz,hyx,hyy,hyz,hzx,hzy,hzz = Character.Head.CFrame:components()
		
		Camera.CFrame = CFramenew(hpx,hpy,hpz,
			hxx,0,hxz,
			0,1,0,
			hzx,0,hzz
		) + (Vector3new(hxy,hyy,hzy)*2.5) --Height in studs above character's head
	end
end

function Accelerate()
	if IsOnSegway then
		local v = Direction*Thruster.Value.CFrame.lookVector*MaxSpeed.Value
		local NewVelocity = Thruster.Value.Velocity:Lerp(v, 0.05) -- Thrust
		local NewRotVelocity = Vector3new(0,-Steer*TurnSpeed.Value/10,0) -- Steering
		local px,py,pz,xx,xy,xz,yx,yy,yz,zx,zy,zz = Thruster.Value.CFrame:components()
		
		if yy > 0.7 then -- If segway is upsided
			Thruster.Value.BodyGyro.MaxTorque = Vector3new(400000, 0, 400000)
			Thruster.Value.Velocity = NewVelocity
			Thruster.Value.RotVelocity = NewRotVelocity
		else
			Thruster.Value.BodyGyro.MaxTorque = Vector3new(0,0,0)
		end
			
	end
end

function CastToGround()
	if Thruster.Value and Thruster.Value.Parent then
		
		-- Raycast to face segway towards ground
		local px,py,pz,xx,xy,xz,yx,yy,yz,zx,zy,zz = Thruster.Value.CFrame:components()
		local SegDnVect = -Vector3new(xy,yy,zy)
		local Ray = Raynew(Thruster.Value.CFrame.p, SegDnVect*50)
		local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(Ray,{SegwayObject.Value,RayTest})
		local HitDepth = (Thruster.Value.Position-position).magnitude
		local NextRayAngle = (normal-SegDnVect).magnitude
		
		if hit and hit.CanCollide and NextRayAngle > 1.7 then
			Thruster.Value.BodyGyro.MaxTorque = Vector3new(400000, 0, 400000)
			Thruster.Value.BodyGyro.CFrame = CFramenew(position, position + normal) * CFrameangles(-Mathpi/2, 0, 0)
		end
	end
end

function Sound()
	if Thruster.Value and 0.85+Mathrad(Thruster.Value.Velocity.Magnitude/1.8) <= RunSoundPitchLimit then
		SeaterObject.Value.Parent.Run.Pitch = 0.85+Mathrad(Thruster.Value.Velocity.Magnitude/1.8)
	end
end

function Tilt()
	if Direction ~= 0 then
		TiltMotor.Value.DesiredAngle = Direction/10
		SeaterObject.Value.Parent.Run.Volume = RunSoundVol
		
	else 
		TiltMotor.Value.DesiredAngle = 0
		
		-- Change sound based on current status
		if Steer == 0 then
			SeaterObject.Value.Parent.Run.Volume = 0
		else --Adjusts the run sound when still and just turning
			SeaterObject.Value.Parent.Run.Volume = RunSoundVol
			SeaterObject.Value.Parent.Run.Pitch = 0.85+Mathrad(Thruster.Value.RotVelocity.Magnitude/1.8)				
		end
		
	end
end

function SetGuiButtons()
	--Exit button
	OffButton.MouseButton1Down:connect(function() OffButton.ImageColor3 = PressedColor end)
	OffButton.MouseButton1Up:connect(function() OffButton.ImageColor3 = LiftedColor Hopoff()end)
	OffButton.MouseLeave:connect(function()OffButton.ImageColor3 = LiftedColor end)
	
	--Left button pressed/lifted
	LeftButton.MouseButton1Down:connect(function()Steer = -1 LeftButton.ImageColor3 = PressedColor end)
	LeftButton.MouseButton1Up:connect(function()Steer = 0 LeftButton.ImageColor3 = LiftedColor end)
	LeftButton.MouseLeave:connect(function()LeftButton.ImageColor3 = LiftedColor end)
	
	--Right button pressed/lifted
	RightButton.MouseButton1Down:connect(function()Steer = 1 RightButton.ImageColor3 = PressedColor end)
	RightButton.MouseButton1Up:connect(function()Steer = 0 RightButton.ImageColor3 = LiftedColor end)
	RightButton.MouseLeave:connect(function()RightButton.ImageColor3 = LiftedColor end)
	
	--Backward button pressed/lifted
	DownButton.MouseButton1Down:connect(function()Direction = -1 DownButton.ImageColor3 = PressedColor end)
	DownButton.MouseButton1Up:connect(function()Direction = 0 DownButton.ImageColor3 = LiftedColor end)
	DownButton.MouseLeave:connect(function()DownButton.ImageColor3 = LiftedColor end)
	
	--Forward button pressed/lifted
	UpButton.MouseButton1Down:connect(function()Direction = 1 UpButton.ImageColor3 = PressedColor end)
	UpButton.MouseButton1Up:connect(function()Direction = 0 UpButton.ImageColor3 = LiftedColor end)
	UpButton.MouseLeave:connect(function()UpButton.ImageColor3 = LiftedColor end)
end

function onGENInput(actionName,inputState,inputObj)
	if WeldObject.Value ~= nil then
		local Key=inputObj.KeyCode
		
		-- Hop off segway if press Spacebar, Backspace or controller A button
		if (Key == Enum.KeyCode.Space or Key == Enum.KeyCode.Backspace or Key == Enum.KeyCode.ButtonA) and inputState == Enum.UserInputState.Begin then	
			Hopoff()
		end
		
		--Forward
		if Key == Enum.KeyCode.W or Key == Enum.KeyCode.Up or Key == Enum.KeyCode.ButtonR2 then
			Direction = (inputState == Enum.UserInputState.Begin and 1) or (Direction == 1 and 0) or Direction
		end
		
		--Backward
		if Key == Enum.KeyCode.S or Key == Enum.KeyCode.Down or Key == Enum.KeyCode.ButtonL2 then
			Direction = (inputState == Enum.UserInputState.Begin and -1) or (Direction == -1 and 0) or Direction
		end
		
		--Left
		if Key == Enum.KeyCode.D or Key == Enum.KeyCode.Right then
			Steer = (inputState == Enum.UserInputState.Begin and 1) or (Steer == 1 and 0) or Steer
		end
		
		--Right
		if Key == Enum.KeyCode.A or Key == Enum.KeyCode.Left then
			Steer = (inputState == Enum.UserInputState.Begin and -1) or (Steer == -1 and 0) or Steer
		end
	end
end