/***************************************************************************
 *                                                                         *
 *   EDTVAL.C                                                              *
 *                                                                         *
 *   Copyright (c) 1987-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   This is the GCOMM.LIB routine for editing data fields on-screen of    *
 *   arbitrary types, with full support for cursor movement, ins/del,      *
 *   home/end, etc.  The global character edtvalc may be used upon exit    *
 *   to determine where to go next (its value can be '\r', TAB, BAKTAB,    *
 *   CRSRUP, CRSRDN, or ESC).  If the Esc key is pressed, edtval() returns *
 *   0, otherwise it returns 1.                                            *
 *                                                                         *
 *                                            - T. Stryker 2/3/92          *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"

#define FILREV "$Revision: 6 $"

INT edtvalc;                       /* last char accepted by edtval()       */

extern INT pxoff;
extern INT pyoff;                  /* proff() off's used by edtval() & prat()*/

static
VOID rfredt(INT sx,INT sy,CHAR *sval,INT mxlnm1,INT atr,INT curx,INT flags);

GBOOL                              /*   FALSE if ESC hit; TRUE otherwise   */
edtval(                            /* edit a string value field            */
INT sx,                            /*   starting x coord (0-based)         */
INT sy,                            /*   starting y coord (0-based)         */
INT maxlen,                        /*   max len of field (incl. '\0')      */
CHAR *sval,                        /*   value edit and return-buffer       */
GBOOL (*valrou)(),                 /*   validation routine address         */
INT flags)                         /*   option flags (see gcomm.h)         */
{
     INT done=0,curx;
     INT inson=0;
     INT savatr,savexo,saveyo,savecur,ignins=0;
     CHAR svsval[81];
     INT mxlnm1;
     typedef GBOOL (*VALFUNC)(INT c,CHAR * stg);

     if (flags&USEPOFF) {
          sx+=pxoff;
          sy+=pyoff;
     }
     mxlnm1=maxlen-1;
     savatr=scngetc(gvscnoff(sx,sy)+1);
     stzcpy(svsval,sval,sizeof(svsval));
     padfld(sval,maxlen);
     curx=strpln(sval);
     savecur=curcurs();
     cursiz(GVIDLILCURS);
     rfredt(sx,sy,sval,mxlnm1,(color ? 0x0F : 0x70),curx,flags);
     while (!done) {
          switch (edtvalc=getchc()) {
          case ESC:
               strcpy(sval,svsval);
               rfredt(sx,sy,sval,mxlnm1,savatr,curx,flags);
               cursiz(savecur);
               return(FALSE);
          case TAB:
          case BAKTAB:
          case CRSRDN:
          case CRSRUP:
               if (!(flags&MULTIEX)) {
                    break;
               }
          case '\r':
               done=1;
               break;
          case '\b':
               if (curx == 0 || (flags&MCHOICE)) {
                    break;
               }
               curx--;
          case DEL:
               if (!(flags&MCHOICE) && curx < maxlen-1) {
                    movmem(sval+curx+1,sval+curx,strlen(sval+curx));
                    sval[strlen(sval)]=' ';
               }
               break;
          case CRSRLF:
               if (curx != 0 && !(flags&MCHOICE)) {
                    curx--;
               }
               else if (flags&MULTIEX) {
                    done=1;
               }
               break;
          case HOME:
               curx=0;
               break;
          case END:
               curx=strpln(sval);
               break;
          case INS:
               if (!(flags&MCHOICE)) {
                    cursiz((inson^=1) ? GVIDBIGCURS : GVIDLILCURS);
               }
               break;
          case CRSRRT:
               if (curx < strlen(sval)-1 && !(flags&MCHOICE)) {
                    ignins=1;
                    edtvalc=sval[curx];
               }
               else {
                    if (flags&MULTIEX) {
                         done=1;
                    }
                    break;
               }
          default:
               savexo=pxoff;
               saveyo=pyoff;
               if (inson && !ignins) {
                    if ((*(VALFUNC)valrou)(edtvalc,sval) && strpln(sval) < maxlen-1) {
                         movmem(sval+curx,sval+curx+1,strpln(sval+curx));
                         sval[curx++]=(flags&ALLCAPS) ? toupper(edtvalc)
                                                      : edtvalc;
                    }
               }
               else if ((*(VALFUNC)valrou)(edtvalc,sval) && curx < maxlen-1) {
                    sval[curx++]=(flags&ALLCAPS) ? toupper(edtvalc) : edtvalc;
               }
               pxoff=savexo;
               pyoff=saveyo;
               if (edtvalc == '\r' || ((flags&MULTIEX)
                                    && (edtvalc == CRSRDN || edtvalc == CRSRUP
                                     || edtvalc == BAKTAB || edtvalc == TAB))){
                    done=1;
               }
               ignins=0;
          }
          rfredt(sx,sy,sval,mxlnm1,(color ? 0x0F : 0x70),curx,flags);
     }
     rfredt(sx,sy,sval,mxlnm1,savatr,curx,flags);
     depad(sval);
     cursiz(savecur);
     return(TRUE);
}

static VOID
rfredt(                            /* utility rou for edtval()             */
INT sx,
INT sy,
CHAR *sval,
INT mxlnm1,
INT atr,
INT curx,
INT flags)
{
     if (curx == mxlnm1) {
          curx=mxlnm1-1;
     }
     locate(sx,sy);
     setatr(atr);
     printf("%s",spr("%-*s",mxlnm1,sval));
     if (flags&MCHOICE) {
          cursiz(GVIDNOCURS);
     }
     else {
          locate(sx+curx,sy);
     }
}
