/*  txttw.c  -- (part of efr)  Copyright © 1989 by William F. Hammond  */
/*           --  the efr window manager                                */
#ifndef TDM_H
#include "tdm.h"
#endif
/*********************************************************************/
SHORT txttw()   /*  return 0 to quit main  */
{
register LONG idff;
register int ichtx;
static UBYTE promptstring[] =
" <sp>:page+, q:quit, <cr>:line+, b:page-, sN:skip N pp, gN:go to line N ";
static UBYTE goprompt[] =
" n:next(pr), c:stop(pr), q:quit, b:page-, sN:skip N pp, gN:go to line N ";
static UBYTE stdinprompt[] =
" <sp>:page+, q:quit, <cr>:line+, sN:skip N pp, gN:go to line N          ";
static UBYTE endstring[] =
" File End -- q:quit,  b:page-,  sN:skip N pp if N < 0,  gN:go to line N ";
static UBYTE stdinend[] =
" File End -- q:quit  (sorry -- cannot back up \"standard input\")         ";
static UBYTE eofstring[] = "[7m End of File [0m";
UBYTE chtxt, ltbuf[2][12]; 
struct LinePart *lp;
struct IntuiMessage *msg;
LONG askline, mwwidth, mwheight, difflines, skiplines, tpline;
LONG pnum, pvmode;
ULONG dmax, pagesize, pvstyle;
UWORD scrollsize;
WORD skippages;
SHORT rowpix, txj;
int sltxb;
BYTE letmeback;
UBYTE gtch, prflag;
UBYTE *cgdstr;
rowpix = (SHORT)rp->TxBaseline;
mwwidth = (LONG)(mw->Width);
mwheight = (LONG)(mw->Height);
SetAPen(rp, 1L);
SetBPen(rp, 0L);
SetDrMd(rp, (LONG)JAM2);
Move(rp, 0L, 0L);
ClearScreen(rp);
drawmode = (LONG)JAMX;
pvmode = drawmode;
SetDrMd(rp, drawmode);
style = (ULONG)FS_NORMAL;
pvstyle = style;
savestyle = SetSoftStyle(rp, style, enable);
dmax = (ULONG)(maxline -1);
screenline = 0;
skippages = 0;
difflines = golinem - txtline;
difflines --;
idff = 0L;
if(idff < difflines)
   while( ( ichtx = getc(stream) ) != EOF )
      {
      if(ichtx==0x0a)
         {
         idff ++;
         if(idff >= difflines) break;
         }
      }
txtline = txtline + idff;
letmeback = NULB;
if(txtline == 0) strcpy(pvstr, "");
while(1) /******  perpetual loop dependent on user directions  ******/
{
while( (bfgets(instr, MAXSTRLN+1, stream) != NULL) || (letmeback) )
   {
   instr[MAXSTRLN] = '\0';
   screenline ++;
   txtline ++;
   if(letmeback)
      {
      if(linesize) txtline = MIN(txtline, linesize);
      strcpy(instr, eofstring);
      if(letmeback <= 2) letmeback ++;
      }
   /*  Compute the screenline -- either set it or return  */
   while ( (screenline > maxline) || (letmeback >= 3) )
      {
      skippages = 0;
      if( (tflag) && !(letmeback) )    /*****    time to "type"    *****/
         {
         chtxt = 't';   /*  This pre-empts the other cases  */
         gtch = NULB;
         while(msg = (struct IntuiMessage *)GetMsg(mw->UserPort))
            {
            if(msg->Class == VANILLAKEY) gtch = (UBYTE)msg->Code;
            ReplyMsg(msg);
            }
         if(gtch == CTRL_C)           /*  Ctrl-C signal to quit  */ 
            {
            return 0;
            }
         if(gtch)           /*  This is a pause request -- no prompt  */
            {
            gtch = NULB;
            while(!gtch)
               {
               Wait(1L << mw->UserPort->mp_SigBit);
               
               while(msg = (struct IntuiMessage *)GetMsg(mw->UserPort))
                  {
                  if(msg->Class == VANILLAKEY) gtch = (UBYTE)msg->Code;
                  ReplyMsg(msg);
                  }
               }
            if(gtch == CTRL_C) return 0;
            if(gtch == 'x')    /*  Exit from scrolling mode  */
               {
               tflag = NULB;
               }
            gtch = NULB;
            }
         if(tflag)
            {
            scrollsize = rp->TxHeight;
            ScrollRaster(rp, 0L, (LONG)scrollsize,
                             0L, 0L, mwwidth, mwheight);
            screenline --;
            }
         }
      if(letmeback)      /*  Choose prompt string  */
         {
         if( (linesize) && (linesize < golinem) )
            {
            golinet = (LONG)(linesize - ((ULONG)maxline) + 1L);
            return 1;
            }
         cgdstr = endstring;
         if(stream == stdin) cgdstr = stdinend;
         }
      else
         {
         cgdstr = promptstring;
         if(gflag) cgdstr = goprompt;
         if(stream == stdin) cgdstr = stdinprompt;
         }
      tpline = txtline - (LONG)screenline + 1L;  /* line at top of screen */
      if(letmeback >=2) tpline = tpline - 1L + (LONG)letmeback;
      if( (letmeback) || !(tflag) )   /*  Put prompt together  */
         {
         pnum = txtline - 1L;
         if( (txtline==linesize) && (letmeback >= 2) )
            pnum = txtline;
         if(linesize) pnum = (100L * pnum)/linesize;
         strcpy(errstr, " ");
         ltoa(ltbuf[0], pnum, 10);
         strcat(errstr, ltbuf[0]);
         if(linesize) strcat(errstr, "%");
         sltxb = strlen(errstr);
         txj = (SHORT)(8 - sltxb);
         while(txj > 0)
            {
            errstr[sltxb] = ' ';
            sltxb ++;
            txj --;
            }
         errstr[sltxb] = '\0';
         strcat(errstr, cgdstr);
         askline = 0L;
         chtxt = getdirs(errstr, &skippages);  /***   Ask user   ***/
         if( (chtxt | 0x20) == 't')
            {
            if(letmeback >=3) return 0;
            tflag = ONEB;
            letmeback = NULB;
            /* new */
            askline = tpline;
            chtxt = 'g';
            }
         }
      if ( (chtxt | 0x20) == 'q') return 0;
      if ( (chtxt | 0x20) == 'c') gflag = NULB;  /* need more directions  */
      if (chtxt == '<')
         {
         askline = 1L;
         chtxt = 'g';
         }
      if (chtxt == '>')
         {
         if(letmeback >= 3) return 0;
         if(!(linesize))
            {
            if (filearg == NULL)
               {
               tflag = ONEB;
               letmeback = NULB;
               askline = tpline;
               chtxt = 'g';
               }
            else
               {
               askline = LINETOOBIG;
               chtxt = 'g';
               }
            }
         if(linesize)
            {
            askline = (LONG)(linesize - ((ULONG)maxline) + 1L);
            if (askline <= 0L) askline = 1L;
            chtxt = 'g';
            }
         }
      if ( ( (chtxt | 0x20) == 'n') && (gflag) )
         {
         golinet = tpline;
         return -1;
         }
      if ( ( (chtxt | 0x20) == 'b') || (chtxt == 0x08) )
         {
         skiplines = (LONG)(maxline);
         skiplines --;
         askline = tpline - skiplines;
         if (askline <= 0L) askline = 1L;
         chtxt = 'g'; 
         }
      if ( (chtxt == 0x0a) || (chtxt == 0x0d) )
         {
         if(letmeback >= 3) return 0;
         askline = tpline;
         askline ++;
         if (askline <= 0L) askline = 1L;
         chtxt = 'g';
         }
      if ( (chtxt == 0x20) || (chtxt == 0xa0) )
         {
         if(letmeback >= 3) return 0;
         if(letmeback == 2)
            {
            askline = tpline;
            askline ++;
            if (askline <= 0L) askline = 1L;
            chtxt = 'g';
            }
         else
            {
            askline = txtline - 1L;
            chtxt = 'g';
            }
         }
      if ( (chtxt | 0x20) == 'u')
         {
         askline = tpline - ( (dmax + 1L)/2L );
         if (askline <= 0L) askline = 1L;
         chtxt = 'g';
         }
      if ( (chtxt | 0x20) == 'd')
         {
         if(letmeback >= 3) return 0;
         askline = tpline + ( (dmax + 1L)/2L);
         chtxt = 'g';
         }
      if ( (chtxt | 0x20) == 'g')
         {
         if(!askline)              /*  get askline from user  */
            {
            strcpy(errstr, " ");
            ltoa(ltbuf[0], tpline, 10);
            errsp[0] = ltbuf[0];
            errsp[1] = (UBYTE *)"-";
            pnum = txtline - 1L;
            if( (txtline==linesize) && (letmeback >= 2) )
               pnum = txtline;
            ltoa(ltbuf[1], pnum, 10);
            errsp[2] = ltbuf[1];
            for(txj = 0; txj < 3; txj ++) strcat(errstr, errsp[txj]);
            sltxb = strlen(errstr);
            errstr[sltxb] = '/';
            sltxb ++;
            errstr[sltxb] = '\0';
            if(!linesize)
               {
               errstr[sltxb] = '?';
               sltxb ++;
               errstr[sltxb] = '\0';
               }
            if(linesize)
               {
               ltoa(ltbuf[0], linesize, 10);
               strcat(errstr, ltbuf[0]);
               }
            strcat(errstr, ":  Go to line > ");
            askline = numget(errstr);
            }
         if (askline <= 0L)
            {
            golinet = 1L;
            return 5;
            }
         else if (askline < tpline)
            {
            golinet = askline;     /*  rewind file  */
            return 5;
            }
         else if (askline <= txtline)
            {
            Move(rp, 0L, (LONG)maxrowpix);
            SetDrMd(rp, (LONG)JAM2);        /*  really clear out the prompt   */
            ClearScreen(rp);
            Move(rp, 0L, (LONG)rowpix); /*  re-write the last line in     */
            drawmode = pvmode;          /*  case its subs were scratched  */
            SetDrMd(rp, drawmode);
            style = pvstyle;
            savestyle = SetSoftStyle(rp, style, enable);
            lp = parseline(pvstr, NULL);
            writeline(lp);
            scrollsize = (rp->TxHeight)*( (UWORD)(askline - tpline) );
            ScrollRaster(rp, 0L, (LONG)scrollsize,
                             0L, 0L, mwwidth, mwheight);
            screenline = screenline - ( (UWORD)(askline - tpline) );
            }
         else
            {
            if(letmeback >=3) return 0;
            golinet = askline;     /*  advance without scroll  */
            return 5;
            }
         }
      if ( (chtxt | 0x20) == 's')
         {
         skiplines = (LONG)(skippages * (maxline - 1));
         if (skiplines > 0)
            {
            if(letmeback) return 0;
            skiplines --;
            }
         else skiplines = skiplines - (LONG)maxline;
         golinet = txtline + skiplines;
         return 6;
         }
      }     /*  loop while (screenline > maxline)  */
   rowpix = (screenline * rp->TxHeight) - rp->TxHeight + rp->TxBaseline;
   Move(rp, 0L, (LONG)rowpix);
   /*  Now rowpix is set.              */
   /*  How must this string be cut up? */
   strcpy(pvstr, instr);  /*  save this line in case it is overwritten  */
   pvstyle = style;
   pvmode = drawmode;
   lp = parseline(instr, NULL);       /*  lp = pointer to first LinePart  */
   writeline(lp);
   }     /*****  loop(bfgets(instr)) *****/
letmeback ++;
tflag = NULB;
prflag = NULB;
if (!(linesize))
      {
      linesize = (ULONG)txtline;  /*  only setting of linesize  */
      pagesize = ( (linesize << 1) + dmax)/(dmax << 1);
      prflag = ONEB;
      }
if(prflag)
   {
   ltoa(ltbuf[0], linesize, 10);
   strcpy(errstr, ltbuf[0]);
   errsp[0] = (UBYTE *)" lines, approx. ";
   ltoa(ltbuf[1], pagesize, 10);
   errsp[1] = ltbuf[1];
   errsp[2] = (UBYTE *)" screen pages\xa";
   for(txj = 0; txj < 3; txj ++) strcat(errstr, errsp[txj]);
   fputs(errstr, stdout);
   }
if ( (linesize < golinem) && (letmeback == 1) ) letmeback =2;
}            /*  end of perpetual loop  */
return 0;    /*  never used             */
}
