package Priority;

/* PriorityQueue defines a priority queue. It has methods for adding a node, deleting a node, and determining if empty or full.
*/

import java.io.*;

public class PriorityQueue
{
     private Node [] queue;
     final int maxSize = 10;
     private int queueRear;
 
     PriorityQueue ()
     {
          queue = new Node [maxSize+1];
          queueRear = 0;
     } // constructor
 
     public boolean isEmpty ()
     {
          if (queueRear == 0) return true;
          else  return false;
     } // method isEmpty
 
     public boolean isFull ()
     {
          if (queueRear == maxSize) return true;
          else  return false;
 } // method isFull
 
  public void addToQueue (Node newNode)
  {
       if (queueRear == maxSize) System.out.println ("Queue is full");
       else
       if (queueRear == 0)
       {
            queueRear ++;
            queue [queueRear] = newNode;
       }
       else
       {
            boolean stop = false;
            queueRear ++;
            int priority = newNode.getPriority ();
            int hole = queueRear;
            while ((hole > 1) && (!stop))
           {
                 if (queue [hole/2].getPriority () < priority) // parent priority is lower
                      stop = true;
                 else // parent priority is greater
                 {
                      queue [hole] = queue [hole/2];
                      hole = hole/2;
                 }
            } // while
            queue [hole] = newNode;
           } // else
      } // method addToQueue
 
     public void outputQueue (PrintStream outfile)
     {
          for (int count = 1; count <= queueRear; count ++)
               queue [count].outputNode (outfile);
     } // method outputQueue
 
     public Node deleteFromQueue ()
     {
          if (queueRear == 0) return null;
          else
          {
               Node deletedNode = queue [1];
               Node moved = queue [queueRear];
               int priority = moved.getPriority ();
               queueRear --;
               int hole = 1;
               boolean stop = false;
               while ((hole < queueRear) && (! stop))
               {
                    if (2*hole > queueRear) // leaf node
                         stop = true;
                    else
                    if (2*hole == queueRear) // no right child
                    {
                         if (queue [2*hole].getPriority () < priority)
                         {
                              queue [hole] = queue [2*hole];
                              hole = 2*hole;
                         }
                         stop = true;
                    }
                    else // two children
                    {
                         int leftPriority = queue [2*hole].getPriority ();
                         int rightPriority = queue [2*hole+1].getPriority ();
                         if (leftPriority < rightPriority) // leftPriority smaller
                         {
                              if (priority > leftPriority)
                              {
                                   queue [hole] = queue [2*hole];
                                   hole = 2*hole;
                              }
                              else stop = true; // location for moved node is hole
                         }
                         else // rightPriority equal or smaller
                         {
                              if (priority > rightPriority)
                              {
                                   queue [hole] = queue [2*hole+1];
                                   hole = 2*hole + 1;
                              }
                              else stop = true; // location for moved node is hole
                         }
                    } // else two children
               } // while
               queue [hole] = moved;
               return deletedNode;
          } // else
     } // method deleteFromQueue
} // class PriorityQueue