// file: ts_model_2.cc
//

// system include files
//
#include <string.h>

// isip include files
//
#include "tie_state.h"
#include "tie_state_constants.h"

// method: write_clist_cc
//
// arguments:
//   FILE* fp_out_clist: (output) file pointer to clist file
//   Hash_table*& phy_models: (output) hash table of the physical models
//   int_4& num_phy_models_a: (input) the number of physical models
//   Cd_model** cd_models: (input) a set of cd_models
//   int_4 num_cd_models_a: (input) the number of cd_models
//   int_4 phone_size_a: (input) the size of the cd phones, such as triphone
//
// return: a logical_1 indicating status
//
// this method loops through the cd_models and writes into the cd_phones
// list
//
logical_1 write_clist_cc(FILE* fp_out_clist_a, Hash_table*& phy_models_a,
			 int_4& num_phy_models_a, Cd_model** cd_models_a,
			 int_4 num_cd_models_a, int_4 phone_size_a) {
  
  // variables about the hash table
  //
  char_1* key_string = new char_1[ISIP_MAX_STRING_LENGTH];
  char_1* tmp = new char_1[ISIP_MAX_STRING_LENGTH];

  num_phy_models_a = 0;
  
  if( phy_models_a == (Hash_table*)NULL) {
    phy_models_a =  new Hash_table(num_cd_models_a);
  }
  
  Hash_cell* logi_model = (Hash_cell*)NULL;
  Hash_cell* model_cell = (Hash_cell*)NULL;
  char_1* item = (char_1*)NULL;
  int_4 k = 0;
  
  // variables about cd_models
  //
  char_1** phones = (char_1**)NULL;
  int_4 num_states ;
  int_4* states_ind = (int_4*)NULL;

  int_4 cd_phone_len = phone_size_a*TS_MAX_PHONE_LENGTH;
  char_1* cd_phone = new char_1[cd_phone_len];
  char_1* prev_phone = (char_1*)NULL;

  // get the cd_models
  //
  for (int_4 i = 0; i < num_cd_models_a; i++) {

    
    if(cd_models_a[i]->get_yesphy_cc() == ISIP_FALSE) {
      continue;
    }
    
    num_states = cd_models_a[i]->get_num_states_cc();
    // get this cd phone
    //
    phones = cd_models_a[i]->get_phones_cc();
    strcpy((char*)cd_phone, (char*)"");

    if(num_states == 1) {
      strcpy((char*)cd_phone, (char*)phones[1]);
    }
    for (k = 0; k < num_states/2; k++) {
      if (strcmp((char*)phones[k], (char*)TS_CDM_EMPTY_PHN) != 0) {
	strcat((char*)cd_phone, (char*)phones[k]);
	strcat((char*)cd_phone, (char*)"-");
      }
    }
    
    strcat((char*)cd_phone, (char*)phones[k]);
    k++;
    
    for (; k < num_states; k++) {
      if (strcmp((char*)phones[k], (char*)TS_CDM_EMPTY_PHN) != 0) {
	strcat((char*)cd_phone, (char*)"+");
	strcat((char*)cd_phone, (char*)phones[k]);
      }
    }
    
    // get the state indices
    //
    states_ind = cd_models_a[i]->get_states_ind_cc(); 
    
    // create the key string
    //
    sprintf((char*)key_string, "%ld", states_ind[0]);
    
    for (int_4 j = 1; j < num_states; j++) {
      strcat((char*)key_string, "-");
      sprintf((char*)tmp, "%ld", states_ind[j]);
      strcat((char*)key_string, (char*)tmp);
    }
          
    // there is no models corresponding to this phone yet
    //
    model_cell = phy_models_a->hash_lookup_cc(key_string);
    
    if(model_cell == (Hash_cell*)NULL) {

      // create a hash cell
      //
      logi_model = new Hash_cell(item, key_string);

      // set the item of the model_cell
      //
      item = new char_1[cd_phone_len];
      strcpy((char*)item, (char*)cd_phone);      
      logi_model->set_item_cc((void_p)item);
      
      // insert this model into the hash table
      //
      phy_models_a->hash_insert_cc(logi_model);
      cd_models_a[i]->set_yesphy_cc(ISIP_TRUE);
      num_phy_models_a ++;
      
      // print this phone into the clist file
      //
      fprintf(fp_out_clist_a, "%s\n", item);      
    }
    
    // this phone shares the same model with others
    //
    else {
      prev_phone = (char_1*)(model_cell->get_item_cc());
      cd_models_a[i]->set_yesphy_cc(ISIP_FALSE);
      fprintf(fp_out_clist_a, "%s\t%s\n", cd_phone, prev_phone);
    }
  }
  
  // free memory
  //
  delete [] key_string;
  delete [] cd_phone;
  delete [] tmp;
  
  // exit gracefully
  //
  return ISIP_TRUE;
}


