// file: lat_wer_4.cc
//

// system include file
//
#include <string.h>

// isip include files
//
#include "lattice.h"
#include "lattice_constants.h"

// method: backtrack_cc
//
// arguments:
//  Lattice_path* best: (input) the best path at this point
//  Word** words: (input) the reference word list
//  int_4 nref: (output) number of words in the reference
//  char_1*& utt: (output) the output utterance
//  int_4& corr: (output) number of correct words
//  int_4& subs: (output) number of substitutions
//  int_4& dels: (output) number of deletions
//  int_4& ins: (output) number of insertions
//
// return: a logical_1 indicating status
//
// this method back-traces the best alignment path and generates the
// resulting word sequence, alongwith counting the number of
// substitution, insertion and deletion errors
//
logical_1 Lattice::backtrack_cc(Lattice_path* best_a, Word** words_a,
				int_4 nref_a, char_1*& utt_a,
				int_4& corr_a, int_4& subs_a,
				int_4& dels_a, int_4& ins_a) {

  // initialize the error counts
  //
  corr_a = (int_4)0;
  subs_a = (int_4)0;
  dels_a = (int_4)0;
  ins_a = (int_4)0;

  // initialize the utterance
  //
  if (utt_a == (char_1*)NULL) {
    utt_a = new char_1[ISIP_MAX_STRING_LENGTH];
  }
  strcpy((char*)utt_a, "");

  // if there was no best path
  //
  if (best_a == (Lattice_path*)NULL) {
    dels_a = nref_a - 2;
    return ISIP_TRUE;
  }
  
  // dummy variables
  //
  int_4 type = LATTICE_PATH_CORRECT;
  Lattice_node* latn = (Lattice_node*)NULL;
  Word* lwrd = (Word*)NULL;

  // generate a link list to hold the path nodes in the correct order
  //
  Link_list* pathlist = new Link_list();

  // loop over the back-pointers of the best path
  //
  Lattice_path* lpath = best_a;
  Lattice_path* plpath = best_a->get_prev_cc();
  while (plpath != (Lattice_path*)NULL) {
    pathlist->insert_cc(lpath);
    lpath = plpath;
    plpath = lpath->get_prev_cc();
  }

  // now do a forward pass to get all the words
  //
  for (Link_node* nd = pathlist->get_curr_cc(); nd != (Link_node*)NULL;
       nd = nd->get_prev_cc()) {

    // get the lattice path node here
    //
    lpath = (Lattice_path*)(nd->get_item_cc());

    // get the type and find if error
    //
    type = lpath->get_type_cc();
    if (type == LATTICE_PATH_SUBSTITUTION) {
      subs_a++;
    }
    else if (type == LATTICE_PATH_DELETION) {
      dels_a++;
    }
    else if (type == LATTICE_PATH_INSERTION) {
      ins_a++;
    }
    else if (type == LATTICE_PATH_SKIP) {
    }
    else {
      corr_a++;
    }

    // get the word and print to stdout if not deletion
    // and not a skip
    //
    if ((type != LATTICE_PATH_DELETION) && (type != LATTICE_PATH_SKIP)) {

      // get the word here
      //
      latn = lpath->get_curr_cc();
      lwrd = latn->get_word_cc();

      // discount for sentence start and end
      //
      if ((lwrd != words_a[0]) && (lwrd != words_a[nref_a - 1])) {

	// add the word
	//
	strcat((char*)utt_a, (char*)(lwrd->get_name_cc()));
	strcat((char*)utt_a, ISIP_STRING_SPACE);
      }

      // otherwise adjust the correct words count
      //
      else {
	corr_a--;
      }
    }
  } // end for loop

  // delete link list
  //
  delete pathlist;
  pathlist = (Link_list*)NULL;
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
