// file: lat_update_0.cc
//

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

// method: update_scores_cc
//
// arguments:
//  Ngram* ngram: (input) the n-gram language model
//  int_4 order: (input) the order of the ngram LM
//  
// return: a logical_1 flag indicating status
//
// this method updates the scores at each lattice node using the given
// ngram LM (currently works only for bigram lms)
//
logical_1 Lattice::update_scores_cc(Ngram* ngram_a, int_4 order_a) {

  // dummy variables
  //
  Word** words = new Word*[order_a];
  int_4 num = (int_4)0;

  Lattice_node* latn = (Lattice_node*)NULL;
  Lattice_node* latnext = (Lattice_node*)NULL;
  
  Link_list* nextlist = (Link_list*)NULL;
  float_4* lmscore = (float_4*)NULL; 
  
  Hash_cell** lcells = lnode_d->get_cells_cc();
  int_4 hsize = lnode_d->get_size_cc();

  // loop over all hash cells
  //
  for (int_4 i = 0; i < hsize; i++) {
    for (Hash_cell* cell = lcells[i]; cell != (Hash_cell*)NULL;
         cell = cell->get_next_cc()) {

      // reset the word array
      //
      num = (int_4)0;
      for (int_4 j = 0; j < order_a; j++) {
	words[j] = (Word*)NULL;
      }
      
      // get the lattice node here
      //
      latn = (Lattice_node*)(cell->get_item_cc());

      // get the word here
      //
      words[num] = latn->get_word_cc();
      if (words[num] != (Word*)NULL) {
	num++;
      }
      
      // get the next nodes and lm score
      //
      lmscore = latn->get_lm_scores_cc();
      nextlist = latn->get_next_nodes_cc();

      // loop over all descendent nodes for the depth of the ngram
      // order
      //
      if (nextlist != (Link_list*)NULL) {
	int_4 ww = (int_4)0;
	for (Link_node* nd = nextlist->get_head_cc();
	     nd != (Link_node*)NULL; nd = nd->get_next_cc()) {

	  // get the lattice node here
	  //
	  latnext = (Lattice_node*)(nd->get_item_cc());
	  
	  // get the word here
	  //
	  words[num] = latnext->get_word_cc();
	  num++;

	  // get the lm score from the ngram lm
	  //
	  lmscore[ww] = ngram_a->get_score_cc(num, words);
	  num--;
	  ww++;
	}
      } // end if next list is not null
    } // end loop over all hash cells
  } // end loop over hash table
  
  // free memory
  //
  delete [] words;
  words = (Word**)NULL;
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
