/******************************************************************************
    Sort observable -- abstract class
----------------------------------------------------
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.util.*;
import java.awt.*;

/** An observable sort of an array of objects using selection sort, including
a runnable interface.

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

public abstract class SortObservable extends Observable implements Runnable {

   private static int sorterCount = 0;
   protected SortObsData sod;
   
/** The array of objects to sort. */

   public Object[] sortArray;

/** Binary predicate to use for sorting. */

   private BinaryPredicate bp;
   
/** Each sort has its own thread. */

   Thread sortThread;

/** Store pointers to the array locally.  Need this as neither start nor
run should have these paramters to conform to the Thread model. */
   
   public SortObservable(final Object[] array, final BinaryPredicate bp) {
      sortArray = array; this.bp = bp;
      sod = new SortObsData(sortArray.length);
   }

/** Runnable interface start method to create a thread for each object of
this class. */

   public void start() {
    if (sortThread == null) {
        sod = new SortObsData(sortArray.length);
        sorterCount++;
        sortThread = new Thread(this, "Sort-"+sorterCount);
        sortThread.start();
   }}

/** Advance to next comparison or swap.  Observable sorts wait at each
comparison and swap so the user can study pictures at their speed. */

  public synchronized boolean step() {
      if (sortThread != null) { notify(); return true; }
      else { return false; }
  }   

/** Do the sort. After sorting sortThread is set to null so the test can
be restarted.  Also nottify observers with end of data flags of -1. */

  public void run() { execute(sortArray,bp);
                      sortThread = null; sod.endOfData = true;
                       for (int i = 0 ; i < sortArray.length ; i++) {
                         sod.tag[i] = Color.black;
                       }
                      setChanged();
                      notifyObservers(sod);
                    }

/** Abstract sort routine to be provided for observation. */

   public abstract void execute(final Object[] array, final BinaryPredicate bp);
}