/*
 *  Team 1
 *  CS575: Software Design
 *  Project Phase I
 *  Imlicit Invocation style
 *  IISorter.java
 */

import java.util.Vector;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.StreamTokenizer;

/**
 *  <p>Sorter class for the Imlicit Invocation KWIC system.
 *
 *  <p><b>PRE:</b> expects to receive a message whenever new object have been 
 * added to the SentenceCollection data object
 * (no assumptions are made about how much data is in it.)
 *  <br><b>POST:</b> after execution, all the sentences will have been sorted
 * and inserted into the outgoing SentenceCollection data object
 *
 *  @author Luiza da Silva
 */

public class IISorter extends IIMaster implements Runnable
{
    boolean verboseFlag;

    /**
     * Constructor
     */
    public IISorter(boolean verbose)
    {
        verboseFlag = verbose;

        new Thread(this, "Sorter Thread").start();
    }

    /**
     * <p> This method will sort the incoming data and place it in the 
     * SentenceCollection data object with all of the new sorted data in it.
     * It will only parse data after receiving a message in the stream pipe.
     */

    public void run()
    {
        StreamTokenizer inPipe = new StreamTokenizer(sorterReadMessagePipe);
        inPipe.parseNumbers();

        try
        {
            // if message was received, start sorting
            while( inPipe.nextToken() == inPipe.TT_NUMBER )
            {
                if( inPipe.nval == 1)
                {
                    //sorts data via an insertion sort algorithm
                    shiftedCollection = insertionSort(shiftedCollection);
                    break;
                }
            }
        }
        catch ( Exception e)
        {
            e.printStackTrace();
            //Send Message(e);
        }

        if( verboseFlag )
        {
            printCollection(shiftedCollection);
        }

        // post message to output that it is time to start
        try{ 
            outputWriteMessagePipe.write("1 ");
            outputWriteMessagePipe.close();
        }
        catch( Exception e ) { }
    }

    private SentenceCollection insertionSort(SentenceCollection data) throws KWICException 
    {
        // if empty, returns without operating on data
        // otherwise sorts data alphanumerically (Unicode)
        if (data.isEmpty())
        {
                return data;
        }		    
        else 
        {
            // sorts the data by direct insertion
            int n = data.size();
            for (int i=1; i<n; i++)
            {
                int temp = i;
                for( int j = i-1; j >= 0; j-- )
                {
                    if( data.isGreaterThan(data.getKWICRowAt(j), data.getKWICRowAt(temp))) 
                    {
                       // the key is smaller, so Sentence at j has to be moved one position up
                       data.swapKWICRows(temp, j);
                       temp = j;
                    }	
                }
            }
            return data;
        }
    }
}
