/* FKeys.c */
#include <exec/types.h>
#include <stdio.h>
#include <fcntl.h>
#include "ConsoleIO.h"

  /* things for function keys */
#define NUMKEYS 10		    /* number of function keys */
#define KEYSIZE 40		    /* maximum length of any one string */
#define BUFSIZE KEYSIZE * NUMKEYS   /* size of total buffer */
#define HEADER  '\x70'    /* first byte of file is version number (7.0) */
#define MAXOPTION 256               /* maximum length of option string */
#define CSI     '\x9b'		    /* Command Sequence Introducer */ 	

extern UBYTE *KeyBuf;
/*********************************************************************
**	  Some routines concerned with the function keys	    **
*********************************************************************/

extern void SetOptions();
extern int  GetOptions();
	       
/************* Attempt to load a Function-Key file ******************/

BOOL LoadKeys(keyfile)    /* returns (BOOL) success	*/

   char *keyfile;  /* the filename */
 {
      int fp;
      int i;
      short optsize;
      BOOL filefound = FALSE;
      BOOL goodfile  = TRUE;
      UBYTE c, opt[ MAXOPTION ];

   if ( (fp = open(keyfile, O_RDONLY)) == -1)
      return FALSE;
   i = read( fp, &c, sizeof( c ) );
   if ( i == sizeof( c ) && c == HEADER  )  /* gotta be a valid key file! */
     {
       filefound = TRUE;
       i = read( fp, &optsize, sizeof( optsize ) ); 
       if ( i != sizeof( optsize ) ||
            !((0 <= optsize) && (optsize < MAXOPTION)) )
	  goodfile = FALSE;
       else if ( read( fp, opt, optsize ) != optsize )
	  goodfile = FALSE;
       else
	 {
	    SetOptions( opt, optsize );
	    if ( read( fp, KeyBuf, BUFSIZE ) != BUFSIZE )
	       goodfile = FALSE;
	 }
      }
		
    close( fp );
    if ( !goodfile )
      {
	PutString( "Key Buffer file has been corrupted...\n." );
	PutString( "  Function Keys May be Invalid.\n" );
      }
	
    return filefound;    /* ahh, success? */
  }
/**************Save Function-Key file *****************/

BOOL SaveFKeys(filename)	/* returns (BOOL) success */
 char *filename;

{
    int fp;
    BOOL goodfile = TRUE;
    short optsize;
    UBYTE c = HEADER, opt[ MAXOPTION ];

    if ( ( fp = open( filename, O_WRONLY + O_CREAT )) == -1)
       return FALSE;

    if ( write( fp, &c, sizeof( c)) != sizeof( c ))
	goodfile = FALSE;
    else if ( ( optsize = GetOptions( opt, MAXOPTION )) > MAXOPTION)
      { 
	PutString( "Can't Happen: Too many options to save.\n" );  
	goodfile = FALSE;
      }
    else if ( write( fp, &optsize, sizeof( optsize )) != sizeof( optsize ))
        goodfile = FALSE;
    else if ( write( fp, opt, optsize ) != optsize )
	goodfile = FALSE;
    else if ( write( fp, KeyBuf, BUFSIZE ) != BUFSIZE )
	goodfile = FALSE;

    close( fp );
    if ( !goodfile )
       PutString( "Error writing file.\n");

    return goodfile;
 }


/*********** Print a character from function-key string ************/

void keychar(key)
   UBYTE key;
 {
   if (key < ' ') /* control character? */
    {
      switch (key)
      { case 0:
	  PutChar('0');
	  break;
	case '\b':
	  PutString("<BS>");
	  break;
	case '\t':
	  PutString("<TAB>");
	  break;
       case '\n':
	  PutString("<NL>");
	  break;
       case '\r':
	  PutString("<CR>");
	  break;
       case 27:
	  PutString("<ESC>");
	  break;
       default:
	  PutChar('^');
	  PutChar(key + 0x40);
       } 
     }
   else PutChar(key);
  }

/************ Print the function-key number **************/
/*		format example: F7:			*/

static void PrintKeyNum(keynum)
    int keynum;
{
   keynum++;
   PutChar('F');
   if (keynum == 10)
      PutString("10: ");
   else
     {
       PutChar(keynum + '0');
       PutString(":  ");
     }
}

/************ Display Function-Key contents **********/

void DoContents()

{
   int x;
   UBYTE c, *offset;
   
 for (x=0; x < NUMKEYS; x++)
  {
    offset = KeyBuf + KEYSIZE * x;
    PrintKeyNum( x );
    while ( c = *offset++ )
      keychar(c);
    PutChar('\n');
   }
 }

/*******	Define a function-key string	*********/

void DefineString()
{
   UBYTE c, character;
   int keynum, count, offset, i;

   PutString( "\x9b33mFunction-Key String Definition:\n\n");
   if ( GetKey() != CSI )
     { PutString( "aborted...\n\n\x9bm" );
       return;
     }
   else
     {
       character = GetKey();	    /* get the meat of the sequence */
       while ( GetKey() != '~' );   /* wait for sequence to end */
     }
   if (!( (character >= '0') && (character <= '9') )) /* isdigit? */
     {
	PutString( "aborted...\n\n\x9bm" );
	return;
      }
   else
      {
	 keynum = character - '0';
	 PrintKeyNum( keynum );
	 offset = KEYSIZE * keynum; /* find correct spot in buffer */
	 i = 0;
	 while ( (character = GetKey()) != CSI )	/* get the string */
	   { if (i<(KEYSIZE-1))
	     {
	        KeyBuf[offset + (i++) ] = character;	/* store it	  */
	        keychar(character);  			/* display it, too */
	      }
	    }
	  while (GetKey() != '~' );	/* skip over rest of F-key	*/
	   	
	  while (i < KEYSIZE)
	    {
	       KeyBuf[offset+i] = '\0';	/* zero out the rest of		*/
	       i++;			/* that string's buffer		*/
	     }
	   PutString("\n\n");
	   PutString("\x9bm");
	  }	/* end else */
 }	/* end DefineString();	*/
