package travellingSalesman;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;

/**
 * Checks TravellingSalesman.sharedCityArray for validity.
 * @author Dave Matuszek
 * @version Apr 13, 2011
 */
public class SolutionSaverAndChecker extends Thread {
    static File outputFile = null;

    /**
     * This method should be called once, at the beginning of
     * the TravellingSalesman program, to choose an output file.
     * The output file will be rewritten multiple times.
     */
    static void init() {
        if (outputFile == null) {
            String msg = "Where shall I save solutions?";
            try {
                outputFile = IO.getOutputFile(msg, null);
            }
            catch (IOException e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
    }
    
    /**
     * Checks TravellingSalesman.sharedCityArray for validity.
     * DO NOT CALL THIS METHOD DIRECTLY; call this Thread's
     * start() method instead.
     * 
     * @see java.lang.Thread#run()
     */
    @Override
    public void run() {
        City[] cities = TravellingSalesman.sharedCityArray;
        PrintStream printer = null;
        try {
            printer = new PrintStream(outputFile);
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
            System.exit(1);
        } 
        int nCities = cities.length;
        int expectedCitySum = ((nCities * (nCities - 1)) / 2);
        int actualCitySum = 0;
        double actualDistance = 0.0;
        double expectedDistance = City.roundTripDistance(cities);
        
        for (int i = 0; i < cities.length; i++) {
            printer.println(cities[i].toString());
            printer.flush();

            actualCitySum += cities[i].getNumber();
            actualDistance += cities[i].distanceTo(cities[(i + 1) % cities.length]);
        }
        if (actualCitySum != expectedCitySum) {
            System.out.println("ERROR! Cities have been duplicated or omitted!");
            System.out.println("Expected city sum = " + expectedCitySum);
            System.out.println("Actual city sum   = " + actualCitySum);
            System.out.println("Difference        = " + 
                               Math.abs(expectedCitySum - actualCitySum));
        }
        if (Math.abs(expectedDistance - actualDistance) > 0.001) {
            System.out.println("ERROR! Reported distance is " + expectedDistance +
                               " but actual distance is " + actualDistance + "!");
        }
        printer.println("\nTotal distance = " + expectedDistance);
    }
}
