/*
 * Test program for class GreymapFile
 *
 * $Date$
 * $Revision$
 *
 */

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

/* turn off debug output from tested class... */
#ifndef DPRINTF
#define DPRINTF(x)
#endif

#include <cmath>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <stdexcept>
#include <iomanip>
#include <cfloat>
#include "../ImageArray.cc"
#include "WImage/PgmReader.hh"
#include "WImage/PgmWriter.hh"
#include "WImage/RawReader.hh"
#include "WImage/RawWriter.hh"
#ifdef PFI
#include <pfi.h>
#include "WImage/PfgReader.hh"
#include "WImage/PfgWriter.hh"
#endif
#include "WImage/debug.h"

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

static void pgmreader (ImageArray<coeff> *ia);
static void pgmwriter (ImageArray<coeff> *ia);
static void rawreader (ImageArray<coeff> *ia);
static void rawwriter (ImageArray<coeff> *ia);
#ifdef PFI
static void pfireader (ImageArray<coeff> *ia);
static void pfiwriter (ImageArray<coeff> *ia);
#endif
static void dump (ImageArray<coeff> *ia);

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

  ImageArray<coeff> *ia = NEW (ImageArray<coeff> (0, 0));

  pgmreader (ia);
  pgmwriter (ia);
  rawreader (ia);
  rawwriter (ia);
#ifdef PFI
  cout << "pfi r" << endl;
  pfireader (ia);
  cout << "pfi w" << endl;
  pfiwriter (ia);
  cout << "done" << endl;
  
#endif

  dump (ia);

  DELETE (ia);

  cout << "Test of class GreymapFile completed successfully.\n";

  return 0;
}

static void
pgmwriter (ImageArray<coeff> *ia)
{
  /*
   * Out directory should not exist!
   */
  GreymapWriter *pw = NEW (PgmWriter ("/nogo/out.pgm", *ia));
  
  try 
    {
      pw->write ();
      assert (0);
    }
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "writing") != NULL);
    }

  DELETE (pw);

  try 
    {
      pw = NEW (PgmWriter ("./out.pgm", *ia));
    }
  catch (const exception &error)
    {
      cout << "PgmWriter: Exception caught: " << error.what () << endl;
      exit (1);
    }

  try 
    {
      pw->write ();
    }
  catch (const exception &error)
    {
      cout << "write: Exception caught: " << error.what () << endl;
      exit (1);
    }

  ImageArray<coeff> *ia2 = NEW (ImageArray<coeff> (0, 0));
  GreymapReader *pr = NEW (PgmReader ("./out.pgm", *ia2));
  pr->read ();
  assert (ia->equals (ia2));

  for (int i = 0; i < ia->size (); i++)
    {
      ia->to (i, ia->at (i) + (coeff)ia->size () / 2);
    }

  try 
    {
      pw->write ();
    }
  catch (const exception &error)
    {
      cout << "write: Exception caught: " << error.what () << endl;
      exit (1);
    }

  for (int i = 0; i < ia->size (); i++)
    {
      ia->to (i, ia->at (i));
    }

  pr->read ();

  dump (ia);
  dump (ia2);

  assert (ia->equals (ia2));

  DELETE (pr);
  DELETE (ia2);
  DELETE (pw);
  
  cout << "PgmWriter OK.\n";
}
  
static void
rawwriter (ImageArray<coeff> *ia)
{
  /*
   * Out directory should not exist!
   */
  GreymapWriter *rw = NEW (RawWriter ("/nogo/out.pgm", *ia));
  
  try 
    {
      rw->write ();
      assert (0);
    }
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "writing") != NULL);
    }

  DELETE (rw);

  rw = NEW (RawWriter ("./out.raw", *ia));

  try 
    {
      rw->write ();
    }
  catch (const exception &error)
    {
      cout << "write: Exception caught: " << error.what () << endl;
      exit (1);
    }

  ImageArray<coeff> *ia2 = NEW (ImageArray<coeff> (0, 0));
  GreymapReader *rr = NEW (RawReader ("./out.raw", *ia2, 4, 4));
  try 
    {
      rr->read ();
    }
  catch (const exception &error)
    {
      cout << "Exception caught: " << error.what () << endl;
      exit (1);
    }
  assert (ia->equals (ia2));

  DELETE (rr);
  DELETE (ia2);
  DELETE (rw);
  cout << "RawWriter OK.\n";
}
  
static void 
pgmreader (ImageArray<coeff> *ia)
{
  /*
   * Check error handling...
   */
  GreymapReader *pr = NEW (PgmReader ("_test_.pgm", *ia));

  try 
    {
      pr->read ();
      assert (0);
    }
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "open") != NULL);
    }

  DELETE (pr);

  pr = NEW (PgmReader ("invalid1.pgm", *ia));

  try 
    {
      pr->read ();
      assert (0);
    }
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "invalid") != NULL);
    }
  DELETE (pr);

  pr = NEW (PgmReader ("invalid2.pgm", *ia));

  try 
    {
      pr->read ();
      assert (0);
    }
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "invalid") != NULL);
    }

  DELETE (pr);

  pr = NEW (PgmReader ("invalid3.pgm", *ia));

  try 
    {
      pr->read ();
      assert (0);
    }
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "invalid") != NULL);
    }

  DELETE (pr);

  pr = NEW (PgmReader ("test.pgm", *ia));
  
  try
    {
      pr->read ();
    }
  catch (const exception &error)
    {
      cout << "Exception caught: " << error.what () << endl;
      exit (1);
    }

  assert (ia->size () == 16);
  
  for (int i = 0; i < ia->size (); i++)
    {
      assert (ia->at (i) == (coeff)i);
    }
  
  DELETE (pr);
  cout << "PgmReader OK.\n";
}

static void 
rawreader (ImageArray<coeff> *ia)
{
  /*
   * Check error handling...
   */
  GreymapReader *rr = NEW (RawReader ("invalid1.raw", *ia, 3, 4));

  ((RawReader*)rr)->cols (4);
  ((RawReader*)rr)->rows (4);
  
  try 
    {
      rr->read ();
      assert (0);
    }
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "invalid") != NULL);
    }

  DELETE (rr);

  rr = NEW (RawReader ("test1.raw", *ia));
  ((RawReader*)rr)->cols (4);
  ((RawReader*)rr)->rows (4);

  try 
    {
      rr->read ();
    }
  catch (const exception &error)
    {
      cout << "Exception caught: " << error.what () << endl;
      assert (0);
    }

  assert (ia->size () == 16);
  
  for (int i = 0; i < ia->size (); i++)
    {
      assert (ia->at (i) == (coeff)i);
    }
  
  DELETE (rr);

  rr = NEW (RawReader ("test2.raw", *ia, 4, 4, 2));

  try 
    {
      rr->read ();
    }
  catch (const exception &error)
    {
      cout << "Exception caught: " << error.what () << endl;
      assert (0);
    }

  assert (ia->size () == 16);
  
  for (int i = 0; i < ia->size (); i++)
    {
      assert (ia->at (i) == (coeff)i);
    }
  
  DELETE (rr);
  cout << "RawReader OK.\n";
}

#ifdef PFI
static void 
pfireader (ImageArray<coeff> *ia)
{
  /*
   * Check error handling...
   */
  GreymapReader *pr = NEW (PfgReader ("invalid1.pfi", *ia));

  try 
    {
      pr->read ();
      assert (0);
    }
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "invalid") != NULL);
    }

  DELETE (pr);
  
  pr = NEW (PfgReader ("test.pfi", *ia));

  try 
    {
      pr->read ();
  cout << "gnasl" << endl;
    }
  catch (const exception &error)
    {
      cout << "Exception caught: " << error.what () << endl;
      assert (0);
    }

  assert (ia->size () == 9);
  
  coeff ar[9] = { sqrt (2.0), sqrt (3.0), sqrt (5.0), 
                   sqrt (6.0), sqrt (7.0), sqrt (8.0),
                   sqrt (10.0), sqrt (11.0), sqrt (12.0) };

  for (int i = 0; i < ia->size (); i++)
    {
      assert (ia->at (i) - ar[i] < DBL_EPSILON);
    }
  
  DELETE (pr);
  cout << "PfgReader OK.\n";
}

static void
pfiwriter (ImageArray<coeff> *ia)
{
  /*
   * Out directory should not exist!
   */
  GreymapWriter *pw = NEW (PfgWriter ("/nogo/out.pfi", *ia));
  
  try 
    {
      pw->write ();
      assert (0);
    }
  catch (const exception &error)
    {
      cout << "Expected exception caught: " << error.what () << endl;
      assert (strstr (error.what (), "writing") != NULL);
    }

  DELETE (pw);

  pw = NEW (PfgWriter ("./out.pfi", *ia));

  try 
    {
      pw->write ();
    }
  catch (const exception &error)
    {
      cout << "write: Exception caught: " << error.what () << endl;
      exit (1);
    }

  ImageArray<coeff> *ia2 = NEW (ImageArray<coeff> (0, 0));
  GreymapReader *pr = NEW (PfgReader ("./out.pfi", *ia2));
  try 
    {
      pr->read ();
    }
  catch (const exception &error)
    {
      cout << "Exception caught: " << error.what () << endl;
      exit (1);
    }
  assert (ia->epsilons (ia2, PFI_EPSILON));

  DELETE (pr);
  DELETE (ia2);
  DELETE (pw);
  cout << "PfgWriter OK.\n";
}
#endif
  
static void 
dump (ImageArray<coeff> *ia)
{
  cout.setf (ios::fixed, ios::floatfield);
  for (int row = 0; row < ia->rows (); row++)
    {
      cout << "[" << std::setw (2) << std::setfill (' ') << row << "] ";
      for (int col = 0; col < ia->cols (); col++)
        {
          cout << std::setprecision (1) << std::setw (4) 
               << ia->at (row, col) << ' ';
        }
      cout << endl;
    }
  cout.setf (FMT0, ios::floatfield);
}

