#include <stdio.h>
#include <fcntl.h>
#include "xl_hzinput.h"
#include "safestring.h"

hz_input_table *cur_table;
char str[80];
char key[20];
char buf[700000];		// 700K *.dat buffer
int offset;			// buffer offset
int MaxKeyLen, HasOneChar;

static void
load_phr (int j, char *tt, int n)
{
  FILE *fp = cur_table->PhraseFile;
  int ofs[2], len;
  int phrno = (int) cur_table->item[j].ch;

  fseek (fp, (phrno + 1) * 4, SEEK_SET);
  fread (ofs, 4, 2, fp);
  len = ofs[1] - ofs[0];

  if (len > n)
    {
      fprintf (stderr, "buffer overrun: %d > %d\n", len, n);
      abort ();
    }
  if (len > 128 || len <= 0)
    {
      printf ("phrase error %d\n", len);
      strncpy (tt, "err", n);
      return 1;
    }

  ofs[0] += (cur_table->PhraseNum + 1) * 4;
  /* Add the index area length */
  fseek (fp, ofs[0], SEEK_SET);
  fread (tt, 1, len, fp);
  tt[len] = 0;
}

int
main (int argc, char **argv)
{
  FILE *fd, *fw;
  int i, j, k, nread, index;
  char magic_number[10];
  hz_input_table *table;
  char fname[FILENAME_MAX + 1], fname_dat[FILENAME_MAX + 1],
    fname_idx[FILENAME_MAX + 1], fname_tab[FILENAME_MAX + 1],
    fname_phr[FILENAME_MAX + 1];

  if (argc <= 1)
    {
      printf ("Enter table file name [.tab] : ");
      fgets (fname, FILENAME_MAX + 1 - 8 + 1, stdin);
      strtok (fname, "\n");	/* Drop the possible final LF character */
      /* fname[] and fname_phr[] will be appended ".tab.phr" suffix */
    }
  else
    safe_strncpy (fname, argv[1], FILENAME_MAX + 1 - 8);

  strcpy (fname_dat, fname);
  strcpy (fname_idx, fname);
  strcpy (fname_tab, fname);
  strcat (fname_dat, ".dat");
  strcat (fname_idx, ".idx");
  strcat (fname_tab, ".tab");
  strcpy (fname_phr, fname_tab);
  strcat (fname_phr, ".phr");

  table = (hz_input_table *) malloc (sizeof (hz_input_table));
  if (table == NULL)
    printf ("load_input_method error");
  cur_table = table;

  printf ("\nGenerating binary *.dat file from %s...\n", fname_tab);

  fd = fopen (fname_tab, "r");
  if (fd == NULL)
    {
      //error("error: Cannot open input method %s", filename); 
      fclose (fd);
      free (table);
      return 1;
    }

  nread = fread (table, sizeof (hz_input_table), 1, fd);
  if (nread != 1)
    {
      //error("error: cannot read file header %s", filename);
      return 1;
    }

  if (strcmp (MAGIC_NUMBER, table->magic_number))
    {
      printf ("is not a valid tab file\n\n");
      return 1;
    }

  table->item = (ITEM *) malloc (sizeof (ITEM) * table->TotalChar);
  if (table->item == NULL)
    {
      printf ("Gosh, can't malloc enough memory");
      return 1;
    }

  nread = fread (table->item, sizeof (ITEM), table->TotalChar, fd);
  if (nread < table->TotalChar)
    {
      printf ("Not enough TotalChar Items!\n");
      exit (1);
    }

  MaxKeyLen = table->MaxPress;
  if (MaxKeyLen > 8)
    MaxKeyLen = 8;
  printf ("Max key press is %d\n", MaxKeyLen);

  fclose (fd);

  table->PhraseFile = fopen (fname_phr, "r");

  if (table->PhraseFile == NULL)
    {
      printf ("Open phrase file error!\n");
      exit (1);
    }

  if ((fw = fopen (fname_idx, "w")) == NULL)
    {
      printf ("Cannot create %s\n", fname_idx);
    }
  offset = 0;

  i = 0;
  while (i < table->TotalChar)
    {
      for (j = 0; j < 5; j++)
	{
	  key[j] = (table->item[i].key1 >> (24 - 6 * j)) & 0x3f;
	  key[5 + j] = (table->item[i].key2 >> (24 - 6 * j)) & 0x3f;
	}
      for (j = 0; j < 10; j++)
	{
	  if (key[j] < 0 || key[j] > 60)
	    printf ("Error Key index!\n");
	  key[j] = table->KeyName[key[j]];
	}
      key[10] = '\0';
      /* now get the key */

      fwrite (key, MaxKeyLen, 1, fw);
      fwrite (&offset, sizeof (int), 1, fw);
      /* write the key and offset */

      HasOneChar = 0;
      k = i;
      while (k < table->TotalChar)
	{
	  if (table->item[k].ch >= 0xA1A1)	/* a char */
	    {
	      if (HasOneChar == 0)
		{
		  HasOneChar = 1;
		  buf[offset++] = '1';
		}
	      buf[offset++] = (table->item[k].ch & 0xFF);
	      buf[offset++] = (table->item[k].ch >> 8);
	      //    printf("%c%c\n",(table->item[k].ch & 0xFF), table->item[k].ch >> 8);
	    }

	  if (k == table->TotalChar - 1 ||
	      table->item[k].key1 != table->item[k + 1].key1 ||
	      (table->item[k].key2 & 0xFFFFF000) != (table->item[k + 1].key2 & 0xFFFFF000))	/* only max 8 key allowed by WZCE */
	    break;		//now from i to k is the same keyname
	  k++;
	}

      for (j = i; j <= k; j++)
	if (table->item[j].ch < 0xA1A1)	/* a phrase */
	  {
	    buf[offset++] = '2';
	    load_phr (j, buf + offset, sizeof (buf) - offset);
	    offset += strlen (buf + offset);
	  }
      buf[offset++] = 0x0A;

      i = k + 1;
    }

  fclose (fw);

  if ((fw = fopen (fname_dat, "w")) == NULL)
    {
      printf ("Cannot create %s\n", fname_dat);
    }
  fwrite (buf, offset, 1, fw);
  fclose (fw);
  return 0;
}
