/*::.
==================================================================================================================================
=================================================¦ Copyright © 2008 Allen Baker ¦=================================================
                                                 +------------------------------+
File:       CircularArrayList.java
Originator: Allen Baker (2008.12.12 19:37)
LayoutRev:  5
================================================================================================================================== */



package cosmicabyss.com.lib;

import java.io.*;
import java.util.*;



/*::
======================================================================================================================== *//**
Instances of this class are circular buffers. A circular buffer or ring buffer is a data structure that uses a single,
fixed-size buffer as if it were connected end-to-end. When the buffer is filled, new data is written starting at the
beginning of the buffer and overwriting the old. This structure lends itself easily to buffering data streams.<P>

The buffer's size is fixed at the time of instantiation. It can be adjusted down only via the trimToSize() method and
can be adjusted up only via the ensureCapacity() method.<P>

The behavior of this implementation is similar to a queue. The oldest element of the buffer is always the element at
index 0. The newest element of the buffer is always the element at index size()-1. Using the "insert" methods --
add(index,object) and addAll(index,collection) -- alters this oldest/newest behavior in the expected way when elements
are inserted between the oldest and newest elements.

<P>
   <DL>
      <DT>
         <B>
            Example usage:
         </B>
         <DD>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  no example provided
               </PRE>
            </BLOCKQUOTE>
         </DD>
      </DT>
      <DT>
         <B>
            View Source:
         </B>
         <DD>
            <A href="CircularArrayList.java.html">
               CircularArrayList.java
            </A>
         </DD>
      </DT>
      <DT>
         <B>
            Author:
         </B>
         <DD>
            <A href="mailto:sourcecode.v01@cosmicabyss.com">
               Allen Baker
            </A>
         </DD>
      </DT>
   </DL>
*//*
======================================================================================================================== */
public class CircularArrayList<Type> extends ArrayList<Type>
   {



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Public Classes, Constants, and Variables  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Inner Classes  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Class Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Class Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Instance Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Instance Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Protected Classes, Constants, and Variables  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Inner Classes  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Class Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Class Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Instance Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Instance Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Private Classes, Constants, and Variables  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Inner Classes  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  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(CircularArrayList.class.getName());
   private static final int      DFLT_LINE_LEN = ConsoleMessage.defaultLineLength();
   /*.
   ==========================================================================================
   ------------------------------------------------------------------------------------------ */
   private static final int  DFLT_SIZE = 10;



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Class Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*.
   ==========================================================================================
   cOut:
      Console output.
   ------------------------------------------------------------------------------------------ */
   private static ConsoleStream  cOut = ConsoleStream.getSingleton();



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Instance Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Instance Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   private int  iMaxCapacity = 0;



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



   static
      {
      /*.
      ==========================================================================================
      Make sure all the class constants and variables are initialized the first time the JVM
      loads this class code and before anything else in this class is accessed
      ------------------------------------------------------------------------------------------ */
      initializeClassConstantsAndVariables();
      }



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



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Constructors  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Instance Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method initializes all the instance constants and variables

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

   *//*
   ---------------------------------------------------------------------------------------------------- */
   private boolean initializeInstanceConstantsAndVariables() throws Exception
      {
      boolean  successCode = true;

      if (successCode)
         {
         }
      return successCode;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method initializes all the class constants and variables

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

   *//*
   ---------------------------------------------------------------------------------------------------- */
   private static void initializeClassConstantsAndVariables()
      {
      }



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Class Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



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



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Constructors  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Instance Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Class Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



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



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Constructors  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates a CircularArrayList class object. Since the size of the buffer is not specified
   as a parameter in this constructor, the size is set to the default size of 10.

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

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CircularArrayList() throws Exception
      {
      super();
      iMaxCapacity = DFLT_SIZE;
      initializeInstanceConstantsAndVariables();
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates a CircularArrayList class object. The buffer size is set to pSize.

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

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CircularArrayList(int pSize) throws Exception
      {
      super(pSize);
      iMaxCapacity = pSize;
      initializeInstanceConstantsAndVariables();
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates a CircularArrayList class object. The buffer size is set to the size of
   pCollection.

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

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CircularArrayList(Collection<? extends Type> pCollection) throws Exception
      {
      super(pCollection);
      iMaxCapacity = super.size();
      initializeInstanceConstantsAndVariables();
      }



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Instance Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds a new object to the buffer. When the buffer reaches its capacity, adding a new
   object will result in the overwriting of the oldest object in the buffer. The next oldest object is
   then set to be the one in the element at array index 0.

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

   @return
      A reference to this object

   @param
      pConsole is a ConsoleStream through which this objects sends its output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public boolean add(Type pObj)
      {
      if (this.size()==iMaxCapacity)
         {
         this.remove(0);
         }
      return super.add(pObj);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method inserts a new object into the buffer. When the buffer reaches its capacity, inserting a
   new object will result in the overwriting of the oldest object in the buffer. The next oldest object
   is then set to be the one in the element at array index 0.

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

   @return
      A reference to this object

   @param
      pConsole is a ConsoleStream through which this objects sends its output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void add(int pIndex, Type pObj)
      {
      if (this.size()==iMaxCapacity)
         {
         this.remove(0);
         }
      super.add(pIndex,pObj);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds all the objects in pCollection to the buffer one at a time. When the buffer reaches
   its capacity, the insertion of each new object will result in the overwriting of the oldest object
   in the buffer. The next oldest object is then set to be the one in the element at array index 0.

   <P><B>Implementation: </B><A HREF="CircularArrayList.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 boolean addAll(Collection<? extends Type> pCollection)
      {
      boolean  result = (pCollection.size() > 0);
      for (Type obj : pCollection)
         {
         this.add(obj);
         }
      return result;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method inserts all the objects in pCollection to the buffer one at a time. When the buffer
   reaches its capacity, inserting a new object will result in the overwriting of the oldest object in
   the buffer. The next oldest object is then set to be the one in the element at array index 0.

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

   @return
      A reference to this object

   @param
      pConsole is a ConsoleStream through which this objects sends its output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public boolean addAll(int pIndex, Collection<? extends Type> pCollection)
      {
      boolean  result = (pCollection.size() > 0);
      ArrayList<Type>  temp = new ArrayList<Type>(this);
      temp.addAll(pIndex,pCollection);
      this.clear();
      for (Type obj: temp)
         {
         this.add(obj);
         }
      return result;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method increases the capacity of the buffer, if necessary, to ensure that it can hold at least
   the number of elements specified by the minimum capacity argument. This method is the only means of
   increasing the buffer size.

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

   @return
      A reference to this object

   @param
      pConsole is a ConsoleStream through which this objects sends its output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void ensureCapacity(int pMinCapacity)
      {
      super.ensureCapacity(pMinCapacity);
      iMaxCapacity = UMath.max(iMaxCapacity,pMinCapacity);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method trims the capacity of the buffer to be the list's current size. This method is the only
   means of decreasing the buffer size and it will no shrink the buffer to a size less than required to
   contain all the object already placed into the buffer.

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

   @return
      A reference to this object

   @param
      pConsole is a ConsoleStream through which this objects sends its output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void trimToSize()
      {
      super.trimToSize();
      iMaxCapacity = super.size();
      }



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

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

   @return
      A reference to this object

   @param
      pConsole is a ConsoleStream through which this objects sends its output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CircularArrayList 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="CircularArrayList.java.html#012">View source</A>

   @return
      A reference to this object
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CircularArrayList 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;
      }



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Class Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Main  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   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.CircularArrayList
            </DD>
         </DT>
      </DL>

   <P><B>Implementation: </B><A HREF="CircularArrayList.java.html#013">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
      ------------------------------------------------------------------------------------------ */
      CircularArrayList<Character>  obj = new CircularArrayList<Character>(5);
      /*.
      ==========================================================================================
      Test code
      ------------------------------------------------------------------------------------------ */
      obj.test();
      char  c = 'a';
      for (int i=0; i<10; i++)
         {
         obj.add(new Character(c));
         cOut.println(obj);
         c++;
         }
      }



   }  // class CircularArrayList



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