package meerkat.voting.gui.ui;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * A special kind of an ArrayBlockingQueue.
 * It is only of size 1, meaning it keeps only one element at most at every point of time.
 * The trample function is similar to put/add except that it overrides the previously kept element.
 * Other functions are similar to the matching functions in ArrayBlockingQueue.
 * For instance, the offer function only "recommends" another element to keep, but if there is a stored element
 * already, than this recommendation is ignored.
 */
public class CommandPend<T> {

    private ArrayBlockingQueue<T> queue;

    public CommandPend () {
        queue = new ArrayBlockingQueue<>(1);
    }

    /**
     * overrides the current kept command
     * @param cmd a command to override the previous one (if existed)
     */
    synchronized public void trample (T cmd) {
        queue.clear();
        queue.add(cmd);
    }

    /**
     * keeps the offered command, but only if there is no other command to handle right now
     * @param cmd a command to keep if we currently do not have another
     */
    synchronized public void offer (T cmd) {
        queue.offer(cmd);
    }

    /**
     * Retrieves and removes the kept command, waiting if necessary until a command becomes available.
     * @return the kept command
     * @throws InterruptedException
     */
    public T take() throws InterruptedException {
        return queue.take();
    }

    /**
     * removes the kept command
     */
    synchronized public void clear () {
        queue.clear();
    }
}
