/*::.
==================================================================================================================================
=================================================¦ Copyright © 2001 Allen Baker ¦=================================================
                                                 +------------------------------+
File:       Queue.java
Originator: Allen Baker (2001.09.02)
LayoutRev:  5
================================================================================================================================== */



/*.
==========================================================================================
Package
------------------------------------------------------------------------------------------ */
package cosmicabyss.com.lib;



/*.
==========================================================================================
Imports
------------------------------------------------------------------------------------------ */
import java.io.*;
import java.util.*;



/*::
======================================================================================================================== *//**
This class ...

<P>
   <DL>
      <DT>
         <B>
            Example usage:
         </B>
         <DD>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  =========================================================================================
                  put strings into a Queue and show that they are removed in the same
                  order that they were put in the Queue.
                  -----------------------------------------------------------------------------------------
                  Queue<XString>  myQueue = new Queue<XString>();

                  for (int i=0; i<50; i++)
                     {
                     myQueue.add(new XString("string_" + i));
                     }

                  System.out.println("myQueue contains " + myQueue.size() + " objects");

                  XString  s;
                  while ((s = myQueue.next()) != null)
                     {
                     System.out.println(s);
                     }
               </PRE>
            </BLOCKQUOTE>
         </DD>
      </DT>
      <DT>
         <B>
            View Source:
         </B>
         <DD>
            <A href="Queue.java.html">
               Queue.java
            </A>
         </DD>
      </DT>
      <DT>
         <B>
            Author:
         </B>
         <DD>
            <A href="mailto:sourcecode.v01@cosmicabyss.com">
               Allen Baker
            </A>
         </DD>
      </DT>
   </DL>
*//*
======================================================================================================================== */
public class Queue<Type>
   {



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method returns a count of the number of objects in the Queue.

   <P><B>Implementation: </B><A HREF="Queue.java.html#000">View source</A>

   @return
      A count of the number of objects in the Queue.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public int size()
      {
      return iList.size();
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method returns true if the queue is empty.

   <P><B>Implementation: </B><A HREF="Queue.java.html#001">View source</A>

   @return
      This method returns true if the queue is empty, otherwise, it returns false.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public boolean isEmpty()
      {
      return (iList.size() == 0);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds an object to the end of the Queue.

   <P><B>Implementation: </B><A HREF="Queue.java.html#002">View source</A>

   @return
      A reference to this object

   @param
      pObj is the object reference that this method adds to the end of the Queue.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Queue<Type> add(Type pObj)
      {
      return (iSync)? syncAdd(pObj) : nosyncAdd(pObj);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method removes the object at the front of the Queue and returns it.

   <P><B>Implementation: </B><A HREF="Queue.java.html#003">View source</A>

   @return
      The object at the front of the Queue or<br> null if the Queue is empty.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Type next()
      {
      return (iSync)? syncNext() : nosyncNext();
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method returns a copy of the object at the front of the Queue without removing it.

   <P><B>Implementation: </B><A HREF="Queue.java.html#004">View source</A>

   @return
      A copy of the object at the front of the Queue or<br> null if the Queue is empty.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Type peek()
      {
      return (iSync)? syncPeek() : nosyncPeek();
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method turns on synchronized access to the Queue. After this method returns all subsequent
   invocations of the add() and next() methods are synchronized.

   <P><B>Implementation: </B><A HREF="Queue.java.html#005">View source</A>

   @return
      A reference to this object
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Queue<Type> sync()
      {
      iSync = true;
      return this;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method turns off synchronized access to the Queue. After this method returns all subsequent
   invocations of the add() and next() methods are not synchronized.

   <P><B>Implementation: </B><A HREF="Queue.java.html#006">View source</A>

   @return
      A reference to this object
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Queue<Type> noSync()
      {
      iSync = false;
      return this;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method sets the ConsoleStream for this object.

   <P><B>Implementation: </B><A HREF="Queue.java.html#007">View source</A>

   @return
      A reference to this object

   @param
      pConsole is a ConsoleStream through which this objects sends its output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Queue setOut(ConsoleStream pConsole)
      {
      cOut = pConsole;
      return this;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This boilerplate method is used for testing an instantiated object of this class and may include any
   code the developer chooses.

   <P><B>Implementation: </B><A HREF="Queue.java.html#008">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Queue test() throws Exception
      {
      cOut.titledPrintf
         (
         "\"HELLO WORLD!\"",
         "%s  %s  %s",
         "I'm an object of the", CLASS_NAME, "class, and I approved this message."
         );
      return this;
      }



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Protected  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Private  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*.
   ==========================================================================================
   Class Constants
      CLASS_NAME:
         The name of this class
      DFLT_LINE_LEN:
         The default line length for word wrapping
   ------------------------------------------------------------------------------------------ */
   private static final XString  CLASS_NAME    = new XString(Queue.class.getName());
   private static final int      DFLT_LINE_LEN = ConsoleMessage.defaultLineLength();
   /*.
   ==========================================================================================
   Class variables
      cOut:
         Console output.
   ------------------------------------------------------------------------------------------ */
   private static ConsoleStream  cOut = ConsoleStream.getSingleton();
   /*.
   ==========================================================================================
   Instance variables
      iList:
         Where the items in the queue are stored
      iSync:
         Flag to turn on synchronized access to the queue
   ------------------------------------------------------------------------------------------ */
   private List<Type>  iList = new ArrayList<Type>();
   private boolean     iSync = false;



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds an object to the end of the Queue.

   <P><B>Implementation: </B><A HREF="Queue.java.html#009">View source</A>

   @return
      A reference to this object

   @param
      pObj is the object reference that this method adds to the end of the Queue.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Queue<Type> nosyncAdd(Type pObj)
      {
      iList.add(pObj);
      return this;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method removes the object at the front of the Queue and returns it.

   <P><B>Implementation: </B><A HREF="Queue.java.html#010">View source</A>

   @return
      The object at the front of the Queue or<br> null if the Queue is empty.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Type nosyncNext()
      {
      if (iList.size() == 0)
         {
         return null;
         }
      return iList.remove(0);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method returns a copy of the object at the front of the Queue without removing it.

   <P><B>Implementation: </B><A HREF="Queue.java.html#011">View source</A>

   @return
      A copy of the object at the front of the Queue or<br> null if the Queue is empty.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public Type nosyncPeek()
      {
      if (iList.size() == 0)
         {
         return null;
         }
      return iList.get(0);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This <B>synchronized</B> method adds an object to the end of the Queue.

   <P><B>Implementation: </B><A HREF="Queue.java.html#012">View source</A>

   @return
      A reference to this object

   @param
      pObj is the object reference that this method adds to the end of the Queue.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public synchronized Queue<Type> syncAdd(Type pObj)
      {
      return nosyncAdd(pObj);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This <B>synchronized</B> method removes the object at the front of the Queue and returns it.

   <P><B>Implementation: </B><A HREF="Queue.java.html#013">View source</A>

   @return
      The object at the front of the Queue or<br> null if the Queue is empty.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public synchronized Type syncNext()
      {
      return nosyncNext();
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method returns a copy of the object at the front of the Queue without removing it.

   <P><B>Implementation: </B><A HREF="Queue.java.html#014">View source</A>

   @return
      A copy of the object at the front of the Queue or<br> null if the Queue is empty.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public synchronized Type syncPeek()
      {
      return nosyncPeek();
      }



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Inner Classes  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Public Static Methods  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method allows this class file to be unit tested as a standalone application. It's the method
   that's called when the class is invoked from the command line by using the java application launcher
   - "java". Main() is not a required method, but the practice of putting one in each class and
   wrapping class test code within it allows easy unit testing of the class; and main does not need to
   be removed when testing is complete.

   <P>
      <DL>
         <DT>
            <B>
               Command line usage:
            </B>
            <DD>
               Java cosmicabyss.com.lib.Queue
            </DD>
         </DT>
      </DL>

   <P><B>Implementation: </B><A HREF="Queue.java.html#015">View source</A>

   @param
      pArgs contains the command line arguments with which this class was invoked as an application.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static void main(String[] pArgs) throws Exception
      {
      /*.
      ==========================================================================================
      Greetings !
      ------------------------------------------------------------------------------------------ */
      cOut.banner(CLASS_NAME);
      /*.
      ==========================================================================================
      Create an object and send its output to the ConsoleStream
      ------------------------------------------------------------------------------------------ */
      Queue  obj = new Queue();
      /*.
      ==========================================================================================
      Test code
      ------------------------------------------------------------------------------------------ */
      obj.test();
      /*.
      ==========================================================================================
      Put strings into a Queue and show that they are removed in the same order that they were
      put in the Queue.
      ------------------------------------------------------------------------------------------ */
      Queue<XString>  myQueue = new Queue<XString>();

      for (int i=0; i<50; i++)
         {
         myQueue.add(new XString("string_" + i));
         }

      cOut.println("myQueue contains " + myQueue.size() + " objects");

      XString  s;
      while ((s = myQueue.next()) != null)
         {
         cOut.println(s);
         }
      }



   }  // class Queue



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Notes  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */