
TOOL.ClientConVar[ "keyup" ] = "9"
TOOL.ClientConVar[ "keydn" ] = "6"
TOOL.ClientConVar[ "speed" ] = "1"
TOOL.ClientConVar[ "resistance" ] = "0"

cleanup.Register( "hoverballs" )

function TOOL:LeftClick( trace )

	if ( trace.Entity && trace.Entity:IsPlayer() ) then return false end
	
	// If there's no physics object then we can't constraint it!
	if ( SERVER && !util.IsValidPhysicsObject( trace.Entity, trace.PhysicsBone ) ) then return false end
	
	if (CLIENT) then return true end
	
	local ply = self:GetOwner()
	
	local key_d 		= tonumber(	self:GetClientInfo( "keydn" ) )
	local key_u 		= tonumber(	self:GetClientInfo( "keyup" ) )
	local speed 		= tonumber(	self:GetClientInfo( "speed" ) )
	local resistance 	= tonumber(	self:GetClientInfo( "resistance" ) )
	
	if ( !self:GetSWEP():CheckLimit( "hoverballs" ) ) then return false end
	
	resistance = math.Clamp( resistance, 0, 20 )
	
	if ( trace.Entity:IsValid() && trace.Entity:GetClass() == "gmod_hoverball" && trace.Entity:GetTable().pl == ply ) then
	
		ball:GetTable():SetSpeed( speed )
		ball:GetTable():SetAirResistance( resistance )	
	
		return true
	
	end
	
	// If we hit the world then offset the spawn position
	if ( trace.Entity:IsWorld() ) then
		trace.HitPos = trace.HitPos + trace.HitNormal * 8
	end

	ball = MakeHoverBall( ply, trace.HitPos, key_d, key_u, speed, resistance )
	
	local const, nocollide
	
	// Don't weld to world
	if ( trace.Entity != NULL && !trace.Entity:IsWorld() ) then
	
		const 		= constraint.Weld( trace.Entity, ball, trace.PhysicsBone, 0, 0 )
		nocollide 	= constraint.NoCollide( ball, trace.Entity, 0, trace.PhysicsBone )
		trace.Entity:DeleteOnRemove( ball )
		
		ball:GetPhysicsObject():EnableCollisions( false )
		ball:GetTable().nocollide = true
		
	end
	
	undo.Create("HoverBall")
		undo.AddEntity( ball )
		undo.AddEntity( const )
		undo.AddEntity( nocollide )
		undo.SetPlayer( ply )
	undo.Finish()
	
	ply:AddCleanup( "hoverballs", ball )
	ply:AddCleanup( "hoverballs", const )
	ply:AddCleanup( "hoverballs", nocollide )
	
	return true

end

function TOOL:RightClick( trace )

	return self:LeftClick( trace )
	
end

if (SERVER) then

	function MakeHoverBall( ply, Pos, key_d, key_u, speed, resistance, Vel, aVel, frozen, nocollide )
	
		if ( !ply:CheckLimit( "hoverballs" ) ) then return nil end
	
		local ball = ents.Create( "gmod_hoverball" )
		if (!ball:IsValid()) then return false end

		ball:SetPos( Pos )
		ball:Spawn()
		ball:GetTable():SetSpeed( speed )
		ball:GetTable():SetPlayer( ply )
		ball:GetTable():SetAirResistance( resistance )

		numpad.OnDown( 	 ply, 	key_u, 	"Hoverball_Up", 	ball, true )
		numpad.OnUp( 	 ply, 	key_u, 	"Hoverball_Up", 	ball, false )
		
		numpad.OnDown( 	 ply, 	key_d, 	"Hoverball_Down", 	ball, true )
		numpad.OnUp( 	 ply, 	key_d, 	"Hoverball_Down", 	ball, false )

		if ( nocollide == true ) then ball:GetPhysicsObject():EnableCollisions( false ) end

		local ttable = 
		{
			key_d	= key_d,
			key_u 	= key_u,
			pl	= ply,
			nocollide = nocollide,
			speed = speed,
			resistance = resistance
		}

		table.Merge( ball:GetTable(), ttable )
		
		ply:AddCount( "hoverballs", ball )

		return ball
		
	end
	
	duplicator.RegisterEntityClass( "gmod_hoverball", MakeHoverBall, "Pos", "key_d", "key_u", "speed", "resistance", "Vel", "aVel", "frozen", "nocollide" )

end

function TOOL:Think()	
end
