package GenRGenS.markov;

import GenRGenS.utility.*;
import GenRGenS.*;
import GenRGenS.utility.callbacks.*;
import java.io.*;
import java.util.*;

public class BuildMarkov
{

  static int order=0;
  static int phase=1;
  static double sigma=0.;
  static boolean verbose=true;
  static String outFileName="";
  static String alphabet = "";
  static Vector<String> inFileNames=new Vector<String>();

  public static void main(String[] argv)
  {
    String usage = "BuildMarkov, Copyright (C) 2005 Alain Denise/Yann Ponty\n"+
          "GenRGenS comes with ABSOLUTELY NO WARRANTY; Details found in LICENCE.\n"+
          "This is free software, and you are welcome to redistribute it \n"+
          "under certain conditions; Details found in LICENCE.\n"+
          "Usage: java -cp . GenRGenS.markov.BuildMarkov [options] files"; 
    CommandLineParser parser = new CommandLineParser(usage);

    StringCallback inFileCallback = new StringCallback()
        {
          public void fun(String s)
          {
              BuildMarkov.inFileNames.add(s);
          }
        };
    parser.setDefaultRule(inFileCallback);

    Callback outfileCallback = new StringCallback()
        {
          public void fun(String s)
          {
            BuildMarkov.outFileName = s;
          }
        };
    parser.addRule("-d",outfileCallback,"Defines the destination output file.\nDefaults to standard output.","");

    Callback alphabetCallback = new StringCallback()
    {
      public void fun(String s)
      {
        BuildMarkov.alphabet = s;
      }
    };
    parser.addRule("-a",alphabetCallback,"Defines which alphabet to use (e.g. -a ACGT for DNA).\nDefaults to letters found in the input file.","");

    Callback phaseCallback = new IntCallback()
        {
          public void fun(int i)
          {
            BuildMarkov.phase = i;
          }
        };
    parser.addRule("-p",phaseCallback,"Defines the number of phases in the Markovian model.\nDefaults to 1.","");

    Callback orderCallback = new IntCallback()
        {
          public void fun(int i)
          {
            BuildMarkov.order = i;
          }
        };
    parser.addRule("-o",orderCallback,"Defines the order of the Markovian model.\nDefaults to 0.","");


    Callback sigmaCallback = new RealCallback()
        {
          public void fun(double i)
          {
            BuildMarkov.sigma = i;
          }
        };
    parser.addRule("-s",sigmaCallback,"Defines the sigma parameter of the pseudo-count (see Laplace rule).\nDefaults to 0.","");
    
    Callback verboseCallback = new BooleanCallback()
        {
          public void fun(boolean b)
          {
            BuildMarkov.verbose = b;
          }
        };
    parser.addRule("-v",verboseCallback,"Toggles verbose mode on(T) and off(F).\nDefaults to F.","");
    parser.parse(argv);
    if (BuildMarkov.phase<=0)
    {
      GenRGenS.err.println("Strictly positive number of phases required!");
      parser.printHelp();
      return;
    }
    if (BuildMarkov.order<0)
    {
      GenRGenS.err.println("The order is supposed to be positive or null!");
      parser.printHelp();
      return;
    }
    if(BuildMarkov.inFileNames.size()==0)
    {
      GenRGenS.err.println("Input file name needed!");
      parser.printHelp();
      return;
    }
    Comptage counter = new Comptage(BuildMarkov.order,BuildMarkov.phase,BuildMarkov.sigma,BuildMarkov.alphabet);
    try
    {
      for(int i=0;i<inFileNames.size();i++)
      {
          counter.countFile((BuildMarkov.inFileNames.elementAt(i)),BuildMarkov.verbose);
      }
      if(BuildMarkov.outFileName.equals(""))
      {
        GenRGenS.out.println(counter.toString());
        GenRGenS.err.print("Counted File(s) ");
        for(int i=0;i<BuildMarkov.inFileNames.size();i++)
        { GenRGenS.err.print( ((i==0)?"\"":", \"")+(BuildMarkov.inFileNames.elementAt(i))+"\""); }
        GenRGenS.err.println( " to Standard Output !");
      }
      else
      {
        FileWriter out = new FileWriter(BuildMarkov.outFileName);
        out.write(counter.toString());
        out.close();
        GenRGenS.err.print("Counted File(s) ");
        for(int i=0;i<BuildMarkov.inFileNames.size();i++)
        { GenRGenS.err.print( ((i==0)?"\"":", \"")+(BuildMarkov.inFileNames.elementAt(i))+"\""); }
        GenRGenS.err.println(" to File \""+BuildMarkov.outFileName+"\" !");
      }
    }
    catch(Exception e3)
    {
      GenRGenS.err.println(e3.toString());
      parser.printHelp();
    }
  }
}
