// file: ht_model_1.cc
//

// isip include files
//
#include "hmm_train.h"
#include "hmm_train_constants.h"
 
// method: read_new_models_cc
//
// arguments:
//  int_4& num_mod : (output) number of models
//  char_1* file : (input) data file name
//  Train_State** states : (input) the array of states
//  float_4*** trans : (input) the array of transition matrices
//  int_4**& st_map : (output) the map from model and temp state to final
//                             state index
//  int_4*& trans_map : (output) the map from the model to transitions
//  
// return: a Train_Model** pointing to a list of phone models
//
Train_Model** read_new_models_cc(int_4& num_mod_a, char_1* file_a,
			   Train_State** states_a, float_4*** trans_a,
			   int_4**& st_map_a, int_4*& trans_map_a) {
  
  // open file
  //
  FILE* fp = fopen((char*)file_a, "r");
  if (fp == (FILE*)NULL) {
    fprintf(stdout, "Cannot open file %s\n", file_a);
    exit(ISIP_PROTO_ERROR);
  }
  
  // variables to read data
  //
  char_1* tmp = new char_1[ISIP_MAX_STRING_LENGTH];
  char_1* name = new char_1[ISIP_MAX_STRING_LENGTH];
  int_4 ind = (int_4)0;
  logical_1 number_flag = ISIP_FALSE;
  
  int_4 num_states = (int_4)0;
  int_4 trans_ind = (int_4)0;
  int_4 state_ind = (int_4)0;
  
  Train_State** state_list = (Train_State**)NULL;
  Train_Model** models = (Train_Model**)NULL;
  
  // read data from file
  //
  while (fscanf(fp, "%s", tmp) != EOF) {
    
    // ignore comment lines
    //
    if (tmp[0] == (char_1)'#') {
      
      // do nothing
      //
      fscanf(fp, "%[^\n]", tmp);
      fscanf(fp, "%[\n]", tmp);
    }
    
    // read the model data
    //
    else if (strcmp((char*)tmp, (char*)HT_STR_NUM_MODELS) == 0) {

      // change the flag
      //
      number_flag = ISIP_TRUE;
      
      // read the number of models
      //
      fscanf(fp, "%s%ld", tmp, &num_mod_a);
      
      // allocate space for the model list
      //
      models = new Train_Model*[num_mod_a];
      st_map_a = new int_4*[num_mod_a];
      trans_map_a = new int_4[num_mod_a];
      
      // now read the model data
      //
      for (int_4 i = 0; i < num_mod_a; i++) {
	
	// read the model index
	//
	fscanf(fp, "%s%ld", tmp, &ind);
	
	// read the model string
	//
	fscanf(fp, "%s%s", tmp, name);
	
	// read the number of states
	//
	fscanf(fp, "%s%ld", tmp, &num_states);
	
	// allocate memory for the data
	//
	state_list = new Train_State*[num_states];
	st_map_a[ind] = new int_4[num_states];
	
	// read the transitions
	//
	fscanf(fp, "%s%ld", tmp, &trans_ind);
        trans_map_a[ind] = trans_ind;
	
	// read the states
	//
	fscanf(fp, "%s", tmp);
	for (int_4 j = 0; j < num_states; j++) {
	  
	  // read the state index
	  //
	  fscanf(fp, "%ld", &state_ind);
	  st_map_a[ind][j] = state_ind;
	  
	  // add to the state array
	  //
	  if (state_ind == 0) {
	    state_list[j] = (Train_State*)NULL;
	  }
	  else {
	    state_list[j] = states_a[state_ind];
	  }
	}

	// create the model
	//
	models[ind] = new Train_Model(num_states, trans_a[trans_ind], state_list);
	
	// free memory
	//
	delete [] state_list;
	state_list = (Train_State**)NULL;
      }
    }
  }

  // check the flag
  //
  if (number_flag == ISIP_FALSE) {
    fprintf(stdout, "Error : no number of models specified in %s\n",
	    (char*)file_a);
    exit(ISIP_PROTO_ERROR);
  }
				  
  // close file
  //
  fclose(fp);
    
  // free memory
  //
  delete [] tmp;
  delete [] name;
  
  // exit gracefully
  //
  return models;
}
