#include <iostream>
#include <fstream>
#include <vector>
#include <tiffio.h>
#include <itk/itk.h>
#include <ocr/get_skew.h>
#include <ocr/find_chars.h>
#include <ocr/get_shape.h>
#include <ocr/dictionary.h>


int
main( int argc, char **argv)
{
  TIFFSetWarningHandler( 0);
  TIFFSetErrorHandler( 0);

  Raster     orig_raster;
  Raster     ocr_raster;
  Get_Skew   get_skew( 20, 3);
  Rotate     rotate;
  Find_Chars find_chars( 11);
  Dictionary dict;
  Dict_Key   key;
  Dict_Token token;
  ifstream   is;
  Page::const_iterator       ip;
  Char_Defs::const_iterator  cp;


  if ((argc < 3) || (4 < argc)) {
    cerr << "usage:" << "\n"
         << "  " << argv[ 0] << " dictimg dicttext dictfile" << "\n"
         << "  " << argv[ 0] << " testimg dictfile" << "\n"
         << "\n"
         << "When given three arguments reads the named image file " << "\n"
         << "and text file and builds the named dictionary file." << "\n"
         << "When given two arguments reads the named image file " << "\n"
         << "and dictionary file, performs recognition, and prints " << "\n"
         << "the results to stdout." << endl;
    return 1;
  }

  if (3 == argc) {
    if (!dict.load( argv[ 2])) {
      cerr << "unable to load dictionary file '" << argv[ 2] << "', aborting" << endl;
      return 2;
    }
  } else {
    is.open( argv[ 2]);
    if (!is) {
      cerr << "unable to open text file '" << argv[ 2] << "', aborting" << endl;
      return 2;
    }
  }
 
  if (!TIFF_Reader( argv[ 1]).load( orig_raster)) {
    cerr << "unable to load image file '" << argv[ 1] << "', aborting" << endl;
    return 3;
  }

  if (orig_raster.is_paletted()) {
    cerr << "can't use paletted images, aborting" << endl;
    return 4;
  }

  if (orig_raster.is_black_low()) {
    cerr << "0 must be white, inverting" << endl;
    orig_raster.is_black_low( false);
    Invert().transform( orig_raster, orig_raster);
  }

  get_skew.get_skew( orig_raster);
  rotate.rotate( orig_raster, ocr_raster, get_skew.skew());
  if (find_chars.find_chars( ocr_raster)) {
    if (3 == argc) {
      for (ip = find_chars.page().begin(); ip != find_chars.page().end(); ++ip) {
        for (cp = ip->begin(); cp != ip->end(); ++cp) {
          key = get_shape( ocr_raster
                         , cp->tl_x(), cp->tl_y()
                         , cp->br_x(), cp->br_y());
          dict.find_key( key, token);
          cout << token;
        }
        cout << "\n";
      }
    } else {
      for (ip = find_chars.page().begin(); ip != find_chars.page().end(); ++ip) {
        for (cp = ip->begin(); cp != ip->end(); ++cp) {
          key = get_shape( ocr_raster
                         , cp->tl_x(), cp->tl_y()
                         , cp->br_x(), cp->br_y());
          if (is >> token) {
            dict.add_key( key, token);
          } else {
            cerr << "unable to read token!  Aborting" << endl;
            return 5;
          }
        }
      }
      if (!dict.save( argv[ 3])) {
        cerr << "unable to save dictionary to '" << argv[ 4] << "', aborting" << endl;
        return 6;
      }
    }
  }

  return 0;
}