#ifndef CLASS__NAMio_h
#define CLASS__NAMio_h


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

#define NAMio_NAME_LENGTH	 40 
#define NAMio_NAME_TOK_LENGTH	 NAMio_NAME_LENGTH/2
#define NAMio_ADRE_LENGTH	 32 
#define NAMio_CITY_LENGTH	 23 
#define NAMio_COUNT_LENGTH	 32 
#define NAMio_ZIP_LENGTH	 9 
#define NAMio_TEL_LENGTH	 17 
#define NAMio_RELATION_LENGTH	 10 
#define NAMio_INFO_LENGTH	 70 

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

#define UNSORTED	 0
#define NAMIO_NAME_INDEX	 1 
#define NAMIO_CITY_INDEX	 2 
#define NAMIO_BIRTH_INDEX	 3 
#define NAMIO_RELATION_INDEX	 4 



typedef struct 
{
   char   _name[NAMio_NAME_LENGTH+1]; 
   char   _adre[NAMio_ADRE_LENGTH+1]; 
   char   _city[NAMio_CITY_LENGTH+1]; 
   char   _count[NAMio_COUNT_LENGTH+1]; 
   char   _zip[NAMio_ZIP_LENGTH+1]; 
   char   _tel[NAMio_TEL_LENGTH+1]; 
   long   __update; 
   long   __birth; 
   char   _relation[NAMio_RELATION_LENGTH+1]; 
   char   _info[NAMio_INFO_LENGTH+1]; 
} record;


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


class NAMio
{
 protected:

   record *static_rec;

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


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

   TBASE  db;
   BTREEa in1;		//Index on field name  
   BTREEa in2;		//Index on field city  
   BTREEl in3;		//Index on field birth  
   BTREEa in4;		//Index on field relation  

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

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

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

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

   void find1(void *k)		{ in1.find(k,&current); }
   void find2(void *k)		{ in2.find(k,&current); }
   void find3(void *k)		{ in3.find(k,&current); }
   void find4(void *k)		{ in4.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  search3(void *k)	{ return in3.search_dat_ge(k,&current); }
   int  search4(void *k)	{ return in4.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); }
   int  skip3(int delta)	{ return in3.skip_dat(delta,&current); }
   int  skip4(int delta)	{ return in4.skip_dat(delta,&current); }

   void in1_ins_tok(void *s)	{ in1.insert(s,&current); }
   void in1_del_tok(void *s)	{ in1.delet(s,&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 tokenize(int once,char *s,const char *delim,int len,void(NAMio::*fun)(void *));
   void synch_index(void);
   void visible_error(int ErrorNr,char *Parm=""); 
   void te(void);  

 public:

 //////////////////////////////// class constructor ////////////////////////////
   NAMio(void); 

 //////////////////////////////// class destructor /////////////////////////////
   ~NAMio(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 * adre(void)           { te(); return static_rec->_adre; } 
   char * city(void)           { te(); return static_rec->_city; } 
   char * count(void)          { te(); return static_rec->_count; } 
   char * zip(void)            { te(); return static_rec->_zip; } 
   char * tel(void)            { te(); return static_rec->_tel; } 
   char * update(void)         { te(); return (char *)_update; } 
   char * birth(void)          { te(); return (char *)_birth; } 
   char * relation(void)       { te(); return static_rec->_relation; } 
   char * info(void)           { te(); return static_rec->_info; } 

 /////////////////////////writing fields //////////////////////////////////////
   void   name(char *s)        { te(); strncpy(static_rec->_name,s,NAMio_NAME_LENGTH); dirty=TRUE; } 
   void   adre(char *s)        { te(); strncpy(static_rec->_adre,s,NAMio_ADRE_LENGTH); dirty=TRUE; } 
   void   city(char *s)        { te(); strncpy(static_rec->_city,s,NAMio_CITY_LENGTH); dirty=TRUE; } 
   void   count(char *s)       { te(); strncpy(static_rec->_count,s,NAMio_COUNT_LENGTH); dirty=TRUE; } 
   void   zip(char *s)         { te(); strncpy(static_rec->_zip,s,NAMio_ZIP_LENGTH); dirty=TRUE; } 
   void   tel(char *s)         { te(); strncpy(static_rec->_tel,s,NAMio_TEL_LENGTH); dirty=TRUE; } 
   void   update(char *s)      { te(); _update=s; dirty=TRUE; } 
   void   birth(char *s)       { te(); _birth=s; dirty=TRUE; } 
   void   relation(char *s)    { te(); strncpy(static_rec->_relation,s,NAMio_RELATION_LENGTH); dirty=TRUE; } 
   void   info(char *s)        { te(); strncpy(static_rec->_info,s,NAMio_INFO_LENGTH); dirty=TRUE; } 

};


#endif
