/* $Id: feature.h,v 1.3 2011/10/17 13:17:08 gildea Exp $ */

#ifndef __ITG_FEATURES_H
#define __ITG_FEATURES_H

#include <string>
#include <fstream>
#include "types.h"
using namespace std;

// typedefs
class Cell;
class Rule;
class FeatureList;
typedef FeatureList(*feature_init_function_ptr)(Cell&, double, double);
typedef hash_map<string,feature_init_function_ptr,hash_string,eq_string> string_init_function_hash;
typedef FeatureList(*feature_merge_function_ptr)(Cell*,Cell*,Cell*,Rule*,double);
typedef hash_map<string,feature_merge_function_ptr,hash_string,eq_string> string_merge_function_hash;

class FeatureList {
public:
  string_double_hash features_;
  bool loaded;

  static string_init_function_hash f_init_hash;
  static string_merge_function_hash f_merge_hash;

  FeatureList() {
    loaded = false;
  }

  FeatureList(const string& str) {
    loaded = false;
    load(str);
  }

  void clear() {
    features_.clear();
  }

  void load(const string&);
  void dump(const string&) const;

  double& operator[] (const string& key) {
    return features_[key]; 
  }
  double& operator[] (string& key) {
    return features_[key]; 
  }
  double& operator[] (const char* key) {
    string skey(key);
    return operator[](skey);
  }
  const double operator[] (string& key) const { 
    if (features_.count(key)) {
      return features_.find(key)->second;
    }
    return 0.0;
  }
};

double operator*(const FeatureList&, const FeatureList&);
FeatureList operator+(const FeatureList&, const FeatureList&);
FeatureList operator-(const FeatureList&, const FeatureList&);
ostream& operator<<(ostream&, const FeatureList&);

/* discriminative functions */

// basic/default -- uses two features (lm weight and itg weight)
FeatureList feature_init_default(Cell&, double, double);
FeatureList feature_merge_default(Cell*,Cell*,Cell*,Rule*,double);

// features comprising phrase pairs and ngrams
FeatureList feature_init_lex(Cell&, double, double);
FeatureList feature_merge_lex(Cell*,Cell*,Cell*,Rule*,double);

extern string_init_function_hash f_init_hash;
extern string_merge_function_hash f_merge_hash;

// call these functions
FeatureList feature_init(Cell&, double, double);
FeatureList feature_merge(Cell*, Cell*, Cell*, Rule*, double);

#endif
