/** 
 * 
 * Copyright 2004 Protique Ltd
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 * 
 **/
package org.activemq.service;

import javax.jms.JMSException;

/**
 * Represents a Queue with List like semantics, allowing addition and removal at
 * any point in the queue. Typically this will be implemented using some kind of LinkedList
 *
 * @version $Revision: 1.1.1.1 $
 */
public interface QueueList {
    Object[] EMPTY_ARRAY = {};

    /**
     * Returns the first element in this list.
     *
     * @return the first element in this list.
     */
    Object getFirst() throws JMSException;

    /**
     * Returns the last element in this list.
     *
     * @return the last element in this list.
     */
    Object getLast() throws JMSException;

    /**
     * Removes and returns the first element from this list.
     *
     * @return the first element from this list.
     */
    Object removeFirst() throws JMSException;

    /**
     * Move the head of the list to the back of the list
     */

    void rotate() throws JMSException;

    /**
     * Removes and returns the last element from this list.
     *
     * @return the last element from this list.
     */
    Object removeLast() throws JMSException;

    /**
     * Inserts the given element at the beginning of this list.
     *
     * @param o the element to be inserted at the beginning of this list.
     * @return the DefaultQueueListEntry
     */
    QueueListEntry addFirst(Object o) throws JMSException;

    /**
     * Appends the given element to the end of this list. (Identical in function to the <tt>add</tt> method; included
     * only for consistency.)
     *
     * @param o the element to be inserted at the end of this list.
     * @return the DefaultQueueListEntry
     */
    QueueListEntry addLast(Object o) throws JMSException;

    /**
     * Returns <tt>true</tt> if this list contains the specified element. More formally, returns <tt>true</tt> if
     * and only if this list contains at least one element <tt>e</tt> such that <tt>(o==null ? e==null
     * : o.equals(e))</tt>.
     *
     * @param o element whose presence in this list is to be tested.
     * @return <tt>true</tt> if this list contains the specified element.
     */
    boolean contains(Object o) throws JMSException;

    /**
     * Returns the number of elements in this list.
     *
     * @return the number of elements in this list.
     */
    int size() throws JMSException;

    /**
     * is the list empty?
     *
     * @return true if there are no elements in the list
     */
    boolean isEmpty() throws JMSException;

    /**
     * Appends the specified element to the end of this list.
     *
     * @param o element to be appended to this list.
     * @return the DefaultQueueListEntry
     */
    QueueListEntry add(Object o) throws JMSException;

    /**
     * Removes the first occurrence of the specified element in this list. If the list does not contain the element, it
     * is unchanged. More formally, removes the element with the lowest index <tt>i</tt> such that <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
     * (if such an element exists).
     *
     * @param o element to be removed from this list, if present.
     * @return <tt>true</tt> if the list contained the specified element.
     */
    boolean remove(Object o) throws JMSException;

    /**
     * Removes all of the elements from this list.
     */
    void clear() throws JMSException;

    /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of element to return.
     * @return the element at the specified position in this list.
     * @throws IndexOutOfBoundsException if the specified index is is out of range (<tt>index &lt; 0 || index &gt;= size()</tt>).
     */
    Object get(int index) throws JMSException;

    /**
     * Replaces the element at the specified position in this list with the specified element.
     *
     * @param index   index of element to replace.
     * @param element element to be stored at the specified position.
     * @return the element previously at the specified position.
     * @throws IndexOutOfBoundsException if the specified index is out of range (<tt>index &lt; 0 || index &gt;= size()</tt>).
     */
    Object set(int index, Object element) throws JMSException;

    /**
     * Inserts the specified element at the specified position in this list. Shifts the element currently at that
     * position (if any) and any subsequent elements to the right (adds one to their indices).
     *
     * @param index   index at which the specified element is to be inserted.
     * @param element element to be inserted.
     * @throws IndexOutOfBoundsException if the specified index is out of range (<tt>index &lt; 0 || index &gt; size()</tt>).
     */
    void add(int index, Object element) throws JMSException;

    /**
     * Removes the element at the specified position in this list. Shifts any subsequent elements to the left
     * (subtracts one from their indices). Returns the element that was removed from the list.
     *
     * @param index the index of the element to removed.
     * @return the element previously at the specified position.
     * @throws IndexOutOfBoundsException if the specified index is out of range (<tt>index &lt; 0 || index &gt;= size()</tt>).
     */
    Object remove(int index) throws JMSException;

    /**
     * Returns the index in this list of the first occurrence of the specified element, or -1 if the List does not
     * contain this element. More formally, returns the lowest index i such that <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     *
     * @param o element to search for.
     * @return the index in this list of the first occurrence of the specified element, or -1 if the list does not
     *         contain this element.
     */
    int indexOf(Object o) throws JMSException;

    /**
     * Returns the index in this list of the last occurrence of the specified element, or -1 if the list does not
     * contain this element. More formally, returns the highest index i such that <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     *
     * @param o element to search for.
     * @return the index in this list of the last occurrence of the specified element, or -1 if the list does not
     *         contain this element.
     */
    int lastIndexOf(Object o) throws JMSException;

    /**
     * Retrieve the first entry for the linked list
     *
     * @return first entry or null
     */
    QueueListEntry getFirstEntry() throws JMSException;

    /**
     * Retrieve the last entry for the linked list
     *
     * @return last entry or null
     */
    QueueListEntry getLastEntry() throws JMSException;

    /**
     * Retrieve the next entry after this entry
     *
     * @param node
     * @return
     */
    QueueListEntry getNextEntry(QueueListEntry node) throws JMSException;

    /**
     * Retrive the previous entry after this entry
     *
     * @param node
     * @return
     */
    QueueListEntry getPrevEntry(QueueListEntry node) throws JMSException;

    /**
     * Insert an Entry before this entry
     *
     * @param o    the elment to insert
     * @param node the Entry to insert the object before
     * @return
     */
    QueueListEntry addBefore(Object o, QueueListEntry node) throws JMSException;

    /**
     * Remove a DefaultQueueListEntry
     *
     * @param node the DefaultQueueListEntry
     */
    void remove(QueueListEntry node) throws JMSException;

    /**
     * Returns an array containing all of the elements in this list in the correct order.
     *
     * @return an array containing all of the elements in this list in the correct order.
     */
    Object[] toArray() throws JMSException;

}
