// file: lat_wer_3.cc
//

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

// method: correct_path_cc
//
// arguments:
//  Lattice_path* stpath: (output) the start path
//  int_4 nref: (input) number of reference words
//  Word** words: (input) list of reference words
//  Link_list* holder: (input) the list that holds all old paths
//  Lattice_path*& best: (output) the best path at this point
//
// return: a logical_1 to indicate status
//
// this method checks if a path exists in the lattice that exactly
// matches the reference transcription
//
logical_1 Lattice::correct_path_cc(Lattice_path* stpath_a, int_4 nref_a,
				   Word** words_a, Link_list* holder_a,
				   Lattice_path*& best_a) {

  // dummy variables
  //
  int_4 pos = (int_4)0;
  Word* lword = (Word*)NULL;
  Lattice_node* latn = (Lattice_node*)NULL;
  Lattice_node* latnode = (Lattice_node*)NULL;
  Link_list* lat_list = (Link_list*)NULL;

  // memory manager
  //
  Memory_manager* manager = Link_list::get_manager_cc();
  
  // lattice paths
  //
  Lattice_path* newpath = (Lattice_path*)NULL;
  Lattice_path* lpath = stpath_a;
  best_a = (Lattice_path*)NULL;
 
  // loop as long as there is a matching word
  //
  while (lpath != (Lattice_path*)NULL) {

    // store the path node in the list
    //
    if (holder_a != (Link_list*)NULL) {
      holder_a->insert_cc(lpath);
    }

    // reset the new path
    //
    newpath = (Lattice_path*)NULL;

    // stop looping if sentence end is found and set the best path
    // node
    //
    pos = lpath->get_pos_cc();
    if (pos == nref_a - 1) {
      best_a = lpath;
      break;
    }
    
    // get the current lattice node
    //
    latnode = lpath->get_curr_cc();
    
    // get the next possible lattice nodes
    //
    lat_list = latnode->get_next_nodes_cc();
    
    // loop over all next lattice nodes
    //
    for (Link_node* lnd = lat_list->get_head_cc();
	 lnd != (Link_node*)NULL; lnd = lnd->get_next_cc()) {
      
      // get the lattice node, the word and the lat node index
      //
      latn = (Lattice_node*)(lnd->get_item_cc());
      lword = latn->get_word_cc();
      
      // compare this word with the corresponding word in the
      // reference list
      //
      if (lword == words_a[pos + 1]) {
	
	// this word matches, so grow a new path with type
	// correct and put it in the correct list
	//
	newpath = manager->new_lpath_cc();
	newpath->project_cc(lpath, latn, LATTICE_PATH_CORRECT);
	break;
      }

      // if the word is a NULL then skip it with no penalty
      //
      if (lword == null_word_d) {
	
	// this word matches, so grow a new path with type
	// correct and put it in the correct list
	//
	newpath = manager->new_lpath_cc();
	newpath->project_cc(lpath, latn, LATTICE_PATH_SKIP);
	break;
      }
    } // end for all next lattice nodes
    
    // update lattice path
    //
    lpath = newpath;

  } // end while loop

  // return false if no perfect match found
  //
  if (best_a == (Lattice_path*)NULL) {
    return ISIP_FALSE;
  }
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
