/****************************************************************************/
/* UW_TUT5.C                                                                */
/*                                                                          */
/* NOTE: THIS FILE IS PUBLIC DOMAIN AND MAY BE MODIFIED AND USED AT WILL    */
/*                                                                          */
/* Now we get serious and add a data structure and entry fields to          */
/* collect information from the user.                                       */
/* We add quite a bit of code but it is really quite straightforward.  The  */
/* bulk of the code is repetive, gathering data for similar data fields.    */
/*   Notice that we add a function to display a customer.  We simply pass   */
/* a pointer to desired customer and a pointer to the window in which to    */
/* display the customer's information.                                      */
/*   We use the function wn_gets_ll (low-level) for maximum flexibility.    */
/* Refer to the function reference for details of this function.  Once the  */
/* basic parameters are understood, it is quite easy to use.                */
/*                                                                          */
/*                                                         Dr. Boyd Gafford */
/*                                                         Kevin Huck       */
/*                                                         EnQue Software   */
/*                                                         09/11/92         */
/****************************************************************************/
#include <time.h>
#include <ctype.h>
#include "uw.h"                           /* include the necessary headers  */

#define MAX_CUST 100

typedef struct cust
{
  int status;
  int cust_no;
  char business[34];
  char name[34];
  char addr[34];
  char city[34];
  char state[4];
  char zip[10];
  char phone[16];
  char fax[16];
  char date[10];
  char memo[34];
  char unused[26];                                /* round out to 256 bytes */
} CUST;

/*----------------------- global window variables --------------------------*/
WINDOW  Desk_wn, Window1;
CUST    Customers[MAX_CUST];

/*-------------------------------- prototypes ------------------------------*/
int disp_time(void);
void disp_cust(CUST *cp, WINDOW *wnp);

/*********/
/* ~main */
/*       ********************************************************************/
/*  Demonstrate data entry capability...                                    */
/****************************************************************************/
int main()
{
  int cust = 0, end_flag = 0;
  WINDOW *wnp;
  CUST *cp;
  
  wnp = &Window1;                         /* set local window pointer       */
  init_video(80, 25);                     /* init video for 80 x 25 screen  */
  init_clock(0x3333);                     /* init clock irq at 91 tics/sec  */

  wn_create(0, 0, V_cols-1, V_rows-1, NO_BDR, WN_NORMAL, &Desk_wn);
  link_window(&Desk_wn);

  set_idle_func(disp_time);               /* set background clock function  */

  wn_create(5, 5, 75, 20, SLD_BDR, WN_POPUP, wnp);
  wn_color(YELLOW, BLUE, wnp);            /* change the window colors       */
  wn_bdr_color(WHITE, BLUE, wnp);         /* change the border's colors     */
  link_window(wnp);

  /*------------- initialize first customer as EnQue Software --------------*/
  cp = &Customers[0];
  strcpy(cp->business, "EnQue Software"); 
  strcpy(cp->name, "Kevin Huck & Boyd Gafford");  
  strcpy(cp->addr, "Rt. 1 Box 116C"); 
  strcpy(cp->city, "Pleasant Hill");  
  strcpy(cp->state, "MO");  
  strcpy(cp->zip, "64080"); 
  strcpy(cp->phone, "(816) 987-2515");  
  strcpy(cp->fax, "(816) 987-2515");       
  strcpy(cp->date, "09/11/92");      
  strcpy(cp->memo, "BBS 816-358-8990"); 
  while(!end_flag)
  {
    cp = &Customers[cust];
    mv_cs(1,1, wnp);
    wn_printf(wnp, "Customer:%3d", cust+1);
    wn_plst(CENTERED, 2,
    "Press <Esc> to exit program", &Desk_wn);
    wn_plst(CENTERED, 3, "Use cursor keypad to select customer", &Desk_wn);
    disp_cust(cp, wnp);
    wait_event();
    switch(Event.key)
    {
      case KEY_ESC: end_flag = 1; break;
      case KEY_HOME:
        cust = 0;
        break; 
      case KEY_END:
        cust = MAX_CUST-1;
        break; 
      case KEY_DN: 
        if( cust < MAX_CUST-1 )
          cust++;
        break;
      case KEY_UP: 
        if( cust > 0 )
          cust--;
        break;
      case KEY_PGUP: 
        if( cust >= 10 )
          cust -= 10;
        else
          cust = 0;
        break;
      case KEY_PGDN: 
        if( cust < MAX_CUST-11 )
          cust += 10;
        else
          cust = MAX_CUST-1;
        break;
      case 'b': case 'B':                         /* get new business name  */
        mv_cs( 11, 3, wnp);
        wn_gets_ll(cp->business, "________________________________",
                                 "********************************",
          swap_nibbles(wnp->att), G_UP_FST_CHAR2 | G_STRIP_END, 32, wnp);
        break;
      case 'n': case 'N':                         /* get new contact name   */
        mv_cs( 11, 4, wnp);
        wn_gets_ll(cp->name, "________________________________",
                             "********************************",
          swap_nibbles(wnp->att), G_UP_FST_CHAR2 | G_STRIP_END, 32, wnp);
        break;
      case 'a': case 'A':                         /* get new address        */
        mv_cs( 11, 5, wnp);
        wn_gets_ll(cp->addr, "________________________________",
                             "********************************",
          swap_nibbles(wnp->att), G_UP_FST_CHAR2 | G_STRIP_END, 32, wnp);
        break;
      case 'c': case 'C':                         /* get new city           */
        mv_cs( 11, 6, wnp);
        wn_gets_ll(cp->city, "________________________________",
                             "********************************",
          swap_nibbles(wnp->att), G_UP_FST_CHAR2 | G_STRIP_END, 32, wnp);
        break;
      case 's': case 'S':                         /* get new state          */
        mv_cs( 51, 6, wnp);
        wn_gets_ll(cp->state, "__", "UU",
          swap_nibbles(wnp->att), G_EXIT_ON_FILL|G_STRIP_END, 2, wnp);
        break;
      case 'z': case 'Z':                         /* get new zip            */
        mv_cs( 60, 6, wnp);
        wn_gets_ll(cp->zip, "_____", "#####",
          swap_nibbles(wnp->att), G_EXIT_ON_FILL|G_STRIP_END, 5, wnp);
        break;
      case 'p': case 'P':                         /* get new phone number   */
        mv_cs( 11, 7, wnp);
        wn_gets_ll(cp->phone, "(___)___-____", " ### ### ####",
          swap_nibbles(wnp->att), G_EXIT_ON_FILL, 14, wnp);
        break;                    
      case 'f': case 'F':                         /* get new fax number     */
        mv_cs( 11, 8, wnp);
        wn_gets_ll(cp->fax, "(___)___-____", " ### ### ####",
          swap_nibbles(wnp->att), G_EXIT_ON_FILL, 14, wnp);
        break;
      case 'd': case 'D':                         /* get new date           */
        mv_cs( 11, 9, wnp);
        wn_gets_ll(cp->date, "__/__/__", "## ## ##", swap_nibbles(wnp->att),
          G_EXIT_ON_FILL, 8, wnp);
        break;
      case 'm': case 'M':                         /* get new memo field     */
        mv_cs( 11, 10, wnp);
        wn_gets_ll(cp->memo, "________________________________",
                             "********************************",
          swap_nibbles(wnp->att), G_STRIP_END, 32, wnp);
        break;

    }
  }
  unlink_window(wnp);                     /* remove the window from screen  */
  wn_destroy(wnp);
  set_idle_func(NULL);                    /* remove background function     */
  unlink_window(&Desk_wn);                /* remove the window from screen  */
  wn_destroy(&Desk_wn);
  end_clock();
  end_video();                            /* clean up before we exit        */
  return(1);
}
/*** end of main ***/

/**************/
/* ~disp_time */
/*            ***************************************************************/
/*  This routine is called in the background by wait_event and will display */
/*  the time once per second.  Notice the use of the global variables       */
/*  Uw_timers.  There is an array of four "countdown" timers that are user  */
/*  accessible.  Each "timer tic" will decrement the counts by one, until   */
/*  0 is reached.  By "reloading" the timer with "Tics_per_sec", we only    */
/*  display the time of day once per second.  "Tics_per_sec" is set         */
/*  by init_clock.                                                          */
/****************************************************************************/
int disp_time(void)
{
  time_t t;
  if( !Uw_timers[0] )                           /* has one second passed?   */
  {
    Uw_timers[0] = Tics_per_sec;                /* if so, reload timer      */
    t = time(NULL);                             /* get time                 */
    mv_cs(55, V_rows-1, &Desk_wn);          /* move window cursor       */
    wn_st_qty(ctime(&t), 24, &Desk_wn);     /* output 24 characters     */
    return(1);
  }
  return(0);
}
/*** end of disp_time ***/

/**************/
/* ~disp_cust */
/*            ***************************************************************/
/*  This routine displays a customer in the desired window...               */
/****************************************************************************/
void disp_cust(CUST *cp, WINDOW *wnp)
{
  int r = 3;

  mv_cs( 1, r++, wnp );
  wn_printf( wnp, "Business: %-32s", cp->business);
  mv_cs( 1, r++, wnp );
  wn_printf( wnp, "Name    : %-32s", cp->name );
  mv_cs( 1, r++, wnp );
  wn_printf( wnp, "Address : %-32s", cp->addr );
  mv_cs( 1, r++, wnp );
  wn_printf( wnp, "City    : %-32s State: %2s  Zip: %5s",
    cp->city, cp->state, cp->zip );
  wn_cleol(wnp);                                    /* clear to end of line */
  mv_cs( 1, r++, wnp );
  wn_printf( wnp, "Phone   : %-16s", cp->phone );
  mv_cs( 1, r++, wnp );
  wn_printf( wnp, "Fax     : %-16s", cp->fax );
  mv_cs( 1, r++, wnp );
  wn_printf( wnp, "Date    : %-10s", cp->date );
  mv_cs( 1, r++, wnp );
  wn_printf( wnp, "Memo    : %-32s", cp->memo );
}
/*** end of disp_cust ***/

/*** END OF FILE ***/
