#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"

#ifndef _NOMAGICK_
int dog( std::string name, image2d &im, image2d &imorig, int median );

int dog( std::string name, image2d &im, image2d &imorig, int median )
{
  Magick::Image mim;
  try
    {
      mim.read( name.c_str() );

      imorig.load( mim, CH_GRAY );

      im.load( mim, CH_GRAY );
      if( median == 1 )
        im.median(7);
      else
        im.median(2);
      im.dog( 10, 20 );
      im.logscale(16384);
      if( im.min() < 0 || im.max() > 65536 )
        {
          std::cout << "IMAGE minmax: "<< im.min() << " : " << im.max() << "\n";
          im.normalizeminmax();
        }
      else
        im.dividefactor( 65536 );
    }
  catch( Magick::Exception &e )
    {
      std::cout << "ERROR: " << e.what() << "\n";
    }
  return 0;
}

#endif

int main( int argc, char *argv[] )
{
#ifdef _NOMAGICK_
  std::cout << "compiled with no image magick\n";
#else
  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");
      cmd.add(dbdir);

      TCLAP::ValueArg<std::string> input("i", "input", "list of files", true, "", "list");
      cmd.add(input);
      cmd.parse(argc, argv);
      image2d ima;
      bdbenv bdb;
      dbimage imstore;
      bdb.open( dbdir.getValue() );
      imstore.init( bdb.envptr() );
      bdb.adddb( &imstore );
      FILE *fp;
      std::string infile;
      infile = input.getValue();
      fp = fopen( infile.c_str(), "r" );
      char buffer[256];
      int slice, channel, stack1, stack2;
      image2d imorig;
      Magick::Image mim;
      int count;
      count = 0;
      while( feof(fp) == 0 )
        {
          memset( buffer, 0, 256 );
          int z;
          z = fscanf( fp, "%s %i %i %i %i\n", (char*)buffer,
                      &stack1, &stack2, &slice, &channel );
          if( strlen( buffer ) > 2 )
            {
              std::cout << "stack: " << stack1 << ":" << stack2
                        << " slice: " << slice
                        << " channel: " << channel << "\n";
              std::cout << "processing " << buffer << " "
                        << stack1 << ":" << stack2 << " " 
                        << slice << " " << channel << "\n";
              dog( buffer, ima, imorig, channel );
              imstore.addimage( stack1, stack2, slice, channel, ima );
              imstore.addimage( stack1, stack2, slice, channel+2, imorig );
              ima.getimage_normalized( mim );
              sprintf( buffer, "dog%i-%i_%02i_%io.png", stack1, 
                       stack2, slice, channel );
              mim.write( buffer );
              ima.del();
              imstore.getimage( stack1, stack2, slice, channel, ima );
              ima.getimage_normalized( mim );
              sprintf( buffer, "dog%i-%i_%02i_%id.png", stack1,
                       stack2, slice, channel );
              mim.write( buffer );
              imorig.del();
              imstore.getimage( stack1, stack2, slice, channel+2, imorig );
              imorig.getimage_normalized( mim );
              sprintf( buffer, "org%i-%i_%02i_%id.png", stack1,
                       stack2, slice, channel );
              mim.write( buffer );
              if( count % 256 == 0 )
                {
                  bdb.cleanlog();
                }
              count++;
            }
        }
      bdb.cleanlog();
      imstore.close();
      bdb.close();
    }
  catch (TCLAP::ArgException &e)
    {
      std::cout << "ERROR: " << e.error() 
                << " for arg " << e.argId() << "\n";
      return 0;
    }
#endif
  return 0;
}
