/**
	Program by Nipun Shah
	Program started on : 02/10/2005
	Program status : circular shift completed, sorting complete
	Phase 2: Descriptor and URL separated
			 Noise Eliminated
			 Accept search string and display the corresponding URL
			 Allow user to click on URL
			 Navigation page
	Program to accept strings from the user, and circular shift it.
	After the circular shift is done, sort the strings
**/
import java.util.StringTokenizer;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;

/*
	This is the KWIC class. It is the main control of the program.
	It creates the rotateword object and the sortstrings objects and uses them on the inputs to obtain the desired output
*/
public class KWIC extends Applet implements ActionListener
{
	// The total number of lines that can exist...can be configured
	final public int MAX_LINES = 250;	
	// Number of results to be shown per screen
	final public int NAV = 5;
	public int curr = 0;

	final public int inputRows = 20;
	final public int inputColumns = 20;
	final public int outputRows = 30;
	final public int outputColumns = 25;
	public int counter=0;
	public TextArea inputArea = null;
	public TextArea outputArea = null;
	public TextArea outputArea1 = null;
	public TextArea inputDescArea = null;
	public TextArea outputSearch = null;

	public TextField inputSearch = null;
	public TextField status = null;

	public Button sortButton = null;
	public Button searchButton = null;
	public Button urlButton = null;
	public Button delurlButton = null;
	public Button nextButton = null;
	public Button prevButton = null;

	public Label input = null;
	public Label inputDesc = null;
	public Label circular = null;
	public Label sort = null;
	public Label searchInput = null;
	public Label searchOutput = null;
	public Label statusStr = null;

	public List outputList = null;

	public String outputStrArray[][] = new String[MAX_LINES][2];
	public String noiseEliminatedArray[][] = new String[MAX_LINES][2];
	public String URLArray[] = new String[MAX_LINES];

	public RotateOneWord ROW = new RotateOneWord();
	public SortString SS = new SortString();
	public NoiseElim noiseElim = new NoiseElim();
	public SearchURL search = new SearchURL();
	
	public void init()
	{
		// The layout
		setLayout(null);
		// The text areas
		inputArea = new TextArea(inputRows, inputColumns);
		inputDescArea = new TextArea(inputRows, inputColumns);
		outputArea = new TextArea(outputRows, outputColumns);
		outputArea1 = new TextArea(outputRows, outputColumns);
		inputSearch = new TextField("", 255);
		status = new TextField("", 255);
		outputSearch = new TextArea(outputRows, outputColumns);
		outputList = new List(250, false);

		outputArea.setEditable(false);
		outputArea1.setEditable(false);
		inputDescArea.setEditable(false);
		outputSearch.setEditable(false);
		status.setEditable(false);

		// The labels
		input = new Label("Input:");
		inputDesc = new Label("Descriptor:");
		circular = new Label("Circularly Shifted:");
		sort = new Label("Noise Eliminated Sorted Strings");
		searchInput = new Label("Search String:");
		searchOutput = new Label("Search Result:");
		statusStr = new Label("Status:");

		// The sort button
		sortButton = new Button("SHIFT & SORT");
		searchButton = new Button("SEARCH");
		urlButton = new Button("GO!");
		delurlButton = new Button("Delete!");
		nextButton = new Button("->");
		prevButton = new Button("<-");

		sortButton.addActionListener(this);
		searchButton.addActionListener(this);
		urlButton.addActionListener(this);
		delurlButton.addActionListener(this);
		nextButton.addActionListener(this);
		prevButton.addActionListener(this);

		// Add the awt to the panel
		add(input);
		add(inputArea);
		add(inputDesc);
		add(inputDescArea);
		add(sortButton);
		add(circular);
		add(outputArea);
		add(sort);
		add(outputArea1);
		add(inputSearch);
		//add(outputSearch);
		add(searchInput);
		add(searchOutput);
		add(searchButton);
		add(outputList);
		add(urlButton);
		add(delurlButton);
		add(nextButton);
		add(prevButton);
		add(status);
		add(statusStr);

		//Set X,Y, width and height
		input.setBounds(10,20,100,20);
		inputArea.setBounds(10,50,300,250);

		inputDesc.setBounds(10,350,100,20);
		inputDescArea.setBounds(10,380,300,250);

		sortButton.setBounds(200,340,100,25);

		circular.setBounds(350,20,100,20);
		outputArea.setBounds(350,50,350,250);

		sort.setBounds(350,350,300,20);
		outputArea1.setBounds(350,380,350,250);

		statusStr.setBounds(750, 20, 100, 25);
		status.setBounds(750, 50, 250, 20);

		searchInput.setBounds(750, 100, 100, 20);
		inputSearch.setBounds(750, 130, 250, 20);

		searchButton.setBounds(850, 200, 75,25);

		searchOutput.setBounds(750, 275, 100, 20);		
		outputList.setBounds(750, 300, 250, 100);

		urlButton.setBounds(1000, 300, 50, 25);
		delurlButton.setBounds(1000, 325, 50, 25);
		nextButton.setBounds(1000, 350, 50, 25);
		prevButton.setBounds(1000, 375, 50, 25);
	
	}

	public KWIC() throws HeadlessException 
	{
		super();
	}

	public void actionPerformed(ActionEvent e)
	{

	  if(e.getSource()==sortButton)
	  {
		int count=0,counter=0;
		String inputMod=new String("");
		//Clear the output array
		for(count=0;count<MAX_LINES;count++) {
			outputStrArray[count][0]="";
			outputStrArray[count][1]="";
			noiseEliminatedArray[count][0]="";
			noiseEliminatedArray[count][1]="";
		}

		//Clear the output area if any previous output is displayed.
		outputArea.setText("");
		outputArea1.setText("");
		inputDescArea.setText("");
		
		String inputStr = new String(inputArea.getText());
		
		// Remove the new Line characters
		inputStr = inputStr.replaceAll("\n", " ");

		// Removing multiple spaces
		StringTokenizer strSpaces = new StringTokenizer(inputStr);
		while(strSpaces.hasMoreTokens())
		{
			inputMod = inputMod + strSpaces.nextToken() + " ";
		}
		inputStr=inputMod;

		StringTokenizer strToken = null;
		//Separate the strings on finding '$' as the delimiter
		StringTokenizer tokenLines = new StringTokenizer(inputStr, "$");  // Can we check for space also???? TBD
		int noOfLines = tokenLines.countTokens();
		if(noOfLines==0) {
			outputArea.setText("No String input");
			outputArea1.setText("No String input");
		}

		//outputArea.setText("Number of Strings :" + noOfLines + "\n\n");
		//outputArea.setText(outputArea.getText() + "\nThe circularly shifted strings are:\n");

		while(tokenLines.hasMoreTokens())
		{
			//outputArea.setText(outputArea.getText() + "\noutputStrArray -- " + outputStrArray + "\nand " +(outputStrArray==null));
			//outputArea.setText(outputArea.getText() + "\nEntered hasmoretokens\n");
			// Line obtained
			inputStr = new String(tokenLines.nextToken());

			// Break the line into descriptor and URL
			// This will return the index of URL
			int paramNumber = inputStr.indexOf("http://");

			if(paramNumber == -1)
				status.setText("Invalid Input Entered!");

			// Now break the desc and the URL
			String inputStrDesc = inputStr.substring(0, paramNumber-1);
			inputStrDesc = inputStrDesc.trim();
			// Display the descriptor to the user
			inputDescArea.setText(inputDescArea.getText() + inputStrDesc + "\n");
			String inputStrURL  = inputStr.substring(paramNumber);
			inputStrURL = inputStrURL.trim();
			// END break URL

			// The line is broken down into words
			//strToken = new StringTokenizer(inputStr);
			strToken = new StringTokenizer(inputStrDesc);
			// Build the output string by rotating each word in the string
			while(strToken.hasMoreTokens())
			{
				outputArea.setText(outputArea.getText() + inputStrDesc + "\n");
				inputStrDesc = ROW.rotateOneWord(inputStrDesc.trim());
				outputStrArray[counter][0] = inputStrDesc;
				outputStrArray[counter++][1] = inputStrURL;
				strToken.nextToken();
			}
		
		}
		//outputArea1.setText(outputArea1.getText() + "\n\n\n" + "The sorted strings are:\n\n");
		
		// The output array is now created. Sort it.
		outputStrArray = SS.sortStrings(outputStrArray);
		outputArea1.setText("");

     	// PHASE 2- NOISE ELIMINATOR
		noiseEliminatedArray = noiseElim.removeNoise(outputStrArray);
		
		// Display the sorted strings in the output box
		for(int i=0; i < noiseEliminatedArray.length && noiseEliminatedArray[i][0]!=null && !noiseEliminatedArray[i][0].equals(""); i++) {
			outputArea1.setText(outputArea1.getText() + noiseEliminatedArray[i][0] + " " + noiseEliminatedArray[i][1] + "\n");
		}

		status.setText("Noise Eliminated Strings Displayed");
		}

		if(e.getSource() == searchButton)
		{
			curr = 0 ;
			// Clear the output List before new search
			outputList.removeAll();
			//status.setText("Search button hit@@!");

			//outputSearch.setText("Search Button pressed!!");
			String searchTextEntered = inputSearch.getText();
			String temp1 =  new String(searchTextEntered.trim());
			searchTextEntered = temp1;

			//outputSearch.setText("Going into findResults" + "\n");
			//outputList.add("Going into findResults");
			
			// Check if the input search string contains AND, OR or NOT
			//status.setText("Going into find results");

			URLArray = search.findResults(searchTextEntered, noiseEliminatedArray);

			
			//outputSearch.setText(outputSearch.getText() + "  Returned from findResults" + "\n");
			//outputList.add("Returned from findResults");
			String temp = "";
			//status.setText("BOUT TO Delete duplicate entries");
			// Delete duplicate URLs
			for(int i=0;i<URLArray.length-2;i++)
				for(int j=i+1;j<URLArray.length-1;j++) {
					if(URLArray[i].equals(URLArray[j]))
						URLArray[j] = "";
			}

			//status.setText("Deleted duplicate entries");
			for(int i=0;i<URLArray.length-1;i++) {
				if(URLArray[i]==null || URLArray[i].equals("") || URLArray[i].equals(" "))
				{
					for(int j = i;j < URLArray.length-2;j++)
						URLArray[j] = URLArray[j+1];
					URLArray[URLArray.length-2]="";
				}
				temp = URLArray[i].trim();
				URLArray[i] = temp;
			}


			//for(int i=curr; i<curr+NAV; i++) {
			for(int i=0,j=0; j<5 && i < URLArray.length-1; i++) {
				if(URLArray[i]!=null && !URLArray[i].equals("") && !URLArray[i].equals(" ")) 
				{
					outputList.add(URLArray[i]);
					j++;
				}					
			}

			status.setText("Results from "+ Integer.toString(curr) + " to " + Integer.toString(curr+NAV));

			curr = curr + NAV;

			// Display the corresponding URL
		}

		if(e.getSource() == urlButton)
		{
			String urlStr = outputList.getSelectedItem();
			try
              {
                 AppletContext ac = getAppletContext();
                 ac.showDocument ( new URL(urlStr) );
              }
              catch (Exception ec)
              {

              }
		}

		if(e.getSource() == delurlButton)
		{
			String delurlStr = outputList.getSelectedItem();
			status.setText("Deleted URL is : " + delurlStr + "----");
			// Clear the list
			outputList.removeAll();
			String temp = new String();
			temp ="";
			// Delete all entries that matches the URL
			for(int i=0; i<URLArray.length-1; i++)  {
				//if(URLArray[i]!=null && !URLArray[i].equals(""))
					if(URLArray[i].equals(delurlStr))
						URLArray[i] = "";

				if(noiseEliminatedArray[i][1].equals(delurlStr)) {
					noiseEliminatedArray[i][1]="";
					noiseEliminatedArray[i][0]="";
					status.setText("Deleted URL is : " + delurlStr + "***");
				}
			}

			for(int i=0;i<URLArray.length;i++) {
				if(URLArray[i]==null || URLArray[i].equals("") || URLArray[i].equals(" "))
				{
					for(int j = i;j < URLArray.length-1;j++)
						URLArray[j] = URLArray[j+1];
					URLArray[URLArray.length-1]="";
				}
				temp = URLArray[i].trim();
				URLArray[i] = temp;
			}

			// Repopulate the list
			curr = 0;
			for(int i=curr; i<curr+NAV; i++)
				 if(URLArray[i]!=null && !URLArray[i].equals("") && !URLArray[i].equals(null) && !URLArray.equals(" "))
					outputList.add(URLArray[i]);
		}

		if(e.getSource() == nextButton)
		{
			int bound = 0, emptyStr=0, limit = 0 ;
			outputList.removeAll();

			// Checking if the navigation does not extend beyond the array length
			if(URLArray.length > curr+NAV)
				bound = curr + NAV;
			else
				bound = URLArray.length;

			// Do not display empty results
			for(int i=curr; i<bound; i++) {
				 if(URLArray[i]!=null && !URLArray[i].equals("") && !URLArray[i].equals(null) && !URLArray.equals(" "))
					 outputList.add(URLArray[i]);
				 else
					 emptyStr++;
			}
			 if(emptyStr==bound-curr)
			{
				 limit = 1;
				 curr = bound-2*NAV;
				 bound = bound - NAV;
				//outputList.add(URLArray[i]);
				for(int i=curr; i<bound; i++) {
				 if(URLArray[i]!=null && !URLArray[i].equals("") && !URLArray[i].equals(null) && !URLArray.equals(" "))
					 outputList.add(URLArray[i]);				
				}			
			}

			status.setText("Results from "+ Integer.toString(curr) + " to " + Integer.toString(bound));

			if(limit!=1)
				curr = bound;
		}

		if(e.getSource() == prevButton)
		{
			int bound =0 , emptyStr=0, limit=0;
			
			// Array boundry checks
			if(curr-NAV < 0) {
				bound = 0;
				curr = NAV;
			}
			else {
				bound = curr-NAV;
				outputList.removeAll();		
			
				// Not displaying empty strings
				for(int i=bound; i<curr; i++) {
					 if(URLArray[i]!=null && !URLArray[i].equals(""))
						outputList.add(URLArray[i]);
					 else
						 emptyStr++;
	
					 if(emptyStr==curr-bound)
						 limit = 1;
				}
				status.setText("Results from "+ Integer.toString(bound) + " to " + Integer.toString(curr));
			}			

			if(limit!=1)
				curr = bound;
		}
	}

	public void paint(Graphics g)
	{
	}
}

