//---------------------------------------------------------------------------
#ifndef _Word_h
#define _Word_h
//---------------------------------------------------------------------------
//#include "alphabet.h"
//#include "erro.h"
#include "const.h"
#include <iostream>
#include <cstring>
#include <vector>
//---------------------------------------------------------------------------

using namespace std;



class Word
{
public:
  static const int MAXLEN=64;          // dac do global
  static const int MAXDESCRLEN=80;     // dac do global

private:
  /// word form
  char f[MAX_FORM];                // w wolnej chwili nazwy mozna zamienic na dluzsze

  /// length
  int _len_suf;  // dlugosc dopasowania koncowki...
  //  int _len_pref; // ... i prefiksu

  /// lemma
  char l[MAX_FORM];

  /// description
  char d[MAX_DESC];

  /// weight (probability)
  float _w_suf; 
  //  float _w_pref;
public:
  static bool cmp_w(Word a, Word b);
  static bool cmp_w_rev(Word a, Word b);

  Word() : _len_suf(-1) { *f='\0'; returned=0; };
  Word(const char* fo, const char* des) : _len_suf(-1) { autodescr(fo,des); _w_suf=1.0; returned=0; };

  Word(const Word& w);

  char* form() { return f; }  // przywrocic const
  char* lemma() { return l; } // przywrocic const
  char* descr() { return d; }
  float w_suf() { return _w_suf; };
  int len_suf() { return _len_suf; }


  void form(const char* s) { strcpy(f,s); }
  void lemma(const char* s) { strcpy(l,s); }
  void descr(const char* s) { strcpy(d,s); };
  void w_suf(float x) { _w_suf=x; };
  void len_suf(int n) { _len_suf=n; };

  bool operator==(const Word& w);
  bool operator!=(const Word& w);
  int cmp(const Word&);
  int cmpi(const Word&);

  char* operator!() { return f; };

  operator bool() { return _len_suf>0; };

  char* str() { return f; }

  void autodescr(const char* fo, const char* des);

  friend istream& operator>>(istream& is, Word& m);
  friend ostream& operator<<(ostream& os, Word& m);

  bool returned;

};


inline Word::Word(const Word& word)
{ strcpy(f,word.f); strcpy(l,word.l); strcpy(d,word.d); _len_suf=word._len_suf; _w_suf=word._w_suf; returned = 0; }

//---------------------------------------------------------------------------

inline bool Word::operator==(const Word& w)
{return _len_suf==w._len_suf && 
   !strcmp(f,w.f) && !strcmp(l,w.l) && !strcmp(d,w.d); }

//---------------------------------------------------------------------------

inline bool Word::operator!=(const Word& w)
{return _len_suf!=w._len_suf || 
   strcmp(f,w.f) || strcmp(l,w.l) || strcmp(d,w.d);}

//---------------------------------------------------------------------------

inline int Word::cmp(const Word& w) { return strcmp(f,w.f); }

//---------------------------------------------------------------------------

//inline int Word::cmpi(const Word& w) { return PL.cmpi(f,w.f); }

//---------------------------------------------------------------------------




bool cmp_w_fun(Word a, Word b);
bool cmp_w_rev_fun(Word a, Word b);


//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

class Words
{
 private:
  int find(const char* word);
  int find(const char* word, const char* descr);
 public:

  static const int MAX=1024;

  Words() : cnt(0) {tab.resize(MAX); };
  ~Words();
  Word& operator[](int i) { return tab[i]; }
  int count() const { return cnt; }
  void clear() { cnt=0; tab.clear(); }
  int add(const char* fo);
  int add(const char* fo, float weight);
  int add(const char* fo, const char* des);

  /* zwraca index nastepnego wyniku, podczas pierwszego wywolania
   * zwraca index wyniku o najwiekszej wadze, przy drugim wywolaniu
   * wynik z druga najwyzsza waga, itd.
   * Jezeli nie ma juz wynikow - zwraca -1.
   */
  int next();

  void sort();
  void sort_rev();

  void prn(ostream& os);

//  friend class Lem;
//  friend class AuxLem;
  friend ostream& operator<<(ostream& os, Words& tab);
  vector<Word> tab;
  int cnt;

};

//---------------------------------------------------------------------------

#endif

