// file: dec_subpth_0.cc
//

// isip include files
//
#include "decoder.h"
#include "decoder_constants.h"
 
// method: lattice_find_subpaths_cc
//
// arguments:
//  FILE* flat: (input) lattice file
//  Decoder* dum_dec_a: (input) dummy decoder. this contains the word lexicon
//                      necessary to get phone transcriptions for words
//  FILE* fwords: (input) file containing words to search for
//  FILE* fout: (input) file to output results
//
// return: logical_1 indicating status
//
// this function parses the search_words string and finds the lexical 
// definition for each according to the word lexicon. a string of 
// search_phones is created, and the input lattice is searched for this 
// sequence of phones. the search results are written to fout.
//
logical_1 Decoder::lattice_find_subpaths_cc(Decoder* dum_dec_a, FILE* flat_a, 
					    FILE* fwords_a, FILE* fout_a) {


  // need to get phone transcription for this word via the lexicon in the 
  // dummy decoder
  //
  Hash_table* word_lexicon = dum_dec_a->lexicon_d;

  // pointer to the Word object in the lexicon
  //  
  Word* search_word = (Word*)NULL;

  // delete the current lattice
  //
  delete lattice_d;
  lattice_d = (Lattice*)NULL;

  // read lattice and do not compact
  //
  read_lattice_cc(flat_a, ISIP_TRUE);

  // string to hold search word sequence
  //
  char_1* current_search_word = new char_1[ISIP_MAX_STRING_LENGTH];
  
  while (fgets((char*)current_search_word, ISIP_MAX_STRING_LENGTH, fwords_a) 
	 != NULL) {
    
    // strip newline from end of string
    //
    int_4 len = strlen((char*)current_search_word);
    if (current_search_word[len-1] == '\n' || 
	current_search_word[len-1] == '\r' ) {
      current_search_word[len-1] = '\0';
    }

    // lookup the search_word in the lexicon. if it doesn't exist, return 
    // an error
    //
    if (word_lexicon->hash_lookup_cc(current_search_word) == NULL) {

      fprintf(stdout, "Error: search word '%s' not found in lexicon\n", 
	      current_search_word);
      return ISIP_FALSE;
    }
    
    search_word = (Word*)((word_lexicon->hash_lookup_cc(current_search_word))->get_item_cc());
    
    //search_word->debug_cc(stdout, (char_1*)"search_word");
    
    // construct string containing search phones
    //
    int_4** word_phones = search_word->get_phone_list_cc();    
    int_4* num_phones = search_word->get_num_phones_cc();
    int_4 num_prons = search_word->get_num_prons_cc();
    char_1** search_words = new char_1*[num_prons];
    
    // loop over the pronunciations
    //
    for (int_4 i = 0; i < num_prons; i++) {
      search_words[i] = new char_1[ISIP_MAX_STRING_LENGTH];        
      memset(search_words[i], 0, ISIP_MAX_STRING_LENGTH);
      
      // loop over phones for this pronunciation
      //
      for (int_4 j = 0; j < num_phones[i]; j++) {
	strcat((char*)search_words[i], 
	       (char*)dum_dec_a->ci_models_d[word_phones[i][j]]);    
	strcat((char*)search_words[i], " ");
      }
    }

    Link_list* results_list = new Link_list();

    for (int_4 i =0; i < num_prons; i++) { 
            
      Link_list* curr_results_list = new Link_list();
      
      int_4 curr_num_results;

      lattice_d->find_subpaths_cc(search_words[i], lexicon_d, curr_num_results, curr_results_list);
      
      // merge the current results with the existing results, removing duplicates
      //
      if (curr_num_results > 0) {
	lattice_d->merge_subpath_results_cc(results_list, curr_results_list);	
      }

      delete curr_results_list;
    }
    
    for (Link_node* lnd = results_list->get_head_cc(); 
	 lnd != (Link_node*)NULL; lnd = lnd->get_next_cc()) {

      Subpath_match* match = (Subpath_match*)lnd->get_item_cc();
      
      fprintf(fout_a, "%s %d %d %f\n", current_search_word, 
	      match->get_start_time_cc(), match->get_end_time_cc(), 
	      match->get_score_cc());
    }
    
          
    // clean up
    //
    for (int_4 i =0; i < num_prons; i++) {
      delete [] search_words[i]; 
      search_words[i] = (char_1*)NULL;
    }
    delete [] search_words;
    search_words = NULL;
  }

  // clean up
  //
  delete [] current_search_word;
  current_search_word = (char_1*)NULL;

  // exit gracefully
  //
  return ISIP_TRUE;
}
