// file: ht_nbest_0.cc
//

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

// isip include files
//
#include "hmm_train.h"
#include "hmm_train_constants.h"

// method: find_nbest_cc
//
// arguments:
//  Train_Link_list** trace_list : (input) list of active traces
//  Train_Link_node** marker : (input) trace position marker
//  int_4 num_nbest : (input) number of best hypotheses requested
//  int_4* active : (input) list of actice elements
//  int_4 num_act : (input) number of active elements
//  int_4& num_hyp : (output) number of best hyps generated
//  Train_Trace** array : (output) the n-best list
//
// return: a logical_1 flag indicating success
//
// this method finds the n-best word-end hypotheses
//
logical_1 find_nbest_cc(Train_Link_list** trace_list_a, Train_Link_node** marker_a,
			int_4 num_nbest_a, int_4* active_a,
			int_4 num_act_a, int_4& num_hyp_a,
			Train_Trace** array_a) {
  
  // dummy variables
  //
  Train_Trace* trace = (Train_Trace*)NULL;
  
  // initialize number of hypotheses
  //
  num_hyp_a = (int_4)0;
  
  // loop over all the active trace lists
  //
  for (int_4 i = 0; i < num_act_a; i++) {
    
    // loop over all active traces
    //
    for (Train_Link_node* node = marker_a[active_a[i]];
	 node != (Train_Link_node*)NULL; node = node->get_next_cc()) {
      
      // get the current trace
      //
      trace = (Train_Trace*)(node->get_item_cc());

      // sort the n-best array
      //
      for (int_4 j = 0; j < num_nbest_a; j++) {

	// if there is a space left in the array insert here
	//
	if (array_a[j] == (Train_Trace*)NULL) {
	  array_a[j] = trace;
	  if (num_hyp_a < num_nbest_a) {
	    num_hyp_a++;
	  }
	  break;
	}
	
	// if the score in the input trace is larger, insert here
	//
	if (array_a[j]->get_score_cc() < trace->get_score_cc()) {
	  for (int_4 k = num_nbest_a - 1; k > j; k--) {
	    array_a[k] = array_a[k-1];
	  }
	  if (num_hyp_a < num_nbest_a) {
	    num_hyp_a++;
	  }
	  array_a[j] = trace;
	  break;
	}
      } // end for j
    } // end for link node
  } // end for i

  // return gracefully
  //
  return ISIP_TRUE;
}
