/**********************************************************************
 * File:        adaptions.cpp  (Formerly adaptions.c)
 * Description: Functions used to adapt to blobs already confidently
 *					identified
 * Author:		Chris Newton
 * Created:		Thu Oct  7 10:17:28 BST 1993
 *
 * (C) Copyright 1992, Hewlett-Packard Ltd.
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 ** http://www.apache.org/licenses/LICENSE-2.0
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 *
 **********************************************************************/

#include "mfcpch.h"
#ifdef __UNIX__
#include          <assert.h>
#endif
#include          <ctype.h>
#include          <string.h>
#include          "tessbox.h"
#include          "tessvars.h"
#include          "memry.h"
#include          "mainblk.h"
#include          "charcut.h"
#include          "imgs.h"
#include          "scaleimg.h"
#include          "reject.h"
#include          "control.h"
#include          "adaptions.h"
#include          "stopper.h"
#include          "charsample.h"
#include          "matmatch.h"
#include          "secname.h"
#include          "tesseractclass.h"

inT32 demo_word = 0;

#define WINDOWNAMESIZE    13     /*max size of name */

#define EXTERN

EXTERN BOOL_VAR (tessedit_reject_ems, FALSE, "Reject all m's");
EXTERN BOOL_VAR (tessedit_reject_suspect_ems, FALSE, "Reject suspect m's");

EXTERN double_VAR (tessedit_cluster_t1, 0.20,
"t1 threshold for clustering samples");
EXTERN double_VAR (tessedit_cluster_t2, 0.40,
"t2 threshold for clustering samples");
EXTERN double_VAR (tessedit_cluster_t3, 0.12,
"Extra threshold for clustering samples, only keep a new sample if best score greater than this value");
EXTERN double_VAR (tessedit_cluster_accept_fraction, 0.80,
"Largest fraction of characters in cluster for it to be used for adaption");
EXTERN INT_VAR (tessedit_cluster_min_size, 3,
"Smallest number of samples in a cluster for it to be used for adaption");
EXTERN BOOL_VAR (tessedit_cluster_debug, FALSE,
"Generate and print debug information for adaption by clustering");
EXTERN BOOL_VAR (tessedit_use_best_sample, FALSE,
"Use best sample from cluster when adapting");
EXTERN BOOL_VAR (tessedit_test_cluster_input, FALSE,
"Set reject map to enable cluster input to be measured");

EXTERN BOOL_VAR (tessedit_matrix_match, TRUE, "Use matrix matcher");
EXTERN BOOL_VAR (tessedit_mm_use_non_adaption_set, FALSE,
"Don't try to adapt to characters on this list");
EXTERN STRING_VAR (tessedit_non_adaption_set, ",.;:'~@*",
"Characters to be avoided when adapting");
EXTERN BOOL_VAR (tessedit_mm_adapt_using_prototypes, TRUE,
"Use prototypes when adapting");
EXTERN BOOL_VAR (tessedit_mm_use_prototypes, TRUE,
"Use prototypes as clusters are built");
EXTERN BOOL_VAR (tessedit_mm_use_rejmap, FALSE,
"Adapt to characters using reject map");
EXTERN BOOL_VAR (tessedit_mm_all_rejects, FALSE,
"Adapt to all characters using, matrix matcher");
EXTERN BOOL_VAR (tessedit_mm_only_match_same_char, FALSE,
"Only match samples against clusters for the same character");
EXTERN BOOL_VAR (tessedit_process_rns, FALSE, "Handle m - rn ambigs");

EXTERN BOOL_VAR (tessedit_demo_adaption, FALSE,
"Display cut images and matrix match for demo purposes");
EXTERN INT_VAR (tessedit_demo_word1, 62,
"Word number of first word to display");
EXTERN INT_VAR (tessedit_demo_word2, 64,
"Word number of second word to display");
EXTERN STRING_VAR (tessedit_demo_file, "academe",
"Name of document containing demo words");
EXTERN BOOL_VAR(tessedit_adapt_to_char_fragments, TRUE,
                "Adapt to words that contain "
                " a character composed form fragments");

namespace tesseract {
BOOL8 Tesseract::word_adaptable(  //should we adapt?
                                WERD_RES *word,
                                uinT16 mode) {
  if (tessedit_adaption_debug) {
    tprintf("Running word_adaptable() for %s rating %.4f certainty %.4f\n",
          word->best_choice == NULL ? "" :
          word->best_choice->unichar_string().string(),
          word->best_choice->rating(), word->best_choice->certainty());
  }

  BOOL8 status = FALSE;
  BITS16 flags(mode);

  enum MODES
  {
    ADAPTABLE_WERD,
    ACCEPTABLE_WERD,
    CHECK_DAWGS,
    CHECK_SPACES,
    CHECK_ONE_ELL_CONFLICT,
    CHECK_AMBIG_WERD
  };

  /*
  0: NO adaption
  */
  if (mode == 0) {
    if (tessedit_adaption_debug) tprintf("adaption disabled\n");
    return FALSE;
  }

  if (flags.bit (ADAPTABLE_WERD)) {
    status |= word->tess_would_adapt;  // result of Classify::AdaptableWord()
    if (tessedit_adaption_debug && !status) {
      tprintf("tess_would_adapt bit is false\n");
    }
  }

  if (flags.bit (ACCEPTABLE_WERD)) {
    status |= word->tess_accepted;
    if (tessedit_adaption_debug && !status) {
      tprintf("tess_accepted bit is false\n");
    }
  }

  if (!status) {                  // If not set then
    return FALSE;                // ignore other checks
  }

  if (flags.bit (CHECK_DAWGS) &&
    (word->best_choice->permuter () != SYSTEM_DAWG_PERM) &&
    (word->best_choice->permuter () != FREQ_DAWG_PERM) &&
    (word->best_choice->permuter () != USER_DAWG_PERM) &&
    (word->best_choice->permuter () != NUMBER_PERM)) {
    if (tessedit_adaption_debug) tprintf("word not in dawgs\n");
    return FALSE;
  }

  if (flags.bit (CHECK_ONE_ELL_CONFLICT) && one_ell_conflict (word, FALSE)) {
    if (tessedit_adaption_debug) tprintf("word has ell conflict\n");
    return FALSE;
  }

  if (flags.bit (CHECK_SPACES) &&
    (strchr(word->best_choice->unichar_string().string(), ' ') != NULL)) {
    if (tessedit_adaption_debug) tprintf("word contains spaces\n");
    return FALSE;
  }

//  if (flags.bit (CHECK_AMBIG_WERD) && test_ambig_word (word))
  if (flags.bit (CHECK_AMBIG_WERD) &&
      !getDict().NoDangerousAmbig(word->best_choice, NULL, false, NULL, NULL)) {
    if (tessedit_adaption_debug) tprintf("word is ambiguous\n");
    return FALSE;
  }

  // Do not adapt to words that are composed from fragments if
  // tessedit_adapt_to_char_fragments is false.
  if (!tessedit_adapt_to_char_fragments) {
    const char *fragment_lengths = word->best_choice->fragment_lengths();
    if (fragment_lengths != NULL && *fragment_lengths != '\0') {
      for (int i = 0; i < word->best_choice->length(); ++i) {
        if (fragment_lengths[i] > 1) {
          if (tessedit_adaption_debug) tprintf("won't adapt to fragments\n");
          return false;  // found a character composed from fragments
        }
      }
    }
  }

  if (tessedit_adaption_debug) {
    tprintf("returning status %d\n", status);
  }
  return status;

}


void Tesseract::collect_ems_for_adaption(WERD_RES *word,
                                         CHAR_SAMPLES_LIST *char_clusters,
                                         CHAR_SAMPLE_LIST *chars_waiting) {
  PBLOB_LIST *blobs = word->outword->blob_list ();
  PBLOB_IT blob_it(blobs);
  inT16 i;
  CHAR_SAMPLE *sample;
  PIXROW_LIST *pixrow_list;
  PIXROW_IT pixrow_it;
  IMAGELINE *imlines;            // lines of the image
  TBOX pix_box;                   // box of imlines
  // extent
  WERD copy_outword;             // copy to denorm
  PBLOB_IT copy_blob_it;
  OUTLINE_IT copy_outline_it;
  inT32 resolution = page_image.get_res ();

  if (tessedit_reject_ems || tessedit_reject_suspect_ems)
    return;                      // Do nothing

  if (word->word->bounding_box ().height () > resolution / 3)
    return;

  if (tessedit_demo_adaption)
                                 // Make sure not set
    tessedit_display_mm.set_value (FALSE);

  if (word_adaptable (word, tessedit_em_adaption_mode)
    && word->reject_map.reject_count () == 0
    && (strchr (word->best_choice->unichar_string().string (), 'm') != NULL
    || (tessedit_process_rns
    && strstr (word->best_choice->unichar_string().string (),
  "rn") != NULL))) {
    if (tessedit_process_rns
    && strstr (word->best_choice->unichar_string().string (), "rn") != NULL) {
      copy_outword = *(word->outword);
      copy_blob_it.set_to_list (copy_outword.blob_list ());
      i = 0;
      while (word->best_choice->unichar_string()[i] != '\0') {
        if (word->best_choice->unichar_string()[i] == 'r'
        && word->best_choice->unichar_string()[i + 1] == 'n') {
          copy_outline_it.set_to_list (copy_blob_it.data ()->
            out_list ());
          copy_outline_it.add_list_after (copy_blob_it.
            data_relative (1)->
            out_list ());
          copy_blob_it.forward ();
          delete (copy_blob_it.extract ());
          i++;
        }
        copy_blob_it.forward ();
        i++;
      }
    }
    else
      copy_outword = *(word->outword);

    copy_outword.baseline_denormalise (&word->denorm);
    char_clip_word(&copy_outword, page_image, pixrow_list, imlines, pix_box);
    pixrow_it.set_to_list (pixrow_list);
    pixrow_it.move_to_first ();

    blob_it.move_to_first ();
    for (i = 0;
      word->best_choice->unichar_string()[i] != '\0';
    i++, pixrow_it.forward (), blob_it.forward ()) {

      if (word->best_choice->unichar_string()[i] == 'm'
        || (word->best_choice->unichar_string()[i] == 'r'
      && word->best_choice->unichar_string()[i + 1] == 'n')) {
        #ifndef SECURE_NAMES
        if (tessedit_cluster_debug)
          tprintf ("Sample %c for adaption found in %s, index %d\n",
            word->best_choice->unichar_string()[i],
            word->best_choice->unichar_string().string (), i);
        #endif
        if (tessedit_matrix_match) {
          sample = clip_sample (pixrow_it.data (),
            imlines,
            pix_box,
            copy_outword.flag (W_INVERSE),
            word->best_choice->unichar_string()[i]);

          if (sample == NULL) {  //Clip failed
            #ifndef SECURE_NAMES
            tprintf ("Unable to clip sample from %s, index %d\n",
              word->best_choice->unichar_string().string (), i);
            #endif
            if (word->best_choice->unichar_string()[i] == 'r')
              i++;

            continue;
          }
        }
        else
          sample = new CHAR_SAMPLE (blob_it.data (),
            &word->denorm,
            word->best_choice->unichar_string()[i]);

        cluster_sample(sample, char_clusters, chars_waiting);

        if (word->best_choice->unichar_string()[i] == 'r')
          i++;                   // Skip next character
      }
    }
    delete[]imlines;             // Free array of imlines
    delete pixrow_list;
  }
}


void Tesseract::collect_characters_for_adaption(
    WERD_RES *word,
    CHAR_SAMPLES_LIST *char_clusters,
    CHAR_SAMPLE_LIST *chars_waiting) {
  PBLOB_LIST *blobs = word->outword->blob_list ();
  PBLOB_IT blob_it(blobs);
  inT16 i;
  CHAR_SAMPLE *sample;
  PIXROW_LIST *pixrow_list;
  PIXROW_IT pixrow_it;
  IMAGELINE *imlines;            // lines of the image
  TBOX pix_box;                   // box of imlines
  // extent
  WERD copy_outword;             // copy to denorm
  inT32 resolution = page_image.get_res ();

  if (word->word->bounding_box ().height () > resolution / 3)
    return;

  if (tessedit_demo_adaption)
                                 // Make sure not set
    tessedit_display_mm.set_value (FALSE);

  if ((word_adaptable (word, tessedit_cluster_adaption_mode)
  && word->reject_map.reject_count () == 0) || tessedit_mm_use_rejmap) {
    if (tessedit_test_cluster_input && !tessedit_mm_use_rejmap)
      return;                    // Reject map set to acceptable
    /* Collect information about good matches */
    copy_outword = *(word->outword);
    copy_outword.baseline_denormalise (&word->denorm);
    char_clip_word(&copy_outword, page_image, pixrow_list, imlines, pix_box);
    pixrow_it.set_to_list (pixrow_list);
    pixrow_it.move_to_first ();

    blob_it.move_to_first ();
    for (i = 0;
      word->best_choice->unichar_string()[i] != '\0';
    i++, pixrow_it.forward (), blob_it.forward ()) {

      if (!(tessedit_mm_use_non_adaption_set
        && STRING(tessedit_non_adaption_set).contains(
            word->best_choice->unichar_string()[i]))
      || (tessedit_mm_use_rejmap && word->reject_map[i].accepted ())) {
        #ifndef SECURE_NAMES
        if (tessedit_cluster_debug)
          tprintf ("Sample %c for adaption found in %s, index %d\n",
            word->best_choice->unichar_string()[i],
            word->best_choice->unichar_string().string (), i);
        #endif
        sample = clip_sample (pixrow_it.data (),
          imlines,
          pix_box,
          copy_outword.flag (W_INVERSE),
          word->best_choice->unichar_string()[i]);

        if (sample == NULL) {    //Clip failed
          #ifndef SECURE_NAMES
          tprintf ("Unable to clip sample from %s, index %d\n",
            word->best_choice->unichar_string().string (), i);
          #endif
          continue;
        }
        cluster_sample(sample, char_clusters, chars_waiting);
      }
    }
    delete[]imlines;             // Free array of imlines
    delete pixrow_list;
  }
  else if (tessedit_test_cluster_input && !tessedit_mm_use_rejmap)
    // Set word to all rejects
    word->reject_map.rej_word_tess_failure ();

}


void Tesseract::cluster_sample(CHAR_SAMPLE *sample,
                               CHAR_SAMPLES_LIST *char_clusters,
                               CHAR_SAMPLE_LIST *chars_waiting) {
  CHAR_SAMPLES *best_cluster = NULL;
  CHAR_SAMPLES_IT c_it = char_clusters;
  CHAR_SAMPLE_IT cw_it = chars_waiting;
  float score;
  float best_score = MAX_INT32;

  if (c_it.empty ())
    c_it.add_to_end (new CHAR_SAMPLES (sample));
  else {
    for (c_it.mark_cycle_pt (); !c_it.cycled_list (); c_it.forward ()) {
      score = c_it.data ()->match_score (sample, this);
      if (score < best_score) {
        best_score = score;
        best_cluster = c_it.data ();
      }
    }

    if (tessedit_cluster_debug)
      tprintf ("Sample's best score %f\n", best_score);

    if (best_score < tessedit_cluster_t1) {
      if (best_score > tessedit_cluster_t3 || tessedit_mm_use_prototypes) {
        best_cluster->add_sample (sample, this);
        check_wait_list(chars_waiting, sample, best_cluster);
        #ifndef SECURE_NAMES
        if (tessedit_cluster_debug)
          tprintf ("Sample added to an existing cluster\n");
        #endif
      }
      else {
        #ifndef SECURE_NAMES
        if (tessedit_cluster_debug)
          tprintf
            ("Sample dropped, good match to an existing cluster\n");
        #endif
      }
    }
    else if (best_score > tessedit_cluster_t2) {
      c_it.add_to_end (new CHAR_SAMPLES (sample));
      #ifndef SECURE_NAMES
      if (tessedit_cluster_debug)
        tprintf ("New cluster created for this sample\n");
      #endif
    }
    else {
      cw_it.add_to_end (sample);
      if (tessedit_cluster_debug)
        tprintf ("Sample added to the wait list\n");
    }
  }
}

void Tesseract::check_wait_list(CHAR_SAMPLE_LIST *chars_waiting,
                                CHAR_SAMPLE *sample,
                                CHAR_SAMPLES *best_cluster) {
  CHAR_SAMPLE *wait_sample;
  CHAR_SAMPLE *test_sample = sample;
  CHAR_SAMPLE_IT cw_it = chars_waiting;
  CHAR_SAMPLE_LIST add_list;     //Samples added to best cluster
  CHAR_SAMPLE_IT add_it = &add_list;
  float score;

  add_list.clear ();

  if (!cw_it.empty ()) {
    do {
      if (!add_list.empty ()) {
        add_it.forward ();
        test_sample = add_it.extract ();
        best_cluster->add_sample (test_sample, this);
      }

      for (cw_it.mark_cycle_pt ();
      !cw_it.cycled_list (); cw_it.forward ()) {
        wait_sample = cw_it.data ();
        if (tessedit_mm_use_prototypes)
          score = best_cluster->match_score (wait_sample, this);
        else
          score = sample->match_sample (wait_sample, FALSE, this);
        if (score < tessedit_cluster_t1) {
          if (score > tessedit_cluster_t3
          || tessedit_mm_use_prototypes) {
            add_it.add_after_stay_put (cw_it.extract ());
            #ifndef SECURE_NAMES
            if (tessedit_cluster_debug)
              tprintf
                ("Wait sample added to an existing cluster\n");
            #endif
          }
          else {
            #ifndef SECURE_NAMES
            if (tessedit_cluster_debug)
              tprintf
                ("Wait sample dropped, good match to an existing cluster\n");
            #endif
          }
        }
      }
    }
    while (!add_list.empty ());
  }
}


void Tesseract::complete_clustering(CHAR_SAMPLES_LIST *char_clusters,
                                    CHAR_SAMPLE_LIST *chars_waiting) {
  CHAR_SAMPLES *best_cluster;
  CHAR_SAMPLES_IT c_it = char_clusters;
  CHAR_SAMPLE_IT cw_it = chars_waiting;
  CHAR_SAMPLE *sample;
  inT32 total_sample_count = 0;

  while (!cw_it.empty ()) {
    cw_it.move_to_first ();
    sample = cw_it.extract ();
    best_cluster = new CHAR_SAMPLES (sample);
    c_it.add_to_end (best_cluster);
    check_wait_list(chars_waiting, sample, best_cluster);
  }

  for (c_it.mark_cycle_pt (); !c_it.cycled_list (); c_it.forward ()) {
    c_it.data ()->assign_to_char ();
    if (tessedit_use_best_sample)
      c_it.data ()->find_best_sample ();
    else if (tessedit_mm_adapt_using_prototypes)
      c_it.data ()->build_prototype ();

    if (tessedit_cluster_debug)
      total_sample_count += c_it.data ()->n_samples ();
  }
  #ifndef SECURE_NAMES
  if (tessedit_cluster_debug)
    tprintf ("Clustering completed, %d samples in all\n", total_sample_count);
  #endif

#ifndef GRAPHICS_DISABLED
  if (tessedit_demo_adaption)
    display_cluster_prototypes(char_clusters);
#endif

}

void Tesseract::adapt_to_good_ems(WERD_RES *word,
                                  CHAR_SAMPLES_LIST *char_clusters,
                                  CHAR_SAMPLE_LIST *chars_waiting) {
  PBLOB_LIST *blobs = word->outword->blob_list ();
  PBLOB_IT blob_it(blobs);
  inT16 i;
  CHAR_SAMPLE *sample;
  CHAR_SAMPLES_IT c_it = char_clusters;
  CHAR_SAMPLE_IT cw_it = chars_waiting;
  float score;
  float best_score;
  char best_char;
  CHAR_SAMPLES *best_cluster;
  PIXROW_LIST *pixrow_list;
  PIXROW_IT pixrow_it;
  IMAGELINE *imlines;            // lines of the image
  TBOX pix_box;                   // box of imlines
  // extent
  WERD copy_outword;             // copy to denorm
  TBOX b_box;
  PBLOB_IT copy_blob_it;
  OUTLINE_IT copy_outline_it;
  PIXROW *pixrow = NULL;

  static inT32 word_number = 0;

#ifndef GRAPHICS_DISABLED
  ScrollView* demo_win = NULL;
#endif

  inT32 resolution = page_image.get_res ();

  if (word->word->bounding_box ().height () > resolution / 3)
    return;

  word_number++;

  if (strchr (word->best_choice->unichar_string().string (), 'm') == NULL
    && (tessedit_process_rns
    && strstr (word->best_choice->unichar_string().string (), "rn") == NULL))
    return;

  if (tessedit_reject_ems)
    reject_all_ems(word);
  else if (tessedit_reject_suspect_ems)
    reject_suspect_ems(word);
  else {
    if (char_clusters->length () == 0) {
      #ifndef SECURE_NAMES
      if (tessedit_cluster_debug)
        tprintf ("No clusters to use for em adaption\n");
      #endif
      return;
    }

    if (!cw_it.empty ()) {
      complete_clustering(char_clusters, chars_waiting);
      print_em_stats(char_clusters, chars_waiting);
    }

    if ((!word_adaptable (word, tessedit_em_adaption_mode) ||
      word->reject_map.reject_count () != 0)
      && (strchr (word->best_choice->unichar_string().string (), 'm') != NULL
      || (tessedit_process_rns
      && strstr (word->best_choice->unichar_string().string (),
    "rn") != NULL))) {
      if (tessedit_process_rns
        && strstr (word->best_choice->unichar_string().string (),
      "rn") != NULL) {
        copy_outword = *(word->outword);
        copy_blob_it.set_to_list (copy_outword.blob_list ());
        i = 0;
        while (word->best_choice->unichar_string()[i] != '\0') {
          if (word->best_choice->unichar_string()[i] == 'r'
          && word->best_choice->unichar_string()[i + 1] == 'n') {
            copy_outline_it.set_to_list (copy_blob_it.data ()->
              out_list ());
            copy_outline_it.add_list_after (copy_blob_it.
              data_relative (1)->
              out_list ());
            copy_blob_it.forward ();
            delete (copy_blob_it.extract ());
            i++;
          }
          copy_blob_it.forward ();
          i++;
        }
      }
      else
        copy_outword = *(word->outword);

      copy_outword.baseline_denormalise (&word->denorm);
      copy_blob_it.set_to_list (copy_outword.blob_list ());
      char_clip_word(&copy_outword, page_image, pixrow_list, imlines, pix_box);
      pixrow_it.set_to_list (pixrow_list);
      pixrow_it.move_to_first ();

                                 // For debugging only
      b_box = copy_outword.bounding_box ();
      pixrow = pixrow_it.data ();

      blob_it.move_to_first ();
      copy_blob_it.move_to_first ();
      for (i = 0;
        word->best_choice->unichar_string()[i] != '\0';
        i++, pixrow_it.forward (), blob_it.forward (),
      copy_blob_it.forward ()) {
        if ((word->best_choice->unichar_string()[i] == 'm'
          || (word->best_choice->unichar_string()[i] == 'r'
          && word->best_choice->unichar_string()[i + 1] == 'n'))
        && !word->reject_map[i].perm_rejected ()) {
          if (tessedit_cluster_debug)
            tprintf ("Sample %c to check found in %s, index %d\n",
              word->best_choice->unichar_string()[i],
              word->best_choice->unichar_string().string (), i);

          if (tessedit_demo_adaption)
            tprintf
              ("Sample %c to check found in %s (%d), index %d\n",
              word->best_choice->unichar_string()[i],
              word->best_choice->unichar_string().string (), word_number,
              i);

          if (tessedit_matrix_match) {
            TBOX copy_box = copy_blob_it.data ()->bounding_box ();

            sample = clip_sample (pixrow_it.data (),
              imlines,
              pix_box,
              copy_outword.flag (W_INVERSE),
              word->best_choice->unichar_string()[i]);

                                 //Clip failed
            if (sample == NULL) {
              tprintf
                ("Unable to clip sample from %s, index %d\n",
                word->best_choice->unichar_string().string (), i);
              #ifndef SECURE_NAMES
              if (tessedit_cluster_debug)
                tprintf ("Sample rejected (no sample)\n");
              #endif
              word->reject_map[i].setrej_mm_reject ();
              if (word->best_choice->unichar_string()[i] == 'r') {
                word->reject_map[i + 1].setrej_mm_reject ();
                i++;
              }
              continue;
            }
          }
          else
            sample = new CHAR_SAMPLE(blob_it.data(),
                                     &word->denorm,
                                     word->best_choice->unichar_string()[i]);

          best_score = MAX_INT32;
          best_char = '\0';
          best_cluster = NULL;

          for (c_it.mark_cycle_pt ();
          !c_it.cycled_list (); c_it.forward ()) {
            if (c_it.data ()->character () != '\0') {
              score = c_it.data ()->match_score (sample, this);
              if (score < best_score) {
                best_cluster = c_it.data ();
                best_score = score;
                best_char = c_it.data ()->character ();
              }
            }
          }

          if (best_score > tessedit_cluster_t1) {
            #ifndef SECURE_NAMES
            if (tessedit_cluster_debug)
              tprintf ("Sample rejected (score %f)\n", best_score);
            if (tessedit_demo_adaption)
              tprintf ("Sample rejected (score %f)\n", best_score);
            #endif
            word->reject_map[i].setrej_mm_reject ();
            if (word->best_choice->unichar_string()[i] == 'r')
              word->reject_map[i + 1].setrej_mm_reject ();
          }
          else {
            if (word->best_choice->unichar_string()[i] == best_char) {
              #ifndef SECURE_NAMES
              if (tessedit_cluster_debug)
                tprintf ("Sample accepted (score %f)\n",
                  best_score);
              if (tessedit_demo_adaption)
                tprintf ("Sample accepted (score %f)\n",
                  best_score);
              #endif
              word->reject_map[i].setrej_mm_accept ();
              if (word->best_choice->unichar_string()[i] == 'r')
                word->reject_map[i + 1].setrej_mm_accept ();
            }
            else {
              #ifndef SECURE_NAMES
              if (tessedit_cluster_debug)
                tprintf ("Sample rejected (char %c, score %f)\n",
                  best_char, best_score);
              if (tessedit_demo_adaption)
                tprintf ("Sample rejected (char %c, score %f)\n",
                  best_char, best_score);
              #endif
              word->reject_map[i].setrej_mm_reject ();
              if (word->best_choice->unichar_string()[i] == 'r')
                word->reject_map[i + 1].setrej_mm_reject ();
            }
          }

          if (tessedit_demo_adaption) {
            if (strcmp (imagebasename.string (),
              tessedit_demo_file.string ()) != 0
              || word_number == tessedit_demo_word1
            || word_number == tessedit_demo_word2) {
#ifndef GRAPHICS_DISABLED
              demo_win =
                display_clip_image(&copy_outword,
                                   page_image,
                                   pixrow_list,
                                   pix_box);
#endif
              demo_word = word_number;
              best_cluster->match_score (sample, this);
              demo_word = 0;
            }
          }
          if (word->best_choice->unichar_string()[i] == 'r')
            i++;                 // Skip next character
        }
      }
      delete[]imlines;           // Free array of imlines
      delete pixrow_list;
    }
  }
}



void Tesseract::adapt_to_good_samples(WERD_RES *word,
                                      CHAR_SAMPLES_LIST *char_clusters,
                                      CHAR_SAMPLE_LIST *chars_waiting) {
  PBLOB_LIST *blobs = word->outword->blob_list ();
  PBLOB_IT blob_it(blobs);
  inT16 i;
  CHAR_SAMPLE *sample;
  CHAR_SAMPLES_IT c_it = char_clusters;
  CHAR_SAMPLE_IT cw_it = chars_waiting;
  float score;
  float best_score;
  char best_char;
  CHAR_SAMPLES *best_cluster;
  PIXROW_LIST *pixrow_list;
  PIXROW_IT pixrow_it;
  IMAGELINE *imlines;            // lines of the image
  TBOX pix_box;                   // box of imlines
  // extent
  WERD copy_outword;             // copy to denorm
  TBOX b_box;
  PBLOB_IT copy_blob_it;
  PIXROW *pixrow = NULL;

  static inT32 word_number = 0;

#ifndef GRAPHICS_DISABLED
  ScrollView* demo_win = NULL;
#endif

  inT32 resolution = page_image.get_res ();

  word_number++;

  if (tessedit_test_cluster_input)
    return;

  if (word->word->bounding_box ().height () > resolution / 3)
    return;

  if (char_clusters->length () == 0) {
    #ifndef SECURE_NAMES
    if (tessedit_cluster_debug)
      tprintf ("No clusters to use for adaption\n");
    #endif
    return;
  }

  if (!cw_it.empty ()) {
    complete_clustering(char_clusters, chars_waiting);
    print_em_stats(char_clusters, chars_waiting);
  }

  if ((!word_adaptable (word, tessedit_cluster_adaption_mode)
  && word->reject_map.reject_count () != 0) || tessedit_mm_use_rejmap) {
    if (tessedit_cluster_debug) {
      tprintf ("\nChecking: \"%s\"  MAP ",
        word->best_choice->unichar_string().string ());
      word->reject_map.print (debug_fp);
      tprintf ("\n");
    }

    copy_outword = *(word->outword);
    copy_outword.baseline_denormalise (&word->denorm);
    copy_blob_it.set_to_list (copy_outword.blob_list ());
    char_clip_word(&copy_outword, page_image, pixrow_list, imlines, pix_box);
    pixrow_it.set_to_list (pixrow_list);
    pixrow_it.move_to_first ();

                                 // For debugging only
    b_box = copy_outword.bounding_box ();
    pixrow = pixrow_it.data ();

    blob_it.move_to_first ();
    copy_blob_it.move_to_first ();
    for (i = 0;
      word->best_choice->unichar_string()[i] != '\0';
      i++, pixrow_it.forward (), blob_it.forward (),
    copy_blob_it.forward ()) {
      if (word->reject_map[i].recoverable ()
      || (tessedit_mm_all_rejects && word->reject_map[i].rejected ())) {
        TBOX copy_box = copy_blob_it.data ()->bounding_box ();

        if (tessedit_cluster_debug)
          tprintf ("Sample %c to check found in %s, index %d\n",
            word->best_choice->unichar_string()[i],
            word->best_choice->unichar_string().string (), i);

        if (tessedit_demo_adaption)
          tprintf ("Sample %c to check found in %s (%d), index %d\n",
            word->best_choice->unichar_string()[i],
            word->best_choice->unichar_string().string (),
            word_number, i);

        sample = clip_sample (pixrow_it.data (),
          imlines,
          pix_box,
          copy_outword.flag (W_INVERSE),
          word->best_choice->unichar_string()[i]);

        if (sample == NULL) {    //Clip failed
          tprintf ("Unable to clip sample from %s, index %d\n",
            word->best_choice->unichar_string().string (), i);
          #ifndef SECURE_NAMES
          if (tessedit_cluster_debug)
            tprintf ("Sample rejected (no sample)\n");
          #endif
          word->reject_map[i].setrej_mm_reject ();

          continue;
        }

        best_score = MAX_INT32;
        best_char = '\0';
        best_cluster = NULL;

        for (c_it.mark_cycle_pt ();
        !c_it.cycled_list (); c_it.forward ()) {
          if (c_it.data ()->character () != '\0') {
            score = c_it.data ()->match_score (sample, this);
            if (score < best_score) {
              best_cluster = c_it.data ();
              best_score = score;
              best_char = c_it.data ()->character ();
            }
          }
        }

        if (best_score > tessedit_cluster_t1) {
          #ifndef SECURE_NAMES
          if (tessedit_cluster_debug)
            tprintf ("Sample rejected (score %f)\n", best_score);
          if (tessedit_demo_adaption)
            tprintf ("Sample rejected (score %f)\n", best_score);
          #endif
          word->reject_map[i].setrej_mm_reject ();
        }
        else {
          if (word->best_choice->unichar_string()[i] == best_char) {
            #ifndef SECURE_NAMES
            if (tessedit_cluster_debug)
              tprintf ("Sample accepted (score %f)\n", best_score);
            if (tessedit_demo_adaption)
              tprintf ("Sample accepted (score %f)\n", best_score);
            #endif
            if (tessedit_test_adaption)
              word->reject_map[i].setrej_minimal_rej_accept ();
            else
              word->reject_map[i].setrej_mm_accept ();
          }
          else {
            #ifndef SECURE_NAMES
            if (tessedit_cluster_debug)
              tprintf ("Sample rejected (char %c, score %f)\n",
                best_char, best_score);
            if (tessedit_demo_adaption)
              tprintf ("Sample rejected (char %c, score %f)\n",
                best_char, best_score);
            #endif
            word->reject_map[i].setrej_mm_reject ();
          }
        }

        if (tessedit_demo_adaption) {
          if (strcmp (imagebasename.string (),
            tessedit_demo_file.string ()) != 0
            || word_number == tessedit_demo_word1
          || word_number == tessedit_demo_word2) {
#ifndef GRAPHICS_DISABLED
            demo_win =
              display_clip_image(&copy_outword,
                                 page_image,
                                 pixrow_list,
                                 pix_box);
#endif
            demo_word = word_number;
            best_cluster->match_score (sample, this);
            demo_word = 0;
          }
        }
      }
    }
    delete[]imlines;             // Free array of imlines
    delete pixrow_list;

    if (tessedit_cluster_debug) {
      tprintf ("\nFinal: \"%s\"  MAP ",
        word->best_choice->unichar_string().string ());
      word->reject_map.print (debug_fp);
      tprintf ("\n");
    }
  }
}
}  // namespace tesseract


void print_em_stats(CHAR_SAMPLES_LIST *char_clusters,
                    CHAR_SAMPLE_LIST *chars_waiting) {
  CHAR_SAMPLES_IT c_it = char_clusters;

  if (!tessedit_cluster_debug)
    return;
  #ifndef SECURE_NAMES
  tprintf ("There are %d clusters and %d samples waiting\n",
    char_clusters->length (), chars_waiting->length ());

  for (c_it.mark_cycle_pt (); !c_it.cycled_list (); c_it.forward ())
    c_it.data ()->print (debug_fp);
  #endif
  tprintf ("\n");
}


CHAR_SAMPLE *clip_sample(              //lines of the image
                         PIXROW *pixrow,
                         IMAGELINE *imlines,
                         TBOX pix_box,  //box of imlines extent
                         BOOL8 white_on_black,
                         char c) {
  TBOX b_box = pixrow->bounding_box ();
  float baseline_pos = 0;
  inT32 resolution = page_image.get_res ();

  if (!b_box.null_box ()) {
    ASSERT_HOST (b_box.width () < page_image.get_xsize () &&
      b_box.height () < page_image.get_ysize ());

    if (b_box.width () > resolution || b_box.height () > resolution) {
      tprintf ("clip sample: sample too big (%d x %d)\n",
        b_box.width (), b_box.height ());

      return NULL;
    }

    IMAGE *image = new (IMAGE);
    if (image->create (b_box.width (), b_box.height (), 1) == -1) {
      tprintf ("clip sample: create image failed (%d x %d)\n",
        b_box.width (), b_box.height ());

      delete image;
      return NULL;
    }

    if (!white_on_black)
      invert_image(image);  // Set background to white
    pixrow->char_clip_image (imlines, pix_box, NULL, *image, baseline_pos);
    if (white_on_black)
      invert_image(image);  //invert white on black for scaling &NN
    return new CHAR_SAMPLE (image, c);
  }
  else
    return NULL;
}


#ifndef GRAPHICS_DISABLED
void display_cluster_prototypes(CHAR_SAMPLES_LIST *char_clusters) {
  inT16 proto_number = 0;
  CHAR_SAMPLES_IT c_it = char_clusters;
  char title[WINDOWNAMESIZE];

  for (c_it.mark_cycle_pt (); !c_it.cycled_list (); c_it.forward ()) {
    proto_number++;

    #ifndef SECURE_NAMES
    tprintf ("Displaying proto number %d\n", proto_number);
    #endif

    if (c_it.data ()->prototype () != NULL) {
      sprintf (title, "Proto - %d", proto_number);
      display_image (c_it.data ()->prototype ()->make_image (),
        title, (proto_number - 1) * 400, 0, FALSE);
    }
  }
}
#endif

// *********************************************************************
// Simplistic routines to test the effect of rejecting ems and fullstops
// *********************************************************************

void reject_all_ems(WERD_RES *word) {
  inT16 i;

  for (i = 0; word->best_choice->unichar_string()[i] != '\0'; i++) {
    if (word->best_choice->unichar_string()[i] == 'm')
                                 // reject all ems
      word->reject_map[i].setrej_mm_reject ();
  }
}


void reject_all_fullstops(WERD_RES *word) {
  inT16 i;

  for (i = 0; word->best_choice->unichar_string()[i] != '\0'; i++) {
    if (word->best_choice->unichar_string()[i] == '.')
                                 // reject all fullstops
      word->reject_map[i].setrej_mm_reject ();
  }
}

namespace tesseract {
void Tesseract::reject_suspect_ems(WERD_RES *word) {
  inT16 i;

  if (!word_adaptable (word, tessedit_cluster_adaption_mode))
  for (i = 0; word->best_choice->unichar_string()[i] != '\0'; i++) {
    if (word->best_choice->unichar_string()[i] == 'm' && suspect_em (word, i))
                                 // reject all ems
      word->reject_map[i].setrej_mm_reject ();
  }
}
}  // namespace tesseract


void reject_suspect_fullstops(WERD_RES *word) {
  inT16 i;

  for (i = 0; word->best_choice->unichar_string()[i] != '\0'; i++) {
    if (word->best_choice->unichar_string()[i] == '.'
      && suspect_fullstop (word, i))
                                 // reject all commas
      word->reject_map[i].setrej_mm_reject ();
  }
}


BOOL8 suspect_em(WERD_RES *word, inT16 index) {
  PBLOB_LIST *blobs = word->outword->blob_list ();
  PBLOB_IT blob_it(blobs);
  inT16 j;

  for (j = 0; j < index; j++)
    blob_it.forward ();

  return (blob_it.data ()->out_list ()->length () != 1);
}


BOOL8 suspect_fullstop(WERD_RES *word, inT16 i) {
  float aspect_ratio;
  PBLOB_LIST *blobs = word->outword->blob_list ();
  PBLOB_IT blob_it(blobs);
  inT16 j;
  TBOX box;
  inT16 width;
  inT16 height;

  for (j = 0; j < i; j++)
    blob_it.forward ();

  box = blob_it.data ()->bounding_box ();

  width = box.width ();
  height = box.height ();

  aspect_ratio = ((width > height) ? ((float) width) / height :
  ((float) height) / width);

  return (aspect_ratio > tessed_fullstop_aspect_ratio);
}
