/***********************************************************/
/* Amiga kanji utilities.                                  */
/* "AK.c" copyright Roger Ang   Oct., 1995                 */
/***********************************************************/

#include "AK.h"

/*
 * Opens the libraries.  Sets global vars/pointers.  Loads the kanji fonts.
 * "font_size" is the pixel height of the font to look for.  This can be 
 * overridden by the font size set in the config file.  If "no_kanji" is FALSE, 
 * all kanji fonts are opened (41 fonts total).  Else if "no_kanji" is TRUE,
 * only 3 fonts (ASCII and kana) are initially opened (the others will be 
 * opened on demand).  If only low level output, AK_Text(), is going to be 
 * used, then the Window should be passed in "wind".  Otherwise, the console 
 * window and ConUnit will be looked for.  Returns -1, if there was a problem.
 */
int AK_init(struct Window *wind, int font_size, BOOL no_kanji)
{
  short i; 
  BOOL found;
  char tmpname[80];

  AK_getconfig();

  if (_AK_font_size > 0)
    font_size = _AK_font_size;

  if (wind != NULL)
    _AK_cust_wind = TRUE;
  else if (Output() == NULL) {
    fprintf(stderr, "No stdout.  You need to run this from a shell.\n");
    return -1;
  }

  /* Open the necessary libraries. */
  if (!IntuitionBase)
    IntuitionBase = 
      (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
  if (!IntuitionBase) {
    fprintf(stderr, "Could not open Intuition library!\n");
    return -1;
  }

  if (!GfxBase) 
    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
  if (!GfxBase) {
    fprintf(stderr, "Could not open Graphics library!\n");
    if (IntuitionBase)  CloseLibrary((struct Library *) IntuitionBase);
    return -1;
  }

  if (!DiskfontBase)
    DiskfontBase = OpenLibrary("diskfont.library", 0);
  if (!DiskfontBase) {
    fprintf(stderr, "Could not open Diskfont library!\n");
    if (GfxBase)        CloseLibrary((struct Library *)GfxBase);
    if (IntuitionBase)  CloseLibrary((struct Library *) IntuitionBase);
    return -1;
  }

  /* set globals */
  if (wind != NULL)
    AK_window = wind;
  else if (findWindow() == NULL) {
    fprintf(stderr, "Not enough free memory\n");
    if (DiskfontBase)   CloseLibrary(DiskfontBase);
    if (GfxBase)        CloseLibrary((struct Library *)GfxBase);
    if (IntuitionBase)  CloseLibrary((struct Library *) IntuitionBase);
    return -1;
  }

  AK_rp = AK_window->RPort;
  AK_curr_encoding = UNKNOWN;

  /* set up all font attributes */
  strcpy (tmpname, "ascii.font");
  AK_font_attr[0].ta_Name = (char*) malloc(strlen(tmpname)+1);
  strcpy(AK_font_attr[0].ta_Name, tmpname);
  AK_font_attr[0].ta_YSize = font_size;
  AK_font_attr[0].ta_Style = FS_NORMAL;
  AK_font_attr[0].ta_Flags = FPF_DISKFONT;

  AK_font[0] = (struct TextFont *) OpenDiskFont(&AK_font_attr[0]);

  /* load kanji fonts */
  found = 0;
  for (i = 1; i < 43; i++) {
    sprintf(tmpname,"jis%d.font", i);
    AK_font_attr[i].ta_Name = (char*) malloc(strlen(tmpname)+1);
    strcpy(AK_font_attr[i].ta_Name, tmpname);
    AK_font_attr[i].ta_YSize = font_size;
    AK_font_attr[i].ta_Style = FS_NORMAL;
    AK_font_attr[i].ta_Flags = FPF_DISKFONT;

    /* if no_kanji loading, initially load only hiragana and katakana */
    if (no_kanji) {
      if (i == 3)
        AK_font[i] = (struct TextFont *) OpenDiskFont(&AK_font_attr[i]);
      else
        AK_font[i] = NULL;
    }
    else /* Try to open a disk font. */
      AK_font[i] = (struct TextFont *) OpenDiskFont(&AK_font_attr[i]);

    if (AK_font[i] != NULL)  found = 1;
  }

  AK_old_font = AK_rp->Font;
  if ((found == 0) || (AK_font[AK_ASCII] == NULL)) {
    AK_cleanup("Could not open fonts.\n");
    return -1;
  }

  SetFont(AK_rp, AK_font[AK_ASCII]);

  if (wind == NULL)
    printf("\033c");    /* resets the console so the new font is used */

  AK_crow = AK_ccol = 0;

  return 0;
}

/*
 * Shutdown: close libraries and fonts.
 * "message" is an optional message to print.
 */
void AK_cleanup(message)
char *message;
{
  int i;

  for (i = 0; i < 43; i++) {
    if (AK_font[i] != NULL)  CloseFont(AK_font[i]);
    free(AK_font_attr[i].ta_Name);
  }

  /* reset the font of the window */
  if (!_AK_cust_wind) {
    SetFont(AK_rp, AK_old_font);
    printf("\033c"); /* reset console */
    ActivateWindow(AK_window); /* wake up window again */
  }

  if (DiskfontBase)   CloseLibrary(DiskfontBase);
  if (GfxBase)        CloseLibrary((struct Library *)GfxBase);
  if (IntuitionBase)  CloseLibrary((struct Library *) IntuitionBase);
  
  if (message)
    if (Output() != NULL)
      fprintf(stderr,"%s\n", message );
}

/* 
 * Guess the encoding of a string.  NOTE: assuming that NULL (byte == 0) 
 * marks the end of the string (i.e. no kanji has an encoding with the 
 * 1st or 2nd byte being 0).
 * Returns type of encoding.
 */
AK_kanji_type AK_guess_encoding(unsigned char *a_str)
{
  AK_kanji_type encoding = UNKNOWN;
  int i, len;

  len = strlen(a_str);
  for (i = 0; i < len; i++) {
    if (len-i >= 3)
      if ((a_str[i] == 27) && (a_str[i+1] == 36)) {
        if (a_str[i+2] == 66) {
          encoding = JIS83;
          break;
        }
        if (a_str[i+2] == 64) {
          encoding = JIS78;
          break;
        }
      }
    if (len-i >= 2) {
      if (((a_str[i] >= 129) && (a_str[i+1] >= 64)) &&
          ((a_str[i] <= 159) && (a_str[i+1] <= 253))) {
        encoding = SJIS;
        break;
      }
      if ((a_str[i] >= 161) && (a_str[i+1] >= 161)) {
        encoding = EUC;
        break;
      }
    }
  }
  return encoding;
}


/*
 * Decode a character to two JIS bytes.  "rawcode" should be the
 * 2-byte (16 bit) value of 1 character.  "encoding" specifies the
 * kanji encoding of the "rawcode" value.  The JIS code for the
 * character is returned in "jbyte1" and "jbyte2".  If the "rawcode"
 * isn't valid, -1 is returned.
 */

int AK_decode_char(unsigned char *jbyte1, unsigned char *jbyte2, 
         unsigned short rawcode, AK_kanji_type encoding)
{
  unsigned char rawch1, rawch2, jch1, jch2;

  rawch1 = (rawcode >> 8) & 0xFF;
  rawch2 = rawcode & 0xFF;

  if ((rawch1 == 0) && (rawch2 <= 127)) {
    /* plain ASCII */
    *jbyte1 = 32;
    *jbyte2 = rawch2;
    return 0;
  }

  switch (encoding) {
  case SJIS:
    /* check valid kanji */
    if ((((rawch1 >= 0x81) && (rawch1 <= 0x9F)) ||
         ((rawch1 >= 0xE0) && (rawch1 <= 0xEF))) &&
        ((rawch2 >= 0x40) && (rawch2 <= 0xFC))) {

      if (rawch1 > 159)
        jch1 = rawch1 - 64;
      else
        jch1 = rawch1;

      jch1 = ((jch1 - 129) << 1) + 33;

      if (rawch2 >= 159)  jch1++; 
      if ((jch1 & 0x1) != 0) { /* if 1st byte odd */
        if (rawch2 >= 127)
          jch2 = rawch2 - 1;
        else
          jch2 = rawch2;

        jch2 = jch2 - 31;
      }
      else
        jch2 = rawch2 - 126;


      *jbyte1 = jch1;
      *jbyte2 = jch2;
      return 0;
    }      
    break;
  case EUC:
    if ((rawch1 >= 0xA1) && (rawch2 >= 0xA1)) {
      *jbyte1 = rawch1 & 0x7F;
      *jbyte2 = rawch2 & 0x7F;
      return 0;
    }
    break;
  default: /* JIS78 or JIS83 */
    if ((rawch1 >= 0x21) && (rawch1 <= 0x74)) {
      *jbyte1 = rawch1;
      *jbyte2 = rawch2;
      return 0;      
    }
    break;
  }

  /* problem, return undefined ASCII char */
  *jbyte1 = 32;
  *jbyte2 = 127;
  return -1;
}

/*
 * Sets AK_ccol and AK_crow to the current cursor position.
 * Converts the current kanji cursor position to pixel coordinates.
 * The coordinates are returned in 'xpix' and 'ypix'.
 */
void AK_get_cursor_pos(int *xpix, int *ypix)
{
  if (_AK_cust_wind)
    return;  /* if not running from console, forget it */

  fflush(stdout);
  AK_ccol = AK_conUnit->cu_XCCP;
  AK_crow = AK_conUnit->cu_YCCP;

  /* assuming ASCII font is default font for console */
  *xpix = AK_window->BorderLeft + (AK_ccol * AK_font[0]->tf_XSize);
  *ypix = AK_window->BorderTop + (AK_crow * AK_font[0]->tf_YSize) + 
          AK_font[0]->tf_Baseline;
}

/*
 * Get number printable characters in a kanji string.
 * Kanji count as two characters.
 */
int AK_strlen(unsigned char *astr)
{
  int i, len, result;
  BOOL jkm = FALSE;  /* kanji mode flag for JIS encodings */

  if (AK_curr_encoding == UNKNOWN)
    AK_curr_encoding = AK_guess_encoding(astr);

  len = strlen(astr);

  i = result = 0;
  while (astr[i] != '\0')
    switch (AK_curr_encoding) {
    case SJIS:
      if ((astr[i] > 128) && (len-i >= 2)) {
        i = i + 2;  /* kanji - skip two bytes */
        result++;
      }
      else
        i++; 

      result++;
      break;
    case EUC:
      if ((astr[i] >= 0xA1) && (len-i >= 2)) {
        i = i + 2;  /* kanji - skip two bytes */
        result++;
      }
      else 
        i++;

      result++;
      break;
    case JIS78:
      if (jkm) { /* kanji mode */
        /* for ESC sequence to turn off kanji mode */
        if ((astr[i] == 0x1B) && (len-i >= 3)) 
          if ((astr[i+1] == 0x28) && (astr[i+2] == 0x4a)) {
            jkm = FALSE;
            i = i+3;
            break;
     }
        /* otherwise, skip 2 bytes for kanji */
        i = i + 2;
        result = result+2;
      }
      else { /* not kanji mode */
        /* check for ESC sequence to turn on kanji mode */
        if ((astr[i] == 0x1B) && (len-i >= 3)) 
          if ((astr[i+1] == 0x24) && (astr[i+2] == 0x40)) {
            jkm = TRUE;
            i = i+3;
            break;
     }
        i++;
        result++;
      }
      break;
    default: /* assume JIS83 */
      if (jkm) { /* kanji mode */
        /* for ESC sequence to turn off kanji mode */
        if ((astr[i] == 0x1B) && (len-i >= 3)) 
          if ((astr[i+1] == 0x28) && (astr[i+2] == 0x42)) {
            jkm = FALSE;
            i = i+3;
            break;
     }

        if (astr[i] == 0x0A) {
          /* linefeed */
          jkm = FALSE;
          i++;
   }
        else {
          i = i + 2;  /* otherwise, skip 2 bytes for kanji */
         result++;
   }
        result++;
      }
      else { /* not kanji mode */
        /* check for ESC sequence to turn on kanji mode */
        if ((astr[i] == 0x1B) && (len-i >= 3)) 
          if ((astr[i+1] == 0x24) && (astr[i+2] == 0x42)) {
            jkm = TRUE;
            i = i+3;
            break;
     }

        i++;
        result++;
      }
      break;
    } /* end switch */
  return result;
}

/*
 * Print single text char in rastport.  "rp" is the RastPort to output to.
 * "ch" is the JIS character to output.
 */
int _AK_char(struct RastPort *rp, unsigned short ch)
{
  int kfont, result; 
  unsigned char jbyte1, jbyte2;

  result = 0;
  
  AK_decode_char(&jbyte1, &jbyte2, ch, AK_curr_encoding);
  kfont = jbyte1 - 32;

  /* if not ASCII, convert to my font codes */
  if (kfont != AK_ASCII) {
    kfont = (jbyte1 - 32)/2 + 1;
    if (jbyte1 & 1)   jbyte2 += 128;
  }

  if ((kfont < 0) || (kfont > 43)) {
    /* bad decode */
    kfont = AK_ASCII;
    jbyte2 = 0x7f;
    result = -1;
  }

  /* find font then print */
  if (AK_font[kfont] == NULL)
    AK_font[kfont] = (struct TextFont *) OpenDiskFont(&AK_font_attr[kfont]);

  if (AK_font[kfont] == NULL) {
    /* couldn't find font, print as ASCII undefined */
    kfont = AK_ASCII;
    jbyte2 = 0x7f;
    result = -1;
  }

  /* print character */
  SetFont(rp, AK_font[kfont]);
  Text(rp, (char *) &jbyte2, 1);

  return result;
}

/*
 * Print single text string in rastport.  "rp" is the RastPort to output to.
 * "astr" is the string to output.  "len" is the number of characters from 
 * the string that will be printed.
 */
void AK_Text(struct RastPort *rp, unsigned char *astr, int len)
{
  UWORD rawch;
  int i, char_count, slen;
  BOOL jkm = FALSE;  /* kanji mode flag for JIS encodings */

  slen = strlen(astr);

  if (AK_curr_encoding == UNKNOWN)
    AK_curr_encoding = AK_guess_encoding(astr);

  i = char_count = 0;
  while (char_count < len)
    switch (AK_curr_encoding) {
    case SJIS:
      if ((astr[i] > 128) && (slen-i >= 2)) {
        /* kanji - concat two bytes */
        rawch = (astr[i] << 8) | astr[i+1];
        i = i + 2;
      }
      else {
        /* assume ASCII */
        rawch = astr[i];
        i++;
      }
      _AK_char(rp, rawch);
      char_count++;
      break;
    case EUC:
      if ((astr[i] >= 0xA1) && (slen-i >= 2)) {
        /* kanji - concat two bytes */
        rawch = (astr[i] << 8) | astr[i+1];
        i = i + 2;
      }
      else {
        /* assume ASCII */
        rawch = astr[i];
        i++;
      }
      _AK_char(rp, rawch);
      char_count++;
      break;
    case JIS78:
      if (jkm) { /* kanji mode */
        /* for ESC sequence to turn off kanji mode */
        if ((astr[i] == 0x1B) && (slen-i >= 3)) 
          if ((astr[i+1] == 0x28) && (astr[i+2] == 0x4a)) {
            jkm = FALSE;
            i = i+3;
            break;
 	  }
        /* otherwise, get 2 bytes for kanji */
        rawch = (astr[i] << 8) | astr[i+1];
        i = i + 2;
        _AK_char(rp, rawch);
        char_count++;
      }
      else { /* not kanji mode */
        /* check for ESC sequence to turn on kanji mode */
        if ((astr[i] == 0x1B) && (slen-i >= 3)) 
          if ((astr[i+1] == 0x24) && (astr[i+2] == 0x40)) {
            jkm = TRUE;
            i = i+3;
            break;
	  }
        /* assume ASCII */
        rawch = astr[i];
        i++;
        _AK_char(rp, rawch);
        char_count++;
      }
      break;
    default: /* assume JIS83 */
      if (jkm) { /* kanji mode */
        /* for ESC sequence to turn off kanji mode */
        if ((astr[i] == 0x1B) && (slen-i >= 3)) 
          if ((astr[i+1] == 0x28) && (astr[i+2] == 0x42)) {
            jkm = FALSE;
            i = i+3;
            break;
     	  }

        if (astr[i] == 0x0A) {
          /* linefeed */
          jkm = FALSE;
          rawch = astr[i];
          i++;
	}
        else {
          /* otherwise, get 2 bytes for kanji */
          rawch = (astr[i] << 8) | astr[i+1];
          i = i + 2;
        }
        _AK_char(rp, rawch);
        char_count++;
      }
      else { /* not kanji mode */
        /* check for ESC sequence to turn on kanji mode */
        if ((astr[i] == 0x1B) && (slen-i >= 3)) 
          if ((astr[i+1] == 0x24) && (astr[i+2] == 0x42)) {
            jkm = TRUE;
            i = i+3;
            break;
     }
        /* assume ASCII */
        rawch = astr[i];
        i++;
        _AK_char(rp, rawch);
        char_count++;
      }
      break;
    } /* end switch */
}


/*
 * Print a kanji character to the standard output.
 * Returns EOF if there was a problem.
 */
int AK_putchar(unsigned short ch)
{
  int xpos, ypos, kfont, result, tmp; 
  unsigned char jbyte1, jbyte2, tmpch;

  if (_AK_cust_wind)
    return EOF;  /* if not running for console, forget it */

  AK_decode_char(&jbyte1, &jbyte2, ch, AK_curr_encoding);
  kfont = jbyte1 - 32;

  result = 0;

  if ((kfont < 0) || (kfont > 84)) {
    /* bad decode */
    kfont = AK_ASCII;
    jbyte2 = 0xff;
    result = EOF;
  }

  if (kfont == AK_ASCII)
    result = putchar(jbyte2);
  else {
    /* convert to my font codes */
    kfont = (jbyte1 - 32)/2 + 1;
    if (jbyte1 & 1)   jbyte2 += 128;

    /* output kanji: find font, get current cursor position, move cursor,
       then draw JIS character in space */
    if (AK_font[kfont] == NULL)
      AK_font[kfont] = (struct TextFont *) OpenDiskFont(&AK_font_attr[kfont]);

    if (AK_font[kfont] == NULL) {
      /* couldn't find font, print as ASCII undefined */
      kfont = AK_ASCII;
      jbyte2 = 0x7f;
      result = EOF;
    }

    AK_get_cursor_pos(&xpos, &ypos);
    /* check if wraparound needed */
    if (kfont != AK_ASCII) {
      if (xpos > (AK_window->Width - AK_window->BorderRight)) {
        putchar('\n');
        fflush(stdout);
        AK_get_cursor_pos(&xpos, &ypos);
      }
      tmpch = jbyte1 | 128;
      putchar(tmpch);   /* print EUC byte 1 */
    }

    /* make space, double space for kanji */
    tmpch = jbyte2 | 128;
    putchar(tmpch);   /* print EUC byte 2 */
    fflush(stdout);
    if (result != EOF)  result = tmp; 

    /* print character */
    Move(AK_rp, xpos, ypos);
    SetFont(AK_rp, AK_font[kfont]);

    SetAPen(AK_rp, AK_conUnit->cu_FgPen);
    SetBPen(AK_rp, AK_conUnit->cu_BgPen);
    SetDrMd(AK_rp, AK_conUnit->cu_DrawMode); 

    Text(AK_rp, (char *) &jbyte2, 1);

    if (result != EOF)  result = jbyte2;
  }

  return result;
}


/*
 * Prints a kanji string.
 */
int _AK_prtstr(unsigned char *astr)
{
  UWORD rawch;
  int i, len, result, tmpres;
  BOOL jkm = FALSE;  /* kanji mode flag for JIS encodings */

  if (_AK_cust_wind)
    return EOF;  /* if not running from console, forget it */

  if (AK_curr_encoding == UNKNOWN)
    AK_curr_encoding = AK_guess_encoding(astr);

  len = strlen(astr);

  i = 0;
  result = 32;
  while (astr[i] != '\0')
    switch (AK_curr_encoding) {
    case SJIS:
      if ((astr[i] > 128) && (len-i >= 2)) {
        /* kanji - concat two bytes */
        rawch = (astr[i] << 8) | astr[i+1];
        i = i + 2;
      }
      else {
        /* assume ASCII */
        rawch = astr[i];
        i++;
      }
      tmpres = AK_putchar(rawch);
      if (result != EOF)  result = tmpres;
      break;
    case EUC:
      if ((astr[i] >= 0xA1) && (len-i >= 2)) {
        /* kanji - concat two bytes */
        rawch = (astr[i] << 8) | astr[i+1];
        i = i + 2;
      }
      else {
        /* assume ASCII */
        rawch = astr[i];
        i++;
      }
      tmpres = AK_putchar(rawch);
      if (result != EOF)  result = tmpres;
      break;
    case JIS78:
      if (jkm) { /* kanji mode */
        /* for ESC sequence to turn off kanji mode */
        if ((astr[i] == 0x1B) && (len-i >= 3)) 
          if ((astr[i+1] == 0x28) && (astr[i+2] == 0x4a)) {
            jkm = FALSE;
            i = i+3;
            break;
     }
        /* otherwise, get 2 bytes for kanji */
        rawch = (astr[i] << 8) | astr[i+1];
        i = i + 2;
        tmpres = AK_putchar(rawch);
        if (result != EOF)  result = tmpres;
      }
      else { /* not kanji mode */
        /* check for ESC sequence to turn on kanji mode */
        if ((astr[i] == 0x1B) && (len-i >= 3)) 
          if ((astr[i+1] == 0x24) && (astr[i+2] == 0x40)) {
            jkm = TRUE;
            i = i+3;
            break;
     }
        /* assume ASCII */
        rawch = astr[i];
        i++;
        tmpres = AK_putchar(rawch);
        if (result != EOF)  result = tmpres;
      }
      break;
    default: /* assume JIS83 */
      if (jkm) { /* kanji mode */
        /* for ESC sequence to turn off kanji mode */
        if ((astr[i] == 0x1B) && (len-i >= 3)) 
          if ((astr[i+1] == 0x28) && (astr[i+2] == 0x42)) {
            jkm = FALSE;
            i = i+3;
            break;
     }

        if (astr[i] == 0x0A) {
          /* linefeed */
          jkm = FALSE;
          rawch = astr[i];
          i++;
   }
        else {
          /* otherwise, get 2 bytes for kanji */
          rawch = (astr[i] << 8) | astr[i+1];
          i = i + 2;
   }
        tmpres = AK_putchar(rawch);
        if (result != EOF)  result = tmpres;
      }
      else { /* not kanji mode */
        /* check for ESC sequence to turn on kanji mode */
        if ((astr[i] == 0x1B) && (len-i >= 3)) 
          if ((astr[i+1] == 0x24) && (astr[i+2] == 0x42)) {
            jkm = TRUE;
            i = i+3;
            break;
     }
        /* assume ASCII */
        rawch = astr[i];
        i++;
        tmpres = AK_putchar(rawch);
        if (result != EOF)  result = tmpres;
      }
      break;
    } /* end switch */
  return result;
}

/*
 * Print a kanji string follow by a newline to the standard output.  
 * Returns EOF if there was a problem.
 */
int AK_puts(unsigned char *astr)
{
  int result;

  if (_AK_cust_wind)
    return EOF;  /* if not running for console, forget it */

  result = _AK_prtstr(astr);
  if (result != EOF)
    result = AK_putchar('\n');
  fflush(stdout);
  return result;
}

/*
 * Formatted output.  Function same as "printf" but strings can have
 * kanji characters in them.
 * Returns EOF if there was a problem.
 */
int AK_printf(char *fmt, ...)
{
  va_list args;
  unsigned char buf[512];
  int result;

  if (_AK_cust_wind)
    return EOF;  /* if not running for console, forget it */

  va_start(args, fmt);
  result = vsprintf(buf, fmt, args);
  if (result == EOF)  return result;
  result = _AK_prtstr(buf);
  fflush(stdout);
  return result;
}

/*
 * Get settings from configuration file (S:kanji.cfg or kanji.cfg)
 * Call this after AK_init().
 * Returns -1 if there was a problem, 0 otherwise.
 */
int AK_getconfig(void)
{
  FILE *configfile;
  char current_inline[80], keyword[40], argstr[80];
  int i, line, argnum, badline;

  badline = 0;
  configfile = fopen("S:kanji.cfg", "r");

  if (!configfile)
    configfile = fopen("kanji.cfg", "r");

  if (!configfile)
    return -1; /* Could not open kanji configuration file. */

  line = 0;
  while (!feof(configfile)) {
    line++;
    if (fgets(current_inline, 79, configfile) == NULL) continue;

    sscanf(current_inline,"%s", keyword);

    /* blank line or a comment */
    if ((keyword[0] == '\0') || (keyword[0] == ';')) continue;

    /* uppercase keyword */
    for (i = 0; keyword[i] != '\0'; i++)
      keyword[i] = toupper(keyword[i]);

    /* set default assumed kanji encoding */
    if (strcmp(keyword,"ENCODING:") == 0)  {
      sscanf(current_inline,"%s %s", keyword, argstr);
      for (i = 0; argstr[i] != '\0'; i++)
	argstr[i] = toupper(argstr[i]);
      if (strcmp(argstr,"JIS83") == 0)         AK_curr_encoding = JIS83;
      else if (strcmp(argstr,"JIS78") == 0)    AK_curr_encoding = JIS78;
      else if (strcmp(argstr,"SJIS") == 0)     AK_curr_encoding = SJIS;
      else if (strcmp(argstr,"EUC") == 0)      AK_curr_encoding = EUC;
      else {
        badline = 1;
        break; /* bad arg */
      }

      continue;
    }

    if (strcmp(keyword,"FONTSIZE:") == 0)  {
      sscanf(current_inline,"%s %d", keyword, &argnum);
      if (argnum > 0)
        _AK_font_size = argnum;
      else {
        badline = 1;
        break; /* bad arg */
      }

      continue;
    }

    if (strcmp(keyword,"TABWIDTH:") == 0)  {
      sscanf(current_inline,"%s %d", keyword, &argnum);
      if (argnum > 0)
        AK_tab_width = argnum;
      else {
        badline = 1;
        break; /* bad arg */
      }

      continue;
    }

    if (strcmp(keyword,"LFISNL:") == 0)  {
      sscanf(current_inline,"%s %s", keyword, argstr);
      argstr[0] = toupper(argstr[0]);
      for (i = 0; argstr[i] != '\0'; i++)
        argstr[i] = toupper(argstr[i]);
      if (strcmp(argstr,"TRUE") == 0) 
        AK_LFisNL = TRUE;
      else if (strcmp(argstr,"FALSE") == 0) 
        AK_LFisNL = FALSE;
      else {
        badline = 1;
        break; /* bad arg */
      }
      continue;
    }

    fprintf(stderr, "Bad line in kanji.cfg: %d.\n", line);
    fclose(configfile);
    return -1;
  }

  if (badline)
    fprintf(stderr, "Bad line in kanji.cfg: %d.\n", line);

  fclose(configfile);

  return badline;
}

