/*
 *  CopyRight 1995. Nicholas Poljakov all rights reserved.
 */
#include <bios.h>
#include <stdio.h>
#include <ctype.h>
#include <dos.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <state1.h>


#define BORDER 1
#define REV_VID 0x70
#define NORM_VID 0x1E
#define MAX_FRAME 31
#define BKSP 8
#define F1 59
#define F2 60
#define F3 61
#define F4 62
#define F5 63
#define F6 64
#define F7 65
#define F8 66
#define F9 67
#define F10 68
#define HM  71   /* Home key     */
#define UP  72   /* Up Arrow     */
#define PU  73   /* Page Up      */
#define LT  75   /* Left Arrow   */
#define RT  77   /* Right Arrow  */
#define END 79   /* End key      */
#define DN  80   /* Down Arrow   */
#define PD  81   /* Page Down    */
#define ESC '\033'
#define DIR 0x10

#define ROWS1 19
#define ROWS2 23
#define ROWS  25
#define COLS 78
#define L_W 20
#define M_W 36
#define R_W 20
#define SCRNSIZE ((ROWS)*(COLS+2)*2)
#define LAST (24 * 80)*2

#define M0C  4     /* Files maping col.s */
#define M0L  14    /* Files maping rows  */
#define M0F (((80 * 5) + 9)) * 2
#define INTR 18*2

extern unsigned int attr1b;
extern unsigned int *ptrs;
extern int size;
extern unsigned char row, col;
extern int adapter;
extern unsigned char far *videomem;
extern int offset;
extern int sw;
extern char *path;
extern char file[12];
extern char tpname[31];
extern char luname[8];
extern char lu_id[8];
extern char mode_name[8];
extern char rcv_file[12];
extern char tp_exist; /* Tp_exist eq. 0 if TP not active, and 1 vice versus.*/
extern char dta[128];
extern char far *vid_mem;
extern short cur_ln;
extern struct  part {            /* partner structure */
		  char	 plu[8] ;	     /* str plu_name	    */
                  int psl;                    /* str plu_s_limit     */
		  char	 mode_name[8] ;	     /* str mode_name	    */
                  int max_ru_size;            /* str ru_h_size       */
                  int pacing;                 /* str =               */
                  unsigned char lu_type;
               }  pstr[4];

extern struct menu_frame {
    int startx, endx, starty, endy;
    unsigned char *p;
    char **menu;
    char *keys;
    int border;
    int count;
    unsigned char attrib;
    int active;
    int curx, cury;
    char *header;
    } frame[MAX_FRAME];

extern struct APL_PARM{
       int status;  /* 0-start aplmain,1-start transaction,2-dos shell */
       char p[80];  /* string for system(p) */
       char args[40];/* string of arguments */
       int rc;      /* aplmain return code */
       char dir[60];/* directory name for aplmain */
       int drlen;   /* directory name length */
       void *tpe;   /* entry of exit program */
       char pgm_state;
}*p_aparm;

extern char p_dcl[21];
extern unsigned char dr_ind[80];
extern char c_pt[60];
extern int drive_ind[10];
extern char tp_id[8];
extern unsigned  long conv_id;

em_tty()
{
    char ts[30];
    char tpn[8];
    unsigned int ch;
    char buff[80];
    char retstr[8];
    int i;
    short cnt;
    unsigned char rts;
    unsigned char wr;
    unsigned int max_length ;
    unsigned long rc;
    struct rc {
                unsigned int prim;
                unsigned long sec;
              } v_rc;
    struct msg {  /*send_data*/
                int len;
                char str[134];
               } gds;
    char p_lu[9];
    char p_mode[9];
    int length;
    unsigned key;

    window(10);
    window_xy(10, 1, 1);
    window_puts(10, "F1 -  Help");
    window_xy(10, 2, 1);
    window_puts(10, "F10 - Exit");
    window_xy(10, 1, 56);
    strcpy(ts, "LU partner: ");
    strcat(ts, pstr[cur_ln].plu);
    window_puts(10, ts);
    window(11);
    if (pstr[cur_ln].lu_type != 6) {
        window(14);
	window_xy(14, 2, 0);
        window_puts(14, "The current LU has inproper type!");
        window_xy(14, 3, 4);
        window_puts(14, "Press ESC to continue");
        while ((ch = getch()) != ESC) ;
        deactivate(14);
        goto Em_exit;
    }
    if (p_aparm -> pgm_state) {  /* Remote control */
	window_xy(10, 3, 1);
	window_puts(10, "Receive state. Wait for a message please.");
        goto ReRead;
    }
    if (!tp_exist) {
        tp_started
                 (lu_id,
                  tp_id,
                  &rc);
        if (rc != 0) {
            window_xy(20, 6, 1);
            window_puts(20, "TP_started failure. Press ESC to exit.");
	    goto Em_exit;
	}
	tp_exist = 1; /* TP_started O.K! */
    }

    strcpy (tpn,"TTY "); /* name of work */
    /*conv_id - return param -id work link */
    strcpy(p_lu, pstr[cur_ln].plu);
    strcpy(p_mode, pstr[cur_ln].mode_name);
    allocate  (p_lu,
               p_mode,
               tpn,
               WHEN_SESSION_ALLOCATED,
               NONE,
               NONE,
               NULL,
               NULL,
               tp_id,
               &conv_id,
               NULL,
               &v_rc) ;

    if (v_rc.prim != 0) {
	window_xy(10, 3, 1);
        window_puts(10, "Allocation failure. Press ESC to exit.");
        while ((ch = getch()) != ESC) ;
        goto Em_exit;
    }

    ReSend:
    window_xy(10, 3, 1);
    window_puts(10, "Send state. Please enter the message...   ");
    while (buff[0] != 0x00) {
           window_xy(11, 16, 1);
           if (window_gets(11, buff) == 1) {
               deallocate (tp_id,
                           conv_id,
                           Flush,
                           &v_rc);
               goto Em_exit;
           }
           if (buff[0] == 0x00)
               continue;
           i = strlen(buff);
           strcpy(gds.str, buff) ;
           gds.len = i + 2;
           length=gds.len;
           send_data(tp_id,
                     conv_id,
                     &gds,
                     0,
                     0,
                     length,
                     &v_rc,
                     &rts);
           if (v_rc.prim != 0) {
               window(14);
               window_xy(14, 1, 4);
               window_puts(14, "Return code from send");
               sprintf(retstr,"%x", v_rc.prim);
               i = (30 - strlen(retstr))/2;
               window_xy(14, 2, i);
               window_puts(14, retstr);
               while ((ch = getch()) != ESC) ;
               deactivate(14);
	       goto Em_exit;
           }
           scrollw(11);
    }
    if (buff[0] == 0x00) {
	window_xy(10, 3, 1);
        window_puts(10, "Receive state. Wait for a message please.  ");
    ReRead:
        if (_bios_keybrd( _KEYBRD_READY ) != 0) {
            key = _bios_keybrd( _KEYBRD_READ );
            key &= 0x00ff;
            if (key == 27) {
                deallocate (tp_id, conv_id, abend_prog ,&v_rc);
                goto Em_exit;
            }
        }
        switch (GetMsg(buff)) {
		case -1 :
			   window_xy(10, 3, 1);
                           window_puts(10, "Read error... Press ESC to exit.         ");
                           while ((ch = getch()) != ESC) ;
                           goto Em_exit;
		case  0 :
                           window_xy(11, 16, 1);
                           window_puts(11, buff);
                           scrollw(11);
                           goto ReRead;
		case  1 :
			   window_xy(10, 3, 1);
                           window_puts(10, "End of conversation. Press ESC to exit.  ");
                           while ((ch = getch()) != ESC) ;
                           goto Em_exit;
		case  2  :
			   window_xy(10, 3, 1);
                           goto ReSend;
         }
    }
    goto ReSend;
Em_exit:
    if (p_aparm -> pgm_state) {
       tp_ended (tp_id, &rc);
    }
    deactivate(11);
    deactivate(10);
    return 0;
}

GetMsg(buff)
char *buff;
{
    unsigned char rts;
    unsigned char wr;
    unsigned int max_length ;
    int i;
    char retstr[10];
    struct rc {
                unsigned int prim;
                unsigned long sec;
              } v_rc;
    struct msg {  /*send_data*/
                int len;
                char str[134];
               } gds;
    char p_lu[9];
    char p_mode[9];
    int length;
    unsigned int ch;

       max_length = 255;
       recwait (tp_id,
                conv_id,
                ll,
                &v_rc,
                &length,
                max_length,
                &rts,
		&gds,
                &wr);
       switch (v_rc.prim) {
                case  deallocate_normal:
                          return 1;   /* end of job */
                case  OK:
                          gds.str[gds.len - 2] = 0x00;  /* for ASCII file only! */
                          strcpy(buff, gds.str);
                          break;
                default:
                          window(14);
                          window_xy(14, 1, 4);
                          window_puts(14, "Return code from receive");
                          sprintf(retstr,"%x", v_rc.prim);
                          i = (30 - strlen(retstr))/2;
                          window_xy(14, 2, i);
                          window_puts(14, retstr);
                          sprintf(retstr,"%x", v_rc.sec);
                          i = (30 - strlen(retstr))/2;
                          window_xy(14, 3, i);
                          window_puts(14, retstr);
                          while ((ch = getch()) != ESC) ;
                          deactivate(14);
                          return -1;   /* receive error */
       }
       if (wr == SenD) {
          return 2;     /* change direction */
       }
       return 0;        /* old direction */
}
