/**
 * Implemented as a circular linked list with a single reference to the back.
 *
 * @author Zach Tomaszewski
 * @param <E>  The data type of elements to be stored in this Queue.
 */
public class CircularQueue<E> implements Queue<E> {

  //Node links should go from back towards front.
  private Node<E> back;
  int size;

  /**
   * Constructs a new empty Queue.
   */
  public CircularQueue() {
    this.back = null;
    this.size = 0;
  }

  @Override
  public void offer(E item) {

//IMPLEMENT THIS

    if (this.back == null) {
      //set this.back equal to a new Node whose next pointer points back to itself

    }else {
      //insert the new node between back and back.getNext()

    }
    this.size++;
  }

  @Override
  public E peek() {
    if (this.back == null) {
      throw new IllegalStateException("Cannot peek() at empty queue.");
    }
    return this.back.getNext().getData();
  }

  @Override
  public E poll() {
    E item = this.peek();  //may throw exception if empty queue
    Node<E> front = this.back.getNext();
    if (front == this.back) {
      //single node left, pointing around to itself
      this.back = null;
    }else {
      this.back.setNext(front.getNext());
    }
    this.size--;
    return item;
  }

  @Override
  public int size() {
    return this.size;
  }

  /**
   * Returns a String showing the contents of the queue from front to back.
   */
  @Override
  public String toString() {
    String str = "[";
    //start curr pointing at front node (if there is one)
    Node<E> curr = (this.back != null) ? this.back.getNext() : null;
    for (int i = 0; i < size; i++) {
      str += curr.getData();
//IMPLEMENT THIS: what should replace the /*???*/?
      if (curr != /*???*/) {
        str += ", ";
      }
      curr = curr.getNext();
    }
    str += "]";
    return str;
  }
}