/******************************************************************************
Insert Sort Observable
----------------------------------------------------
Copyright (c) Gunnar Gotshalks. All Rights Reserved.

Permission to use, copy, modify, and distribute this software
and its documentation for NON-COMMERCIAL purposes and
without fee is hereby granted. 
*******************************************************************************/

package FlexOr.searchAndSort;

import FlexOr.container.*;
import java.awt.Color;

/** Sort an array of objects using insert sort.

<P>
@author Gunnar Gotshalks
@version 1.0 1999 Jan 15
*/

public class InsertObs extends SortObservable implements ArraySort {

  public InsertObs(final Object[] array, final BinaryPredicate bp) {
      super(array, bp);
  }

/**
@param array Array of elements to be sorted.
@param bp Defines how array elements are compared.
*/
   public void sort(final Object[] array, final BinaryPredicate bp) {
       execute(array, bp);
   }

/** The insert sort method.

<P><B>Loop invariant:</B><PRE>
&nbsp;   for i : 0..array.length :: ( sorted(array[0..i-1])
</PRE>

@param array Array of elements to be sorted.
@param bp Defines how array elements are compared.
*/
   public void execute(final Object[] array, final BinaryPredicate bp) {
       Object tmp;
       
       sod.tag[0] = Color.black;
       for (int i = 1 ; i < array.length ; i++) {
           
           // Loop invariant: array[j] bp array[j+1..i]
       
           for (int j = i ; j > 0 ; j--) {

               // Comparison -- Added to make the sort observable. >>>>
               setChanged(); sod.tag[j] = Color.magenta;
               sod.tag[j-1] = Color.magenta; sod.swap = false;
               notifyObservers(sod);
                 try { synchronized(this) { wait(); }
                 } catch (InterruptedException e) {}
                sod.tag[j-1] = Color.black; sod.tag[j] = Color.black; 
               // <<<<
           
              if (bp.execute(array[j], array[j-1])) {

           // Swap -- Added to make the sort observable. >>>>
           setChanged(); sod.tag[j] = Color.cyan;
               sod.tag[j-1] = Color.cyan; sod.swap = true;
           notifyObservers(sod);
           try { synchronized(this) { wait(); }
           } catch (InterruptedException e) {}
           // <<<<

                tmp = array[j]; array[j] = array[j-1]; array[j-1] = tmp;
                sod.tag[j] = Color.black;
                sod.tag[j-1] = Color.black;
              }
              else break;
           }
       }
   }
}