package code.loop;

import java.util.*;

import code.space.*;
import code.term.*;
import code.stuff.*;

// MUST OPTIMIZE

/**
 * Description of the Class
 *
 * @author Sergio Antoy
 * @since June 17, 2003
 */
public class IOQueue {

    private final int queueMax = 3;
    private Vector queue = new Vector();


    /**
     * Sets the output attribute of the IOQueue object
     *
     * @param object The new output value
     */
    public synchronized void setOutput(Object object) {
        if (Tracer.output) {
            String string;
            if (object == null) {
                string = "End outputs";
            } else {
                string = "Enqueueing output " + ((Computation) object).getTerm();
            }
            Logger.logln(string);
        }
        queue.add(object);
        notify();
        while (queue.size() == queueMax) {
            try {
                wait();
            } catch (InterruptedException ex) {
                break;
            }
        }
    }


    /**
     * Gets the output attribute of the IOQueue object
     *
     * @return The output value
     */
    public synchronized Object getOutput() {
        while (queue.size() == 0) {
            try {
                wait();
            } catch (InterruptedException ex) {
                throw new RuntimeException
                        ("Output queue interrupted " + ex.getMessage());
            }
        }
        Object object = queue.remove(0);
        if (Tracer.output) {
            Term term = ((Computation) object).getTerm();
            Logger.logln("Dequeueing output " + term);
        }
        notify();
        return object;
    }


    /**
     * Description of the Method
     */
    public synchronized void clear() {
        while (queue.size() > 0) {
            queue.remove(0);
        }
        if (Tracer.output) {
            Logger.logln("Clearing all outputs");
        }
        notify();
    }


    /**
     * Description of the Method
     *
     * @return Description of the Return Value
     */
    public synchronized int size() {
        return queue.size();
    }


    /**
     * Description of the Method
     */
    public void debug() {
        for (int i = 0; i < queue.size(); i++) {
            System.out.print("IOQueue[" + i + "]=");
            Computation computation = (Computation) queue.elementAt(i);
            if (computation == null) {
                System.out.println("*");
            } else {
                System.out.println(computation.getTerm().toString());
            }
        }
    }

}
