// file: tr_lxt_tree_2.cc
//

// isip include files
//
#include "train_lex_tree.h"
#include "train_lex_tree_constants.h"
#include <string.h>
// method: build_train_tree_cc
//
// arguments:
//  int_4* phn_ind : (input) the phone indexes
//  int_4* phones : (input) the monophone indexes
//  int_4 num_ph : (input) the number of the phones
//  int_4 num_mono : (input) the number of monophones
//  Train_Lattice_node* lat_node : (input) the end lattice node
//
// return: a logical_1 indicating success
//
// this method loops over all the phones in the transcription file
// and bulids a train tree
//
logical_1 Train_Lex_tree::build_traintree_cc(int_4* phn_ind_a, int_4* phones_a,
					int_4 num_ph_a, int_4 num_mono_a,
					Train_Lattice_node* lat_node_a) {
  
  // phone / word parameters
  //
  int_4 phone = (int_4)-1;
  int_4 phone_index = (int_4)0;
  head_d = new Train_Lex_node; 
  float_8 default_score = (float_8)0;
  
  // dummy lexical nodes
  //
  Train_Lex_node* curr_node = (Train_Lex_node*)NULL;
  Train_Lex_node* next_node = (Train_Lex_node*)NULL;
  Train_Lex_node* stop_node = (Train_Lex_node*)NULL;
  Train_Lex_node* st_node = (Train_Lex_node*)NULL;

  // memory manager
  //
  Train_Memory_manager* manager = Train_Link_list::get_manager_cc();

  // set the tree pointer in the head node
  //
  if (head_d->get_tree_cc() == (void_p)NULL) {
    head_d->set_tree_cc((void_p)this);
  }

  
    // set the next node as current
    //
    stop_node = (Train_Lex_node*)NULL;
    next_node = head_d;
    
    // loop over all phones in this pronunciations
    //
    for (int_4 j = 0; j < num_ph_a; j++) {
      
      // set the current node
      //
      curr_node = next_node;
      
      // the jth phone of this ith pronunciation
      //
      phone = phones_a[j];
      
      // get the node in the tree that contains this phone
      //
      next_node = curr_node->make_node_cc(phone);
      if (next_node->get_tree_cc() == (void_p)NULL) {
	next_node->set_tree_cc(this);
      }

      // set the phone index to the corresponding lex_tree node
      //
      phone_index = phn_ind_a[j];
      next_node->set_phone_ind_cc(phone_index);
      
      // add the current word to the list at this node and adjust LM
      // score
      //
      next_node->add_word_cc(lat_node_a, default_score);
    }

    // set one last phone node with "sil" for the SENT_END word
    //
    stop_node = manager->new_lex_cc();
    stop_node->set_phone_cc(TRAIN_LXT_SILENCE);
    stop_node->set_phone_ind_cc((int_4)1);
    stop_node->set_tree_cc((void_p)this);
    stop_node->add_word_cc(lat_node_a, default_score);
    // insert it in the appropriate place
    //
    next_node->add_child_cc(stop_node);
    next_node = stop_node;
    
    // add the stop node at the end of word
    //
    st_node = next_node->get_node_cc(TRAIN_LXN_STOP_PHONE);
    if (st_node != (Train_Lex_node*)NULL) {
      st_node->add_word_cc(lat_node_a, default_score);
      st_node = (Train_Lex_node*)NULL;
    }
    
    else {

      // create a stop node
      //
      stop_node = manager->new_lex_cc();
      stop_node->set_phone_cc(TRAIN_LXN_STOP_PHONE);
      stop_node->set_tree_cc((void_p)this);
      stop_node->add_word_cc(lat_node_a, default_score);
      
      // insert it in the appropriate place
      //
      next_node->add_child_cc(stop_node);
    }

    
    // exit gracefully
    //
    return ISIP_TRUE;  
}


