
#include "guess.h"

#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <assert.h>
#include <time.h>

#define DICT 1
#define COR 2
#define DICT_P 3
#define COR_P 4

#define W_PRE 0.1
#define W_SUF 0.9

#define PREF_SIGN '_'


using namespace std;


Guess::Guess(const char* suf_file)
  : _suf(suf_file) {
  /*  _suf = NULL;
  _pref = NULL;

   if (strlen(suf_file) > 0)
    _suf = new TFTiv<char, char>(suf_file);
  if (strlen(pref_file) > 0)
    _pref = new TFTiv<char, char>(corp_file);
  */
}


  char buf[MAX_LINE];
  char out[MAX_LINE];
  char* buf0_s = buf;
  char* word_t = NULL;
  long state_s = 0;
  unsigned length_s = buf0_s - buf;
  long len = 0;
  int i=0;

int Guess::ana(const char* word, Words& result) {

  assert(word && &result);

  /* Word zawiera wyraz, ktory mamy zbadac.
   * Nalezy przepisac go w odwrotnej kolejnosci do bufora,
   * znalezc najdluzszy prefiks pasujacy do tego bufora
   * separatorem jest '/' - za tym znakiem znajduje sie
   * prawdopodobienstwo wystapienia danego opisu */

  buf0_s = buf;
  word_t = strdup(word);

  if (reverse(word, buf) != 0)
    return -1;

 

  state_s = -1;
  //  printf("#buf0_s=%s, ", buf0_s);
  state_s = _suf.pref(buf0_s, PREF_SIGN);
  //  printf("#word=%s, buf0_s=%s\t", word, buf0_s);
  /* jezeli state_s != -1 to oznacza, ze w slowniku jest zawarta
   * informacja o prefiksie tego slowa.
   * nie jest ona odwrocona, wiec porownujemy do word a nie do buf
   */
  //  printf("state_s=%d\t", state_s);
  if (state_s != -1) {
    state_s = _suf.pref(word_t, '~', state_s);
    //    printf("state_s(wp)=%d, word_t=%s, word=%s\n", state_s, word_t, word);
  }
  if (state_s == -1) {
  //  if (_suf != NULL) 
    buf0_s = buf;
    state_s = _suf.pref(buf0_s, '~');
    //    printf("state_s=%d\n", state_s);
  }

  length_s = buf0_s - buf;
 
  /* state jest stanem, od ktorego zaczyna sie sciezka opisujaca
   * prawdopodobienstwo przeciwienstwa wystapienia opisu
   * znajdujacego sie dalej na tej sciezce.
   * Im mniejsza wartosc liczby tym wieksze prawdopodobienstwo */

  len = 0;
  i=0;
  
  //  if (_suf != NULL)
    len = _suf.cont(state_s, out);
  while (len > 0) {
    i++;
    add_word_prob(result, word, out, length_s, DICT);
    len = _suf.cont(-1, out);
  }
    
  return i;

}


int Guess::add_word_prob(Words& tab, const char* word, const char* path, unsigned len, int source) {

  /* Dodaje do tablicy tab wyraz word wraz
   * z prawdopodobienstwem i opisem zawartym
   * w sciezce path */

  //  printf("add_word_prob(");
  //  fflush(stdout);
  char p[MAX_LINE];

  strcpy(p, path);

  int probLen = strcspn(p, ";");
  char prob[probLen+1];
  strncpy(prob, p, probLen);
  prob[probLen] = '\0';

  char* desc = p + probLen+1; // +2 bo pomijamy jeszcze znak ';'

  int i = tab.add(word, desc);

  if (source==DICT) {
    tab[i].len_suf(len);
    tab[i].w_suf(atof(prob)); // + W_PRE*tab[i].w_suf()));
    //    tab[i].w_suf((float)(W_SUF*(1000-atof(prob)) + W_PRE*tab[i].w_suf()));
  }
//   if (source==COR) {
//     tab[i].len_pref(len);
//     tab[i].w_pref(W_SUF*(1000-atof(prob)) + W_PRE*tab[i].w_pref());
//   }
//   printf(")\n");
//   fflush(stdout);

  return i;

}
