// file: latp_score_0.cc
//

// isip include files
//
#include "lattice_path.h"
#include "lattice_path_constants.h"

// method: path_likelihood_cc
//
// arguments:
//  Lattice_node* lnode: (input) pointer to the current lattice path node
//  Lattice_path* prev_lpath: (input) pointer to the previous Lattice_path
//                            when this pointer is NULL, the beginning of 
//                            the path has been reached  
//  float_4 lm_scale: (input) language model scaling factor
//  float_4 word_penalty (input) word insertion penalty
//  float_4 ac_score: (input/output) acoustic likelihood accumulated during traceback
//  float_4 lm_score: (input/output) language_model likelihood accumulated during traceback
//                 
//
// return: a logical_1 indicating status
//
// this recursive method backtracks a Lattice_path and accumulates the score
// of the path.
//
logical_1 Lattice_path::path_likelihood_cc(Lattice_node* lnode_a, 
					   Lattice_path* prev_lpath_a,
					   float_4 lm_scale_a,
					   float_4 word_penalty_a,
					   float_4& ac_score_a,
					   float_4& lm_score_a) {

  if (prev_lpath_a == (Lattice_path*) NULL) {
    return ISIP_TRUE;
  }
  else {
    
    // get the node from the previous lattice_path pointer
    //
    Lattice_node* lnode = prev_lpath_a->get_curr_cc();
    
    // get the list of next nodes from the previous node. 
    //
    Link_list* next_list = lnode->get_next_nodes_cc();
    
    // find the index of the node lnode_a in the list of next nodes. this index
    // is needed in order to get the correct acoustic and language model 
    // likelihoods
    //
    int_4 idx = 0;
    
    for (Link_node* lnd = next_list->get_head_cc();
	 lnd != (Link_node*)NULL; lnd = lnd->get_next_cc()) {  
      
      if ((Lattice_node*)lnd->get_item_cc() == lnode_a) {
	break;
      }
      
      // increment index
      //
      idx++;
    }
    
    float_4* ac_scores = lnode->get_ac_scores_cc();
    float_4* lm_scores = lnode->get_lm_scores_cc();

    // update scores
    //
    ac_score_a += ac_scores[idx];
    lm_score_a += word_penalty_a + (lm_scale_a * lm_scores[idx]);

    // recursive call to previous node
    //
    path_likelihood_cc(lnode, prev_lpath_a->get_prev_cc(), lm_scale_a, 
		       word_penalty_a, ac_score_a, lm_score_a);
    
  }

  // exit gracefully
  //
  return ISIP_TRUE;
}
