/*
 * Print a histogram on an image
 *
 * $Date$
 * $Revision$
 *
 */

#include <iostream>
#include <iomanip>
#include <stdexcept>
#include <cstdio>
#include <cstring>
#include <WTools.hh>

#if !(defined __WATCOMC__ && __WATCOMC__ < 1230)
using namespace std;
#endif

int
main (int argc, char *argv[])
{
  cerr << "pgmhist version " << WAVE_VERSION << " (c) 2001-2004 by Herbert"
#ifdef PFI
       << " (pfi support enabled)"
#endif
       << endl;

  bool standard = false;

  if (argc > 2 && strcmp (argv[1], "-s") == 0)
    {
      standard = true;
      argc--;
      argv++;
    }

  if (argc < 2 || argc > 6)
    {
      cerr << "Usage: pgmhist [-s] <file> [delta [filter [dstage [sstage]]]]\n";
      return 1;
    }

  char *fname;
  FilterSet *flt;
  double delta = 1.0;
  int dstage = 0;
  int sstage = 0;
  int correction = 0;

  fname = argv[1];
  cerr << "File " << fname << endl;

  Image *image = NEW (StillImage ());

  try
    {
      image->read (fname);
    }
  catch (const exception &error)
    {
      cerr << "Reading image: " << error.what () <<endl;
      return 1;
    }

  if (argc > 2)
    {
      if (sscanf (argv[2], "%lf", &delta) != 1)
        {
          cerr << "Invalid delta: " << argv[2] << endl;
          return 1;
        }
    }

  if (argc > 3)
    {
      try
        {
          flt = &FilterSet::filterFromString (argv[3]);
        }
      catch (const exception &error)
        {
          cerr << "Error, : " << error.what () << endl;
          return 1;
        }

      WaveletTransform *transform;

      if (standard)
        {
          transform = NEW (StandardTransform (*image, *flt)); 
        }
      else
        {
          transform = NEW (PyramidTransform (*image, *flt));
        }
      
      if (argc > 5)
        {
          if (sscanf (argv[5], "%d", &sstage) != 1 || sstage < 1)
            {
              cerr << "Invalid sstage: " << argv[5] << endl;
              return 1;
            }
        }
      
      if (argc > 4)
        {
          if (sscanf (argv[4], "%d", &dstage) != 1 || dstage <= sstage)
            {
              cerr << "Invalid dstage: " << argv[4] << endl;
              return 1;
            }
        }

      if (dstage > 0)
        {
          try
            {
              transform->analysis (dstage);
            }
          catch (const exception &error)
            {
              cerr << "Analysis: " << error.what () <<endl;
              return 1;
            }
        }

      if (dstage > 0)
        {
          int yoffs, xoffs, ysize, xsize;
          transform->where (LL, dstage, yoffs, xoffs, ysize, xsize);
          correction = ysize * xsize;
          transform->fill (0.0, LL, dstage);
        }
      
      if (sstage > 0)
        {
          Image *tmp = transform->subband (LL, sstage);
          DELETE (image);
          image = tmp;
        }
      
      DELETE (transform);
    }

  Histogram *hist = NEW (Histogram (*image, delta));

  try 
    {
      hist->add (0.0, -correction);
    }
  catch (const exception &error)
    {
      cerr << "Exception caught: " << error.what () << endl;
      return 1;
    }

  hist->print ();
  
  DELETE (image);
  DELETE (hist);

  return 0;
}

