/*
 * RawConsole.c
 *
 * Shell 2.07M  17-Jun-87
 * console handling, command line editing support for Shell
 * using new console packets from 1.2.
 * Written by Steve Drew. (c) 14-Oct-86.
 * 16-Dec-86 Slight mods to rawgets() for Disktrashing.
 *
 * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
 *
 */

#if RAW_CONSOLE

char *tyahdptr;

myget()
{
if (*tyahdptr) return *tyahdptr++;
return getchar();
}

extern int aux; /* for use with aux: */

#define SETRAW setrawcon(-1L);
#define SETCON setrawcon(0L);

int width;

newwidth()
{
extern struct Window *w;

width=(w->Width- (w->BorderLeft + w->BorderRight)) / w->RPort->TxWidth;
}

char *rawgets(line,prompt)
char *line, *prompt;
{
char *get_var();
char *gets();
register int n, pl;
register int max, i;
unsigned char c1,c2,c3;
char fkeys[5];
char *s;
char *ps;
char typeahd[256];
int fkey, savn;
int insert = 1;
int recall = -1;
struct HIST *hist;

newwidth();

if (aux) {
	printf("%s",prompt);
	fflush(stdout);
	}
if (!IsInteractive(Input()) || aux ) return(gets(line));
if (WaitForChar((long)Input(), 100L) ||   /* don't switch to 1L ...*/
		stdin->_bp < stdin->_bend) {     /* else causes read err's*/
	gets(line);
	return(line);
	}
SETRAW;
printf("\015%s\2336n",prompt);
savn = pl = n = 0;
tyahdptr = typeahd;
while((typeahd[n]=getchar()) != 'R') {
	if ((unsigned char)typeahd[n] == 155) savn = n;
	n++;
	}
	/* typeahd now contains possible type a head chars
	   followed by <CSI> cursor position report.
	*/
typeahd[savn]  = '\0';
if (typeahd[n-2] != ';') pl = (typeahd[n-2] - 48) * 10;
pl += typeahd[n-1] - 49;
ps = line + pl;
line[max = i = pl] = '\0';

if (s = get_var (LEVEL_SET, "_insert")) insert = atoi(s) ? 1 : 0;

while( (c1 = myget()) != 255) {
        switch(c1) {
            case 155:
                 c2 = myget();
                 switch(c2) {
                     case 'A':                  /* up arrow   */
                        n = ++recall;
                     case 'B':                  /* down arrow */
                        line[pl] = '\0';
                        if (recall >= 0 || c2 == 'A') {
                            if (c2 == 'B') n = --recall;
                            if (recall >= 0) {
                                for(hist = H_head; hist && n--;
                                    hist = hist->next);
                                if (hist) strcpy(&line[pl],hist->line);
                                else recall = H_len;
                            }
                        }
                        if (i != pl)
                            printf("\233%dD",i);
                        printf("\015\233J%s%s",prompt,ps);
                        i = max = strlen(ps) + pl;
                        break;
                     case 'C':                  /* right arrow*/
                        if (i < max) {
                            i++;
                            printf("\233C");
                        }
                        break;
                     case 'D':                  /* left arrow */
                        if (i > pl) {
                            i--;
                            printf("\233D");
                        }
                        break;
                     case 'T':           /* shift-up   */
                       n = recall = H_len-1;
                     case 'S':           /* shift-down */
                       line[pl] = '\0';
                       if (c2 == 'S') {
                           n = recall = 0;
                           if (H_head) strcpy(&line[pl], H_head->line);
                       }
                       else if (H_tail) strcpy(&line[pl], H_tail->line);
                       printf("\015\233J%s%s", prompt, ps);
                       i = max = strlen(ps) + pl;
                       break;
                    case ' ':                   /* shift -> <-*/
                        c3 = myget();
                                     switch(c3) {
                    case('@'):      /* shift ->   */
                        while (ps[i-pl-1] == ' ' && i<max) {
      		            i++;
      		            printf("\233C");
		        }
                        while (ps[i-pl-1] != ' ' && i<max) {
      		            i++;
		            printf("\233C");
               		}
                        break;
                    case('A'):      /* shift <-   */
                        while (ps[i-pl-1] == ' ' && i>pl) {
                            i--;
                            printf("\233D");
                        }
                        while (ps[i-pl-1] != ' ' && i>pl) {
                            i--;
                            printf("\233D");
                        }
                        break;
                        default:
                        break;
                    }
                        break;
                    default:
                        c3 = myget();
                        if (c3 == '~') {
                            fkey = c2;
                            fkeys[0] = 'f';
                            if (c2 == '?') {
                                strcpy(ps,"help");
                                goto done;
                            }
                        }
                        else if (myget() != '~') { /* window was resized */
                            while(myget() != '|');
                            newwidth();
                            break;
                        }
                        else {
                            fkey = c3;
                            fkeys[0] = 'F';
                        }
                        sprintf(fkeys+1,"%d",fkey - 47);
                        if (s = get_var(LEVEL_SET, fkeys))
                                tyahdptr = strcpy(typeahd,s);
                        break;
                    }
                break;
            case 8:
                if (i > pl) {
                    i--;
                    printf("\010");
                }
                else break;
            case 127:
                if (i < max) {
                    int j,t,l = 0;
                    movmem(&line[i+1],&line[i],max-i);
                    --max;
                    printf("\233P");
                    j = width - i % width - 1;   /* amount to end     */
                    t = max/width - i/width;     /* no of lines       */
                    for(n = 0; n < t; n++) {
                        l += j;                  /* no. of char moved */
                        if (j) printf("\233%dC",j); /* goto eol       */
                        printf("%c\233P",line[width*(i/width+n+1)-1]);
                        j = width-1;
                    }
                    if (t)
                    printf("\233%dD",l+t);   /* get back */
                }
                break;
            case 18:
                n = i/width;
                if (n) printf("\233%dF",n);
                printf("\015\233J%s%s",prompt,ps);
                i = max;
                break;
            case 27:
                break;
            case 1:
                insert ^= 1;
                break;
            case 21:
            case 24:
            case 26:
                if (i>pl) printf("\233%dD",i-pl);
                i = pl;
                if (c1 == 26) break;
            case 11:        /* ^K */
                printf("\233J");
                max = i;
                line[i] = '\0';
                break;
            case 28:        /* ^\ */
                SETCON;
                return(NULL);
            case 5:
                if (i!=max) printf("\233%dC",max - i);
                i = max;
                break;
            case 10:
            case 13:
                line[max] = '\0';
done:           printf("\233%dC\n",max - i);

                SETCON;
                strcpy(line, ps);
                return(line);
            default:
                c1 &= 0x7f;
                if (c1 == 9) c1 = 32;
                if (c1 > 31 & i < 256) {
                    if (i < max && insert) {
                        int j,t,l = 0;
                        movmem(&line[i], &line[i+1], max - i);
                        printf("\233@%c",c1);
                        t = max/width - i/width;
                        j = width - i % width - 1;
                        for(n = 0; n < t; n++) {
                            l += j;
                            if (j) printf("\233%dC",j);
                            printf("\233@%c",line[width*(i/width+n+1)]);
                            j = width-1;
                        }
                        if (t) printf("\233%dD",l + t);
                        ++max;
                    }
                    else {
                        if(i == pl && max == i) printf("\015%s%s",prompt,ps);
                        putchar(c1);
                    }
                    line[i++] = c1;
                    if (max < i) max = i;
                    line[max] = '\0';
                }
        }
	}
SETCON;
return(NULL);
}

setrawcon(flag) /* -1L=RAW:, 0L=CON: */
long flag;
{
long packargs[8];

packargs[0]=flag;
SendPacket(994L, packargs, Myprocess->pr_ConsoleTask);
}

#endif
