// file: ht_prune_2.cc
//
// isip include files
//
#include "hmm_train.h"
#include "hmm_train_constants.h"

// method: trace_compare_cc
//
// arguments:
//  Train_Link_node* node1 : (input) node containing the first trace
//  Train_Link_node* node2 : (input) node containing the second trace
//
// return: an int_4 containing result of comparison
//
// this method compares two traces purely by score
//
static int trace_compare_cc(const void* node1_a, const void* node2_a) {

  // result value of comparison
  //
  int_4 value = (int_4)0;
  
  // traces in the two nodes
  //
  Train_Trace* tr1 = (Train_Trace*)(((Train_Link_node*)node1_a)->get_item_cc());
  Train_Trace* tr2 = (Train_Trace*)(((Train_Link_node*)node2_a)->get_item_cc());

  // scores of the two traces
  //
  float_8 score1 = tr1->get_score_cc();
  float_8 score2 = tr2->get_score_cc();

  // compare the two and set value
  //
  if (score1 > score2) {
    value = (int_4)-1;
  }
  if (score1 < score2) {
    value = (int_4)1;
  }

  // exit gracefully
  //
  return (int)value;
}

// method: sort_traces_cc
//
// arguments:
//  Train_Link_node** marker : (input) marker position in trace list
//  int_4* active : (input) list of active phones
//  int_4 num_act : (input) number of active phones
//  int_4 nact : (input) number of active traces
//  int_4 max_act : (input) maximum number of active traces
//  float_8& thresh : (output) the threshold cutoff score
//
// return: a logical_1 to indicate status
//
// this method sorts all active phone-end traces and returns the score
// of the max_act^th trace
//
logical_1 sort_traces_cc(Train_Link_node** marker_a, int_4* active_a,
			 int_4 num_act_a, int_4 nact_a, int_4 max_act_a,
			 float_8& thresh_a) {

  // dummy variables
  //
  int_4 ind = (int_4)0;
  Train_Trace* tr = (Train_Trace*)NULL;
  Train_Link_node* node = (Train_Link_node*)NULL;

  // create the active nodes array
  //
  Train_Link_node** node_list = new Train_Link_node*[nact_a];

  // loop over all active trace lists and fill the array
  //
  for (int_4 ww = 0; ww < num_act_a; ww++) {
    
    // loop over all traces
    //
    for (Train_Link_node* nd = marker_a[active_a[ww]]; nd != (Train_Link_node*)NULL;
	 nd = nd->get_next_cc()) {

      node_list[ind++] = nd;
    }
  }

  // now sort this array in descending order according to the trace
  // scores
  //
  qsort(node_list, nact_a, sizeof(Train_Link_node*), trace_compare_cc);

  // get the score at the cut-off trace
  //
  node = node_list[max_act_a - 1];
  tr = (Train_Trace*)(node->get_item_cc());
  thresh_a = tr->get_score_cc();

  // free memory
  //
  delete [] node_list;
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
