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

// method: insert_token_cc
//
// arguments:
//  Train_Link_list*& tok_list : (input) the token linked list
//  Train_Trace* trace : (input) the trace to insert
//  int_4 st : (input) the destination state index
//  int_4& ngen : (output) number of new traces generated
//  float_8& max_score : (output) the max path score so far
//
// return: a logical_1 to indicate status
//
// this method inserts the given trace in the appropriate state token
// after Viterbi pruning. if the trace needs to create a node, return
// true. if the trace gets pruned or prunes another trace, returns
// false to indicate no growth in number of traces
//
logical_1 insert_token_cc(Train_Link_list*& tok_list_a, Train_Trace* trace_a, int_4 st_a,
			  int_4& ngen_a, float_8& max_score_a) {

  // dummy variable
  //
  logical_1 st_flag = ISIP_FALSE;
  Train_Token* tok = (Train_Token*)NULL;

  // allocate token list if one doesn't exist yet
  //
  if (tok_list_a == (Train_Link_list*)NULL) {
    tok_list_a = new Train_Link_list();
  }
  
  // loop over all states i.e. tokens for this phone
  //
  for (Train_Link_node* nd = tok_list_a->get_head_cc(); nd != (Train_Link_node*)NULL;
       nd = nd->get_next_cc()) {

    // get the token
    //
    tok = (Train_Token*)(nd->get_item_cc());
    
    // if a token for this state exists
    //
    if (tok->get_state_cc() == st_a) {
      st_flag = ISIP_TRUE;
      break;
    }
  }
	      
  // otherwise create a token for this state
  //
  if (st_flag == ISIP_FALSE) {
    tok = new Train_Token(st_a);
    tok_list_a->insert_cc(tok);
  }
  
  // insert the trace in this token
  //
  if (tok->insert_trace_cc(trace_a, max_score_a) == ISIP_TRUE) {
    ngen_a++;
  }

  // exit gracefully
  //
  return ISIP_TRUE;
}
