package basics.collections;

import java.util.ArrayList;
import java.util.Iterator;
import basics.testing.Units;

/**
 * @author kst
 */
public class QueueSimple<T>
{
private boolean      lifo    = false;
private ArrayList<T> vector  = null;
int                  maxsize = Integer.MAX_VALUE;

public QueueSimple(int max)
{
   vector = new ArrayList<T>();
   this.maxsize = max;
}

/**
 * Set size and set last in first out ordering (default is false).
 * @param max
 * @param lifo
 */
public QueueSimple(int max, boolean lifo)
{
   vector = new ArrayList<T>();
   this.maxsize = max;
   this.lifo = lifo;
}

public synchronized void put(T object)
{
   vector.add(object);
   if(vector.size() > maxsize)
      vector.remove(0);
}

public boolean contains(T object)
{
   return vector.contains(object);
}

/**
 * Get the last object out of the queue. Return null if the queue is empty.
 */
public synchronized T poll()
{
   T object = peek();
   if(object != null)
      vector.remove(next());
   return object;
}

/**
 * Peek to see if something is available.
 */
public T peek()
{
   if(isEmpty())
      return null;
   return vector.get(next());
}

private int next()
{
   if(lifo)
      return vector.size() - 1;
   else
      return 0;
}

/**
 * Is the queue empty?
 */
public boolean isEmpty()
{
   return vector.isEmpty();
}

/**
 * How many elements are there in this queue?
 */
public int size()
{
   return vector.size();
}

public Iterator<T> iterator()
{
   return vector.iterator();
}

public static void unittest()
{
   QueueSimple<String> q = new QueueSimple<String>(3);
   for(int i = 0; i < 4; i++)
      q.put("" + i);
   // nomal order, content is: 1 2 3
   Units.assertTrue(q.size() == 3, "wrong size, not 3");
   Units.assertFalse(q.isEmpty(), "empty is wrong");
   Units.assertEqualsTrue(q.peek(), "1", "peek: first value not 1");
   Units.assertEqualsTrue(q.poll(), "1", "poll: first value not 1");
   Units.assertEqualsTrue(q.poll(), "2", "poll: first value not 2");
   Units.assertEqualsTrue(q.poll(), "3", "poll: first value not 3");
   Units.assertTrue(q.isEmpty(), "should be empty");
   Units.assertNull(q.peek(), "should be null");
   Units.assertNull(q.poll(), "poll should be null");
   q = new QueueSimple<String>(3, true);
   for(int i = 0; i < 4; i++)
      q.put("" + i);
   // lifo order, content is: 3 2 1 
   Units.assertTrue(q.size() == 3, "wrong size, not 3");
   Units.assertFalse(q.isEmpty(), "empty is wrong");
   Units.assertEqualsTrue(q.peek(), "3", "peek: first value not 1");
   Units.assertEqualsTrue(q.poll(), "3", "poll: first value not 3");
   Units.assertEqualsTrue(q.poll(), "2", "poll: first value not 2");
   Units.assertEqualsTrue(q.poll(), "1", "poll: first value not 1");
   Units.assertTrue(q.isEmpty(), "should be empty");
}
}
