// file: $isip/util/speech/isip_model_converter/imc_phone_0.cc
// version: $Id: imc_phone_0.cc 8977 2003-01-12 06:37:52Z jelinek $
//
// isip include files
//
#include "isip_model_converter.h"
 
// method: read_phones_cc
//
// arguments:
//  char* file : (input) data file name
//  Vector<VectorLong>& phone_mono_map : (output) the map from phone to
//                                       monophone sequence
//  VectorLong& phone_model_map : (output) the map from the phone
//                                to physical model
//  Vector<String>& phone_names : (output) the names of the phones
//  
// return: a boolean indicating status
//
// this method parses the prototype phones file
//
boolean read_phones_cc(char_1* file_a, Vector<VectorLong>& phone_mono_map_a,
		       VectorLong& phone_model_map_a,
		       Vector<String>& phone_names_a,
		       long total_num_mono_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_phon = (long)0;
  boolean number_flag = false;
  
  long num_mono = (long)0;
  long model_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_PHONES) == 0) {
      
      // change the flag
      //
      number_flag = true;
      
      // read the number of phones
      //
      fscanf(fp, "%s%ld", tmp, &num_phon);
      
      // allocate space for the model mappings
      //
      phone_mono_map_a.setLength(num_phon);
      phone_model_map_a.setLength(num_phon);
      phone_names_a.setLength(num_phon);
      
      // now read the phone data
      //
      for (long i = 0; i < num_phon; i++) {
	
	// read the phone string
	//
	fscanf(fp, "%s", name);
	phone_names_a(i).assign((byte*)name);
	
	// read the number of constituent monophones
	//
	fscanf(fp, "%ld", &num_mono);
	
	for (long j = 0; j < num_mono; j++) {

	  // throw indices away
	  //
	  fscanf(fp, "%ld", &ind);
	}

	// allocate memory for the monophone map
	//
	phone_mono_map_a(i).setLength(IMC_TRIPHONE_SIZE);
	
	// read the map index
	//
	long ind_map;
	fscanf(fp, "%ld", &ind_map);
	
	fprintf(stdout, "reading phone: %s: ", name);
	
	// determine the monophone indices
	//
	for (long j = 0; j < IMC_TRIPHONE_SIZE; j++) {
	  
	  // read the monophone index
	  //
	  (phone_mono_map_a(i))(j) = ind_map % total_num_mono_a;
	  ind_map = ind_map / total_num_mono_a;
	  fprintf(stdout, " %ld%ld:%ld ", i, j,
		  (long)(phone_mono_map_a(i))(j));
	}

	fscanf(fp, "%ld", &model_ind);
	phone_model_map_a(i) = model_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;
}
