// file: dec_project_2.cc
//
 
// isip include files
//
#include "decoder.h"
#include "decoder_constants.h"
 
// method: enter_models_cc
//
// arguments: none
//  
// return: a logical_1 indicating status
//
// this method loops over all word and model level traces, and
// projects traces into the entry states of new models
//
logical_1 Decoder::enter_models_cc() {

  // dummy variables
  //
  float_4 score = (float_4)0;
  float_4 lmahead = (float_4)0;
  Trace* trace = (Trace*)NULL;
  Link_node* next = (Link_node*)NULL;
  Link_list* trlist = (Link_list*)NULL;
  
  // loop over all active word-level trace lists
  //
  for (int_4 ww = 0; ww < num_active_words_d; ww++) {
    
    // make sure traces exist
    //
    trlist = word_trlist_d[active_words_d[ww]];
    if (trlist != (Link_list*)NULL) {
    
      // loop over all the active traces
      //
      for (Link_node* node = trlist->get_head_cc();
	   node != (Link_node*)NULL; node = next) {
	
	// get the next node
	//
	next = node->get_next_cc();
	
	// get the trace in this node
	//
	trace = (Trace*)(node->get_item_cc());
	score = trace->get_score_cc();
	
	// prune this trace away if necessary
	//
	if ((beam_thresh_d[DEC_WORD_LEVEL] > score) ||
	    (wordend_thresh_d > score)) {
	  trace->decr_ref_cc();
	}
	
	// otherwise propagate traces to states
	//
	else {
	  next_models_cc(trace);
	}
	
	// remove this trace
	//
	manager_d->delete_cc(trace);
	trlist->remove_cc(node);
	num_traces_del_d[DEC_WORD_LEVEL]++;
      }

      // remove this trace list
      //
      delete word_trlist_d[active_words_d[ww]];
      word_trlist_d[active_words_d[ww]] = (Link_list*)NULL;
      active_words_d[ww] = (int_4)-1;
      
    } // end if trace list is not null
  } // end for loop over all active words
  
  // loop over all active phone-level trace lists
  //
  for (int_4 pp = 0; pp < num_active_models_d; pp++) {
    
    // make sure traces exist
    //
    trlist = model_trlist_d[active_models_d[pp]];
    if (trlist != (Link_list*)NULL) {
    
      // loop over all the active traces
      //
      for (Link_node* node = trlist->get_head_cc();
	   node != (Link_node*)NULL; node = next) {
	
	// get the next node
	//
	next = node->get_next_cc();
	
	// get the trace in this node
	//
	trace = (Trace*)(node->get_item_cc());
	score = trace->get_score_cc();
	
	// prune this trace away if necessary, otherwise project trace
        //
        if (beam_thresh_d[DEC_MODEL_LEVEL] <= score) {

	  // remove the lm looakahead score from trace
	  //
	  lmahead = trace->get_inst_cc()->get_lmscore_cc();
	  lmahead *= lmscale_d;
	  trace->incr_score_cc(-lmahead);

	  // project this trace
	  //
	  next_models_cc(trace);
        }
		
	// remove this trace
	//
	manager_d->delete_cc(trace);
	trlist->remove_cc(node);
	num_traces_del_d[DEC_MODEL_LEVEL]++;
      }

      // remove this trace list
      //
      delete model_trlist_d[active_models_d[pp]];
      model_trlist_d[active_models_d[pp]] = (Link_list*)NULL;
      cd_models_d[active_models_d[pp]]->set_active_cc(ISIP_FALSE);
      active_models_d[pp] = (int_4)-1;
      
    } // end if trace list is not null
  } // end for loop over all active phones

  // exit gracefully
  //
  return ISIP_TRUE;
}
