I=(S=Uno.Collision = function(){
}).prototype;

S.RayIntersectsSphere = function(ray, sphere, distance)
{
    var v = Uno.Float3.operator_Sub(ray.Position, sphere.Center);
    var b = Uno.Vector.Dot(v, ray.Direction);
    var c = Uno.Vector.Dot(v, v) - (sphere.Radius * sphere.Radius);

    if ((c > 0.0) && (b > 0.0))
    {
        distance(0.0);
        return false;
    }

    var discriminant = (b * b) - c;

    if (discriminant < 0.0)
    {
        distance(0.0);
        return false;
    }

    distance((-b) - Math.sqrt(discriminant));

    if (distance() < 0.0)
    {
        distance(0.0);
    }

    return true;
};

S.PlaneIntersectsSphere = function(plane, sphere)
{
    var distance = Uno.Vector.Dot(plane.Normal, sphere.Center);
    distance = distance + plane.D;

    if (distance > sphere.Radius)
    {
        return 1;
    }

    if (distance < (-sphere.Radius))
    {
        return 0;
    }

    return 2;
};

S.FrustumContainsSphere = function(frustum, sphere)
{
    var rn = Uno.Collision.PlaneIntersectsSphere(frustum.Near, sphere);

    if (rn == 1)
    {
        return 0;
    }
    else if (rn == 2)
    {
        return 2;
    }

    var rf = Uno.Collision.PlaneIntersectsSphere(frustum.Far, sphere);

    if (rf == 1)
    {
        return 0;
    }
    else if (rf == 2)
    {
        return 2;
    }

    var rt = Uno.Collision.PlaneIntersectsSphere(frustum.Top, sphere);

    if (rt == 1)
    {
        return 0;
    }
    else if (rt == 2)
    {
        return 2;
    }

    var rb = Uno.Collision.PlaneIntersectsSphere(frustum.Bottom, sphere);

    if (rb == 1)
    {
        return 0;
    }
    else if (rb == 2)
    {
        return 2;
    }

    var rl = Uno.Collision.PlaneIntersectsSphere(frustum.Left, sphere);

    if (rl == 1)
    {
        return 0;
    }
    else if (rl == 2)
    {
        return 2;
    }

    var rr = Uno.Collision.PlaneIntersectsSphere(frustum.Right, sphere);

    if (rr == 1)
    {
        return 0;
    }
    else if (rr == 2)
    {
        return 2;
    }

    return 1;
};
