// 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 Equals extends ProcedureN
{
    public Object apply0 (Stack stack) throws SchemeException
    {
        throw new ArgumentCountException(this, 0, 0);
    }

    public Object apply1 (Stack stack) throws SchemeException
    {
        throw new ArgumentCountException(this, 1, 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 ((n2.longValue()   != n1.longValue()) &&
            (n2.doubleValue() != n1.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);

        long longResult = n1.longValue();
        double doubleResult = n2.doubleValue();

        if ((n2.longValue()   != longResult) &&
            (n2.doubleValue() != doubleResult))
        {
            return Boolean.FALSE;
        }

        if ((n3.longValue()   != longResult) &&
            (n3.doubleValue() != doubleResult))
        {
            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);

        long longResult = n1.longValue();
        double doubleResult = n2.doubleValue();

        if ((n2.longValue()   != longResult) &&
            (n2.doubleValue() != doubleResult))
        {
            return Boolean.FALSE;
        }

        if ((n3.longValue()   != longResult) &&
            (n3.doubleValue() != doubleResult))
        {
            return Boolean.FALSE;
        }

        if ((n4.longValue()   != longResult) &&
            (n4.doubleValue() != doubleResult))
        {
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    public Object applyN (int n, Stack stack) throws SchemeException
    {
        Number number       = Scheme.number(stack.array[stack.inUse-n],
                                            this);
        long   longResult   = number.longValue();
        double doubleResult = number.doubleValue();

        for (int i = 1; i <= n; i++) {
            number = Scheme.number(stack.array[stack.inUse-i], this);
            if ((number.longValue()   != longResult) &&
                (number.doubleValue() != doubleResult))
            {
                return Boolean.FALSE;
            }
        }
        return Boolean.TRUE;
    }
}
