// file: ht_project_1.cc
//
// isip include files
//
#include "hmm_train.h"
#include "hmm_train_constants.h"

// method: project_phones_cc
//
// arguments:
//  Train_Link_node** wdmarker : (input) marker positions in word-level trace lists
//  Train_Link_node** phmarker : (input) marker positions in phone-level trace lists
//  Train_Link_list** token_list : (input) lists of all tokens
//  Train_Phone** phones : (input) all phone models
//  Train_Link_list* treelist : (input) list of active lexical trees
//  Train_Lattice* lattice: (input) the lattice for this application
//  int_4 num_mono : (input) number of monophones
//  int_4 ph_size : (input) size of phonetic context
//  int_4* ph_map : (input) the phone map
//  int_4*& wd_active : (output) list of active words
//  int_4& wd_numact : (output) number of active words
//  int_4*& ph_active : (output) list of active phones
//  int_4& ph_numact : (output) number of active phones
//  int_4*& ngen : (input) number of new traces generated
//  float_8& max_score : (input) the maximum path score so far
//  logical_1 mlf_mode : (input) the mlf mode flag
//
// return: a logical_1 indicating status
//
// this method loops over all word and phone level traces, projects
// them onto new phones to create state-level traces and generates
// crossword phones if required
//
logical_1 project_phones_cc(Train_Link_node** wdmarker_a, Train_Link_node** phmarker_a,
			    Train_Link_list** token_list_a, Train_Phone** phones_a,
			    Train_Link_list* treelist_a, Train_Lattice* lattice_a,
			    int_4 num_mono_a, int_4 ph_size_a, int_4* ph_map_a,
			    int_4*& wd_active_a, int_4& wd_numact_a,
			    int_4*& ph_active_a, int_4& ph_numact_a,
			    int_4*& ngen_a, float_8& max_score_a,
			    int_4 context_mode_a, logical_1 mlf_mode_a,
			    int_4 num_sph_a, int_4* sph_index_a) {
  
  // dummy variables
  //
  Train_Trace* trace = (Train_Trace*)NULL;
  
  // loop over all active word-level trace lists
  //
  for (int_4 ww = 0; ww < wd_numact_a; ww++) {
    
    // loop over all the active traces
    //
    for (Train_Link_node* node = wdmarker_a[wd_active_a[ww]];
	 node != (Train_Link_node*)NULL; node = node->get_next_cc()) {
      
      // get the trace in this node
      //
      trace = (Train_Trace*)(node->get_item_cc());
      
      // project traces
      //
      generate_phones_cc(trace, token_list_a, phones_a, treelist_a,
			 lattice_a, num_mono_a, ph_size_a, ph_map_a,
			 wd_active_a, wd_numact_a, ph_active_a, ph_numact_a,
			 ngen_a, max_score_a, context_mode_a, mlf_mode_a,
			 num_sph_a, sph_index_a);
    }
  }

  // loop over all active phone-level trace lists
  //
  for (int_4 ww = 0; ww < ph_numact_a; ww++) {
    
    // loop over all the active traces
    //
    for (Train_Link_node* node = phmarker_a[ph_active_a[ww]];
	 node != (Train_Link_node*)NULL; node = node->get_next_cc()) {
      
      // get the trace in this node
      //
      trace = (Train_Trace*)(node->get_item_cc());
      
      // project traces
      //
      generate_phones_cc(trace, token_list_a, phones_a, treelist_a,
			 lattice_a, num_mono_a, ph_size_a, ph_map_a,
			 wd_active_a, wd_numact_a, ph_active_a, ph_numact_a,
			 ngen_a, max_score_a, context_mode_a, mlf_mode_a,
			 num_sph_a, sph_index_a);
    }
  }

  // exit gracefully
  //
  return ISIP_TRUE;
}
