// file: dec_lmch_0.cc
//
 
// isip include files
//
#include "decoder.h"
#include "decoder_constants.h"
 
// method: switch_lm_cc
//
// arguments:
//  Trace* trace: (input) the input trace to project
//  Lex_node* strlex: (input) the current lexical node
//  int_4* phn: (input) the ci phone symbols that make up the cd model
//  
// return: a logical_1 indicating status
//
// this method switches the LM to the appropriate network given by the
// word node in the lexical node, creates the next model trace
// parameters and handles path projection at word-boundary
//
logical_1 Decoder::switch_lm_cc(Trace* trace_a, Lex_node* strlex_a) {

  // find new word node to use for LM switching
  //
  void_p* newhist = get_newhist_cc(strlex_a);

  // if the LM needs to be switched
  //
  if (newhist != (void_p)NULL) {

    // dummy trace variables
    //
    Trace* tr = (Trace*)NULL;
    float_4 score = (float_4)0;
    
    // flags
    //
    logical_1 slx_type = LXN_WORDGRAPH;
    logical_1 elx_type = LXN_WORDGRAPH;
    logical_1 his_type = HISTORY_WORDGRAPH;
    
    // identify the current LM type
    //
    logical_1 lextype = strlex_a->get_type_cc(); 
    
    // if this is ngram, need to switch to network LM
    //
    if (lextype == LXN_NGRAM) {
      
      // set lex node types
      //
      slx_type = LXN_WORDGRAPH;
      elx_type = LXN_NGRAM;
      his_type = HISTORY_WORDGRAPH;
      
    } // end if lex type is ngram 
    
    // otherwise for word graph type, need to switch to ngram LM
    //
    else if (lextype == LXN_WORDGRAPH) {
      
      // set lex node types
      //
      slx_type = LXN_NGRAM;
      elx_type = LXN_WORDGRAPH;
      his_type = HISTORY_NGRAM;
      
    } // end else lex type is word graph 
    
    // get the current lex node
    //
    Lex_node* lxn = trace_a->get_inst_cc()->get_lex_node_cc();
    
    // temporarily set the type of the current lex node
    //
    lxn->set_type_cc(slx_type);
    
    // create a new trace
    //
    tr = manager_d->new_trace_cc();
    tr->project_trace_cc(trace_a);
    score = trace_a->get_score_cc();
    tr->set_level_cc(DEC_WORD_LEVEL);
    
    // set the trace history
    //
    History* history = manager_d->new_hist_cc();
    history->init_cc(newhist, DEC_WORD_LEVEL, trace_a->get_phone_ind_cc(),
		     (int_4)0, frame_d, score);
    history->set_type_cc(his_type);
    history_list_d->insert_cc((void_p)history);
    
    // insert history parameters in trace
    //
    History* hist = trace_a->get_hist_cc();
    tr->set_max_hist_cc(num_hist_d);
    tr->set_hist_cc(history);
    tr->add_path_cc(hist, score);
    
    // project path with this trace
    //
    next_models_cc(tr);
    
    // remove this trace
    //
    manager_d->delete_cc(tr);
    
    // reset the lex node type
    //
    lxn->set_type_cc(elx_type);
    
  } // end if this is the first LM transition for this phone
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
