// Michael Thomas

import edu.neu.ccs.*;
import edu.neu.ccs.gui.*;
import edu.neu.ccs.codec.*;
import edu.neu.ccs.console.*;
import edu.neu.ccs.filter.*;
import edu.neu.ccs.jpf.*;
import edu.neu.ccs.parser.*;
import edu.neu.ccs.pedagogy.*;
import edu.neu.ccs.quick.*;
import edu.neu.ccs.util.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
import java.util.*;
import java.math.*;
import java.beans.*;
import java.lang.reflect.*;
import java.net.URL;
import java.util.regex.*;
import java.text.ParseException;

public class Thomas_ListSearcher extends TablePanel {
    
    private static int width =
        TextFieldView.getSampleWidth(20, '0');
    
    private TextFieldView list =
        new TextFieldView("( ... )", width);
    
    private TextFieldView searchItem =
        new TextFieldView("", width);
    
    private TextFieldView itemIndex =
        new TextFieldView("", width);
    
    private TextFieldView numSteps =
        new TextFieldView("", width);
    
    private TextFieldView indexComparisonList =
        new TextFieldView("", width);
    
    private TextFieldView valueComparisonList =
        new TextFieldView("", width);
    
    private SimpleAction searchAction =
        new SimpleAction("Linear Search List") {
            public void perform() { OrderedLinearSearch(); }
        
    };
    
    private Object[][] dataStuff =
        new Object[][] {
            { "Scheme-style Ordered List:", new Halo(list) },
            { "Element to Search For:", new Halo(searchItem) },
            { "Item Index:", new Halo(itemIndex) },
            { "Number of Steps:", new Halo(numSteps) },
            { "Indexes Compared:", new Halo(indexComparisonList) },
            { "Values Compared:", new Halo(valueComparisonList) }
    };
    
    private TablePanel dataPanel =
        new TablePanel(
            dataStuff, 10, 10, WEST);
    
    private Object[] mainStuff =
        new Object[] { dataPanel, searchAction };
    
    private TablePanel mainPanel =
        new TablePanel(
            mainStuff, VERTICAL, 10, 10, CENTER);
    
    
    public Thomas_ListSearcher() {
    	add(new Halo(mainPanel, 10, 10));
        addListeners();
        
        frame("Ordered List Searcher");
    }
    
    private void OrderedLinearSearch() {
        double[] numericList = convertSchemeArrayInput(list.demandString());
        double x = searchItem.demandDouble();
        int numberOfSteps = 0;
        ArrayList indexComparedList = new ArrayList();
        ArrayList valuesComparedList = new ArrayList();
        
        int searchItemIndex = -1;
        for (int i = 0; i<= numericList.length - 1; i++)
        {
        	indexComparedList.add(new Integer(i));
        	valuesComparedList.add(new Double(numericList[i]));
        	
        	if (numericList[i] == x)
        	{
        		searchItemIndex = i;
        		numberOfSteps++;
        		break;
        	}
        	else if (numericList[i] > x)
        	{
        		numberOfSteps++;
        		numberOfSteps++;
        		
        		// Not in list
        		break;	
        	}
        	else
        	{
        		numberOfSteps++;
        		numberOfSteps++;
        	}
        }
        
        if (searchItemIndex != -1)
        {
        	// Search Item (x) was found
        	itemIndex.setViewState(String.valueOf(searchItemIndex + 1));
        	numSteps.setViewState(String.valueOf(numberOfSteps));
        	indexComparisonList.setViewState(listToSchemeArrayString(indexComparedList));
        	valueComparisonList.setViewState(listToSchemeArrayString(valuesComparedList));
        }
        else
        {
        	// Search Item (x) was not found
        	itemIndex.setViewState("Not found");
        	numSteps.setViewState(String.valueOf(numberOfSteps));
        	indexComparisonList.setViewState(listToSchemeArrayString(indexComparedList));
        	valueComparisonList.setViewState(listToSchemeArrayString(valuesComparedList));
        }
    }
    
    // Convert an ArrayList to a String in the form of a Scheme-style array for output
    private String listToSchemeArrayString(ArrayList theList)
    {
    	String arrayString = "(";
    	for (int i = 0; i <= theList.size() - 1; i++)
    	{
    		arrayString += theList.get(i) + " ";
    	}
    	arrayString = arrayString.substring(0, arrayString.length() -1) + ")";
    	
    	return arrayString;
    }
    
    // Convert a Scheme-style string of doubles to an array of doubles
    private double[] convertSchemeArrayInput(String input)
    {
    	//if ((input.charAt(0) == '(') && (input.charAt(numList.length()) == ')'))
        //{
        	String[] stringArray = input.substring(1, input.length() - 1).split(" ");
        	double[] numberArray = new double[0];
        	try
        	{
        		numberArray = Strings.stringsToDoubles(stringArray);
        	}
        	catch (ParseException ex)
        	{
        		//TODO: Need to handle the error & validate input
        	}
        	return numberArray;
        //}
    }
    
    private void addListeners() {
    	list.addActionListener(searchAction);
    	searchItem.addActionListener(searchAction);
    }
}

