package ac.essex.gp.interfaces;

import ac.essex.gp.Evolve;
import ac.essex.gp.problems.Problem;
import ac.essex.gp.params.GPParams;

/**
 * <p/>
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version,
 * provided that any use properly credits the author.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details at http://www.gnu.org
 * </p>
 *
 * @author Olly Oechsle, University of Essex, Date: 17-Jan-2007
 * @version 1.0
 */
public class ConsoleInterface extends GPInterface {

    public static final int HIGH_VERBOSITY = 3;
    public static final int LOW_VERBOSITY = 2;
    public static final int SILENT = 1;

    public static final String DOT = ".";

    private int counter = 0;
    private long startTime;
    private int verbosity = LOW_VERBOSITY;
    private int generation = 0;
    private long totalTime = 0;

    public ConsoleInterface() {
        this(HIGH_VERBOSITY);
    }

    public ConsoleInterface(int verbosity) {
        this.verbosity = verbosity;
    }

    public void dispose() {
        System.out.println("// Disposing.");
    }

    Problem p;

    public void onStartEvolution(Evolve e, Problem p) {
        this.p = p;
        if (verbosity == HIGH_VERBOSITY) {
        System.out.println("// " + Evolve.APP_NAME);
        System.out.println("// by Olly Oechsle");
        System.out.println("// Problem: " + p.getName());
        }
        startTime = System.currentTimeMillis();
    }

    public void onGenerationStart() {
        if (verbosity > SILENT) System.out.println("// GENERATION " + currentGeneration);
    }

    public void incrementIndividualEvaluations() {
        super.incrementIndividualEvaluations();
        if (verbosity == HIGH_VERBOSITY) {
            //System.out.print(DOT);
            //counter++;
            //if (counter % 50 == 0) System.out.println();
        }
    }

    public void onStopped() {
        System.out.println("// Genetic Programming halted by the user");
    }

    public void onGenerationEnd() {
        if (verbosity == SILENT) {
            //System.out.println("// GEN: " + generation + " FITNESS: " + bestIndividual.getKozaFitness());
        }
        if (verbosity > SILENT) {
            System.out.println("\n// Gen, Time, Hits, Size");
            System.out.println("// " + generation + ", " + (System.currentTimeMillis() - startTime) + ", " + bestIndividual.getHits() + ", " + bestIndividual.getTree().getTreeSize());
        }
        if (verbosity == HIGH_VERBOSITY) {
            //TreeOptimiser.optimise(bestIndividual, params);
            System.out.println(bestIndividual.toJava());
        }        
        counter = 0;
        //if (((System.currentTimeMillis() - startTime) / 1000) >= 100) System.exit(0);
        generation++;
    }

    public void onEndEvolution(GPParams params) {
        if (isIdeal)  {
            if (verbosity > SILENT) System.out.println("// Found ideal individual");
        }
        totalTime = System.currentTimeMillis() - startTime;
        if (verbosity == HIGH_VERBOSITY) {
            //TreeOptimiser.optimise(bestIndividual, params);
            System.out.println(bestIndividual.toJava());
        }
        if (verbosity >= SILENT) System.out.println("// Finished Evolution. " + (totalTime/1000) + "secs. " + generation + " generations.");
    }


    public long getTotalTime() {
        return totalTime;
    }

    public void fatal(String message) {
        System.err.println("// " + message);
    }

    public void message(String message) {
        System.out.println("// " + message);
    }
    
}
