
TOOL.ClientConVar[ "ropelength" ]	= "64"
TOOL.ClientConVar[ "ropematerial" ]	= "cable/rope"
TOOL.ClientConVar[ "force" ]		= "500"

TOOL.ClientConVar[ "r" ]		= "255"
TOOL.ClientConVar[ "g" ]		= "255"
TOOL.ClientConVar[ "b" ]		= "0"

TOOL.ClientConVar[ "skin" ]		= "models/balloon/balloon"

cleanup.Register( "balloons" )

function TOOL:LeftClick( trace, attach )

	if trace.Entity && trace.Entity:IsPlayer() then return false end
	if (CLIENT) then return true end
	if (attach == nil) then attach = true end
	
	// If there's no physics object then we can't constraint it!
	if ( SERVER && attach && !util.IsValidPhysicsObject( trace.Entity, trace.PhysicsBone ) ) then return false end
	
	local ply = self:GetOwner()
	
	if ( !self:GetSWEP():CheckLimit( "balloons" ) ) then return false end
	
	if ( trace.Entity:GetClass() == "gmod_balloon" && trace.Entity:GetTable().Player == ply ) then
		local force 	= tonumber( self:GetClientInfo( "force" ) )
		trace.Entity:GetTable():SetForce( force )
		trace.Entity:GetPhysicsObject():Wake()
		return true
	end
	
	local length 			= tonumber( self:GetClientInfo( "ropelength" ) )
	local material 			= self:GetClientInfo( "ropematerial" )
	local force 			= tonumber( self:GetClientInfo( "force" ) )
	local r 				= tonumber( self:GetClientInfo( "r" ) )
	local g 				= tonumber( self:GetClientInfo( "g" ) )
	local b 				= tonumber( self:GetClientInfo( "b" ) )
	local skin 				= self:GetClientInfo( "skin" )
	
	if (skin != "models/balloon/balloon" &&
		skin != "models/balloon/balloon_hl2") then
		
		r = 255
		g = 255
		b = 255
		
	end

	local Pos = trace.HitPos + trace.HitNormal * 10
	balloon = MakeBalloon( ply, Pos, Angle(0), r, g, b, force, skin )

	undo.Create("Balloon")
	undo.AddEntity( balloon )

	if (attach) then
	
		// The real model should have an attachment!
		local attachpoint = Pos + Vector( 0, 0, -10 )
			
		local LPos1 = balloon:WorldToLocal( attachpoint )
		local LPos2 = trace.Entity:WorldToLocal( trace.HitPos )
		
		if (trace.Entity:IsValid()) then
			
			local phys = trace.Entity:GetPhysicsObjectNum( trace.PhysicsBone )
			if (phys:IsValid()) then
				LPos2 = phys:WorldToLocal( trace.HitPos )
			end
		
		end
		
		local constraint, rope = constraint.Rope( balloon, trace.Entity, 
												0, trace.PhysicsBone, 
												LPos1, LPos2, 
												0,length,
												0, 
												1.5, 
												material, 
												nil )

		undo.AddEntity( rope )
		undo.AddEntity( constraint )
		ply:AddCleanup( "balloons", rope )
		ply:AddCleanup( "balloons", constraint )
	end
	
	undo.SetPlayer( ply )
	undo.Finish()
	
	
	ply:AddCleanup( "balloons", balloon )

	return true

end

function TOOL:RightClick( trace )

	return self:LeftClick( trace, false )

end

function MakeBalloon(pl, Pos, Ang, r, g, b, force, skin, vel, avel, frozen)

	if ( !pl:CheckLimit( "hoverballs" ) ) then return nil end

	local balloon = ents.Create( "gmod_balloon" )
	if (!balloon:IsValid()) then return end
		balloon:SetPos( Pos )
		balloon:SetAngles( Ang )
	balloon:Spawn()

	if balloon:GetPhysicsObject():IsValid() then
		Phys = balloon:GetPhysicsObject()
		if Vel then Phys:SetVelocity(Vel) end
		if Vel then Phys:AddAngleVelocity(aVel) end
		Phys:EnableMotion(frozen != true)
	end

	balloon:SetRenderMode( RENDERMODE_TRANSALPHA )
	balloon:SetColor( r, g, b, 255 )
	balloon:GetTable():SetForce( force )
	balloon:GetTable():SetPlayer( pl )
	
	balloon:SetMaterial( skin )
	
	local btable = {
		Player = pl,
		r = r,
		g = g,
		b = b,

		skin = skin,
		force = force
		}

	table.Merge(balloon:GetTable(), btable )
	
	
	pl:AddCount( "balloons", balloon )
	
	return balloon

end

duplicator.RegisterEntityClass( "gmod_balloon", MakeBalloon, "Pos", "Ang", "r", "g", "b", "force", "skin", "Vel", "aVel", "frozen" )
