/***********************************************************************



		     A demo ADDRESS database.

			   Version 1.2



					   Copyright(c) 1994-1996
							  ComBits
						  The Netherlands
***********************************************************************/


#include "ctype.h"
#include "csa.h"
#include "cst.h"
#include "csaddio.h"

//  Menu Options

#define mREINDEX	700
#define mCREATE_DB	701
#define mEXPORT_ASCII	702
#define mEXPORT_DBASE	703
#define mIMPORT_ASCII	704

#define mUNSORT 	501
#define mSORT_NAME	502
#define mSORT_CITY	503
#define mSORT_BIRTHDAY	504
#define mSORT_RELATION	505





//////////////////////////// A pop up window for messages /////////////////////
WINDOW w_mess;

void message_window_clear(void) { w_mess.remove(); }


void message_window(char *s)
{
     w_mess.height(10);
     w_mess.width(40);
     w_mess.head(" ** Message ** ");
     w_mess.border(W_BORDER_DOUBLE);
     w_mess.activate();
     gotoxy(max(1,(40-2-(int)strlen(s))/2),4);
     cputs(s);
}


///////////////////////////////////////////////////////////////////////////


class NAM: public NAMio
{
 protected:

   int choice;

   MENU   m1,m2,m3,m4,m5;
   PANEL  panel;


 public:


   void insert(void);
   void def_menu(void);
   int	use_menu(void)	{ return (m1.choose(choice)==ENTER) ? choice: -1; }
   int	use_menu(int n) { m1.find_path(n); return use_menu(); }

   void edit(void);
   void display(void)	{ panel.display(); }
   void recreate(void)	{ panel.recreate(); }
   void create(void);

};


/////////////////////////////////////////////////////////////////////////
void NAM::insert(void)
{

  append_blank();

  _update.now();

  recreate();
  display();
  panel.read();

}

/////////////////////////////////////////////////////////////////////////
void NAM::create(void)
{

  panel.remove();

  panel.set_dim(3,-1,18,65);		       // Size and Position of panel
  panel.head(" Address DataBase ");            // Heading
  panel.border(BORDER_DOUBLE);		       // Type of border
  panel.activate();			       // Make panel-window visible

  gotoyx(3,10); cprintf("Name: ");
  panel.add_field(4,10,25,NAMio_NAME_LENGTH,static_rec->_name);

  gotoyx(3,40); cprintf("City: ");
  panel.add_field(4,40,15,NAMio_CITY_LENGTH,static_rec->_city);

  gotoyx(6,10); cprintf("Address: ");
  panel.add_field(7,10,25,NAMio_ADRE_LENGTH,static_rec->_adre);

  gotoyx(6,40); cprintf("Telephone: ");
  panel.add_field(7,40,15,NAMio_TEL_LENGTH,static_rec->_tel);

  gotoyx(9,10); cprintf("Zip code: ");
  panel.add_field(10,10,NAMio_ZIP_LENGTH,static_rec->_zip);

  gotoyx(9,40); cprintf("Country: ");
  panel.add_field(10,40,15,NAMio_COUNT_LENGTH,static_rec->_count);


  gotoyx(1,43); cprintf("Updated: ");
  panel.add_field(1,53,_update);
  panel.protect(DISPLAY);

  gotoyx(12,10); cprintf("Birthday: ");
  panel.add_field(13,10,_birth);

  gotoyx(12,40); cprintf("Relation: ");
  panel.add_field(13,40,NAMio_RELATION_LENGTH,static_rec->_relation );

  gotoyx(15,10); cprintf("Info: ");
  panel.add_field(16,10,50,NAMio_INFO_LENGTH,static_rec->_info );

  panel.exit_key(CTRL_END);
  panel.escape_off();
  panel.display();

}

/////////////////////////////////////////////////////////////////////////
void NAM::edit(void)
{

  WINDOW help;
  help.set_dim( 21,-1,3,40);
  help.border(W_BORDER_DOUBLE);
  help.activate();
  cprintf("    Use CTRL_END to exit editing.");

  panel.read();

  if(panel.changed())
  {
    dirty=TRUE;
    _update.now();
  }

}
/////////////////////////////////////////////////////////////////////////

void NAM::def_menu(void)
{


/////////////////////////// Define the options for menu 1  //////////////

 m1.add_option(" e~Xit "        ,ALT_X );
 m1.add_option(" ~Insert "      ,ALT_I );
 m1.add_option(" ~Delete "      ,ALT_D );
 m1.add_option(" ~Edit "        ,ALT_E );
 m1.add_option(" ~Sort order "  ,ALT_S );
 m1.add_option(" ~Output "      ,ALT_O );
 m1.add_option(" ~Utilities "   ,ALT_U );
 m1.add_option(" Se~tup "       ,ALT_T );
 m1.add_option("      ~Help=F1 ",F1 );


/////////// Define the options for the output submenu ///////////////////////

 m2.add_option(" P~ages " , 601 );
 m2.add_option(" P~rinten ",602 );


/////////// Define the options for the utility submenu //////////////////////

 m3.add_option(" ~Pack  "             ,ALT_P );
 m3.add_option(" ~Rebuild Indexes "   ,mREINDEX);
 m3.add_option(" ~Create new database",mCREATE_DB);
 m3.add_option(" ~Export to ASCII "   ,mEXPORT_ASCII);
 m3.add_option(" Export to d~BASE "   ,mEXPORT_DBASE);
 m3.add_option(" ~Import from ASCII " ,mIMPORT_ASCII);

/////////// Define the options for the setup submenu ////////////////////////


 m4.add_option(" Directories ",603 );
 m4.add_option(" Colors "     ,604 );
 m4.add_option(" Save Setup"  ,605 );

/////////// Define the options for the 'sort' submenu ///////////////////////


 m5.add_option(" ~Unsorted "          ,mUNSORT);
 m5.add_option(" Sorted by ~Name "    ,mSORT_NAME);
 m5.add_option(" Sorted by ~City "    ,mSORT_CITY);
 m5.add_option(" Sorted by ~Relation ",mSORT_RELATION);
 m5.add_option(" Sorted by ~Birthday ",mSORT_BIRTHDAY);

///////////////// Make menu 1 'special' (main menu) ////////////////////


  m1.type(MENU_HOR);		     // Display options horizontally
  m1.hold(MENU_HOLD);		     // Make it 'always visible'
  m1.border(BORDER_NONE);	     // No border
  m1.width(80); 		     // Set the width to the full screen


//////////////////////////// Define the colors //////////////////////////


  int bor_col;
  int scr_col;
  int opt_col;
  int key_col;


  if(is_color())
  {
    bor_col=make_color(WHITE,CYAN);
    scr_col=make_color(WHITE,CYAN);
    opt_col=make_color(WHITE,RED);
    key_col=make_color(YELLOW,CYAN);
  }
  else
  {
    bor_col=make_color(LIGHTGRAY,BLACK);
    scr_col=bor_col;
    opt_col=make_color(BLACK,WHITE);
    key_col=make_color(WHITE,BLACK);
  }


/////////////////////////////// Set the colors of each (Sub) menu /////////

//  m1.color(bor_col,make_color(YELLOW,RED),key_col,key_col);

  m1.color(bor_col,scr_col,opt_col,key_col);
  m2.color(bor_col,scr_col,opt_col,key_col);
  m3.color(bor_col,scr_col,opt_col,key_col);
  m4.color(bor_col,scr_col,opt_col,key_col);
  m5.color(bor_col,scr_col,opt_col,key_col);

///////////////////////// Set the postions of the menus ////////////////////

  m1.coord(1,1);
  m2.relative_pos(TO_CURSOR);
  m2.coord(1,1);
  m3.relative_pos(TO_CURSOR);
  m3.coord(1,1);
  m4.relative_pos(TO_CURSOR);
  m4.coord(1,1);
  m5.relative_pos(TO_CURSOR);
  m5.coord(1,1);

////////////// Create the entire menu by connecting the sub-menus //////////

  m1.connect(5,m5);
  m1.connect(6,m2);
  m1.connect(7,m3);
  m1.connect(8,m4);

  m1.standby();

}


/////////////////////////////////////////////////////////////////////////

void main(int argc,char *argv[])
{

   if(argc>=2 && !strcmp(argv[1],"/?"))
   {

      printf("\n  * * * * * * * An address database.  * * * * * * *    ");
      printf("\n\n\n ADDRESS version 1.0.d ");
      printf("\n\n Compiled at:  %s, %s ",__DATE__,__TIME__);
      printf("\n Copyright (c) ComBits");
      printf("\n\n USAGE:  address [/reindex] [/create] [/?] ");
      printf("\n  /reindex  To rebuild the indexes. ");
      printf("\n  /create   To create a new database. ");
      printf("\n  /?        To display this screen.   ");
      printf("\n\n");
      return;
   }

   char inp[50]="";

   NAM	nam;


////////////////// Program already running? /////////////////////////////

   if(nam.lock_file_exist())
   {
	  message_window("Lock file exist! Cannot start.\r\n\n\nAny key to continue.");
	  cskey();
	  message_window_clear();
	  return;
   }

////////////////// Create a new database ////////////////////////////////


   if(argc==2 && !strcmp(argv[1],"/create"))  nam.define();


////////////////// Reindex when started with '/reindex' /////////////////
   if(argc==2 && !strcmp(argv[1],"/reindex"))
   {
     nam.open();
     nam.reindex();
     nam.close();
     exit(0);
   }

   int	choice=-1;
   int	leng;

   clrscr();


////////////////// Open database and indexes. ///////////////////////////

   nam.open();
   if(nam.numrec()==0) nam.append_blank();


////////////////// Setup background /////////////////////////////////////
   WINDOW bckgrnd;
   bckgrnd.border(BORDER_SINGLE);
   bckgrnd.set_dim(2,1,23,80);
   bckgrnd.activate();


////////////////// Create input window. /////////////////////////////////
   WINDOW input;
   input.border(BORDER_SINGLE);
   input.set_dim(21,4,3,73);
   input.activate();


////////////////// Create menus /////////////////////////////////////////
   nam.def_menu();


   nam.order(NAMIO_NAME_INDEX);
   nam.top();



////////////////// Create & display PANEL. //////////////////////////////
   nam.create();


////////////////// Display Warning /////////////////////////////////////

   WINDOW warning;

   warning.border(BORDER_DOUBLE);
   warning.height(14);
   warning.width(46);
   warning.color(make_color(WHITE,RED),make_color(YELLOW,RED));
   warning.head(" ** ALERT! ** ");
   warning.activate();

   cputs("\n\n\n\r");
   cputs(    "\n\r         This User-Interface is ");
   cputs(    "\n\r                  NOT" );
   cputs(    "\n\r         part of CSLIB!! ");
   cputs("\n\n\n\r         Please read 'readme.txt' for ");
   cputs(    "\n\r         more info.");
   cputs("\n\n\n\rAny key to continue.");
   cskey();

   warning.remove();


////////////////// Main processing loop. ////////////////////////////////
    do
    {
      if(choice==-1)
      {
	nam.display();
	input.activate();
	gotoxy(5,1);
	cprintf("Search string: %s",inp); clreol();
	gotoxy(50,1);
	cprintf("Record %ld/%ld",nam.curr_rec(),nam.numrec());
	clreol();
	gotoxy(69,1);
	if(nam.is_delet()) putch('D');
	else		   putch(' ');
	gotoxy(20+strlen(inp),1);
	choice=cskey();
      }

      switch(choice)
      {
	 case mUNSORT:
		     nam.order(UNSORTED);
		     nam.top();
		     choice=-3;
		     break;
	 case mSORT_NAME:
		     nam.order(NAMIO_NAME_INDEX);
		     choice=-2;
		     break;
	 case mSORT_CITY:
		     nam.order(NAMIO_CITY_INDEX);
		     choice=-2;
		     break;
	 case mSORT_RELATION:
		     nam.order(NAMIO_RELATION_INDEX);
		     choice=-2;
		     break;
	 case mSORT_BIRTHDAY:
		     nam.order(NAMIO_BIRTH_INDEX);
		     choice=-2;
		     break;
	 case 601:
	 case 602:
	 case 603:
	 case 604:
	 case 605:
		     message_window("Sorry, option not implemented.\n\rHit any key...");
		     waitkb(3500);
		     message_window_clear();
		     choice=-1;
		     break;
	 case mCREATE_DB:
		     message_window("Deleting entire database! \n\rARE YOU SURE (y/n).");
		     if(cskey()=='y')
		     {
			message_window("Creating new database.");
			nam.close();
			nam.define();
			nam.open();
			nam.append_blank();
		     }
		     message_window_clear();
		     choice=-3;
		     break;
	 case mREINDEX:
		     message_window("Indexing... A moment please.");
		     nam.reindex();
		     message_window_clear();
		     choice=-2;
		     break;
	 case mEXPORT_ASCII:
		     message_window("Exporting to 'backup.txt'.");
		     nam.export("backup.txt");
		     message_window_clear();
		     choice=-1;
		     break;
	 case mEXPORT_DBASE:
		     message_window("Exporting to 'DBASE.dbf'.");
		     nam.to_DBASE("DBASE.dbf");
		     message_window_clear();
		     choice=-1;
		     break;
	 case mIMPORT_ASCII:
		     message_window("Importing from 'backup.txt'.");
		     nam.import("backup.txt");
		     message_window_clear();
		     choice=-3;
		     break;
	 case F1:
	 case ALT_H:
		     {
			WINDOW help;
			help.set_dim(-1,-1,14,50);
			help.head(" Help Screen ");
			help.browse("address.hlp");
		     }
		     choice=-1;
		     break;
	 case ALT_D:
		     if(nam.is_delet()) nam.undelet();
		     else		nam.delet();
		     choice=-1;
		     break;
	 case ALT_E:
		     nam.edit();
		     choice=-3;
		     break;
	 case ALT_I:
		     nam.insert();
		     choice=-3;
		     break;
	 case ALT_P:
		     message_window("Packing... A moment please.. ");
		     nam.pack();
		     if(nam.numrec()==0) nam.append_blank();
		     message_window_clear();
		     nam.top();
		     choice=-3;
		     break;
	 case ALT_X:
		     break;
	 case ALT_O:
	 case ALT_S:
	 case ALT_T:
	 case ALT_U:
		     choice=nam.use_menu(choice);
		     break;
	 case F10:
		     choice=nam.use_menu();
		     break;
	 case CURSOR_UP:
		     nam.skip(-1);
		     choice=-3;
		     break;
	 case CURSOR_DOWN:
		     nam.skip(1);
		     choice=-3;
		     break;
	 case PAGE_DOWN:
		     nam.skip(10);
		     choice=-3;
		     break;
	 case PAGE_UP:
		     nam.skip(-10);
		     choice=-3;
		     break;
	 case HOME:
		     nam.top();
		     choice=-3;
		     break;
	 case END:
		     nam.bottom();
		     choice=-3;
		     break;
	 case BACKSPACE:
		     if(strlen(inp))
		     {
		       inp[strlen(inp)-1]=0;
		       choice=-2;
		     }
		     else choice=-1;
		     break;
	 case ESC:
		     inp[0]=0;
	 case -2:
		     nam.search(inp);
	 case -3:
		     // Adjust panel to new record.
		     nam.recreate();
		     choice=-1;
		     break;
	 default:
		     if(isprint(choice))
		     {
			// Modify search string.
			leng=strlen(inp);
			inp[leng]=choice;
			inp[leng+1]=0;
			choice=-2;
		     }
		     else choice=-1;
		     break;
      }

    } while(choice!=ALT_X);


////////////////// Remove all windows. //////////////////////////////////
    win_remove_all();


////////////////// Close database. //////////////////////////////////////
    nam.close();


}

