/*
** POPUP - Popup Menu/Window Driver
**
** Copyright (c) 1985-1988 Philip A. Mongelluzzo
** All rights reserved.
*/

#include "windows.h"                    /* window header */

#undef UARROW                          /* dont argue with windows.h */
#undef DARROW      
#undef LARROW      
#undef RARROW      
#undef BS          
#undef DEL         
#undef RET         
#undef ESC         


#define UARROW  0x48                    /* define key codes */
#define DARROW  0x50
#define LARROW  0x4b
#define RARROW  0x4d
#define BS      0x0e
#define DEL     0x53
#define RET     0x1c
#define ESC     0x01
#define SPACE   0x39

#define v_setrev(atrib) ((atrib&0x88) | ((atrib>>4)&0x07) | ((atrib<<4)&0x70) )

/*
** Popup structure templates
*/

  struct mitem {                        /* menu item template */
    int r;                              /* row */
    int c;                              /* col */
    char *t;                            /* text */
    int rv;                             /* return value */
  };

  struct pmenu {                        /* popup menu structure */
    WINDOWPTR wpsave;                   /* place to hold window id */
    int winopn;                         /* leave window open flag */
    int lndx;                           /* last index */
    int fm;                             /* first menu item index */
    int lm;                             /* last menu item index */
    struct mitem scrn[25];              /* a bunch of menu items */
  };

/*
** Prototypes 
*/

#if BORLAND | WATCOM | MSC
int popup(int page,
              int row,
              int col,
              int width,
              int height,
              int atrib,
              int batrib,
              struct pmenu *mx,
              int cflag);
WINDOWPTR qpopup(int page,
              int row,
              int col,
              int width,
              int height,
              int atrib,
              int batrib,
              struct pmenu *mx);
#endif

/*
*********
* popup *
*********
*/

popup(page,row,col,width,height,atrib,batrib,mx,cflag)
int page;                               /* video page */
int row, col;                           /* window - upper row/col */
int width, height;                      /* window - height & width */
struct pmenu *mx;                       /* pointer to popup menu struct */
int cflag;                              /* close on return strike flag */
int atrib, batrib;                      /* attributes - window & border */
{


int i;                                  /* scratch integer */
WINDOWPTR w;                            /* window pointer */
unsigned int c;                         /* key scan code,,char */
int j;                                  /* 1st char scan index */
char ch;                                /* CHARACTER (!scan code) Entered */


  if(mx->winopn) {                      /* window is still open */
    goto d0;                            /* enter processing loop */
  }
  mx->lndx = -1;                        /* set index out of range */
  w = wn_open(page, row, col, width, height, atrib, batrib);
  wn_sync(w,FALSE);                     /* sync cursor */
  mx->wpsave = w;                       /* save pointer */
  if (w == NULL) return(99);            /* out of mem or just fubar */
  mx->winopn = TRUE;                    /* say window is open */

  i = 0;                                /* init index */

  while(mx->scrn[i].r != 99) {          /* for as long as we have data */
    wn_putsa(w, mx->scrn[i].r, mx->scrn[i].c, mx->scrn[i].t, atrib);
    i++;
  }

d0:
  w = mx->wpsave;                       /* restore pointer */
  i = mx->lndx;                         /* BLINDLY assume that we're back */
  if(i < mx->fm) i = mx->fm;            /* and reset if "i" is now out of */
  if(i > mx->lm) i = mx->fm;            /* range - (dumb, but it works) */
  while(TRUE) {                         /* till we exit */
    wn_putsa(w, mx->scrn[i].r, mx->scrn[i].c, mx->scrn[i].t, v_setrev(atrib));
    c = v_getch();                      /* Fetch keyboard character */
    ch = c & 0xFF;                      /* character */
    c = c >> 8;                         /* scan code */
    if(c == ESC) break;                 /* ESC (user wants out) */
    if(c == RET) {                      /* so RETURN */
      if(cflag) {                       /* close window on return strike ? */
        wn_close(w);                    /* close the window */
        mx->winopn = FALSE;             /* say window is closed */
      }
      mx->lndx = i;                     /* remember last indx */
      return(mx->scrn[i].rv);           /* return with rv */
    }
    if(c == DARROW) c = SPACE;          /* Down arrow acts like Space */
    if(c == RARROW) c = SPACE;          /* Right arrow does too */
    if(c == LARROW) c = BS;             /* Left arrow acts like Back Space */
    if(c == UARROW) c = BS;             /* Up arrow does too */
    if(c == SPACE || c == DEL || c == BS) {
      wn_putsa(w, mx->scrn[i].r, mx->scrn[i].c, mx->scrn[i].t, atrib);
      if(c == SPACE)                    /* foreward ?? */
        i++;                            /* bump index */
      else
        i--;                            /* decrement */
      if(i < mx->fm) i = mx->lm;        /* wrap on either */
      if(i > mx->lm) i = mx->fm;        /* end */
    }                                   /* endif */
    ch = toupper(ch);                   /* lets see if we can use 1st char */
    for (j=mx->fm; j<=mx->lm; j++) {
      if (ch == *mx->scrn[j].t) {  
        wn_putsa(w, mx->scrn[i].r, mx->scrn[i].c, mx->scrn[i].t, atrib);
        i=j;                           
        break;
      }
    }                                   /* end 1st char scan */
  }                                     /* end while */
  wn_close(w);                          /* bye bye */
  mx->winopn = FALSE;                   /* say window is closed */
  return(99);                           /* nothing selected */
}

#ifdef COMMENTS
/*
**********                              /* quick popup... */
* qpopup *                              /* this is a hack of popup */
**********                              /* but the code fragment */
*/                                      /* could be of value */
#endif

WINDOWPTR qpopup(page,row,col,width,height,atrib,batrib,mx)
int page;                               /* video page */
int row, col;                           /* window - upper row/col */
int width, height;                      /* window - height & width */
int atrib, batrib;                      /* atributes - window & border */
struct pmenu *mx;                       /* pointer to text struct */
{
int i;                                  /* scratch integer */
WINDOWPTR w;                            /* window pointer */

  w = wn_open(page, row, col, width, height, atrib, batrib);

  i = 0;                                /* init index */
  while(mx->scrn[i].r != 99) {          /* for as long as we have data */
    wn_puts(w, mx->scrn[i].r, mx->scrn[i].c, mx->scrn[i].t);
    i++;
  }
  return(w);
}

/* End */
