
-- Physics entity.
PhysEntity = {};

-- Create.
function PhysEntity:new( iobj )
    local obj = {};
    obj.index = nil;
    
    if( type( iobj ) == "number" ) then
        if( iobj > 0 ) then
            obj.index = iobj;
        end
    elseif( type( iobj ) == "table" ) then
        obj.index = iobj.index;
    end
    
    setmetatable( obj, self );
    self.__index = self;

    return obj;
end

-- Check entity.
function PhysEntity:Exists( )
    if( self.index ~= nil and _EntExists( self.index ) ) then
        return true;
    end
    return false;
end

-- Apply force centered.
function PhysEntity:ApplyLocalForce( force )
    if( not self:Exists() ) then
        return;
    end
    
    -- Legacy.
    if( type( force ) == "userdata" ) then
        _phys.ApplyForceCenter( self.index, force );
    else
        _phys.ApplyForceCenter( self.index, force:GetVector3() );
    end
end

-- Apply force offset.
function PhysEntity:ApplyWorldForce( force, pos )
    if( not self:Exists() ) then
        return;
    end
    
    -- Legacy.
    local vForce = force;
    if( type( vForce ) == "userdata" ) then
        vForce = Vector:new( vForce );
    end
    local vPos = pos;
    if( type( vPos ) == "userdata" ) then
        vPos = Vector:new( vPos );
    end
    
    -- Legacy.
    _phys.ApplyForceOffset( self.index, vForce:GetVector3(), vPos:GetVector3() );
end

-- Apply torque
function PhysEntity:ApplyTorque( force )
    if( not self:Exists() ) then
        return;
    end
    
    -- Legacy.
    if( type( force ) == "userdata" ) then
        _phys.ApplyTorqueCenter( self.index, force );
    else
        _phys.ApplyTorqueCenter( self.index, force:GetVector3() );
    end
end

-- Enable drag.
function PhysEntity:EnableDrag( enabled )
    if( not self:Exists() ) then
        return;
    end
    
    _phys.EnableDrag( self.index, enabled );
end

-- Enable motion.
function PhysEntity:EnableMotion( enabled )
    if( not self:Exists() ) then
        return;
    end
    
    _phys.EnableMotion( self.index, enabled );
end

-- Enable gravity.
function PhysEntity:EnableGravity( enabled )
    if( not self:Exists() ) then
        return;
    end
    
    _phys.EnableGravity( self.index, enabled );
end

-- Enable collisions.
function PhysEntity:EnableCollisions( enabled )
    if( not self:Exists() ) then
        return;
    end
    
    _phys.EnableCollisions( self.index, enabled );
end

-- Get mass.
function PhysEntity:GetMass( )
    if( not self:Exists() ) then
        return nil;
    end
    
    return _phys.GetMass( self.index );
end

-- Set mass.
function PhysEntity:SetMass( mass )
    if( not self:Exists() ) then
        return nil;
    end
    
    return _phys.SetMass( self.index, mass );
end

-- Sleep.
function PhysEntity:Sleep( )
    if( not self:Exists() ) then
        return;
    end
    
    _phys.Sleep( self.index );
end

-- Wake.
function PhysEntity:Wake( )
    if( not self:Exists() ) then
        return;
    end
    
    _phys.Wake( self.index );
end

-- IsAsleep.
function PhysEntity:IsAsleep( )
    if( not self:Exists() ) then
        return nil;
    end
    
    return _phys.IsAsleep( self.index );
end

-- Set constraint entities..
function PhysEntity:SetConstraintEntities( enta, entb )
    if( not self:Exists() ) then
        return;
    end
    
    local a = enta;
    if( type(enta) == "table" ) then
        a = enta.index;
    end
    
    local b = entb;
    if( type(entb) == "table" ) then
        b = entb.index;
    end
    
    _phys.SetConstraintSents( self.index, a, b );
end
