/******************************************************************************
Bubble 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.*;

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

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

public class BubbleObs extends SortObservable implements ArraySort {

  public BubbleObs(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 bubble sort method.

<P><B>Loop invariant:</B><PRE>
&nbsp;   for i : 0..array.length :: ( sorted(array[0..i-1])
&nbsp;     and for j = i .. arrayLength-1 :: array[i-1] bp array[j] )
</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;
       boolean swapWasNotDone = true;
       
       for (int i = 0 ; i < array.length-1 ; i++) {
          swapWasNotDone = true;
           
           // Loop invariant: array[j] bp array[j+1 .. array.length-1]
       
           for (int j = array.length-1 ; j > i ; j--) {

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

               if (bp.execute(array[j], array[j-1])) {

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

                   tmp = array[j]; array[j] = array[j-1]; array[j-1] = tmp;
                   swapWasNotDone = false;
               }
           }
           sod.tag[i] = Color.black;
           if (swapWasNotDone) break;
       }
   }
}