/*->c.vxkey */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"
#include "h.bbc"
#include "h.flex"
#include "h.swis"


#include "h.def"
#include "h.wos"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.key"
#include "h.dir"
#include "h.batch"
#include "h.ftp"
#include "h.file"
#include "h.pr"

#include "h.serial"

#include "h.term"
#include "h.xext"


#include "h.vxdef"

#include "h.vxwimp"
#include "h.vxbuff"
#include "h.vxterm"
#include "h.vxedit"
#include "h.vxcol"
#include "h.vxsend"
#include "h.vxprint"
#include "h.vxmenu"

#include "h.vxkey"



/***************************************************************************/
/*
 Code to handle Viewdata keys
*/
/*****************************************************************************/


/*

void retransmit(void)
{
 viewline('*');
 viewline('0');
 viewline('9');
}


void update(void)
{
 viewline('*');
 viewline('0');
 viewline('0');
}


void gotoroot(void)
{
 viewline('*');
 viewline('0');
 viewline(95);
}

void senddelete(void)
{
 viewline('*');
 viewline('*');
}


void sendprevious(void)
{
 viewline('*');
 viewline(95);
}

  

void leave(void)
{
 viewline('*');
 viewline('9');
 viewline('0');
 viewline(95);
}

*/



char mxkeycodes[9][16]=
{
 /* envoi */

 "|[!4|M",

 /* suite */

 "|[(4|M",

 /* retour */

 "|[\"4|M",

 /* guide */

 "|[$4|M",

 /* repetition */

  "|[#4|M",

 /* sommaire */

  "|[&4|M",

 /* annulation */

  "|[/4|M",
 
 /* correction */

  "|['4|M",

 /* fin */

  "|[)4|M"
};



char vxkeycodes[4][16]=
{
 /*  gotoroot */
  "*0_",

 /*  retransmit */

  "*09",

 /*  sendprevious */

 "*_",

 /*  leave */

 "*90_"
};









char vxbuttons[4][12]=
{
 /*  gotoroot */
 "Index",

 /*  retransmit */

 "Retran",

 /*  sendprevious */

 "Back",

 /*  leave */

 "Leave"
};



char * mxfrbuttons[9]=
{

 "Envoi",

 /* suite */

 "Suite",

 /* retour */

 "Retour",

 /* guide */

 "Guide",

 /* repetition */

 "Repttn",

 /* sommaire */

 "Sommre",

 /* annulation */

 "Annltn",
 
 /* correction */

 "Corrct",

 /* fin */

 "Fin"
};




char * mxukbuttons[9]=
{

 /* Envoi */

 "Send",

 /* suite */

 "Next",

 /* retour */

 "Back",

 /* guide */

 "Guide",

 /* repetition */

 "Repeat",

 /* sommaire */

 "Index",

 /* annulation */

 "Cancel",
 
 /* correction */

 "Corrct",

 /* fin */

 "End"
};




char mxbuttons[9][12]=
{
 /* envoi */

 "Envoi",

 /* suite */

 "Suite",

 /* retour */

 "Retour",

 /* guide */

 "Guide",

 /* repetition */

 "Repttn",

 /* sommaire */

 "Sommre",

 /* annulation */

 "Annltn",
 
 /* correction */

 "Corrct",

 /* fin */

 "Fin"
};


void vxwritekeystrings(void)
{
 int handle;
 int i;

 handle=whandle[KEYPAD];

 if(handle)
 {
  for(i=12;i<=15;i++) writeicon(handle,i,vxbuttons[i-12]);
  for(i=78;i<=86;i++) writeicon(handle,i,mxbuttons[i-78]);
 }
}


/* setvxkeypadcode(int VXTERM/MXTERM,int button,string & s); */

void setvxkeypadcode(int fp)
{
 int term;
 int button;

 term=stack[fp];
 if(term==0 || term==1)
 {
  button=stack[fp+1];

  if(button>=0)
  {
   if(term==0 && button<4)
   {
    if(strlen(stringptr(stack[fp+2]))<16)
       strcpy(vxkeycodes[button],stringptr(stack[fp+2]));
   }
   else
   if(term==1 && button<9)
   {
    if(strlen(stringptr(stack[fp+2]))<16)
       strcpy(mxkeycodes[button],stringptr(stack[fp+2]));
   }
   vxwritekeystrings();
  }
 }
}


/* setvxkeypadstring(int VXTERM/MXTERM,int button,string & s); */

void setvxkeypadstring(int fp)
{
 int term;
 int button;

 term=stack[fp];
 if(term==0 || term==1)
 {
  button=stack[fp+1];

  if(button>=0)
  {
   if(term==0 && button<4)
   {
    if(strlen(stringptr(stack[fp+2]))<16)
       strcpy(vxbuttons[button],stringptr(stack[fp+2]));
   }
   else
   if(term==1 && button<9)
   {
    if(strlen(stringptr(stack[fp+2]))<16)
       strcpy(mxbuttons[button],stringptr(stack[fp+2]));
   }
   vxwritekeystrings();
  }
 }
}



/* setvxlanguage(int VXTERM/MXTERM,int language); */

void setvxlanguage(int fp)
{
 int term;
 int language;
 int i;

 term=stack[fp+0];
 language=stack[fp+1];

 if(term==0)
 {
   /* nothing always UK */
 }
 else
 if(term==1)
 {
  if(language==1) /* British */
  {
   for(i=0;i<9;i++) strcpy(mxbuttons[i],mxukbuttons[i]);
  }
  else
  if(language==4) /* French */
  {
   for(i=0;i<9;i++) strcpy(mxbuttons[i],mxfrbuttons[i]);
  }
  vxwritekeystrings();
 }
}


char vxterminator[2][16]=
{
 "_",

 "|[!4|M"
};


/* setvxterminator(int VXTERM/MXTERM,int language); */

void setvxterminator(int fp)
{
 int term;

 term=stack[fp];

 if(term==0 || term==1)
 {
  if(strlen(stringptr(stack[fp+1]))<16)
       strcpy(vxterminator[term],stringptr(stack[fp+1]));
 }
}


/****************************************************************************/



int viewkey1(int key)
{
 if(vxtxcrlnf && key==CR)
 {
  viewline(CR);
  viewline(LF);
  return(0);                         /* keep compiler happy */
 }
 if(key==127)
 {
  viewline(8);
  viewline(32);
  viewline(8);
 }
 else
 {
  if(key==35)  key=95;
  else
  if(key==163) key=35;
  else
  if(key==164) key=127;
  else
  if(key==95)  key=96;
  /* else
  if(key==13 && vedit && local) vsay(10);  */
  viewline(key);
 }
 return(0);
}







static void veditkey(int * key)
{
 int c=*key;

 if(c>=F1 && c<=F7) viewkey1(c-F1+VALPHARED);
 else
 if(c>=SHFT_F1 && c<=SHFT_F7) viewkey1(c-SHFT_F1+VGRAPHRED);
 else
 switch(c)
 {
   case       F8:
                 viewkey1(VFLASH);
                 break;

   case  SHFT_F8:
                 viewkey1(VSTEADY);
                 break;

   case       F9:
                 viewkey1(VDOUBLE);
                 break;

   case  SHFT_F9:
                 viewkey1(VSINGLE);
                 break;

   case      F10:
                 viewkey1(VSEP);
                 break;

   case SHFT_F10:
                 viewkey1(VCONT);
                 break;
    
   case      F11:
                 viewkey1(VNEWBACK);
                 break;

   case SHFT_F11:
                 viewkey1(VBLKBACK);
                 break;

/*   case SHFT_F12:
                 vxstopedit();
                 break;   */

 case CTRL_CDOWN:
                 insertline();
                 break;

   case CTRL_CUP:
                 deleteline();
                 break;

 case CTRL_CLEFT:
                 deletechar();
                 break;

case CTRL_CRIGHT:
                 insertchar();
                 break;

         default:
                 return;
                 break;
 }
 *key=-1;
}




void viewfnkey(int * key)
{
 int c;

 if(vedit) veditkey(key);  /* sets key to -1 if it does anything */

 c=*key;

 switch(c)
 {
     case F1:                        /* show quick set up */
             popquicksetup();
             break;

     case F2:                        /* show directory */
             dirshow();
             break;

     case F3:
             if(vxcbuff!=-1) opensave(SAVEVXBUFFFRAME);
             break;

     case F4:
             connect();
             break;

     case F5:
             ftpreceivep(PCET);
             break;

     case F6:
             openrxbatch();
             break;

     case F7:
             macrosshow();
             break;

     case F8:
             longbreak();
             break;

     case F9:
             vxbcopy(vxcbuff);
             break;

    case F10:
             vxbgoto(vxcbuff);
             break;

    case F11:
             vxcbbackward();
             break;
                                                                                 case PRINTK:
             popvxprint();
             break;

case SHFT_F1:
             vxanswerback();
             break;

case SHFT_F2:
             diallast();
             break;

case SHFT_F3:
             opensave(SAVEVXCSPRITE);
             break;

case SHFT_F4:
             disconnect();
             break;

case SHFT_F5:
             sendscreen();
             break;

case SHFT_F6:
             opentxbatch();
             break;

case SHFT_F7:
             togglekeypad();
             break;

case SHFT_F8:
             shortbreak();
             break;

case SHFT_F9:
             vxbopen(vxcbuff);
             break;

case SHFT_F10:
              vxbpaste(vxcbuff);
              break;

case SHFT_F11:
              /* vxgombxref(); */

              vxcbforward();
              break;
                                                                               
/* case SHFT_F12:
              vxstartedit();
              break; */


  case  COPY:     /* Copy code under cursor */
             if(!minitel) viewline(vscr->tcbuf[ttvy][ttvx]);
             else
                dprintf(0,"code=%x %x",vscr->tcbuf[ttvy][ttvx],vscr->tvbuf[ttvy][ttvx]);
             break;                    

case BACKSPACE:
               viewline(BS);
               break;

  case  CLEFT:
  case CRIGHT:
  case  CDOWN:
  case    CUP:
             viewline(c-CLEFT+8);
             break;


    case  K0:
    case  K1:
    case  K2:
    case  K3:
    case  K4:
    case  K5:
    case  K6:
    case  K7:
    case  K8:
    case  K9:
             viewkey1('0'+c-K0);
             break;

 case  KPLUS:
             viewkey1('+');
             break;

 case KMINUS:
             viewkey1('-');
             break;

 case  KHASH:
             viewkey1('#');
             break;
                                                                                 case KSLASH:
             viewkey1('/');
             break;

case KASTERIX:
             viewkey1('*');
             break;

case   KPOINT:
             viewkey1('.');
             break;

case       ENTER:
case SHFT_RETURN:
                 if((!ttns && vxreturnishash) || (ttns && campusreturnishash))
                                                              viewkey1(CR); 
                 else         viewconvertstringline(vxterminator[minitel]);
                 break;


case CTRL_RETURN:viewconvertstringline(vxsolseq);
                 break;

     default:
             return;
 }

 *key=-1;                  
}



void viewkey0(int key)
{
 if(!vedit)
 {
  if(key==CR && ((!ttns && vxreturnishash) || (ttns && campusreturnishash)))
  {
   viewconvertstringline(vxterminator[minitel]);   /*  key='#'; */
   return;
  }
 }
 viewkey1(key);
}




/* key presses from main loop come here */

void viewkey(int * key)
{

 if(*key<256)
 {
  viewkey0(*key);
  *key=-1;
 }
 else
  viewfnkey(key);
}




void viewintkey(int key)
{
 viewkey(&key);
}



/****************************************************************************/


char vxcodesmap[11]=
                    {
                     VFLASH,
                     VSTEADY,
                     VDOUBLE,
                     VSINGLE,
                     VHOLD,
                     VRELEASE,
                     VCONT,
                     VSEP,
                     VNEWBACK,
                     VBLKBACK,
                     VCONCEAL
                    };



static int vxselected;

void vxkeypadzero(void)
{
 getpointer();
 if(whandle[KEYPAD])
 {
  if(mhandle!=whandle[KEYPAD] || micon!=vxselected || !buttons)
  {
   deselect(whandle[KEYPAD],vxselected);
   remzeroevent(VXKEYZERO);
  }
 }
}


void vxkeypadflash(int icon)
{
 addzeroevent(VXKEYZERO);

 if(icon!=vxselected) deselect(whandle[KEYPAD],vxselected);
 vxselected=icon;
 select(whandle[KEYPAD],vxselected);
}



void vxkeypadicon(void)
{
 if(buttons==1 || buttons==4)
 switch(icon)
 {
  case 77:
  case 11:
          viewline(95);
          vxkeypadflash(icon);
          break;

  case 75:
  case 10:
          viewline('*');
          vxkeypadflash(icon);
          break;

  case 16:
          reveal();
          break;

  case 89:
  case 21:
  case 65:
          vxbopen(vxcbuff);
          break;

  case 88:
  case 20:
  case 64:
          vxbcopy(vxcbuff);
          break;


  case 12:
  case 13:
  case 14:
  case 15:
          viewconvertstringline(vxkeycodes[icon-12]);
          vxkeypadflash(icon);
          break;


  case 17:
          vxstartedit();
          break;

  case 52:
          vxstopedit();
          break;

  default:
          if(icon>=54 && icon<=61) vxedtool(icon-54);
          else
          {
           if(icon>=0 && icon<10)   viewline('0'+icon);
           else
           if(icon>=66 && icon<75)  viewline('0'+icon-65);
           else
           if(icon==76)             viewline('0'); 
           else
           if(icon>=26 && icon<=32) viewline(VALPHARED+icon-26);
           else
           if(icon>=33 && icon<=39) viewline(VGRAPHRED+icon-33);
           else
           if(icon>=40 && icon<=50) viewline(vxcodesmap[icon-40]);
           else
           if(icon>=78 && icon<=86) viewconvertstringline(mxkeycodes[icon-78]);
           else break;
           vxkeypadflash(icon);
          }
          break;
 }
}



void vxkeypadclose(void)
{
#ifndef VICK
 if(vedit) vxstopedit();
 closedownt(KEYPAD);
#endif
}



/* called by wimps, changes vxkeypad state */

void vxkeypadclosew(void)
{
 vxkeypadclose();
 vxkeypad=0;
}



void vxwriterates(void)
{
 if(whandle[KEYPAD]) writeicon(whandle[KEYPAD],25,ratedisplay);
 if(whandle[KEYPAD]) writeicon(whandle[KEYPAD],93,ratedisplay);
}


void vxwritetime(void)
{
 if(whandle[KEYPAD]) writeicon(whandle[KEYPAD],24,onlinetimedisplay);
 if(whandle[KEYPAD]) writeicon(whandle[KEYPAD],92,onlinetimedisplay);
}


void vxwriteonline(void)
{
 if(whandle[KEYPAD]) writeicon(whandle[KEYPAD],23,onlinedisplay);
 if(whandle[KEYPAD]) writeicon(whandle[KEYPAD],91,onlinedisplay);
} 


void vxkeypadopen(void)
{
 int mx1;
 int my1;
 int handle;

 getw(whandle[VDATA]);
 mx1=x1+48;
 my1=y1;
 vxecreatekeypad();
 handle=createwindow(KEYPAD);
 vxwritekeystrings();
 vxbupdatecurrent();
 vxwriterates();
 vxwritetime();
 vxwriteonline();
 getw(handle);

 if(minitel) open(handle,mx1,my1-788,mx1+(x1-x0),my1,0,792,-1);
 else        open(handle,mx1,my1-692,mx1+(x1-x0),my1,0,0,-1);
}



/* toggle keypad */

void togglekeypad(void)
{
 if(vxkeypad)
 {
  vxkeypadclose();
 }
 else
 {
  vxkeypadopen();
 }
 vxkeypad^=1;
}







#ifdef XXXXXXXX
 

void vxkeypadredraw(void)
{
 wimp_redrawstr redrawstr;
 int            more;
 int            ox;
 int            oy;
 int             i;
 os_regset      rx;
 char           pixtrn[16];
 int            magblk[4];

 redrawstr.w=ewindow;
 
 wimp_redraw_wind(&redrawstr,&more);

 while(more)
 {
  ox=redrawstr.box.x0-redrawstr.scx;
  oy=redrawstr.box.y1-redrawstr.scy;

  if(vedit)     /* got to find those icons and redraw them */
  {
   rx.r[0]=0x100;                 /* wimp_readpixtrans */
   rx.r[1]=(int)sprites;          /* wimp.colours      */
   rx.r[2]=(int)"mosaic";
   rx.r[6]=(int)magblk;
   rx.r[7]=(int)pixtrn; 
   os_swix(0x40000+0xED,&rx);


   for(i=42;i<49;i++)
   {
    geti(whandle[KEYPAD],i);

    rx.r[0]=0x134;
    rx.r[1]=(int)sprites;
    rx.r[2]=(int)"mosaic";
    rx.r[3]=ox+ix0; 
    rx.r[4]=oy+iy0;
    rx.r[5]=8;
    rx.r[6]=(int)magblk;
    rx.r[7]=(int)pixtrn;

    pixtrn[1]=vxphysicalcolour(RED+i-42);
    if(ln2bpp!=3) pixtrn[1]&=0xF;

    os_swix(OS_SpriteOp,&rx);
   }






  }

  wimp_get_rectangle(&redrawstr,&more);
 }
}



#endif








void vxkeypadredraw(void)
{
 wimp_redrawstr redrawstr;
 int            more;
 int            ox;
 int            oy;
 int             i;

 redrawstr.w=ewindow;
 
 wimp_redraw_wind(&redrawstr,&more);

 while(more)
 {
  ox=redrawstr.box.x0-redrawstr.scx;
  oy=redrawstr.box.y1-redrawstr.scy;

  if(vedit)     /* got to find those icons and redraw them */
  {
   for(i=26;i<33;i++)
   {
    geti(whandle[KEYPAD],i);
    vxsetgcol(RED+i-26);
    bbc_rectanglefill(ox+ix0,oy+iy0,ix1-ix0-deltax,iy1-iy0-deltay);
   }

   for(i=33;i<40;i++)
   {
    geti(whandle[KEYPAD],i);
    vxsetgcol(RED+i-33);
    bbc_rectanglefill(ox+ix0,oy+iy0,ix1-ix0-deltax,iy1-iy0-deltay);
   }

   geti(whandle[KEYPAD],51);
   vxsetgcol(vxecurcolour);
   bbc_rectanglefill(ox+ix0,oy+iy0,ix1-ix0-deltax,iy1-iy0-deltay);

  }

  wimp_get_rectangle(&redrawstr,&more);
 }
}







