// Copyright (c) 1996-2002 Brian D. Carlstrom

package bdc.scheme.procedure;

import bdc.scheme.Stack;
import bdc.scheme.Scheme;
import bdc.scheme.SchemeException;
import bdc.scheme.exception.ArgumentCountException;
import bdc.scheme.expression.ProcedureN;

/**
    (< x y &hellip;)
*/
public class LessThan extends ProcedureN
{
    public Object apply0 (Stack stack) throws SchemeException
    {
        throw new ArgumentCountException(this, 2, 0);
    }

    public Object apply1 (Stack stack) throws SchemeException
    {
        throw new ArgumentCountException(this, 2, 1);
    }

    public Object apply2 (Stack stack) throws SchemeException
    {
        Object o1 = stack.array[stack.inUse-1];
        Object o2 = stack.array[stack.inUse-2];
        Number n1  = Scheme.number(o1, this);
        Number n2  = Scheme.number(o2, this);

        if (!((n1.longValue()    < n2.longValue()) ||
              (n1.doubleValue() < n2.doubleValue())))
        {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    public Object apply3 (Stack stack) throws SchemeException
    {
        Object o1 = stack.array[stack.inUse-1];
        Object o2 = stack.array[stack.inUse-2];
        Object o3 = stack.array[stack.inUse-3];
        Number n1  = Scheme.number(o1, this);
        Number n2  = Scheme.number(o2, this);
        Number n3  = Scheme.number(o3, this);

        if (!((n1.longValue()    < n2.longValue()) ||
              (n1.doubleValue() < n2.doubleValue())))
        {
            return Boolean.FALSE;
        }

        if (!((n2.longValue()    < n3.longValue()) ||
              (n2.doubleValue() < n3.doubleValue())))
        {
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    public Object apply4 (Stack stack) throws SchemeException
    {
        Object o1 = stack.array[stack.inUse-1];
        Object o2 = stack.array[stack.inUse-2];
        Object o3 = stack.array[stack.inUse-3];
        Object o4 = stack.array[stack.inUse-4];
        Number n1  = Scheme.number(o1, this);
        Number n2  = Scheme.number(o2, this);
        Number n3  = Scheme.number(o3, this);
        Number n4  = Scheme.number(o4, this);

        if (!((n1.longValue()    < n2.longValue()) ||
              (n1.doubleValue() < n2.doubleValue())))
        {
            return Boolean.FALSE;
        }

        if (!((n2.longValue()    < n3.longValue()) ||
              (n2.doubleValue() < n3.doubleValue())))
        {
            return Boolean.FALSE;
        }

        if (!((n3.longValue()    < n4.longValue()) ||
              (n3.doubleValue() < n4.doubleValue())))
        {
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    public Object applyN (int n, Stack stack) throws SchemeException
    {
        Number number       = Scheme.number(stack.array[stack.inUse-1],
                                            this);
        long   longResult   = number.longValue();
        double doubleResult = number.doubleValue();

        for (int i = 2; i <= n; i++) {
            number = Scheme.number(stack.array[stack.inUse-i], this);

            if (!((longResult   < number.longValue()) ||
                  (doubleResult < number.doubleValue())))
            {
                return Boolean.FALSE;
            }

            longResult   = number.longValue();
            doubleResult = number.doubleValue();
        }
        return Boolean.TRUE;
    }
}
