/*
 * Test program for the class Histogram
 *
 * $Date$
 * $Revision$
 *
 */

#ifdef NDEBUG
#undef NDEBUG
#endif /* NDEBUG */

#include "WTools/Histogram.hh"
#include "WImage/StillImage.hh"
#include <cassert>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <stdexcept>

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

static void idump (Image *img);
static void hdump (Histogram *hist);

int
main (void)
{
  cout << "Testing class Histogram...\n";

  Image *img = NEW (StillImage (8, 8));

  for (int i = 0; i < img->size (); i++)
    {
      img->to (i, (coeff)i);
    }
  
  Histogram *hist;
  coeff lower;
  try
    { 
      hist = NEW (Histogram (*img, 0.0));
      assert (0);  
    }            
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "zero") != NULL);            
    }                                                    
  
  hist = NEW (Histogram (*img, 1.0));

  try
    {
      (void)hist->at (-1, lower);
      assert (0);  
    }            
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "out of bounds") != NULL);            
    }                                                    

  try
    {
      (void)hist->at (hist->size (), lower);
      assert (0);  
    }            
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "out of bounds") != NULL);            
    }                                                    

  idump (img);

  hdump (hist);
  for (int i = 0; i < hist->size (); i++)
    {
      assert (hist->at (i, lower) == 1 && lower == (coeff)i);
    }

  for (int i = 0; i < img->size (); i++)
    {
      img->to (i, (coeff)i - img->size () / 2);
    }
  hist->update ();
  hdump (hist);
  
  for (int i = 0; i < hist->size (); i++)
    {
      assert (hist->at (i, lower) == 1 
              && lower == (coeff)i - hist->size () / 2);
    }
  
  DELETE (hist);

  for (int i = 0; i < img->size (); i++)
    {
      img->to (i, (coeff)i);
    }
  ImageInformation ii (*img);
  hist = NEW (Histogram (ii, 1.0));

  idump (img);

  hdump (hist);

  for (int i = 0; i < hist->size (); i++)
    {
      assert (hist->at (i, lower) == 1 && lower == (coeff)i);
    }

  for (int i = 0; i < img->size (); i++)
    {
      (ii.at (i)).val ((coeff)i - img->size () / 2);
    }
  hist->update ();
  hdump (hist);
  
  for (int i = 0; i < hist->size (); i++)
    {
      assert (hist->at (i, lower) == 1 
              && lower == (coeff)i - hist->size () / 2);
    }
  
  DELETE (img);
  DELETE (hist);

  cout << "Test of class Histogram completed successfully.\n";
  return 0;
}

#if 0
static void
idump (Image *img)
{
  cout.setf (ios::fixed, ios::floatfield);
  for (int i = 0; i < img->size (); i++)
    {
      cout << std::setprecision (1) << std::setw (4) << img->at(i) << ' ';
    }
  cout << endl << endl;
  cout.setf (FMT0, ios::floatfield);
}

static void
hdump (Histogram *hist)
{
  coeff lower;
  cout.setf (ios::fixed, ios::floatfield);
  for (int i = 0; i < hist->size (); i++)
    {
      cout << '(' << std::setprecision (1)
           << hist->at(i, lower);
      cout << '/' << lower << ") ";
    }
  cout << endl << endl;
  cout.setf (FMT0, ios::floatfield);
}
#else
static void
idump (Image *img)
{
}

static void
hdump (Histogram *hist)
{
}
#endif
