// file: ngram.h
//
// this is the header for the ngram class
//

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

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

// forward declaration of classes
//
#ifndef __ISIP_HASH_TABLE
#include <hash_table.h>
#endif

#ifndef __ISIP_NGRAM_LIST
#include <ngram_list.h>
#endif

// Ngram: a class that is used to store the ngram language model
//
class Ngram {
  
  //---------------------------------------------------------------------------
  //
  // protected data
  //
  //---------------------------------------------------------------------------
protected:
  
  // order of ngram
  //
  int_4 ngram_order_d;
  
  // lists of ngram nodes for each order
  //
  Ngram_list** ngram_lists_d;

  // language modeling parameters
  //
  float_4 lmscale_d;
  float_4 wdpenalty_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);
  int_4 size_cc();  
  
  // destructors/constructors
  //
  ~Ngram();                                             // destructor
  Ngram();                                              // default constructor
  Ngram(int_4 order, Ngram_list** ngram_lists);         // overloaded
  Ngram(Ngram& ngram);                                  // copy constructor

  // set methods
  //
  logical_1 set_order_cc(int_4 order) {
    ngram_order_d = order;
    return ISIP_TRUE;
  }
  
  logical_1 set_lists_cc(Ngram_list** ngram_lists) {
    ngram_lists_d = ngram_lists;
    return ISIP_TRUE;
  }

  logical_1 set_list_cc(int_4 index, Ngram_list* ngram_list);

  logical_1 set_lmscale_cc(float_4 value) {
    lmscale_d = value;
    return ISIP_TRUE;
  }
  
  logical_1 set_wdpenalty_cc(float_4 value) {
    wdpenalty_d = value;
    return ISIP_TRUE;
  }
  
  // get methods
  //
  int_4 get_order_cc() {
    return ngram_order_d;
  }
  
  Ngram_list** get_lists_cc() {
    return ngram_lists_d;
  }

  Ngram_list* get_list_cc(int_4 index);

  float_4 get_lmscale_cc() {
    return lmscale_d;
  }

  float_4 get_wdpenalty_cc() {
    return wdpenalty_d;
  }
  
  // ngram lm methods
  //
  float_4 get_score_cc(int_4 num, Word** words);
  float_4 get_score_cc(int_4 num, Word** history, Word* word);
  float_4 get_backoff_cc(int_4 num, Word** words);
  Ngram_node* get_unigram_cc(Word* word);

  // read ngram file to create ngram
  //
  logical_1 read_ngram_cc(FILE* fp, Hash_table* lexicon);
  
  // a method to compare nodes based on their word pointers
  //
  static int ngnode_compare_cc(Ngram_node** first, Ngram_node** second);
  
  //---------------------------------------------------------------------------
  //
  // private methods
  //
  //---------------------------------------------------------------------------
private:

  // private read methods
  //
  int_4 rearrange_nodes_cc(int_4 index,
				  int_4 prefix_items,
				  Link_list& tmp_symbol_list,
				  Ngram_node** prefix_node,
				  int_4* num_read);
};

// end of file
//
#endif
