// file: bw_param_0.cc
//
// function to read data from parameter file
//

// isip include files
//
#include "bw_train.h"
#include "bw_train_constants.h"

// method: read_params_cc
//
// arguments:
//  FILE* fp : (input) file pointer to params file
//  char_1* trans_file : (input) name of transitions data file
//  char_1* state_file : (output) name of file containing updated states data
//  char_1* new_trans_file : (output) name of updated transitions data file
//  char_1* new_state_file : (input) name of file containing states data
//  char_1* model_file : (output) name of file containing models
//  char_1* mfcclist_file : (output) name of file containing mfcc file list
//  char_1* mono_file : (output) name of file containin monophones
//  char_1* phones_file : (output) name of file containing triphones
//  char_1* lablist_file : (output) name of file containing transcription file
//                                  list
//  char_1* acc_file : (output) name of accumulators file (batch mode)
//  char_1* acclist_file : (output) name of accumulator files list
//                                  (combine mode)
//  char_1* var_floor_file : (output) name of variance floor file
//  char_1* state_occ_file : (output) name of state occupancy file
//  int_4& input_mode : (output) input mfcc file mode
//  int_4& output_mode : (output) output file mode
//  int_4& context_mode : (output) the context mode
//  int_4& train_mode : (output) the training mode
//  int_4& occ_mode : (output) the state occupancy mode
//  float_4& width : (output) the beam width used in pruning
//  float_4& min_mpd : (output) the minimum model prob. deviance
//  float_4& min_occp : (output) the minimum occpancy probability
//  int_4& min_mod_cnt : (output) the minimum number of times a model must
//                       occur before the parameters of that model are updated
//  int_4& input_feature_format: (output) input feature file format
//  int_4& delta_win: (output) delta_win for delta & acc. calculations
//  logical_1& delta: (output) delta calculations
//  logical_1& acc: (output) acceleration calculations
//
// return: a logical flag to indicate success
//

// this method reads through the params file and reads the name of
// other files that are required
//
logical_1 read_params_cc(FILE* fp_a, char_1* trans_file_a,
			 char_1* state_file_a, char_1* new_trans_file_a,
			 char_1* new_state_file_a, char_1* model_file_a,
			 char_1* mfcclist_file_a, char_1* mono_file_a,
			 char_1* phones_file_a, char_1* lablist_file_a,
			 char_1* acc_file_a, char_1* acclist_file_a,
			 char_1* state_occ_file_a, char_1* var_floor_file_a,
			 int_4& input_mode_a, int_4& output_mode_a,
			 int_4& context_mode_a, int_4& train_mode_a,
			 int_4& occ_mode_a, float_4& width_a,
			 float_4& min_mpd_a, float_4& min_occp_a,
			 int_4& min_mod_cnt_a, int_4& input_feature_format_a,
			 int_4& delta_win_a, logical_1& delta_a,
			 logical_1& acc_a ) {
  
  // string to hold temporary data
  //
  char_1* tmp = new char_1[ISIP_MAX_STRING_LENGTH];

  // read data from file
  //
  while (fscanf(fp_a, "%s", tmp) != EOF) {
    
    // ignore comment lines 
    //
    if (tmp[0] == (char_1)'#') {
      
      // do nothing
      //
      fscanf(fp_a, "%[^\n]", tmp);
      fscanf(fp_a, "%[\n]", tmp);
    }

    // read name of monophones file
    //
    else if (strcmp((char*)tmp, BW_MONOPHONE_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)mono_file_a, (char*)tmp); 
      expand_filename_cc(mono_file_a);
    }

    // read name of transitions data file
    //
    else if (strcmp((char*)tmp, BW_TRANSITIONS_FILE ) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)trans_file_a, (char*)tmp); 
      expand_filename_cc(trans_file_a);
    }
    
    // read name of states data file
    //
    else if (strcmp((char*)tmp,  BW_STATES_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)state_file_a, (char*)tmp); 
      expand_filename_cc(state_file_a);
    }

    // read name of updated transitions data file
    //
    else if (strcmp((char*)tmp, BW_UPDATED_TRANS_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)new_trans_file_a, (char*)tmp); 
      expand_filename_cc(new_trans_file_a);
    }
    
    // read name of updated states data file
    //
    else if (strcmp((char*)tmp, BW_UPDATED_STATE_FILE ) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)new_state_file_a, (char*)tmp); 
      expand_filename_cc(new_state_file_a);
    }
    
    // read name of HMM models data file
    //
    else if (strcmp((char*)tmp, BW_MODELS_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)model_file_a, (char*)tmp); 
      expand_filename_cc(model_file_a);
    }
    
    // read name of triphones data file
    //
    else if (strcmp((char*)tmp,  BW_PHONES_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)phones_file_a, (char*)tmp); 
      expand_filename_cc(phones_file_a);
    }

    // read name of transcription file list
    //
    else if (strcmp((char*)tmp, BW_LABLIST_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)lablist_file_a, (char*)tmp);
      expand_filename_cc(lablist_file_a);
    }

    // read name of mfcc files list
    //
    else if (strcmp((char*)tmp, BW_MFCCLIST_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)mfcclist_file_a, (char*)tmp);
      expand_filename_cc(mfcclist_file_a);
    }
    
    // read name of accumulator file
    //
    else if (strcmp((char*)tmp, BW_ACC_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)acc_file_a, (char*)tmp);
      expand_filename_cc(acc_file_a);
    }

    // read name of the accumulator files list
    //
    else if (strcmp((char*)tmp, BW_ACCLIST_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)acclist_file_a, (char*)tmp);
      expand_filename_cc(acclist_file_a);
    }
    
    // read name of the state occupancy file
    //
    else if (strcmp((char*)tmp, BW_STATE_OCC_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)state_occ_file_a, (char*)tmp);
      expand_filename_cc(state_occ_file_a);
    }
    
    // read name of the variance floor file
    //
    else if (strcmp((char*)tmp, (char*)BW_VARIANCE_FLOOR_FILE) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      strcpy((char*)var_floor_file_a, (char*)tmp);
      expand_filename_cc(var_floor_file_a);
    }

    // read beam width for pruning
    //
    else if (strcmp((char*)tmp, (char*)BW_BEAM_WIDTH_NAME) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      width_a = (float_4)atof((char*)tmp);
    }

    // read minimal deviance
    //
    else if (strcmp((char*)tmp, (char*)BW_MIN_MPD_NAME) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      min_mpd_a = (float_4)atof((char*)tmp);
    }

    // read minimum occupancy probability
    //
    else if (strcmp((char*)tmp, (char*)BW_MIN_OCCP_NAME) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      min_occp_a = (float_4)atof((char*)tmp);
    }
    
    // read input mode
    //
    else if (strcmp((char*)tmp, (char*)BW_INPUT_MODE_NAME) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      if (strcmp((char*)tmp, (char*)BW_ASCII) == 0) {
	input_mode_a = BW_ASCII_MODE;
      }
      else if (strcmp((char*)tmp, (char*)BW_BINARY) == 0) {
	input_mode_a = BW_BINARY_MODE;
      }
    }

    // read input feature file format
    //
    else if (strcmp((char*)tmp, (char*)BW_INPUT_FEATURE_FORMAT) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      if (strcmp((char*)tmp, (char*)BW_HTK) == 0) {
	input_feature_format_a = BW_HTK_FORMAT;
      }
      else
	input_feature_format_a = BW_ISIP_PROTO_FORMAT;
    }
    
    // read output mode
    //
    else if (strcmp((char*)tmp, (char*)BW_OUTPUT_MODE_NAME) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      if (strcmp((char*)tmp, (char*)BW_ASCII) == 0) {
	output_mode_a = BW_ASCII_MODE;
      }
      else if (strcmp((char*)tmp, (char*)BW_BINARY) == 0) {
	output_mode_a = BW_BINARY_MODE;
      }
    }

    // read context mode
    //
    else if (strcmp((char*)tmp,(char*)BW_CONTEXT_MODE_NAME) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      if(strcmp((char*) BW_WORD_INTERNAL_NAME, (char*)tmp) ==0){
	context_mode_a = BW_WRD_INTERNAL;
      }
      else if(strcmp((char*)BW_MONO_PHONE_NAME, (char*)tmp) ==0){
	context_mode_a = BW_MONOPHONE;
      }
      else if(strcmp((char*)BW_CROSS_WORD_NAME, (char*)tmp) ==0){
	context_mode_a = BW_CROSS_WORD;
      }
      else {
	fprintf(stdout, "\nbw_param_0.cc:  context mode error\n\n");

	// exit ungracefully 
	//
	exit(ISIP_PROTO_ERROR);
      }
    }

    // read the training mode
    //
    else if (strcmp((char*)tmp, (char*)BW_TRAIN_MODE_NAME) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      if (strcmp((char*)BW_BATCH_MODE_NAME, (char*)tmp) == 0) {
	train_mode_a = BW_BATCH_MODE;
      }
      else if (strcmp((char*)BW_NORMAL_MODE_NAME, (char*)tmp) == 0) {
	train_mode_a = BW_NORMAL_MODE;
      }
      else if (strcmp((char*)BW_COMBINE_MODE_NAME, (char*)tmp) == 0) {
	train_mode_a = BW_COMBINE_MODE;
      }
      else {
	fprintf(stdout, "\nbw_param_0.cc: training mode error\n\n");
	
	// exit ungracefully
	//
	exit(ISIP_PROTO_ERROR);
      }
    }

    // read the state occupancy mode
    //
    else if (strcmp((char*)tmp, (char*)BW_STATE_OCC_NAME) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      if (strcmp((char*)BW_OPT_ON_NAME, (char*)tmp) == 0) {
	occ_mode_a = BW_OPT_ON;
      }
      else if (strcmp((char*)BW_OPT_OFF_NAME, (char*)tmp) == 0) {
	occ_mode_a = BW_OPT_OFF;
      }
      else {
	fprintf(stdout, "\nbw_param_0.cc: state occupancy mode error\n\n");
	
	// exit ungracefully
	//
	exit(ISIP_PROTO_ERROR);
      }
    }
    
    // read the minimum model count
    //
    else if (strcmp((char*)tmp, (char*)BW_MIN_MODEL_COUNT_NAME) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      min_mod_cnt_a = (int_4)atoi((char*)tmp);

      if (min_mod_cnt_a <= 0) {
	min_mod_cnt_a = 1;
      }
    }
    
    // read the delta window
    //
    else if (strcmp((char*)tmp, (char*)BW_OPT_DELTA_WIN) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      delta_win_a = (int_4)atoi((char*)tmp);
    }
    
    // read the delta parameter
    //
    else if (strcmp((char*)tmp, (char*)BW_OPT_COMPUTE_DELTA) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      if(strcmp((char*) BW_YES, (char*)tmp) == 0){
	delta_a = ISIP_TRUE;
      }
    }
    
   // read the acceleration parameters
    //
    else if (strcmp((char*)tmp, (char*)BW_OPT_COMPUTE_ACC) == 0) {
      fscanf(fp_a, "%s", tmp);
      fscanf(fp_a, "%s", tmp);
      if(strcmp((char*) BW_YES, (char*)tmp) == 0){
	acc_a = ISIP_TRUE;
      }
    }
    
    // otherwise ignore the line
    //
    else {
      fscanf(fp_a, "%[^\n]", tmp);
      fscanf(fp_a, "\n");
    }
  }
  
  // delete memory
  //
  delete [] tmp;
  
  // return gracefully
  //
  return(ISIP_TRUE);
}
