/*
 *  Team 1
 *  CS575: Software Design
 *  Project Phase II
 *  Imlicit Invocation style
 *  IIMain.java
 */

import java.util.Vector;
import java.lang.Thread;

/**
 *  <p>Master coordinator class for the Imlicit Invocation KWIC system.
 *  
 *  <p>Orchestrates the different worker threads of the Implicit Invocation KWIC system.
 *  This class extends the KWICBroadcaster class, so it acts as the broadcaster as well.
 *  It also implements the KWICListener interface, so that it can listen in on the events
 *  being sent out by the worker classes.  It listens for specific events that tell it when 
 *  to terminate the program.  
 *  </p>
 *  @author Diana Tetelman
 */

public class IIMain extends KWICBroadcaster implements Runnable, KWICListener
{
    
    /**
     * keeps track of the files to be parsed for input
     */
    private Vector files;
    
    /**
     * keeps track of the files to be parse for noise words
     */
    private Vector noiseFiles;
    
    /**
     * keeps track of the noise words returned by the INPUT_NOISE request message
     */
    private Vector noiseWords;
    
    static public void main(String[] args) 
    {
        IIMain main = new IIMain(args);
    }
    
    /**
     * 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)
    {
        if( event.getEventType() == KWICEvent.INPUT_NOISE_DONE )
            noiseWords = (Vector)(event.getPayLoad());		
    }

        
    /**
     * This constructor will parse the commandline arguments and start this thread.
     */
    public IIMain(String[] args)
    {
        files = new Vector(); //args;
            noiseFiles = new Vector();
		
        // command line parsing + usage clause
        int optind;   // option index
        if (args.length < 1) {
            System.out.println("Usage: java PNFMain [-n [noisefile1]] [infile1] [infile2]");
            System.exit(1);
        } 
		else {                
            noiseFiles.add("noiseWords");

            for (optind=0; optind < args.length; optind++) 
            {
                if( args[optind].equalsIgnoreCase("-n") )
                {
                    noiseFiles.removeAllElements();
					optind++;
					noiseFiles.addElement(args[optind]);
                    continue;
                }
                
				files.add (args[optind]);                
            }
        }

        new Thread(this, "IIMain").start();
    }
    
    /**
     * This method is called when the thread is started.  It will create all the worker
     * classes and register them and itself to itself.
     */
    public void run()
    {
        try{            
            boolean verbose = false;

            IIInput input = new IIInput((KWICBroadcaster)this, ' ', '\n', verbose);
            IIShifter shifter = new IIShifter((KWICBroadcaster)this, verbose);
            IISorter sorter = new IISorter((KWICBroadcaster)this, verbose);
            IIOutput output = new IIOutput((KWICBroadcaster)this);

            addListener((KWICListener)this);
            addListener((KWICListener)output);
            addListener((KWICListener)sorter);
            addListener((KWICListener)shifter);
            addListener((KWICListener)input);
            
            eventBroadcast(new KWICEvent(
                            "Main",
                            KWICEvent.INPUT_NOISE,
                            noiseFiles));

            eventBroadcast(new KWICEvent(
                            "Main",
                            KWICEvent.SET_NOISE,
                            noiseWords));
			
            eventBroadcast(new KWICEvent(
                            "Main",
                            KWICEvent.INPUT_DATA,
                            files));
        }
        catch( Exception e )
        {
            e.printStackTrace();
        }
    }    

    public String getName()
    {
            return "Main";
    }
}  
