TOOL.ClientConVar[ "locked" ] 	= "0"
TOOL.ClientConVar[ "key" ] 		= "0"

cleanup.Register( "cameras" )

GAMEMODE.CameraList = GAMEMODE.CameraList or {}

function TOOL:LeftClick( trace, Tracking )

	local Tracking = Tracking or false
	
	local key			= tonumber(	self:GetClientInfo( "key" ) )
	if (key == -1) then return false end
	
	if (CLIENT) then return true end
	
	local ply 			= self:GetOwner()
	local locked		= tonumber(	self:GetClientInfo( "locked" ) )
	
	local pid 					= ply:UniqueID()
	GAMEMODE.CameraList[ pid ] 	= GAMEMODE.CameraList[ pid ] or {}
	local CameraList = GAMEMODE.CameraList[ pid ]
	
	local Pos = trace.StartPos// + trace.Normal * 16
	
	// If the camera already exists then just move it into position
	if (CameraList[ key ] && CameraList[ key ] != NULL ) then
	
		local ent = CameraList[ key ]
		
		// Remove all constraints
		constraint.RemoveAll( ent )

		ent:SetPos( Pos )
		ent:SetAngles( ply:EyeAngles() )
		
		local phys = ent:GetPhysicsObject()
		if (phys:IsValid()) then phys:Sleep() end
		
		ent:GetTable():SetLocked( locked )
		ent:GetTable():SetTracking( NULL, Vector( 0,0,0 ))
		
		return true, ent
		
	end
	
	local camera = ents.Create( "gmod_cameraprop" )
	if (!camera:IsValid()) then return false end
		
		camera:SetAngles( ply:EyeAngles() )
		camera:SetPos( Pos )
		camera:Spawn()
		
		camera:GetTable():SetKey( key )
		camera:GetTable():SetPlayer( ply )
		camera:GetTable():SetLocked( locked )

		numpad.OnDown(	ply,		key, 	"Camera_Toggle", 	camera )
		
		camera:GetTable():SetTracking( NULL, Vector(0) )
	
	undo.Create("Camera")
		undo.AddEntity( camera )
		undo.SetPlayer( ply )
	undo.Finish()
	
	ply:AddCleanup( "camera", camera )

	
	CameraList[ key ] = camera
	
	return true, camera

end

function TOOL:RightClick( trace )

	_, camera = self:LeftClick( trace, true )
	
	if (CLIENT) then return true end

	if ( !camera || !camera:IsValid() ) then return end
	
	if ( trace.Entity:IsWorld() ) then
	
		trace.Entity = self:GetOwner()
		trace.HitPos = self:GetOwner():GetPos()
	
	end

	camera:GetTable():SetTracking( trace.Entity, trace.Entity:WorldToLocal( trace.HitPos ))
	
	return true
	
end
