#include "hmm.h"
#include "GLCP.h"
#include "GLCPimage.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", "image database dirctory",
                                         true, "", "databaase");
      TCLAP::ValueArg<std::string> hmmdir("s", "sqlite", "hmm sqlitedb",
                                          true, "", "sqlite database");
      TCLAP::ValueArg<int> aid("a", "aid", "tile id", true, 0, "id");
      TCLAP::ValueArg<int> si("i", "id", "image d", true, 0, "0" );
      TCLAP::ValueArg<int> ch("c", "channel", "channel", true, 0, "0" );

      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< int > mid( "m", "mid", "model number", true, 1, 
                                  "the model number to use" );

      TCLAP::ValueArg<std::string> immaskarg("k", "mask", "image mask",
                                             false, "", "image mask");

      cmd.add(dbdir);
      cmd.add(hmmdir);
      cmd.add(aid);
      cmd.add(si);
      cmd.add(ch);
      cmd.add(fmean);
      cmd.add(fentropy);
      cmd.add(fcontrast);
      cmd.add(fcorrelation);
      cmd.add(fpower);
      cmd.add(mid);
      cmd.add( immaskarg );
      cmd.parse(argc, argv);

      bdbenv bdb, bdbhmm;
      dbhmm dbh;
      dbalnimage dba;
      classifierdb classdb;


      std::string hmmdbdir;

      hmmdbdir = hmmdir.getValue();

      std::cout << "hmmdbdir = \"" << hmmdbdir << "\"\n";

      bdb.open( dbdir.getValue() );
      dba.init( bdb.envptr() );
      bdb.adddb( &dba );
      bdb.cleanlog();

      classdb.open( hmmdir.getValue() );
      dbh.init( &classdb, mid.getValue(), 0, 0, 0 );

      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 myaid;
      std::cout << "checking aid\n";
      myaid = aid.getValue();

      GLCPimage gi;
      image2d im;
      int goodimage;
      goodimage = 0;
      if( dba.checkaid( myaid ) == 1 )
        {
          std::set<int> channels;
          std::cout << "getting channels\n";
          dba.get_channels(myaid, channels );
          std::cout << "checking for valid channel\n";
          int mych;
          mych = ch.getValue();
          if( channels.count( mych ) > 0 )
            {
              dba.get_aligned_image( myaid, si.getValue(), mych, &im );
              im.normalize( 0, 256.0/4096.0 );
              goodimage = 1;
            }
        }
      else
        {
          std::cout << "invalid aid\n";
        }
      std::cout << "\n";

      bdb.close();
      if( goodimage == 1 )
        {
          int mysi;
          mysi = si.getValue();
          Magick::Image mim;
          image2d immask;
          if( immaskarg.getValue().size() > 0 )
            {
              mim.read( immaskarg.getValue() );
              immask.load( mim, CH_GRAY );
            }

          im.getimage( mim );
          char buffer[512];
          sprintf( buffer, "myimage_%i.png", mysi );
          mim.write( buffer );
          //gi.classifyimage( &im, &dbh, mymask, 7 );
          if( immaskarg.getValue().size() > 0 )
            gi.classifyimage( &im, &dbh, mymask, 1, &immask );
          else
            gi.classifyimage( &im, &dbh, mymask, 1, NULL );
          gi.overlay( mim );
          sprintf( buffer, "class_%i.png", mysi );
          mim.write( buffer );
          im.getimage( mim );
          gi.seperate_histogram( mim );
          sprintf( buffer, "seperated_%i.png", mysi );
          mim.write( buffer );
        }
      bdbhmm.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;
}
