// file: dec_project_6.cc
//
 
// isip include files
//
#include "decoder.h"
#include "decoder_constants.h"
 
// method: exit_word_cc
//
// arguments: none
//  
// return: a logical_1 indicating status
//
// this method loops over all model level traces, performs beam
// pruning and projects traces into words
//
logical_1 Decoder::exit_word_cc() {

  // local variables 
  //
  float_4 score = (float_4)0;
  Trace* trace = (Trace*)NULL;
  Lex_node* lexnode = (Lex_node*)NULL;
  Link_list* trlist = (Link_list*)NULL;
  Link_node* nd = (Link_node*)NULL;
  int_4 end_ph = (int_4)0;

  // reset the number of active words
  //
  num_active_words_d = (int_4)0;
  
  // loop over all active phone-level trace lists
  //
  for (int_4 pp = 0; pp < num_active_models_d; pp++) {
  
    // for the currently active phone-level traces at end of word make
    // word-level traces
    //
    trlist = model_trlist_d[active_models_d[pp]];
    if (trlist != (Link_list*)NULL) {

      // now loop over all the active phone-end traces and grow
      // word ends
      //
      for (Link_node* node = trlist->get_head_cc();
	   node != (Link_node*)NULL; node = nd) {
	
	// get the next node
	//
	nd = node->get_next_cc();
	
	// get the trace in this node
	//
	trace = (Trace*)(node->get_item_cc());
	score = trace->get_score_cc();
	
	// check for beam pruning
	//
	if (beam_thresh_d[DEC_MODEL_LEVEL] > score) {

	  // update reference counts if required
	  //
	  if ((align_mode_d == DEC_STATE_ALIGN_MODE) ||
	      (align_mode_d == DEC_MODEL_ALIGN_MODE)) {
	    trace->decr_ref_cc();
	  }
	  
	  // delete the trace
	  //
	  manager_d->delete_cc(trace);
	  trlist->remove_cc(node);
	  num_traces_del_d[DEC_MODEL_LEVEL]++;
	  
	} // end if beam pruning
	
	// otherwise grow word-level traces
	//
	else {
	  
	  // the current trace parameters
	  //
	  lexnode = trace->get_inst_cc()->get_lex_node_cc();
	  end_ph = lexnode->get_phone_cc();
	    
	  // if this is an end of word trace create the word-level
	  // trace
	  //
	  if (end_ph == LXN_STOP_PHONE) {
	    
	    // create a word-level trace
	    //
	    set_history_cc(trace, lexnode, active_models_d[pp]);
	    
	    // delete the phone-level trace if it is not cross-word
	    //
	    if ((context_mode_d != DEC_CROSS_WORD_MODE) ||
		(active_models_d[pp] == sil_model_d)) {
	      manager_d->delete_cc(trace);
	      trlist->remove_cc(node);
	      num_traces_del_d[DEC_MODEL_LEVEL]++;
	    }
	  } // end if phone with word end next
	} // end else grow word-level
      } // end for all current link nodes
    } // end if trace list is not NULL
  } // end for all active phones

  // exit gracefully
  //
  return ISIP_TRUE;
}
