#ifndef CLASS__DEMO_h
#define CLASS__DEMO_h


#include "csdate.h" 
#include "cstbase.h" 
#include "csbtree.h" 

#define DEMO_NAME_LENGTH	 50 
#define DEMO_DATA_LENGTH	 32 

////////// Indexes to be used with the 'order()' function./////////////

#define UNSORTED	 0
#define DEMO_NAME_INDEX	 1 
#define DEMO_DATA_INDEX	 2 



typedef struct 
{
   char   _name[DEMO_NAME_LENGTH+1]; 
   char   _data[DEMO_DATA_LENGTH+1]; 
} Record;


///////////////////////////////////////////////////////////////////////
//////////////////////////// The New Class ////////////////////////////
///////////////////////////////////////////////////////////////////////


class DEMO
{
 protected:

   Record *static_rec;

   csSTR   e_name; // Used in error messages.
   long    current;
   int     dirty;
   int     is_open;
   int     iOrder;
   int     NeedSync;
   int     errnr;


   int  (DEMO::*bof_fun)(void);
   int  (DEMO::*eof_fun)(void);
   int  (DEMO::*skip_fun)(int delta);
   void (DEMO::*top_fun)(void);
   void (DEMO::*bottom_fun)(void);
   int  (DEMO::*search_fun)(void *k);

   TBASE  db;
   BTREEa in1;		//Index on field name  
   BTREEa in2;		//Index on field data  

   int bof0(void)		{ return (current==1); }
   int bof1(void)		{ return in1.tBOF(); }
   int bof2(void)		{ return in2.tBOF(); }

   int eof0(void)		{ return (current==db.numrec()); }
   int eof1(void)		{ return in1.tEOF(); }
   int eof2(void)		{ return in2.tEOF(); }

   void top0(void)		{ current=1; }
   void top1(void)		{ in1.min_dat(&current); }
   void top2(void)		{ in2.min_dat(&current); }

   void bottom0(void)		{ current=db.numrec(); }
   void bottom1(void)		{ in1.max_dat(&current); }
   void bottom2(void)		{ in2.max_dat(&current); }

   void find1(void *k)		{ in1.find(k,&current); }
   void find2(void *k)		{ in2.find(k,&current); }

   int  search0(void * )	{ return TRUE; } 
   int  search1(void *k)	{ return in1.search_dat_ge(k,&current); }
   int  search2(void *k)	{ return in2.search_dat_ge(k,&current); }

   int  skip0(int delta); 
   int  skip1(int delta)	{ return in1.skip_dat(delta,&current); }
   int  skip2(int delta)	{ return in2.skip_dat(delta,&current); }

   Record *locate_curr(void) { return (Record *)db.locate_rec(current); } 
   void write_rec2(void);
   void write_rec(void) { if(dirty) write_rec2(); }
   void read_rec(void);

   void synch_index(void);
   void visible_error(int ErrorNr,char *Parm=""); 
   void te(void);  

 public:

 //////////////////////////////// class constructor ////////////////////////////
   DEMO(void); 

 //////////////////////////////// class destructor /////////////////////////////
   ~DEMO(void);

 //////////////////////////////// current record number ////////////////////////
   long curr_rec(void)   { return current; }

 //////////////////////////////// messages & errors ////////////////////////////
   U16  display_error(void); 

   int  error_nr(void); 
   void error_nr(int ErrorNr) { errnr=ErrorNr; } 


 //////////////////////////////// read-only ////////////////////////////////////
   int  read_only(int TrueOrFalse);
   int  read_only(void) { return db.read_only(); }

 //////////////////////////////// lock files ///////////////////////////////////
   int  use_lock_file(int TrueOrFalse);
   int  use_lock_file(void) { return db.use_lock_file(); } 

   int  lock_file_exist(void);  
   int  remove_lock_file(void); 

 //////////////////////////////// define ///////////////////////////////////////
   int  define(void);  

 //////////////////////////////// open & close ////////////////////////////////
   int  open(int kB=100); // Use 100 kB ram for buffering.   
   int  close(void);  

   int  close2(void);  

   int  already_open(void)  { return is_open; }  

 //////////////////////////////// delete //////////////////////////////////////
   int  is_delet(void)   { te(); return db.is_delet(current); } 
   void undelet(void)    { te(); db.undelet(current); }         
   void delet(void)      { te(); db.delet(current); }           

   int  is_delet(long n) { te(); return db.is_delet(n); } 
   void undelet(long n)  { te(); db.undelet(n);         } 
   void delet(long n)    { te(); db.delet(n);           } 

 //////////////////////////////// number of records ///////////////////////////
   long numrec(void)     { return db.numrec(); } 

 //////////////////////////////// import/export ///////////////////////////////
   int  import(char *s);
   int  export(char *s);
   int  to_DBASE(char *s);

 //////////////////////////////// reindexing //////////////////////////////////
   int  reindex(void); 

 //////////////////////////////// append //////////////////////////////////////
   void append(void);        //Indexes are NOT updated.
   void append_blank(void);  //Indexes ARE updated.

 //////////////////////////////// data in header //////////////////////////////
   int data_2_header(void *p,U16 size) { return db.data_2_header(p,size); } 
   int header_2_data(void *p,U16 size) { return db.header_2_data(p,size); } 
   U16 max_data_in_header(void)        { return db.max_data_in_header();  } 

 //////////////////////////////// pack ////////////////////////////////////////
   int  pack(void);

 //////////////////////////////// (change) active index ///////////////////////
   int  order(int nr);    
   int  order(void)      { return iOrder; } 

 //////////////////////////////// testing begin/end ///////////////////////////
   int  tBOF(void);
   int  tEOF(void);

 //////////////////////////////// relocating //////////////////////////////////
   int  skip(int delta=1);
   int  prev(int delta=1) { return -skip(-delta); }
   int  next(int delta=1) { return  skip( delta); }
   int  bottom(void);
   int  top(void);
   int  search(void *k);
   int  go_to(long n);

 /////////////////////////reading fields //////////////////////////////////////
   char * name(void)           { te(); return static_rec->_name; } 
   char * data(void)           { te(); return static_rec->_data; } 

 /////////////////////////writing fields //////////////////////////////////////
   void   name(char *s)        { te(); strncpy(static_rec->_name,s,DEMO_NAME_LENGTH); dirty=TRUE; } 
   void   data(char *s)        { te(); strncpy(static_rec->_data,s,DEMO_DATA_LENGTH); dirty=TRUE; } 

};


#endif
