package basics.collections;

import java.util.ArrayList;
import java.util.List;
import basics.testing.Test;
import basics.utl.SysUtl;

public class QueueRevolving<T>
{
private List<T> vector          = null;
int             maxsize         = Integer.MAX_VALUE;
int             currentPosition = -1;

public QueueRevolving(int max)
{
   vector = new ArrayList<T>();
   this.maxsize = max;
}

public synchronized void put(T object)
{
   int x = vector.indexOf(object);
   if(x > -1)
      currentPosition = x;
   else
   {
      vector.add(object);
      if(vector.size() > maxsize)
         vector.remove(0);
      currentPosition = vector.size() - 1;
   }
   currentPosition++;
}

public T previous()
{
   if(isEmpty())
      return null;
   return vector.get(adjust(-1));
}

public T next()
{
   if(isEmpty())
      return null;
   return vector.get(adjust(+1));
}

public T last()
{
   if(isEmpty())
      return null;
   currentPosition = 0;
   return vector.get(adjust(-1));
}

public T first()
{
   if(isEmpty())
      return null;
   currentPosition = 0;
   return vector.get(0);
}

/**
 * vector must not be empty
 * @param d
 */
private int adjust(int d)
{
   currentPosition = currentPosition + d;
   if(currentPosition < 0)
      currentPosition = vector.size() - 1;
   else
      if(currentPosition >= vector.size())
         currentPosition = 0;
   return currentPosition;
}

public boolean isEmpty()
{
   return currentPosition == -1;
}

public int size()
{
   return vector.size();
}

public String toString()
{
   StringBuilder s = new StringBuilder();
   synchronized(vector)
   {
      int size = vector.size();
      int ndx = currentPosition;
      for(int i = 0; i < size; i++, ndx++)
      {
         if(ndx == size)
            ndx = 0;
         T object = vector.get(ndx);
         s.append(object.toString());
         if(i < size - 1)
         {
            s.append(Character.toChars(183));
         }
         // if (i < size-1) {s.append(" "); s.append(Character.toChars(183));
         // s.append(" ");}
      }
   }
   return s.toString();
}

public static void unittest()
{
   QueueRevolving<String> r = new QueueRevolving<String>(3);
   Test.assertTrue(r.isEmpty(), "new queue must be empty");
   r.put("a");
   Test.assertTrue(r.size() == 1, "size must be 1");
   r.put("b");
   r.put("c");
   Test.assertTrue(r.size() == 3, "size must be 3");
   r.put("A");
   Test.assertTrue(r.size() == 3, "size must still be 3");
   r.put("B");
   r.put("C");
   String x = r.last();
   Test.assertEqualsTrue(x, "C", "last not C but " + x);
   x = r.first();
   Test.assertEqualsTrue(x, "A", "first not A but " + x);
   x = r.next();
   Test.assertEqualsTrue(x, "B", "next not B but " + x);
   x = r.next();
   Test.assertEqualsTrue(x, "C", "next not C but " + x);
   x = r.next();
   Test.assertEqualsTrue(x, "A", "next not A but " + x);
   x = r.previous();
   Test.assertEqualsTrue(x, "C", "previous not C but " + x);
}
}
