#include <fstream>

#include "jpgencoder.h"
#include "bmpdecoder.h"

using namespace Colosseum ;
using namespace std ;

void Progress (BitmapImageCoder &coder,
               void *data,
               unsigned int currentpass,
               unsigned int passcount,
               unsigned int progress,
               bool &cancel)
{
  cout << currentpass << " of " << passcount << " " << progress << "%             \r" << flush ;
  return ;
}

void Usage (int argc, char *argv [])
{
  char *file ;
  if (argc != 0)
    file = argv [0] ;
  else
    file = argv [0] ;

  cerr << "Usage:  " << file << " [-flags] bmp-file jpg-file " << endl ;
  cerr << "Flags:  -g          Grayscale Output" << endl ;
  cerr << "        -p          Progressive Output" << endl ;
  cerr << "        -qVAL       Quality" << endl ;
  cerr << "        -sVAL       Y Component Sampling [1, 2, or 4]" << endl ;
  exit (1) ;
}

int main (int argc, char *argv [])
{
  if (argc < 3)
    Usage (argc, argv) ;

  JpegEncoder encoder ;
  // Change the default. Place each component in a separate scan.
  try
  {
    for (int ii = 1 ; ii < argc - 2 ; ++ ii)
    {
      if (argv [ii][0] != '-')
        Usage (argc, argv) ;
      switch (argv [ii][1])
      {
      case 'g':
        encoder.setGrayscale (true) ;
        break ;
      case 'p':
        encoder.setProgressive (true) ;
        break ;
      case 'q':
        {
          int quality = atoi (&argv [ii][2]) ;
          encoder.setQuality (quality) ;
        }
        break ;
      case 's':
        {
          int sampling = atoi (&argv [ii][2]) ;
          switch (sampling)
          {
          case 1: case 2: case 4: break ;
          default: Usage (argc, argv) ;
          }
          encoder.setSamplingFrequency (JpegEncoder::YCOMPONENT, sampling, sampling);
          if (sampling > 2)
          {
            encoder.setScanAttributes (0, 1<<JpegEncoder::YCOMPONENT, 0, 0) ;
            encoder.setScanAttributes (1, (1<<JpegEncoder::CBCOMPONENT)|(1<<JpegEncoder::CRCOMPONENT), 0, 0) ;
          }
        }
        break ;

      default:
        Usage (argc, argv) ;
      }
    }
  }
  catch (exception &ee)
  {
    cerr << ee.what () << endl ;
    return 1 ;
  }

  BmpDecoder decoder ;
  BitmapImage image ;
  try
  {
    string input = argv [argc-2] ;
    decoder.readImageFile (input, image) ;
  }
  catch (exception &ee)
  {
    cerr << ee.what () << endl ;
    return 1 ;
  }

  try
  {
    string output = argv [argc-1] ;
    encoder.writeImageFile (output, image) ;
  }
  catch (exception &ee)
  {
    cerr << ee.what () << endl ;
    return 1 ;
  }
  return 0 ;
}
