#ifndef __HACNVLIB_H
#define __HACNVLIB_H

#ifndef __CONFIG_H
#include <config.h>
#endif

#ifndef __DICTION_H
#include <diction.h>
#endif

#ifndef __ISAM_H
#include <isam.h>
#endif

#ifndef __ODBCRECSET_H
#include <odbcrset.h>
#endif

#ifndef __PROGIND_H
class TProgind;
#endif

#ifndef __MODAUT_H
#include <modaut.h>
#endif

#ifndef __REPUTILS_H
#include <reputils.h>
#endif

#ifndef __CLIFOR_H
#include "../ve/clifor.h"
#endif

#include "../ve/velib.h"

class TCache_th;

class THardy_log : public TLog_report
{
public:
  THardy_log() : TLog_report("Conversione Hardy") {}
};

class THardy_transfer : public TObject
{
  TString _query_header;
  THardy_log* _log;
  TConfig _config;
  
  TRecordset* _recset;
  bool _write_enabled;
  TODBC_recordset* _outset;
  TCache_th* _tab;

protected:
  const TString& build_insert_query(const char* table, const char* f, const char* v) const;

  TRecordset& create_recordset(const char* query);
  long odbc_exec(const char* command);

  const TString& decode_value(const char* tab, const TString& field_value);
  const TString& decode_field(const char* tab, const char* recset_field);

  THardy_transfer();
  virtual bool trasferisci() pure;
  void aggiorna_record(TRectype& rec, const TString_array& lista_campi);
  void aggiorna_ini(TConfig& conf, const TString_array& lista_campi);

public:
  void init(const char* rh, const char* qh, THardy_log& log);
  const TString& title() const;
  TConfig& config() { return _config; }
  const TString& query_header() const { return _query_header; }

  void log(const char* msg, int sev = 0) const;
  bool log_error(const char* msg);
  bool log_cancelled();
  void show_log();

  const TRecordset& recordset() const;
  TRecordset& recordset();

  const TString& get_str(const char* campo) const;       // Get string from current recordset
  real get_real(const char* campo) const;       // Get real from current recordset
  const TString& get_real_str(const char* campo) const;  // Get eventually empty string from numeric field
  long get_long(const char* campo) const; 

  bool write_enabled() const { return _write_enabled; }
  
  bool test_write(TBaseisamfile& file);

  virtual ~THardy_transfer();
};

class THardy_iterator
{
  THardy_transfer* _ht;
  TProgind* _pi;
  TRecnotype _rec;

public:
  bool ok() const;
  bool cancelled() const;
  THardy_iterator& operator=(TRecnotype n);
  THardy_iterator& operator++();
  operator int() const { return ok(); }

  THardy_iterator(THardy_transfer* ht);
  ~THardy_iterator();
};

///////////////////////////////////////////////////////////
// Cache generica per il trasferimento 
///////////////////////////////////////////////////////////

class TCache_th : public TCache
{
  THardy_transfer* _ht;

protected:
  void log(const char* msg, int sev) const { _ht->log(msg, sev); }
  bool test_write(TBaseisamfile& file) const { return _ht->test_write(file); }
  const TRecordset& recordset() const { return _ht->recordset(); }
  TConfig& config() const { return _ht->config(); }
  const TString& query_header() const { return _ht->query_header(); }

public:
  const TString& get_str(const char* campo) const { return _ht->get_str(campo); }
  const TString& get_real_str(const char* campo) const { return _ht->get_real_str(campo); }
  long get_long(const char* campo) const { return _ht->get_long(campo); }
  virtual const TString& decode(const TToken_string& tokens) pure;

  TCache_th(THardy_transfer* ht) : _ht(ht) {}
};

#endif