// file: $isip/util/speech/isip_model_converter/imc_model_0.cc
// version: $Id: imc_model_0.cc 8977 2003-01-12 06:37:52Z jelinek $
//
// isip include files
//
#include "isip_model_converter.h"
 
// method: read_models_cc
//
// arguments:
//  char_1* file : (input) data file name
//  Vector<VectorLong>& model_state_map : (output) the map from model to
//                                        state sequence
//  VectorLong& trans_map : (output) the map from the model to transitions
//  Vector<String>& model_names : (output) the names of the models
//  
// return: a boolean indicating status
//
// this method parses the prototype models file
//
boolean read_models_cc(char_1* file_a, Vector<VectorLong>& model_state_map_a,
		       VectorLong& model_trans_map_a,
		       Vector<String>& model_names_a) {

  // open file
  //
  FILE* fp = fopen((char*)file_a, "r");
  if (fp == (FILE*)NULL) {
    String out(L"Cannot open file ");
    out.concat((byte*)file_a);
    Console::put(out);
    Integral::exit();
    return (Model**)NULL;
  }
  
  // variables to read data
  //
  char* tmp = new char[File::MAX_FNAME_SIZE];
  char* name = new char[File::MAX_FNAME_SIZE];
  long ind = (long)0;
  long num_mod = (long)0;
  boolean number_flag = false;
  
  long num_states = (long)0;
  long trans_ind = (long)0;
  long state_ind = (long)0;
  
  // read data from file
  //
  while (fscanf(fp, "%s", tmp) != EOF) {
    
    // ignore comment lines
    //
    if (tmp[0] == (char)'#') {
      
      // do nothing
      //
      fscanf(fp, "%[^\n]", tmp);
      fscanf(fp, "%[\n]", tmp);
    }
    
    // read the model data
    //
    else if (strcmp((char*)tmp, (char*)IMC_STR_NUM_MODELS) == 0) {
      
      // change the flag
      //
      number_flag = true;
      
      // read the number of models
      //
      fscanf(fp, "%s%ld", tmp, &num_mod);
      
      // allocate space for the model mappings
      //
      model_state_map_a.setLength(num_mod);
      model_trans_map_a.setLength(num_mod);
      model_names_a.setLength(num_mod);
      
      // now read the model data
      //
      for (long i = 0; i < num_mod; i++) {
	
	// read the model index
	//
	fscanf(fp, "%s%ld", tmp, &ind);
	
	// read the model string
	//
	fscanf(fp, "%s%s", tmp, name);
	model_names_a(i).assign((byte*)name);
	
	// read the number of states
	//
	fscanf(fp, "%s%ld", tmp, &num_states);
	
	// read the transitions index
	//
	fscanf(fp, "%s%ld", tmp, &trans_ind);
        model_trans_map_a(ind) = trans_ind;
	
	// allocate memory for the state map
	//
	model_state_map_a(ind).setLength(num_states - 2);
	
	// read the states
	//
	fscanf(fp, "%s", tmp);

	// read the dummy start state index
	//
	fscanf(fp, "%ld", &state_ind);

	// read the other states
	//
	for (long j = 1; j < num_states - 1; j++) {
	  
	  // read the state index
	  //
	  fscanf(fp, "%ld", &state_ind);
	  (model_state_map_a(ind))(j-1) = state_ind - 1;
	}

	// read the dummy end state index
	//
	fscanf(fp, "%ld", &state_ind);
      }
    }
  }
  
  // check the flag
  //
  if (!number_flag) {
    fprintf(stdout, "Error : no number of models specified in %s\n",
	    (char*)file_a);
    fflush(stdout);
    exit(Integral::exit());
    return false;
  }
  
  // close file
  //
  fclose(fp);
  
  // free memory
  //
  delete [] tmp;
  delete [] name;
  
  // exit gracefully
  //
  return true;
}
