#include "hmm.h"
#include "GLCP.h"
#include "dbimage.h"
#include "bdbenv.h"
#include "dbalnimage.h"
#include "dbtmpfeature.h"
#include <tclap/CmdLine.h>
#include "dbhmm.h"
#include <string>

int main( int argc, char *argv[] )
{

#ifndef _NOMAGICK_
  try
    {
      ///set up the command line parsing
      TCLAP::CmdLine cmd("Image alignment program", ' ', "0.001");

      TCLAP::ValueArg<std::string> dbdir("d", "db", "database dirctory", true,
                                         "", "databaase");
      TCLAP::ValueArg<std::string> dbname("t", "tmpdb", "tmp database dirctory", true,
                                          "", "file");
      TCLAP::ValueArg<int> classid("i", "classid", "class id to assign to hmm model",
                                   true, 0, "class");
      TCLAP::ValueArg<int> nstates("s", "states", "number of states in  hmm model",
                                   true, 0, "states");

      TCLAP::ValueArg< bool > fmean("", "mean", "mean flag", false,
                                    true, "true/false" );
      TCLAP::ValueArg< bool > fentropy("", "entropy", "entropy flag", false,
                                       true, "true/false" );
      TCLAP::ValueArg< bool > fcontrast("", "contrast", "contrast flag", false,
                                        true, "true/false" );
      TCLAP::ValueArg< bool > fcorrelation("", "correlation", "correlation flag",
                                           false, true, "true/false" );
      TCLAP::ValueArg< bool > fpower("", "power", "power flag", false,
                                     true, "true/false" );
      TCLAP::ValueArg< bool > tsaverage( "", "average", "average deltas", false,
                                         false, "true/false");

      TCLAP::ValueArg< std::string > sqlitepath( "l", "sqlite", "sqlite path", true,
                                                 "", "path" );
      TCLAP::ValueArg<bool> clear("n", "new", "new hmm models", false,
                                  false, "<true/false>");
      TCLAP::ValueArg< int > modelid("m", "mid", "model id", false, 0,
                                     "model id in the sqlite database" );
      TCLAP::ValueArg< int > fvid("f", "fvid", "feature vector id", false, 0,
                                  "feature vector id in sqlite database" );
      TCLAP::ValueArg< int > cvid("c", "cvid", "feature vector id", false, 0,
                                  "feature vector id in sqlite database" );

      cmd.add(dbdir);
      cmd.add(classid);
      cmd.add(dbname);
      cmd.add( clear );
      cmd.add(nstates);
      cmd.add( fmean );
      cmd.add( fentropy );
      cmd.add( fcontrast );
      cmd.add( fcorrelation );
      cmd.add( fpower );
      cmd.add( tsaverage );
      cmd.add(sqlitepath);
      cmd.add( modelid );
      cmd.add( fvid );
      cmd.add( cvid );

      bdbenv bdb;
      dbtmpfeature dbtf_b;
      dbhmm dbh;
      dbalnimage dba;
      classifierdb classdb;

      cmd.parse(argc, argv);

      dbtf_b.setname( dbname.getValue() );

      bdb.open( dbdir.getValue() );
      classdb.open( sqlitepath.getValue() );

      dbtf_b.init( bdb.envptr(), 0 );

      dba.init( bdb.envptr() );

      bdb.adddb( &dba );
      bdb.adddb( &dbtf_b );
      bdb.cleanlog();

      dbh.init( &classdb, modelid.getValue(), fvid.getValue(),
                cvid.getValue(), clear.getValue() );
      
      std::map< int, std::vector< double* > > samples;

      unsigned int maxid;
      maxid = dbtf_b.maxid();

      GLCP::mask mymask;
      if( fmean.getValue() == true )
        mymask.mean = 1;
      else
        mymask.mean = 0;

      if( fentropy.getValue() == true )
        mymask.entropy = 1;
      else
        mymask.entropy = 0;

      if( fcontrast.getValue() == true )
        mymask.contrast = 1;
      else
        mymask.contrast = 0;

      if( fcorrelation.getValue() == true )
        mymask.correlation = 1;
      else
        mymask.correlation = 0;

      if( fpower.getValue() == true )
        mymask.power = 1;
      else
        mymask.power = 0;

      int numfeatures;
      numfeatures = 0;
      int bsz;
      dbtf_b.getrecsize( bsz );

      char *buff;

      buff = new char [bsz];
      GLCP myglcp;
      for( unsigned i = 1; i < maxid; i = i + 48 )
        {
          dbtf_b.get( i, buff );
          std::vector< double * > s;
          s.clear();
          myglcp.del();
          myglcp.deserialize( buff, bsz );
          int nf;
          nf = 0;

          if( tsaverage.getValue() == false )
            myglcp.getfeaturets( s, mymask, nf );
          else
            myglcp.getfeaturetsavg( s, mymask, nf );

          if( i > 1 && nf != numfeatures )
            {
              std::cout << "ERROR number of features inconsistant\n";
              exit(0);
            }
          numfeatures = nf;
          samples[i] = s;
        }
      delete [] buff;

      ///////////////////////////////////////////////
      dbh.train( classid.getValue(), samples, numfeatures, nstates.getValue(), 1 );

      samples.clear();

      dbtf_b.close();
      bdb.close();
    }
  catch (TCLAP::ArgException &e)
    {
      std::cout << "ERROR: " << e.error() 
                << " for arg " << e.argId() << "\n";
      return 0;
    }
  
#else
  std::cout << "compiled with no image magick\n";
#endif
  return 0;
}

