
TOOL.ClientConVar[ "keyup" ] = "9"
TOOL.ClientConVar[ "keydn" ] = "6"
TOOL.ClientConVar[ "effect" ] = "1"
TOOL.ClientConVar[ "altitude" ] = "32"

cleanup.Register( "hoverballs" )

function TOOL:LeftClick( trace, _altitude )

	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 effect		= tonumber(	self:GetClientInfo( "effect" ) )
	local altitude		= _altitude or tonumber(	self:GetClientInfo( "altitude" ) )
	
	if ( !self:GetSWEP():CheckLimit( "hoverballs" ) ) then return false end
	
	if ( trace.Entity:IsWorld() ) then
	
		trace.HitPos = trace.HitPos + trace.HitNormal * 8
	
	end

	ball = MakeHoverBall( ply, trace.HitPos, key_d, key_u, effect, altitude, trace.Entity:IsValid() )
	
	local const, nocollide
	
	// Don't weld to world
	if ( trace.Entity:IsValid() ) then
	
		const 		= constraint.Weld( trace.Entity, ball, trace.PhysicsBone, 0, 0, systemmanager )
		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:AddCount( "hoverballs", ball )
	
	ply:AddCleanup( "hoverballs", ball )
	ply:AddCleanup( "hoverballs", const )
	ply:AddCleanup( "hoverballs", nocollide )
	
	return true

end

function TOOL:RightClick( trace )

	local StartPos = trace.HitPos
	
	local tr 	= {}
	tr.start	= StartPos
	tr.endpos	= StartPos - Vector( 0, 0, 40960 )
	
	tr.mask		= MASK_NPCWORLDSTATIC
	
	local trace2	= util.TraceLine( tr )
	
	return self:LeftClick( trace, (trace.HitPos - trace2.HitPos):Length() )
	
end

if (SERVER) then

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

		ball:SetPos( Pos )
		ball:Spawn()

		ball:GetTable():SetEffect( effect )
		ball:GetTable():SetAltitude( altitude )

		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,
			effect	= effect,
			altitude = altitude,
			nocollide = nocollide
		}

		tablex.Merge( ball:GetTable(), ttable )

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

end

function TOOL:Think()	
end
