/*
 *  Team 1
 *  CS575: Software Design
 *  Project Phase II
 *  Imlicit Invocation style
 *  IIShifter.java
 */

import java.util.Vector;
import java.io.StreamTokenizer;

/**
/**
 *  <p>Shifter class for the Imlicit Invocation KWIC system.
 *
 *  <p>Listens for events that enable it to input data into its data collection.
 *  Once that event is received, it will input all the data in the given message
 *  and shift every sentence and insert the shifted sentences into the data collection.
 *  It will broadcast messages to inform others of the progress it is making.</p>
 *
 *  <p>This class implements the KWICListener interface which enables it to 
 *  receive message sent by a KWICBroadcaster it is registered with. The class must 
 *  registered by a third party class; it cannot register on its own.
 *  </p>
 *
 *  <p>First, the constructor of the class must be called.  After that, the class will 
 *  simply wait for message to come in to its eventArrived() method.  These events
 *  will indicate what the class should do.  Those events that are not of importance to 
 *  this class will simply be ignored by the event handling processing of this class.
 *  </p>
 *
 *  <p>This class is capable of performing the following two functions.  The first thing 
 *  it can do is set the noise filter of its data collection.  This functionality will
 *  be invoked when a message is received with a vector of words to be filtered.  
 *  The second functionality of this class is inputing new sentences into its collection
 *  and all the shifted sentences derived from the original.  This will be invoked, 
 *  on a sentence by sentence basis, by messages with one sentence each.
 *  </p>
 *
 *  @author Diana Tetelman
 */

public class IIShifter implements KWICListener
{
    /**
     * specifies whether or not verbose output is to be generated
     */
    boolean verboseFlag;
    
    /**
     * KWICBroadcaster object which allows this module to interact with the 
     * rest of the system
     */
    KWICBroadcaster broadcaster;   
    
    /**
     * SentenceCollection object that is maintained by this class.
     */
    SentenceCollection collection;
    
    public IIShifter(KWICBroadcaster _broadcaster, boolean verbose)
    {
        broadcaster = _broadcaster;
        verboseFlag = verbose;
		collection = new SentenceCollection();
    }
    
    /**
     * Implements the KWICListener interface method.  This method will receive events and 
     * process them accordingly base on their content.
     * @param   event       KWICEvent which has been broadcasted
     */
    public void eventArrived(KWICEvent event) 
    {
        try{
            if( event.getEventType() == KWICEvent.SENTENCE_INPUTED )
                shift((Vector)(event.getPayLoad()));
            else if( event.getEventType() == KWICEvent.INPUT_DONE )
            {
                if( verboseFlag )
                    System.out.println("SHIFTER_DONE Message sent");

                broadcaster.eventBroadcast(new KWICEvent(
                        "Shifter",
                        KWICEvent.SHIFTER_DONE,
                        collection));
            }
			else if( event.getEventType() == KWICEvent.SET_NOISE )
			{
				Object[] temp = new Object[((Vector)(event.getPayLoad())).size()];
				for(int i=0; i<((Vector)(event.getPayLoad())).size(); i++)
					temp[i] = ((Vector)(event.getPayLoad())).elementAt(i);
				
				collection.setNoiseWords(temp);
			}
        }
        catch( KWICException e )
        {
            if( verboseFlag )
                System.out.println("EXCEPTION Message sent");
            
            broadcaster.eventBroadcast(new KWICEvent(
                            "Shifter",
                            KWICEvent.EXCEPTION,
                            e));
        }
    }
        
    /**
     * <p> This method will shift the incoming data and place it in the 
     * SentenceCollection data object with all of the new shifted data in it.  
     * It will only parse data after receiving a message in the stream pipe.
     */
    public void shift(Vector words) throws KWICException
    {
        try{
            collection.addKWICRow((Object[])(words.toArray()));
            int position = collection.size()-1;
			int numOfWords = words.size();
            
            for( int wIndex=1; wIndex < numOfWords; wIndex++ )
            {
				collection.addKWICShift(position, wIndex);				
            }
        }
        catch( Exception e )
        {
            throw new KWICException(e.toString());
        }
    }
   
    /** 
     * Returns the name of the class.  Used for broadcasting purposes.
     * @return  "Shifter"
     */
    public String getName() 
    {
        return "Shifter";
    }    
}