// file: dec_insert_0.cc
//
 
// isip include files
//
#include "decoder.h"
#include "decoder_constants.h"
 
// method: insert_model_cc
//
// arguments:
//  Link_list*& tr_list: (input) the model level trace list
//  Trace* trace: (input) the trace to be inserted
//  
// return: a logical_1 indicating status
//
// this method inserts the given trace in the specified model level
// trace list
//
logical_1 Decoder::insert_model_cc(Link_list*& tr_list_a, Trace* trace_a) {

  // dummy variables
  //
  logical_1 flag = ISIP_FALSE;
  Trace* tr = (Trace*)NULL;
  Trace* betr = (Trace*)NULL;
  
  // allocate trace list if one doesn't exist yet
  //
  if (tr_list_a == (Link_list*)NULL) {
    tr_list_a = new Link_list();
  }

  // update maximum score
  //
  float_4 score = trace_a->get_score_cc();
  if (score > max_score_d[DEC_MODEL_LEVEL]) {
    max_score_d[DEC_MODEL_LEVEL] = score;
  }

  // loop over all active traces for this frame
  //
  for (Link_node* nd = tr_list_a->get_head_cc(); nd != (Link_node*)NULL;
       nd = nd->get_next_cc()) {
    
    // get the trace in this node
    //
    tr = (Trace*)(nd->get_item_cc());
    
    // compare this trace with the input trace and determine which is
    // better
    //
    betr = trace_a->compare_cc(tr);
    
    // if this was a valid comparison
    //
    if (betr != (Trace*)NULL) {
      
      // if the input trace is the better path
      //
      if (betr == trace_a) {
	
	// substitute input trace
	//
	nd->set_item_cc(trace_a);
	
	// if this is state or model-level alignment adjust reference
	// count
	//
	if ((align_mode_d == DEC_STATE_ALIGN_MODE) ||
	    (align_mode_d == DEC_MODEL_ALIGN_MODE)) {
	  tr->decr_ref_cc();
	}
	
	// delete old trace
	//
	manager_d->delete_cc(tr);
	
	// set flag
	//
	flag = ISIP_TRUE;
      }
      
      // or if the other trace is the better path
      //
      else {
	
	// if this is state or model-level alignment adjust reference
	// count
	//
	if ((align_mode_d == DEC_STATE_ALIGN_MODE) ||
	    (align_mode_d == DEC_MODEL_ALIGN_MODE)) {
	  trace_a->decr_ref_cc();
	}
	
	// remove new trace
	//
	manager_d->delete_cc(trace_a);
      }
    
      // return gracefully
      //
      return flag;
    }
  } // end for loop
  
  // if here, then insert the trace and update count
  //
  tr_list_a->insert_cc(trace_a);
  num_traces_gen_d[DEC_MODEL_LEVEL]++;

  // exit gracefully
  //
  return ISIP_TRUE;
}
