/***********************************************************************

GECCO, a platform for command and control gaming

Copyright (C) 2001 Henrik Bäärnhielm, Andreas Enblom, Niklas
Hallenfur, Karl Hasselström, Henrik Hägerström, Oskar Linde, Jing Fu
Zi and Jon Åslund

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.

***********************************************************************/

package gecco.client;

import java.util.*;

/**
 *  This is a Queue (with methods get, peek, put, remove, empty and isEmpty)
 *  that contains actions. All elements currently in the queue are accessible
 *  via the actions() method.
 *
 * @author     Andreas Enblom
 * @created    June 27, 2001
 */
public class ActionQueue {
    /**
     *  Description of the Field
     */
    private QueueNode first = null;
    /**
     *  Description of the Field
     */
    private QueueNode last = null;


    /**
     *  Description of the Method
     *
     * @return    Description of the Returned Value
     */
    public Action get() {
        if (first == null) {
            return null;
        }
        QueueNode qn = first;
        first = qn.getNext();
        if (first == null) {
            last = null;
        }
        return qn.getAction();
    }


    /**
     *  Gets the Empty attribute of the ActionQueue object
     *
     * @return    The Empty value
     */
    public boolean isEmpty() {
        return (first == null);
    }


    /**
     *  Description of the Method
     *
     * @return    Description of the Returned Value
     */
    public Action peek() {
        if (first == null) {
            return null;
        }
        return first.getAction();
    }


    /**
     *  Description of the Method
     *
     * @param  a  Description of Parameter
     */
    public void put(Action a) {
        QueueNode qn = new QueueNode(a);
        if (last == null) {
            first = last = qn;
        } else {
            last.setNext(qn);
            last = qn;
        }
    }


    /**
     *  Description of the Method
     *
     * @param  a  Description of Parameter
     */
    public void remove(Action a) {
        if (a == null) {
            return;
        }
        if (a == first.getAction()) {
            first = first.getNext();
            return;
        }
        QueueNode parent = first;
        QueueNode current = first.getNext();
        while ((current != null) && (current.getAction() != a)) {
            parent = current;
            current = current.getNext();
        }
        if (current != null) {
            parent.setNext(current.getNext());
        }
    }


    /**
     *  Description of the Method
     */
    public void empty() {
        first = null;
        last = null;
    }


    /**
     *  Returns a Vector with the actions that are currently in the queue.
     *
     * @return    Description of the Returned Value
     */
    public Vector actions() {
        Vector v = new Vector();
        QueueNode qn = first;
        while (qn != null) {
            v.addElement(qn.getAction());
            qn = qn.getNext();
        }
        return v;
    }


    /**
     *  An element in the queue.
     *
     * @author     d98-kha
     * @created    June 27, 2001
     */
    private class QueueNode {
        /**
         *  Description of the Field
         */
        public Action action = null;
        /**
         *  Description of the Field
         */
        public QueueNode next = null;


        /**
         *  Constructor for the QueueNode object
         *
         * @param  a  Description of Parameter
         */
        public QueueNode(Action a) {
            action = a;
        }


        /**
         *  Sets the Next attribute of the QueueNode object
         *
         * @param  qn  The new Next value
         */
        public void setNext(QueueNode qn) {
            next = qn;
        }


        /**
         *  Gets the Action attribute of the QueueNode object
         *
         * @return    The Action value
         */
        public Action getAction() {
            return action;
        }


        /**
         *  Gets the Next attribute of the QueueNode object
         *
         * @return    The Next value
         */
        public QueueNode getNext() {
            return next;
        }
    }
}
