// file: cmmf_read_2.cc
//
 
// isip include files
//
#include "convert_mmf.h"
#include "convert_mmf_constants.h"
 
// method: read_states_bin_cc
//
// arguments:
//  int_4& num_st : (output) number of states
//  int_4& num_feat : (output) number of features in data vector
//  char_1* file : (input) data file name
//  
// return: a State** pointing to a list of States
//
// this method reads the State models from file --- each mixture
// component in the States is assumed to have a diagonal covariance
// matrix
//
Train_State** read_states_bin_cc(int_4& num_st_a, int_4& num_feat_a,
			   char_1* file_a) {
  
  // open file
  //
  FILE* fp = fopen((char*)file_a, "rb");
  if (fp == (FILE*)NULL) {
    fprintf(stdout, "cannot open file %s\n", file_a);
    exit(ISIP_PROTO_ERROR);	
  }	
  
  // variables to read data
  //
  int_4 num_mix = (int_4)0;
  float_4* weights = (float_4*)NULL;
  float_4* scale = (float_4*)NULL;
  float_4** mean = (float_4**)NULL;
  float_4** covar = (float_4**)NULL;
  
  Train_State** states = (Train_State**)NULL;
  
  // read the number of features and number of states
  //
  fread((void*)&num_feat_a, sizeof(int_4), 1, fp);
  fread((void*)&num_st_a, sizeof(int_4), 1, fp);
  
  // initialize the states
  //
  Train_State::set_num_features_cc(num_feat_a);
  states = new Train_State*[num_st_a];
  
  // for each state read the contents
  //
  for (int_4 i = 0; i < num_st_a; i++) {

    // read the number of mixtures in the state
    //
    fread((void*)&num_mix, sizeof(int_4), 1, fp);

    if (num_mix != 0) {
      
      // declare memory for the mean, covar, scale and weights for this state
      //
      weights = new float_4[num_mix];
      scale = new float_4[num_mix];
      mean = new float_4*[num_mix];
      covar = new float_4*[num_mix];
      
      for (int_4 j = 0; j < num_mix; j++) {
	mean[j] = new float_4[num_feat_a];
	covar[j] = new float_4[num_feat_a];
      }
      
      // read in mean and covar for each mix
      //
      for (int_4 j = 0; j < num_mix; j++) {
	
	// read the mixture weight
	//
	fread((void*)&weights[j], sizeof(float_4), 1, fp);
	
	// read the mean
	//
	for (int_4 k = 0; k < num_feat_a; k++) {
	  fread((void*)&mean[j][k], sizeof(float_4), 1, fp);
	}
	
	// read the covar
	//
	for (int_4 k = 0; k < num_feat_a; k++) {
	  fread((void*)&covar[j][k], sizeof(float_4), 1, fp);
	}
	
	// read in the scale factor
	//
	fread((void*)&scale[j], sizeof(float_4), 1, fp);
      }
      
      // create the state
      //
      states[i] = new Train_State();
      states[i]->set_num_mixtures_cc(num_mix);
      states[i]->set_weights_cc(weights);
      states[i]->set_scale_cc(scale);
      states[i]->set_covar_cc(covar);
      states[i]->set_mean_cc(mean);
    
    
      // clean up
      //
      delete [] weights;
      delete [] scale;
      for (int_4 j = 0; j < num_mix; j++) {
	delete [] mean[j];
	delete [] covar[j];
      }
      delete [] covar;
      delete [] mean;
    }
  }

  // close file
  //
  fclose(fp);
    
  // exit gracefully
  //
  return states;
}
