#ifndef __DBHMM_H__
#define __DBHMM_H__

#include "classifierdb.h"
#include "hmm.h"
#include "databuffer.h"
#include <time.h>
#include <map>
#include <iostream>

/// database to store hmm models for GLCM matrix
class dbhmm
{
 public:
  struct thread_d
  {
    long double *smatrix;
    long double *calc_buffer;
  };

  dbhmm();
  ~dbhmm();
  int close();
  int init( classifierdb *sqlitedb, int id, 
            int fvid, int cvid, int del = 0);

  /// train a model
  /**
   * @param id the class id to assign this model as
   * @param seq map of sequences
   * @param fs feature size for each step time step
   * @param nstates number of states to train with
   * @param del if true function will delete memory pointed to by seq
   */
  int train( int id,
             std::map< int, std::vector< double * > > &seq,
             int fz, int nstates, int del );

  int prepthread( int numthreads, int tssize,
                  std::vector< thread_d > &thread_data );

  int cleanthreaddata( std::vector< thread_d > &thread_data );

  /// classify a time series
  /**
   * @return class id that sequence belongs to
   */
  int classify(std::vector< double * > &sequences, int fz);

  /// classify threaded version
  int classify_t( std::vector< matrix > &seq, 
                  thread_d &thread_data );


  /// return difference in class score for a sequence
  /**
   * @return score(class1) - score(class2) 
   */
  double scorediff( std::vector< double * > &seq, int fz,
                    int class1, int class2 );
 private:

  int savemodels();
  int loadmodels();

  std::map< int, hmm* > myhmms;
  classifierdb *classdb;
  int myfvid;
  int mycvid;
  int myid;
  std::string notes;
  std::string createdate;
};

#endif
