package genesom;

// import refprop.ReflectProperties;
//   -Drefprop.reflectproperties.reflect=true
//   -Drefprop.reflectproperties.debug=true

import java.io.IOException;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.Properties;
import java.util.Enumeration;

public class Main {


  static ReflectProperties initprops = new ReflectProperties();

  public Map map;
  public SOM som;


  String patternfile;
  public void setPatternfile(String patternfile) { this.patternfile = patternfile; }

  boolean patternblock = true;
  public void setPatternblock(boolean patternblock) { this.patternblock = patternblock; }

  String file_map_out;
  public void setFile_map_out(String file_map_out) { this.file_map_out = file_map_out; }

  String file_map_in;
  public void setFile_map_in(String file_map_in) { this.file_map_in = file_map_in; }

  boolean bell;
  public void setBell(boolean bell) { this.bell = bell; }


	protected static void getConfiguration(String parameter_file) {

    InputStream in = Main.class.getResourceAsStream(parameter_file);

    if(in != null) {

			try {

				initprops.load(in);

        Properties sprops = System.getProperties();

        // to be assigned from cmdline even though not yet present
        if(sprops.containsKey("file_map_in"))
          initprops.setProperty("file_map_in", sprops.getProperty("file_map_in"));

        if(sprops.containsKey("file_map_out"))
          initprops.setProperty("file_map_out", sprops.getProperty("file_map_out"));


        // merge with System.Properties
        for(Enumeration e = initprops.keys() ; e.hasMoreElements() ;) {

          String name = (String)e.nextElement();

          if(sprops.containsKey(name))
            initprops.setProperty(name, sprops.getProperty(name));
        }
		  }
			catch (IOException ioe) {}
			finally {
				try { in.close(); } catch (IOException ioe) {}
			}
    }
	}


  public static void main(String a[])
    throws IOException, FileNotFoundException
  {

    if(a.length == 0) throw new IOException("Need configuration properties as arg 1 !");

    getConfiguration(a[0]);


    Main main = new Main();

    if(!initprops.initThruSetMethods(main))
      throw new IOException("initprops thru set methods failed on main.");

    boolean persistent_map = main.file_map_in != null && !main.file_map_in.equals("");

    main.map = persistent_map ?
      (Map)new PersistentMap(new FileReader(main.file_map_in)) :
      (Map)new RadialTriangleGridGenerator(6, 37);

    SOM som = main.som = new SOM(main.map);


    if(!initprops.recursiveInitThruSetMethods(main))
      throw new IOException("recursive initprops thru set methods failed.");


    InputPatterns input_patterns = new InputPatterns(
        new InputStreamReader(
           (main.patternfile.equals("") || main.patternfile.equals("-")) ?
            System.in : new FileInputStream(main.patternfile)));

    if(main.patternblock) input_patterns.blockMode();

    som.setInputPatterns(input_patterns);


    main.map.init();

    som.init();

    if(!persistent_map) som.reset();


    som.train();

    som.test();


    persistent_map = main.file_map_out != null && !main.file_map_out.equals("");

    if(persistent_map) {
      FileWriter fw = new FileWriter(main.file_map_out);
      fw.write(initprops.toString());
      PersistentMap.nodesPersistence(som.map.getNodes(), fw);
    }
    else {
      System.out.println(initprops);
      som.output();
    }

//    java.awt.Toolkit.getDefaultToolkit().beep();
//    RadialTriangleGridGenerator rt = (RadialTriangleGridGenerator)(main.map);
//    rt.testInter();

    if(main.bell) java.awt.Toolkit.getDefaultToolkit().beep();

  }
}

