#ifndef ETABLE_H
#define ETABLE_H

#include "eutils.h"

#include "evar.h"
#include "evararray.h"
#include "evarhash.h"
#include "evarclass.h"
#include "estrarrayof.h"

class etable;
class efile;
class evar;
template <class T>
class earray;
typedef earray<evar> evararray;

class erow : public evararray
{
 public:
  int index;
  etable *table;
  
  erow();
  erow(etable *table,int index);

  size_t size() const;

  evar& operator[](size_t i);
  evar& operator[](const estr &field);
  const evar& operator[](size_t i) const;
  const evar &operator[](const estr &field) const;
};

class etable
{
 public:
  estrhashof<evararray> cols;
  eintarray blocks;

  etable();
  etable(const estrarray &fields);
  etable(const etable &table);
  ~etable();
 
  inline size_t size() const { if(cols.size()==0) return(0); else return(cols[0].size()); }

  etable& operator=(const etable& table);

  void addfield(const estr &field);  
  void setfields(const estrarray &fields);

  evararray& operator[](size_t i);
  const evararray& operator[](size_t i) const;
  evararray& operator[](const estr& field);
  const evararray& operator[](const estr& field) const;

  erow row(size_t i);

  void clear();

  void save(efile file) const;
  void load(efile file);

  void add(size_t i,const evar& var);
  void add(const estr& field,const evar& var);
  void add(const estrarray& strarr);
  void add(const evarhash& vhash);

  void append(const etable& t);

  void json_serial(estr& data) const;
  void serial(estr& data) const;
  size_t unserial(const estr& data,size_t i);
  void serial(const efile& f) const;
  bool unserial(const efile& f);

  etable getBlockTable(int bi);

  etable filter(const estr& expression);
};

//#include "eregexp.h"

etable etableLoadCSV2(const estr& filename);
bool etableSave(const etable& t,const estr& filename,const evarhash& options=evarhash());
etable etableLoad(const estr& filename,const evarhash& options=evarhash());
etable etableLoadCols(const estr& filename,const evarhash& options=evarhash());

estrarrayof<etable> tablesLoad(const estr& filename,const evarhash& options);

inline etable etableLoadCSV(const estr& filename) { evarhash options; options.add("sep",","); return(etableLoad(filename,options)); }

void etableTSV(const etable& t);

ostream& operator<<(ostream& stream,const etable& table);
ostream& operator<<(ostream& stream,const erow& row);

#endif

