// file: lattice_path.h
//
// this is the header for the lattice path class
//

// make sure definitions are only made once
//
#ifndef __ISIP_LATTICE_PATH
#define __ISIP_LATTICE_PATH

// isip include files
//
#ifndef __ISIP_LINK_LIST
#include <link_list.h>
#endif

#ifndef __ISIP_INTEGRAL
#include <integral.h>
#endif

#ifndef __ISIP_INTEGRAL_CONSTANTS
#include <integral_constants.h>
#endif

#ifndef __ISIP_LATTICE_NODE
#include <lattice_node.h>
#endif

// forward declaration of classes
//
//class Lattice_node;

// Lattice_path: a class that is used to store a path through the
// lattice nodes that keeps track of the path score depending on the
// insertions, deletions, substitutions and correct matches in
// comparison with the words of the reference utterance transcription
//
class Lattice_path {
  
  //---------------------------------------------------------------------------
  //
  // protected data
  //
  //---------------------------------------------------------------------------
protected:

  // path parameters
  //
  int_4 word_pos_d;       // position index in terms of words consumed
  int_4 path_type_d;      // current type of the path
  int_4 score_d;          // cumulative penalty score

  // lattice node parameters
  //
  Lattice_node* curr_d;   // the currently covered lattice node
  Lattice_path* prev_d;   // the back-pointer path
    
  //---------------------------------------------------------------------------
  //
  // 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);
  int_4 size_cc();
    
  // destructors/constructors
  //
  ~Lattice_path();                             // destructor
  Lattice_path();                              // default constructor
  Lattice_path(Lattice_path& lpath);           // copy constructor

  // methods to access path position
  //
  logical_1 set_pos_cc(int_4 pos) {
    word_pos_d = pos;
    return ISIP_TRUE;
  }
  
  int_4 get_pos_cc() {
    return word_pos_d;
  }
  
  logical_1 incr_pos_cc() {
    word_pos_d++;
    return ISIP_TRUE;
  }

  // methods to access path type
  //
  logical_1 set_type_cc(int_4 type) {
    path_type_d = type;
    return ISIP_TRUE;
  }
  
  int_4 get_type_cc() {
    return path_type_d;
  }

  // methods to access score
  //
  logical_1 set_score_cc(int_4 score) {
    score_d = score;
    return ISIP_TRUE;
  }

  int_4 get_score_cc() {
    return score_d;
  }

  logical_1 incr_score_cc(int_4 score) {
    score_d += score;
    return ISIP_TRUE;
  }

  // methods to access current lattice node
  //
  logical_1 set_curr_cc(Lattice_node* latn) {
    curr_d = latn;
    return ISIP_TRUE;
  }
  
  Lattice_node* get_curr_cc() {
    return curr_d;
  }

  // methods to access previous lattice path node
  //
  logical_1 set_prev_cc(Lattice_path* lpath) {
    prev_d = lpath;
    return ISIP_TRUE;
  }
  
  Lattice_path* get_prev_cc() {
    return prev_d;
  }
  
  // methods to compare two paths
  //
  Lattice_path* compare_cc(Lattice_path* lpath);

  // methods to grow paths
  //
  logical_1 project_cc(Lattice_path* lpath, Lattice_node* lnode, int_4 type);

  // method to clear the contents of the lattice path
  //
  logical_1 clear_cc();

  // get the likelihood score of a path
  //
  logical_1 path_likelihood_cc(float_4 lm_scale, float_4 word_penalty, 
			       float_4& ac_score, float_4& lm_score) {
    // initialize scores
    //
    ac_score = 0;
    lm_score = 0;

    return path_likelihood_cc(curr_d, prev_d, lm_scale, word_penalty, ac_score, lm_score);
  }
  
  //---------------------------------------------------------------------------
  //
  // private methods
  //
  //---------------------------------------------------------------------------
private:

  logical_1 path_likelihood_cc(Lattice_node* lnode, Lattice_path* prev_lpath,
			       float_4 lm_scale, float_4 word_penalty, 
			       float_4& ac_score, float_4& lm_score);

};

// end of file
// 
#endif
