/*
 * Raw video to pgm converter
 *
 * $Date$
 * $Revision$
 *
 */

#include <cassert>
#include <iostream>
#include <cstdio>
#include <stdexcept>
#include <iomanip>
#include <cstring>
#include <WImage.hh>

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

int 
main (int argc, char *argv[])
{
  cout << "vid2pgm version " << WAVE_VERSION << " (c) 2001-2004 by Herbert"
       << endl;
  char *infile = NULL;
  char *outfile = NULL;
  int y = 0;
  int x = 0;
  int to = 0;
  int from = 0;
  int o = 0;
  double frameRate = 1.0;

  if (argc < 5 || argc > 9)
    {
      cerr << "Usage: vid2pgm <infile> <outfile> "
           << "<y> <x> [<from> [<to> [<header> [<framerate>]]]]" << endl;
      return 1;
    }

  infile = argv[1];
  outfile = argv[2];

  if (sscanf (argv[3], "%d", &y) != 1)
    {
      cerr << "Invalid y: " << argv[3] << endl;
      return 1;
    }
  if (sscanf (argv[4], "%d", &x) != 1)
    {
      cerr << "Invalid x: " << argv[4] << endl;
      return 1;
    }
  
  if (argc > 5)
    {
      if (sscanf (argv[5], "%d", &from) != 1)
        {
          cerr << "Invalid from: " << argv[5] << endl;
          return 1;
        }
    }
  
  if (argc > 6)
    {
      if (sscanf (argv[6], "%d", &to) != 1)
        {
          cerr << "Invalid to: " << argv[6] << endl;
          return 1;
        }
    }
  
  if (argc > 7)
    {
      if (sscanf (argv[7], "%d", &o) != 1)
        {
          cerr << "Invalid header: " << argv[7] << endl;
          return 1;
        }
    }

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

  int frames = to - from;

  if (frames <= 0)
    {
      try
        {
          frames = VidReader::framesInFile (infile, y, x, 1, o);
        }
      catch (const exception &)
        {
          cerr << "Error getting number of frames." << endl;
          return 2;
        }
    }
  
  cout << "Allocating memory...\n";
  ColorVideo *inVid = NULL; 
  Image *inFrame = NULL;

  try 
    {
      inVid = NEW (ColorVideo (1, cm_grey, y, x, frames));
    }
  catch (const exception &error)
    {
      cerr << "Exception caught: " << error.what () << endl;
      return 2;
    }

  cout << "Reading...\n";
  try
    {
      inVid->read (infile, from, to, y, x, 1, cm_grey, o);
    }
  catch (const exception &error)
    {
      cerr << "Exception caught: " << error.what () << endl;
      return 2;
    }

  cout << endl << "Writing output...\n";

  int outNameSize = strlen (outfile) + 1 + frames / 10 + 1;
  char *outName = NEW (char [outNameSize + 1]);
  outName[outNameSize] = '\0';
#define FORMSIZE 14
  char format[FORMSIZE + 1];
  format[FORMSIZE] = '\0';
  sprintf (format, "%%s_%%0%dd", frames / 10 + 1);
  assert (format[FORMSIZE] == '\0');
#undef FORMSIZE

  for (int i = 0; i < frames; i++)
    {
      inVid->current (i);
      inFrame = &inVid->currentFrameChannel (0);
      sprintf (outName, format, outfile, i);
      assert (outName[outNameSize] == '\0');
      cout << outName << endl;
      try
        {
          inFrame->write (outName, fn_pgm);
        }
      catch (const exception &error)
        {
          cerr << "Exception caught: " << error.what () << endl;
          return 2;
        }
    }

  cout << "Done.\n";

  DELETE (outName);
  DELETE (inVid);
  
  return 0;
}

