<?php

/* 
 * Przykładowy kod do książki: Algorytmy i struktury danych w języku PHP 7
 * 
 * Autor: Mizanur Rahman <mizanur.rahman@gmail.com>
 * 
 */

interface Queue {

   public function enqueue(string $item);

   public function dequeue();

   public function peek();

   public function isEmpty();
}


class CircularQueue implements Queue {

   private $queue;
   private $limit;
   private $front = 0;
   private $rear = 0;   
   
   public function __construct(int $limit = 5) {
      $this->limit = $limit;
      $this->queue = [];
   }

   public function size() {
      if ($this->rear > $this->front)
         return $this->rear - $this->front;
      return $this->limit - $this->front + $this->rear;
   }

   public function isEmpty() {
      return $this->rear == $this->front;
   }

   public function isFull() {
      $diff = $this->rear - $this->front;
      if ($diff == -1 || $diff == ($this->limit - 1))
         return true;
      return false;
   }

   public function enqueue(string $item) {
      if ($this->isFull()) {
         throw new OverflowException("Kolejka jest pełna.");
      } else {
         $this->queue[$this->rear] = $item;
         $this->rear = ($this->rear + 1) % $this->limit;
      }
   }

   public function dequeue() {
      $item = "";
      if ($this->isEmpty()) {
         throw new UnderflowException("Kolejka jest pusta");
      } else {
         $item = $this->queue[$this->front];
         $this->queue[$this->front] = NULL;
         $this->front = ($this->front + 1) % $this->limit;
      }
      return $item;
   }

   public function peek() {
      return $this->queue[$this->front];
   }

}


try {
   $cq = new CircularQueue;
   $cq->enqueue("One");
   $cq->enqueue("Dwa");
   $cq->enqueue("Trzy");
   $cq->enqueue("Cztery");
   $cq->dequeue();
   $cq->enqueue("Pięć");
   echo $cq->size();
} catch (Exception $e) {
   echo $e->getMessage();
}