local ents = ents
local pairs = pairs
local table = table
local tonumber = tonumber
local SERVER = SERVER
local duplicator = duplicator
local print = print
local numpad = numpad
local Msg = Msg

module("construct")

if SERVER then

	function SetPhysProp( pl, ent, Bone, motionb, gravityb, mass, dragb, drag, buoyancy, rotdamping, speeddamping, material )
		
		// Get the physics object
		local PhysBone = ent:GetPhysicsObjectNum( Bone )
		if ( !PhysBone:IsValid() ) then return end

		// Set the physics properties on the bone
		if (motionb != nil )	then PhysBone:EnableMotion( motionb ) end
		if (gravityb!= nil ) 	then PhysBone:EnableGravity( gravityb ) end
		if (mass!=nil)			then PhysBone:SetMass( mass ) end
		if (dragb!=nil)			then PhysBone:EnableDrag( dragb ) end
		if (drag!=nil)			then PhysBone:SetDragCoefficient( drag ) end
		if (buoyancy!=nil)		then PhysBone:SetBuoyancyRatio( buoyancy ) end
		if (rotdamping!=nil)	then PhysBone:SetDamping( PhysBone:GetSpeedDamping(), rotdamping ) end
		if (speeddamping!=nil)	then PhysBone:SetDamping( speeddamping, PhysBone:GetRotDamping() ) end
		if (material!=nil)		then PhysBone:SetMaterial( material ) end

		// Add the settings to the bone's table
		if not ent:GetTable().Bones then ent:GetTable().Bones = {} end
		if not ent:GetTable().Bones[Bone] then ent:GetTable().Bones[Bone] = {} end
		
		local btable = {
			motionb	=	motionb,
			gravityb =	gravityb,
			mass =		mass,
			dragb =		dragb,
			drag =		drag,
			buoyancy =	buoyancy,
			rotdamping =	rotdamping,
			speeddamping =	speeddamping,
			matrial = material
			}
			
		ent:GetTable().Bones[Bone].physprops = btable
		
		// HACK HACK
		// If we don't do this the prop will be motion enabled and will
		// slide through the world with no gravity.
		if ( !PhysBone:IsMoveable() ) then
		
			PhysBone:EnableMotion( true )
			PhysBone:EnableMotion( false )
		
		end

	end
	duplicator.RegisterEntityBoneModifier( "physprops",  SetPhysProp, "motionb", "gravityb", "mass", "dragb", "drag", "buoyancy", "rotdamping", "speeddamping", "material" )

	
	local function MagnetOff( pl, magnet )
	
		if ( !magnet || !magnet:IsValid() ) then return false end
		if ( magnet:GetTable().toggle != 0 ) then return true end
		
		magnet:Fire( "TurnOff", "" , 0 )
		
		return true

	end
	

	local function MagnetOn( pl, magnet )
	
		if ( !magnet || !magnet:IsValid() ) then return false end
		
		if ( magnet:GetTable().toggle != 0 ) then 
		
			magnet:GetTable().toggle_state = !magnet:GetTable().toggle_state
			
			if (magnet:GetTable().toggle_state) then magnet:Fire( "TurnOn", "" , 0 )
			else magnet:Fire( "TurnOff", "" , 0 ) end
				
			return true 
		
		end
		
		magnet:Fire( "TurnOn", "" , 0 )
		
		return true

	end
	
	numpad.Register( "MagnetOff", MagnetOff )
	numpad.Register( "MagnetOn", MagnetOn )
	
	function Magnet( pl, pos, angle, model, material, key, maxobjects, strength, nopull, allowrot, alwayson, toggle, Vel, aVel, frozen )
	
		local magnet = ents.Create("phys_magnet")
		magnet:SetPos(pos)
		magnet:SetAngles(angle)
		magnet:SetModel( model )
		magnet:SetMaterial( material )
					
		local spawnflags = 4
		if (nopull > 0) then		spawnflags = spawnflags - 4		end		// no pull required: remove the suck flag
		if (allowrot > 0) then		spawnflags = spawnflags + 8		end
					
		magnet:SetKeyValue( "maxobjects", maxobjects )
		magnet:SetKeyValue( "forcelimit", strength )
		magnet:SetKeyValue( "spawnflags", spawnflags )
		magnet:SetKeyValue( "overridescript", "surfaceprop,metal")
		magnet:SetKeyValue( "massScale", 0 )
		
		magnet:Activate()
		magnet:Spawn()
		
		if magnet:GetPhysicsObject():IsValid() then
			Phys = magnet:GetPhysicsObject()
			if Vel then Phys:SetVelocity(Vel) end
			if Vel then Phys:AddAngleVelocity(aVel) end
			Phys:EnableMotion(frozen != true)
		end
	
		if (alwayson > 0) then
			magnet:Input("TurnOn", nil, nil, nil)
		else
			magnet:Input("TurnOff", nil, nil, nil)
		end
		
		local mtable = {
			model = model,
			material = material,
			key = key,
			maxobjects = maxobjects,
			strength = strength,
			nopull = nopull,
			allowrot = allowrot,
			alwayson = alwayson,
			toggle = toggle
		}
		
		magnet:SetTable( mtable )
		
		numpad.OnDown( 	 pl, 	key, 	"MagnetOn", 	magnet )
		numpad.OnUp( 	 pl, 	key, 	"MagnetOff", 	magnet )
		
		return magnet
		
	end
	
	duplicator.RegisterEntityClass( "phys_magnet", Magnet, "pos", "angle", "model", "material", "key", "maxobjects", "strength", "nopull", "allowrot", "alwayson", "toggle", "Vel", "aVel", "frozen" )


end
