// file: ts_context_0.cc
//

// system include files
//
#include <string.h>

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

// method: pool_context_cc
//
// arguments:
//    FILE* fpm : (input)  file pointer to model file
//    int_4 num_states : (input) number of states in input
//    int_4 num_context : (input) context size
//    char_1** mono           : (input)  monophone list
//    int_4 num_mono          : (input)  number of monophones
//    int_4**& l_context : (output) left context list for states 
//    int_4**& r_context : (output) right context list for states
//
// return: a logical_1 showing status
//
// this is method is used to pool the left and right context of all the states
// the parsing of model files are designed for tri-phone models 
//
logical_1 pool_context_cc(FILE* fpm_a, int_4 num_states_a,
			  int_4 num_context_a, char_1** mono_a,
			  int_4 num_mono_a, int_4**& l_context_a,
			  int_4**& r_context_a) { 
			    
  // variables to read data
  //
  char_1* tmp = new char_1[ISIP_MAX_STRING_LENGTH];
  char_1* name = new char_1[ISIP_MAX_STRING_LENGTH];
  char_1* temp_str = (char_1*)NULL;
  
  int_4 num_model;
  int_4 temp_int;
  int_4 state_ind = (int_4)0;
  int_4 num_states = (int_4)0;
  
  int_4 i;
  int_4 j;

  char_1* lph = (char_1*)NULL;
  char_1* cph = (char_1*)NULL;
  char_1* rph = (char_1*)NULL;
  int_4 n_lph = 0;
  int_4 n_cph = 0;
  int_4 n_rph = 0;
  
  // reset the file pointer position
  //
  fseek(fpm_a,0,SEEK_SET);
  
  // read data from file
  //
  while (fscanf(fpm_a, "%s", tmp) != EOF) {
    
    // ignore comment lines
    //
    if (tmp[0] == (char_1)'#') {
      
      // do nothing
      //
      fscanf(fpm_a, "%[^\n]", tmp);
      fscanf(fpm_a, "%[\n]", tmp);
    }
    
    // read the model data
    //
    else if (strcmp((char*)tmp, TS_STR_NUM_MODELS) == 0) {
      
      // read the number of models
      //
      fscanf(fpm_a, "%s%ld", tmp, &num_model);

      // allocate memory for the left and right context list
      // we keep the dummy state[0]
      //
      l_context_a = new int_4*[num_states_a];
      r_context_a = new int_4*[num_states_a];
      
      for(i=0; i<num_states_a; i++) {
	l_context_a[i] = new int_4[num_context_a];
	r_context_a[i] = new int_4[num_context_a];
      }

      // now read the model data
      //
      for (int_4 i = 0; i < num_model; i++) {
	
	// read the model index
	//
	fscanf(fpm_a, "%s%ld", tmp, &temp_int);    // index line 
	fscanf(fpm_a, "%s%s", tmp, name);          // phone name
	fscanf(fpm_a, "%s%ld", tmp, &num_states);  // num_states	 
	fscanf(fpm_a, "%s%ld", tmp, &temp_int);    // skip this transition line
	
	if(num_states>3) {	

	  // check if the left context exist
	  //
	  temp_str = (char_1*)strstr((char*)name, "-");

	  // if not
	  //
	  if(temp_str == (char_1*)NULL) {
	    lph = (char_1*)NULL;
	    
	    // check if right context exist
	    //
	    temp_str = (char_1*)strstr((char*)name, "+");
	    if(temp_str == (char_1*)NULL) {
	      cph = name ;
	      rph = (char_1*)NULL;
	    }
	    else {
	      cph = (char_1*)strtok((char*)name, "+");
	      rph = (char_1*)strtok((char*)NULL, ISIP_STRING_SPACE);
	    } 
	  }

	  // if left context exist
	  //
	  else {
	       
	    // check if right context exist
	    //
	    temp_str = (char_1*)strstr((char*)name, "+");
	    lph = (char_1*)strtok((char*)name, "-");
	    
	    if(temp_str == (char_1*)NULL) {
	      cph = (char_1*)strtok((char*)NULL, ISIP_STRING_SPACE);
	      rph = (char_1*)NULL;
	    }
	    else {
	      cph = (char_1*)strtok((char*)NULL, "+");
	      rph = (char_1*)strtok((char*)NULL, ISIP_STRING_SPACE);
	    } 
	  }

	    
	  // 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;
	  }
	  
	  // read the states
	  //
	  fscanf(fpm_a, "%s", tmp);
	  for (j = 0; j < num_states; j++) {
	    
	    // set the state index
	    //
	    fscanf(fpm_a, "%ld", &state_ind);	    
	    if((j>0)&&(j<num_states-1)) {
	      
	      l_context_a[state_ind][0] = n_lph;
	      r_context_a[state_ind][0] = n_rph;
	      
	    }
	  }	  
	}     
	
	// skip the next line
	//
	else {
	  
	  fscanf(fpm_a, "%[^\n]", tmp);
	  fscanf(fpm_a, "%[\n]", tmp);
	  
	  fscanf(fpm_a, "%[^\n]", tmp);
	  fscanf(fpm_a, "%[\n]", tmp);
	} 
      }      
    }
  }
  
  // free memory
  //  
  delete [] name;
  delete [] tmp;
  
  return ISIP_TRUE;
}
