#ifndef _NOMAGICK_
#include <Magick++.h>
#endif

#include <iostream>
#include <string>
#include <math.h>
#include "imagealign.h"
#include "image2d.h"
#include <fftw3.h>
#include <tclap/CmdLine.h>
#include "bdbenv.h"
#include "dbimage.h"
#include "pso.h"
#include "histequalize.h"

int main( int argc, char *argv[] )
{
  try
    {
      ///set up the command line parsing
      TCLAP::CmdLine cmd("Image alignment program", ' ', "0.001");

      TCLAP::ValueArg<int>
        sr("r", "row", "Row", true, 0, "row");
      TCLAP::ValueArg<int>
        sa("a", "stacka", "Stack A", true, 0, "stack");
      TCLAP::ValueArg<int>
        sb("b", "stackb", "Stack B", true, 1, "stack");

      TCLAP::ValueArg<std::string> dbdir("d", "db", "database dirctory", true, "", "databaase");
#ifndef _NOMAGICK_
      Magick::Image mim;
#endif
      cmd.add(sr);
      cmd.add(sa);
      cmd.add(sb);
      cmd.add(dbdir);

      cmd.parse(argc, argv);

      bdbenv bdb;
      dbimage imstore;
      bdb.open( dbdir.getValue() );
      imstore.init( bdb.envptr() );
      bdb.adddb( &imstore );
      bdb.cleanlog();

      std::vector< image2d* > ima;
      std::vector< image2d* > imb;
      for( int i = 15; i < 35; i++ )
        {
          image2d *t1, *t2;
          int ret;
          ima.push_back( new image2d );
          t1 = ima.back();
          ret = imstore.getimage( sr.getValue(), sa.getValue(), i,
                                  2, *t1 );
          if( ret != 0 )
            exit(0);

          imb.push_back( new image2d );
          t2 = imb.back();
          ret = imstore.getimage( sr.getValue(), sb.getValue(), i,
                                  2, *t2 );
          if( ret != 0 )
            exit(0);

          histequalize heq;

          heq.init( QUANTIZEFACTOR );
          t1->gaussian(25);
          heq.addimage( t1 );
          t2->gaussian(25);
          heq.addimage( t2 );
          
          heq.equalize( t1 );
          heq.equalize( t2 );
          
#ifndef _NOMAGICK_
          t1->getimage( mim );
          mim.write( "abc1.jpg" );


          t2->getimage( mim );
          mim.write( "abc2.jpg" );
#endif
        }
      imstore.close();
      bdb.close();
      pso opt;
      image2d map1, map2;
      map1.load( ima[0] );
      map2.load( imb[0] );
      map1.setall( 1 );
      map2.setall( 1 );
      opt.init( ima, imb, map1, map2 );
      opt.optimize( 20, -32, 10, 32, 500 );
      double tx, ty;
      double tscore;
      opt.getresult( tx, ty, tscore );
      imagealign::transform it;
      std::vector< transformation > trans;
      opt.getresult( trans );
      for( unsigned i = 0; i < trans.size(); i++ )
        {
          std::cout << trans[i].score << "\n";
        }
      it.xoff = tx;
      it.yoff = ty;

#ifndef _NOMAGICK_
      for( unsigned i = 0; i < ima.size(); i++ )
        {
          imagealign imaln;
          imaln.write( *(ima[i]), *(imb[i]), it, mim);
          char buff[512];
          sprintf( (char*)buff, "result_%u.png", i );
          mim.write( buff );
        }
#endif

      for( unsigned i = 0; i < ima.size(); i++ )
        {
          delete ima[i];
          delete imb[i];
        }
      std::cout << "transformation: " << tx << " " << ty << " " << tscore << "\n";
    }
  catch (TCLAP::ArgException &e)
    {
      std::cout << "ERROR: " << e.error() 
                << " for arg " << e.argId() << "\n";
      return 0;
    }
  return 0;
}
