// Fancy integer array class for COMP2100
// Richard Walker, 2005
// $Revision: 1.2 $
// $Date: 2005/05/22 06:29:50 $

public class IntegerArray {

    // The value of arrayObject is the address in memory of the
    // C array.  Lucky for us everything is 32 bits long.
    private int arrayObject;

    // These are used for mapping between the client's indexes and the
    // indexes of the C array.  To the client of this class, the array
    // is indexed from lower..upper.  We know that the C array is
    // indexed from 0..(upper-lower).
    private int lower;
    private int upper;

    // We pass in arrayObject as the parameter to the C calls.
    // We do so for convenience and efficiency, but it is not
    // necessary - the C code has access to all of the fields of "this".

    // Remember that all "index" parameters to these native routines
    // are used to index the C array directly.  Therefore the actual
    // parameters must always be in the range 0..(upper-lower).

    // FIX ME: define the wrappers here.  The name "mangling"
    //         has been done for you.  Replace each occurrence of
    //         "..." with something else.

    // private ... new_array(...);
    // private ... c_item(...);
    // private ... c_put(...);
    // private ... c_swap(...);
    // private ... c_sort_descending(...);

    static {
        // On Linux this loads libintegerarray.so.
        System.loadLibrary("integerarray");
    }

    //@ requires lower <= upper;
    public IntegerArray(int lower, int upper)
        throws IllegalArgumentException {
        // FIX ME: compare lower and upper.  If lower > upper,
        //         throw an IllegalArgumentException

        // FIX ME: assign the value of tne parameter "lower"
        //         to the field "lower"and the value of the
        //         parameter "upper" to the field "upper"
        // OOPS - the names of the fields are the same as the names
        //        of the parameters, so "lower = lower;" won't work!
        //        Remember the standard way of doing this?
        //        Do NOT change the names of either the fields or
        //        the formal parameters!

        // FIX ME: call new_array here
    }

    public int lower() {
        return lower;
    }

    public int upper() {
        return upper;
    }

    public int length() {
        return upper - lower + 1;
    }

    //@ requires index >= lower() && index <= upper();
    public int item(int index)
        throws ArrayIndexOutOfBoundsException {
        // FIX ME: compare index with both lower and upper.
        //         if either index < lower or index > upper
        //         then throw an ArrayIndexOutOfBoundsException
        //         using index as the parameter

        // FIX ME: change the "0" in the following line to a
        //         call to c_item with the appropriate parameter values
        return 0;
    }

    // Store the value "value" at the index "index".
    // Note the order of the two parameters!
    //@ requires index >= lower() && index <= upper();
    //@ ensures item(index) == value;
    public void put(int value,int index)
        throws ArrayIndexOutOfBoundsException,RuntimeException {
        // FIX ME: compare index with both lower and upper.
        //         if either index < lower or index > upper
        //         then throw an ArrayIndexOutOfBoundsException
        //         using index as the parameter

        // FIX ME: call c_put here!

        // FIX ME: check that calling item(index) now returns
        //         value.  If it doesn't, throw a RuntimeException

    }

    //@ requires index1 >= lower() && index2 <= upper() &&
    //@          index2 >= lower() && index2 <= upper();
    //@ ensures item(index1) == \old(item(index2)) &&
    //          item(index2) == \old(item(index1));
    public void swap(int index1,int index2)
        throws ArrayIndexOutOfBoundsException,RuntimeException {
        // FIX ME: compare index1 with both lower and upper.
        //         if either index1 < lower or index1 > upper
        //         then throw an ArrayIndexOutOfBoundsException
        //         using index1 as the parameter
        // FIX ME: now do the same, but with index2 instead of index1

        // FIX ME: call c_swap here!

        // FIX ME: what about that postcondition?  Remember how
        //         to handle \old?  Throw a RuntimeException if
        //         the postcondition is violated.
    }

    public void sortDescending() {
        // FIX ME: call c_sort_descending here!
    }

    public void sortAscending() {
        // FIX ME: write this in Java
    }
}

