// CS 461: Machine Learning
// Winter 2008
// Author: Kiri Wagstaff
// Homework 1, NearestNeighbor.java, due Jan. 10, 2008

import java.io.*;
import java.util.*;

public class NearestNeighbor {
  private ArrayList<ArrayList<Double>> database;
  private ArrayList<String> labels;

  /**
   * Constructor
   */
  NearestNeighbor() {
    database = null;
    labels = null;
  }

  /**
   * Train the classifier using data stored in trainfilename.
   *
   * @param trainfilename         name of the training data set file
   */
  public void train(String trainfilename) 
    throws FileNotFoundException {

    System.out.println("Training on " + trainfilename);

    // Clear the current data base
    database = new ArrayList<ArrayList<Double>>();
    labels = new ArrayList<String>();
    
    File trainFile = new File(trainfilename);
    Scanner input = new Scanner(trainFile);
    // Read in the training data set
    while (input.hasNextLine()) {
      String line = input.nextLine();
      Scanner instance = new Scanner(line).useDelimiter(",");
      // Label comes first (String)
      String l = instance.next();

      //----- Store this label in labels -----//
    

      // Then the features
      ArrayList<Double> features = new ArrayList<Double>();
      while (instance.hasNext())
	features.add(instance.nextDouble());
      //----- Store the feature vector in the database -----//

    }

    System.out.println("Stored " + database.size() + " instances.");
  }

  /**
   * Classify a single instance by finding its nearest neighbor.
   *
   * @param instance      the feature vector to be classified
   * @return  classification (label) of the new instance
   */
  public String classify(ArrayList<Double> instance) {
    int nearest = 0;     //----- update these ------//
    double minDist = 0;  //----- update these -----//

    //----- Find the nearest neighbor ------//
    // (You may want to implement the Euclidean distance
    // calculation as a separate method)

    // Report the nearest neighbor
    System.out.print("The nearest neighbor to " + instance);
    System.out.printf(" is item %d, distance %.2f.\n", nearest, minDist);

    // Return the nearest neighbor's label
    return "Implement me";
  }

  /**
   * Test the classifier using data stored in testfilename.
   *
   * @param testfilename         name of the testing data set file
   * @return  average accuracy
   */
  public double test(String testfilename) 
    throws FileNotFoundException {
    //----- Create local variables to store the test data -----//
    // (do not add them to the training data!)

    System.out.println("Testing on " + testfilename);

    File testFile = new File(testfilename);
    Scanner input = new Scanner(testFile);
    // Read in the testing data set
    while (input.hasNextLine()) {
      String line = input.nextLine();
      Scanner instance = new Scanner(line).useDelimiter(",");
      // Label comes first (String)
      String l = instance.next();
      //----- Store this label -----//
    
      // Then the features
      ArrayList<Double> features = new ArrayList<Double>();
      while (instance.hasNext())
	features.add(instance.nextDouble());
      //----- Store this feature vector -----//
      
    }

    //----- Report how many test instances were read in. -----//

    //----- Classify each of the test items, compare the output
    // to their true labels, and report average accuracy across the test set.
    double acc = 0;
    
    return acc;
  }

  /**
   * Main method.
   *
   * @param args      training and test file names.
   */
  public static void main(String args[]) {
    if (args.length != 2) {
      System.err.println("Error: specify training and test file names.");
      System.exit(1);
    }

    // Train the classifier
    NearestNeighbor classifier = new NearestNeighbor();
    try {
      classifier.train(args[0]);
    } catch (FileNotFoundException e) {
      System.out.println("Ooops, " + args[0] + " doesn't exist!");
    }

    // Test the classifier
    try {
      classifier.test(args[1]);
    } catch (FileNotFoundException e) {
      System.out.println("Ooops, " + args[1] + " doesn't exist!");
    }      
  }

}
