#include <stdio.h>
#include <fcntl.h>
#include <hzinput.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;
}
