// file: $ISIP_DT/class/v1.0/decision_tree/decision_tree.h
//

// make sure the definitions are made only once
//
#ifndef __ISIP_DECISION_TREE
#define __ISIP_DECISION_TREE

// isip include files
//
#ifndef __ISIP_INTEGRAL
#include <integral.h>
#endif

#ifndef __ISIP_DT_NODE
#include <dt_node.h>
#endif

// Decision_tree: a class that defines a decision tree for state tying
//
class Decision_tree {
  
  //---------------------------------------------------------------------------
  //
  // protected data
  //
  //---------------------------------------------------------------------------
protected:
  
  // declare a variable for debugging
  //
  int_4 debug_level_d;

  // central phone for the states in the current tree and position of state 
  // in a model
  //
  char_1* cph_d;
  int_4 state_pos_d;
  
  // pointer to the root of the tree
  //
  Dt_node* root_d;
  
  // user specified threshold value used for decision whether a certain node
  // should be split or not
  //
  float_4 split_threshd_d;
  float_4 merge_threshd_d;
  float_4 num_occ_threshd_d;          // minimum number of states in a dt_node
  
  // pointer to link_list of all the leaf nodes
  //
  Link_list* leaf_nodes_d;
  
  // number of leaf nodes in the tree
  //
  int_4 num_leaf_d;
  
  //---------------------------------------------------------------------------
  //
  // public methods
  //
  //---------------------------------------------------------------------------
public:
  
  // required methods
  //
  char_1* name_cc();
  volatile void error_handler_cc(char_1* mname, char_1* msg);
  logical_1 debug_cc(FILE* fp, char_1* message);
  logical_1 set_debug_cc(int_4 debug_level);
  int_4 size_cc();
  
  // destructor/constructor
  //
  ~Decision_tree();
  Decision_tree();
  Decision_tree(Dt_node* root);
  Decision_tree(Decision_tree& dec_tree);  
  
  // set and get the central phone and state position of the tree
  //
  logical_1 set_cph_cc(char_1* cph);
  char_1* get_cph_cc() {
    return cph_d;
  }
  logical_1 set_state_pos_cc(int_4 phn_pos) {
    state_pos_d = phn_pos;
    return ISIP_TRUE;
  }
  int_4 get_state_pos_cc() {
    return state_pos_d;
  }
  
  //set and get threshold for splitting and merging
  //
  logical_1 set_split_threshd_cc(float_4 split_threshd) {
    split_threshd_d = split_threshd;
    return ISIP_TRUE;
  }
  float_4 get_split_threshd_cc() {
    return split_threshd_d;
  }
  logical_1 set_merge_threshd_cc(float merge_threshd) {
    merge_threshd_d = merge_threshd;
    return ISIP_TRUE;
  }
  float_4 get_merge_threshd_cc() {
    return merge_threshd_d;
  }
  
  logical_1 set_num_occ_threshd_cc(float_4 num_occ) {
    num_occ_threshd_d = num_occ;
    return ISIP_TRUE;
  }
  float_4 get_num_occ_threshd_cc() {
    return num_occ_threshd_d;
  }
  
  // set and get the pointer to the link list of the leaf nodes
  //
  logical_1 set_leaf_list_cc(Link_list* leaf_list) {
    leaf_nodes_d = leaf_list;
    return ISIP_TRUE;
  }
  Link_list* get_leaf_list_cc() {
    return leaf_nodes_d;
  }
  
  // set and get the number of leaf nodes
  //
  logical_1 set_num_leaf_cc(); // this method can count number of leaf in the
                               // leaf_list and set the number
  logical_1 set_num_leaf_cc(int_4 num_leaf) {
    num_leaf_d = num_leaf;
    return ISIP_TRUE;
  }
  int_4 get_num_leaf_cc() {
    return num_leaf_d;
  }
  
  // set and get the root_node of the tree
  //
  Dt_node* get_root_cc() {
    return root_d;
  }
  logical_1 set_root_cc(Dt_node* node) {
    root_d = node;
    return ISIP_TRUE;
  }
  
  // method to compute the likelihood of the current tree
  //
  float_4 compute_likelihood_cc();
  
  // methods to merge two nodes of the tree, and compute the likelihood
  // decrease aftr merging
  //
  float_4 compute_lk_dec_cc(Dt_node* dt_node_1, Dt_node* dt_node_2,
			    State** states, float_4* occupancy,
			    int_4 num_feat, int_4 num_mix);
  
  Dt_node* merge_nodes_cc(Dt_node* dt_node_1, Dt_node* dt_node_2);
  
  // method to output the Decision tree into a file
  // 
  logical_1 write_tree_cc(FILE* fpdt);
  logical_1 write_states_cc(FILE* fpst);
  logical_1 read_tree_cc(FILE* fpdt);

  //---------------------------------------------------------------------------
  //
  // private methods
  //
  //---------------------------------------------------------------------------
private:
  
};

//end of file
//
#endif
