import java.util.Arrays;
/**
 * Queue Interface that ADT supports
 * @author Prateek
 * @param <T>
 */
interface IQueue<T> {
	/**
	 * Inserts an item to Queue, pointed by Rear.
	 * @param item
	 */
	 void enqueue(T item);

	 /**
	  * @return oldest element in the queue, pointer by front pointer
	  */
	 T dequeue();
	 
	 boolean isEmpty();
	 
	 /*return size of Queue*/
	 int size();
	 
	 boolean isFull();
}

/**
 * Circular Queue
 * @author Prateek....
 */
class CircularQueue implements IQueue<Integer>{

	private static final int DEFAULT_CAPACITY = 5;
	private int N,front,rear;
	private int[] arr;

	public CircularQueue() {
		arr = new int[DEFAULT_CAPACITY];
		N=DEFAULT_CAPACITY;
		Arrays.fill(arr, -1);
		front = rear =0;
	}

	public CircularQueue(int capacity){
		arr = new int[capacity];
		N=DEFAULT_CAPACITY;
		Arrays.fill(arr, -1);
		front = rear =0;
	}

	@Override
	public void enqueue(Integer item) {
		if(isFull())
			System.err.println("Stack is Full");
		else {
			arr[rear] = item;
			rear = (rear +1 ) % N;
		}
	}

	@Override
	public Integer dequeue() {
		if(isEmpty()){
			System.err.println("Stack is Empty");
			return null;
		}
		else{
			int val=arr[front];
			arr[front] = -1;
			front = (front +1) % N ;
			return val;
		}
	}

	@Override
	public boolean isEmpty() {
		return (front == rear) ? true : false;
	}

	@Override
	public boolean isFull() {
		int diff = rear - front;
		return (diff == N-1 || diff == -1) ? true : false; 
	}

	@Override
	public int size() {
		return (rear > front) ? (rear-front) : (N - (front - rear));
	}
	
	/**
	 * Displays the content of the Queue
	 */
	public void display(){
		int size = size();
		int index = front;
		int count=0;
		
		while(count!=size){
			System.out.print(arr[index]+"\t");
		     index = (index + 1) % N;
		     count++;
		}
	}
	
	public static void main(String[] args) {
		CircularQueue queue = new CircularQueue();
		queue.enqueue(1);
		queue.enqueue(2);
		queue.enqueue(3);
		queue.enqueue(4);
		queue.enqueue(5);
		queue.enqueue(6);
		queue.dequeue();
		queue.dequeue();
		queue.enqueue(7);
		queue.display();
		
	}
}
