// file: ts_model_4.cc
//

// isip include files
//
#include "tie_state.h"
#include "tie_state_constants.h"

// method: update_models_cc
//
// arguments:
//   char_1** mono       : (input)  monophone list
//   int_4 num_mono      : (input)  number of monophones
//   int_4 num_cd_models : (output) number of Cd_models
//   Cd_model**& cd_models: (input)  pointers to all Cd_models
//   int_4 num_spe_model    :  (input) number of special phones
//   char_1** special_model :  (input) special phone list
//   Decision_trees** trees :  (input) pointers to all decision trees
//   int_4 ph_size_a        :  (input) phone size
//   Hash_table* answers    :  (input) answers to questions in decision trees
//
// return: a logical_1 showing status
//
// this method pools all the Cd_models and update the state information
//
logical_1 update_models_cc(char_1** mono_a, int_4 num_mono_a, 
			   int_4 num_cd_models_a, Cd_model**& cd_models_a,
			   int_4 num_spe_models_a, char_1** special_models_a,
			   Decision_tree** trees_a, int_4 ph_size_a,
			   Hash_table* answers_a) {
  
  // local variables 
  //
  int_4 st_pos;
  int_4 tree_index;
  int_4 state_index;
  logical_1 result;
  logical_1 leaf_flag;
  Dt_node* curr_dt_node;
  
  int_4 j;
  
  char_1* lph ; 
  char_1* cph ; 
  char_1* rph ;  
  int_4 n_lph = 0;
  int_4 n_cph = 0;
  int_4 n_rph = 0;
  char_1** phn = (char_1**)NULL;
  logical_1 tag_special_model = ISIP_FALSE; 

  for (int_4 i = 0; i < num_cd_models_a; i++) {
    
    // get the phones in the Cd_models
    //
    phn = cd_models_a[i]->get_phones_cc();
    cph = phn[1];

    // check if this is a special model
    //
    for(j=0; j < num_spe_models_a ;j++) {
      if(strcmp((char*)cph, (char*)special_models_a[j])==0) {
	tag_special_model = ISIP_TRUE;
	break;
      }
    }

    if(tag_special_model != ISIP_TRUE) {

      lph = phn[0];
      rph = phn[2];

      // reset the phone indices
      //
      n_lph = 0;
      n_cph = 0;
      n_rph = 0;
      
      // get the left context index
      //
      if(lph!=(char_1*)NULL) {
	for(j=0; j<num_mono_a; j++) {
	  if(strcmp((char*)lph, (char*)mono_a[j])==0) {
	    n_lph = j;
	    break;
	  }
	}
      }
      else {
	n_lph = TS_EMPTY_PHN;
      }
      
      // get the control phone index
      //
      if(cph!=(char_1*)NULL) {
	
	for(j=0;j<num_mono_a;j++) {  
	  if(strcmp((char*)cph, (char*)mono_a[j])==0) {
	    n_cph = j;
	    break;
	  }
	}
      }
      else {
	n_cph = TS_EMPTY_PHN;
      }
      
      // get the right context index
      //
      if(rph!=(char_1*)NULL) {
	
	for(j=0; j<num_mono_a; j++) {	    
	  if(strcmp((char*)rph, (char*)mono_a[j])==0) {
	    n_rph = j;
	    break;
	  }
	}
      }
      else {
	n_rph = TS_EMPTY_PHN;
      }
      
	
      // get the states of the current phone
      //
      for(st_pos = 1; st_pos < CDM_DEFAULT_NUM_STATES - 1; st_pos++) {
	tree_index = map_tr_index_cc(n_cph, num_spe_models_a, st_pos);
	curr_dt_node = trees_a[tree_index]->get_root_cc();
	leaf_flag = curr_dt_node->get_leaf_flag_cc();
	  
	if(leaf_flag == ISIP_TRUE) {
	  state_index = curr_dt_node->get_label_cc();
	  cd_models_a[i] ->set_state_ind_cc(state_index, st_pos);
	}
	else {
	  while(leaf_flag != ISIP_TRUE) {
	    result = curr_dt_node->ask_opt_question_cc(answers_a,
						       n_lph, n_rph);
	    if(result == ISIP_TRUE) {
	      curr_dt_node = curr_dt_node->get_l_child_cc();
	    }
	    else {
	      curr_dt_node = curr_dt_node->get_r_child_cc();
	    }
	    leaf_flag = curr_dt_node->get_leaf_flag_cc();
	  }
	  state_index = curr_dt_node->get_label_cc();
	  cd_models_a[i] ->set_state_ind_cc(state_index, st_pos);
	}
      }
    }
    
    else {
	tag_special_model = ISIP_FALSE;
    }

  }
       
  // exist gracefully
  //
  return ISIP_TRUE;
  
}


