// a priority queue using sorted arrays
// items higher priority are later in array
// items with same priority are in increasing order of tenure
// get: O(1)
// put: O(n)

class PQAsSortedArray implements SeqStructure {

    private Object[] a;   // collection of items
    private int size;     // number of items
    private int MAXSIZE;  // max allowed number of items
    private int cursor;   // current position in PQ

    public PQAsSortedArray(int n) { 
	a = new Object[n];
	MAXSIZE = n;
	size = 0;
    }

    public boolean isEmpty() {
	return (size == 0);
    }

    public int size() {
	return size;
    }

    // binary search on array sorted in increasing order
    // it takes O(log(n)) time for an array of size n:
    public boolean search(Object o) {

	int left = 0;
	int right = size - 1;
	int middle = 0; //initialization needed for empty array case
	int count = 0;  //keep track of comparisons
	
	while (left <= right) {
	    middle = (left + right)/2;
	    int test = ((Comparable) (a[middle])).compareTo(o);
	    if (test < 0) left = middle+1;
	    else if (test == 0) { cursor = middle; return true; }
	    else right = middle-1;
	}

	// if we reach here, we didn't find the object:
	cursor = right + 1;
	return false;
    }

    // get the rightmost item, because sorted in ascending order
    // (want highest priority item):
    public Object get() {
	// check for empty PQ:
	if (size == 0) {
	    System.out.println("Empty array error!");
	    return null;
	}
	return a[--size];
    }
    
    // insert into right place in sorted array (ascending order):
    public void put(Object o) {
	if (size == MAXSIZE) {
	    System.out.println("Overflow error!");
	    return;
	}
	// set the cursor to point to where insertion should take place:
	boolean found = search(o);  
	
	// find leftmost object equal to o (could have repeats):
	while (cursor > 0 && ((PQElement)(a[cursor - 1])).compareTo(o) == 0)
	    cursor--;

	// make room for new element by shifting elements to left of cursor
	for (int i = size -1; i >= cursor;i--)
	    a[i+1] = a[i];
	
	// insert new element
	a[cursor] = (PQElement)o; // throw exception if o is not PQElement
	size++;
    }

    // Stingify the PQ:
    public String toString() {
	String s = "PQ: [";
	for (int i = 0; i < size; i++) {
	    s += a[i];
	    if (i < size-1) s+=",";
	}
	s += "]";
	return s;
    }
    
}

