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

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


#define PI 3.14159265358979323846

#ifndef _NOMAGICK_

int addimage( int offset, int alnend, image2d &aln,
              image2d &data, Magick::Image &mim, int c );

int align( int ab, int bc, int cd, int de,
           int ef, int fg, int gh,
           int channel, image3d &im3,
           dbimage &imstore );

int addimage( int offset, int alnend, image2d &aln,
              image2d &data, Magick::Image &mim, int c )
{
  double nf;
  nf = alnend-offset;
  Magick::PixelPacket *pc;
  Magick::Geometry geo;
  geo = mim.size();
  pc = mim.getPixels(0, 0, geo.width(), 512 );

  for( int i = 0; i < 512; i++ )
    {
      Magick::ColorRGB rgb(0,0,0);
      for( int j = 0; j < 512; j++ )
        {
          double v;
          if( j < nf )
            {
              double ov, p;
              ov = aln.getpixel(i, j+offset );
              p = sin( ( (double)j )/(nf) * PI +PI/2)/2.0 + 0.5;
              v = data.getpixel(i,j) * (1-p) + p*ov;
            }
          else
            v = data.getpixel(i,j);
          aln.setpixel(i, j+offset, v );
          v = data.getpixel(i,j);
          if( v < 0 )
            v = 0;
          if( v > 1 )
            v = 1;
          rgb = pc[i*geo.width()+j+offset];
          if( c == 0 )
            rgb.red(v);
          else if( c == 1 )
            rgb.green(v);
          else
            rgb.blue(v);
          pc[i*geo.width()+j+offset] = rgb;
        }
    }
  mim.syncPixels();
  return offset+512;;
}

int align( int ab, int bc, int cd, int de,
           int ef, int fg, int gh,
           int channel, image3d &im3,
           dbimage &imstore )
{
  ab = bc = cd = de = ef = fg = gh;
  channel = 1;
  im3.del();
  std::vector< int > stackx;
  imstore.rows( stackx );
  return 0;
}

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

      TCLAP::ValueArg<std::string> dbdir( "i", "db", "database dirctory",
                                          true, "", "databaase" );

      TCLAP::ValueArg<int> ab("a", "aboffset", "Stack A", true, 'A', "stack");
      TCLAP::ValueArg<int> bc("b", "bcoffset", "Stack B", true, 'B', "stack");
      TCLAP::ValueArg<int> cd("c", "cdoffset", "Stack B", true, 'B', "stack");
      TCLAP::ValueArg<int> de("d", "deoffset", "Stack B", true, 'B', "stack");
      TCLAP::ValueArg<int> ef("e", "efoffset", "Stack B", true, 'B', "stack");
      TCLAP::ValueArg<int> fg("f", "fgoffset", "Stack B", true, 'B', "stack");
      TCLAP::ValueArg<int> gh("g", "ghoffset", "Stack B", true, 'B', "stack");

      cmd.add(dbdir);
      cmd.add(ab);
      cmd.add(bc);
      cmd.add(cd);
      cmd.add(de);
      cmd.add(ef);
      cmd.add(fg);
      cmd.add(gh);

      cmd.parse(argc, argv);

      bdbenv bdb;
      dbimage imstore;
      std::cout << "opening database\n";
      bdb.open( dbdir.getValue() );
      imstore.init( bdb.envptr() );
      bdb.adddb( &imstore );
      std::cout << "cleaning log\n";
      bdb.cleanlog();

      ////////////
      image3d im3;
      /*
      align(ab.getValue(), bc.getValue(), cd.getValue(), de.getValue(),
            ef.getValue(), fg.getValue(), gh.getValue(), 3, im3, imstore);
      im3.normalizeminmax();
      im3.gamma( 1.0/2.2 );
      im3.write( "aln_1" );
      */
      align(ab.getValue(), bc.getValue(), cd.getValue(), de.getValue(),
            ef.getValue(), fg.getValue(), gh.getValue(), 2, im3, imstore);
      im3.medianfilter( 3 );
      im3.normalizeminmax();
      im3.gamma( 1.0/2.2 );
      im3.write( "aln_2" );
      

      imstore.close();
      bdb.close();

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