/* Construct an SCIM IMEngine from a data file from http://www.chinesecj.com/
 * Copyright (C) 2007  http://www.vyvy.org/
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/*
 * Changes:
 *   07-Nov-07:  Release
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <uuid/uuid.h>


void print_header(void)
{
  puts("### File header must not be modified");
  puts("### This file must be encoded into UTF-8.");
  puts("### This file is derived from a raw data file from http://www.chinesecj.com");
  puts("SCIM_Generic_Table_Phrase_Library_TEXT");
  puts("VERSION_1_0");
  puts("");

  puts("### Begin Table definition.");
  puts("BEGIN_DEFINITION");
  puts("");

  uuid_t uu;
  char uuid_str[37];
  uuid_generate(uu);
  uuid_unparse(uu, uuid_str);
  puts("### An unique id to distinguish this table among others.");
  puts("### Use uuidgen to generate this kind of id.");
  printf("UUID = %s\n", uuid_str);
  puts("");

  time_t t;
  char serial_number[9];
  t = time(NULL);
  strftime(serial_number, 9, "%Y%m%d", localtime(&t));
  puts("### A unique number indicates the version of this file.");
  puts("### For example the last modified date of this file.");
  puts("### This number must be less than 2^32.");
  printf("SERIAL_NUMBER = %s\n", serial_number);
  puts("");

  puts("ICON = /usr/share/scim/icons/CangJie.png");
  puts("");

  puts("### The default name of this table");
  puts("NAME = CangJie 5 Simp");
  puts("");

  puts("### The local names of this table ");
  puts("NAME.zh_CN = 第五代簡体仓颉");
  puts("NAME.zh_TW = 第五代簡體倉頡");
  puts("NAME.zh_HK = 第五代簡體倉頡");
  puts("");

  puts("### Supported languages of this table");
  puts("LANGUAGES = zh_CN,zh_SG,zh_TW,zh_HK");
  puts("");

  puts("### Prompt string to be displayed in the status area.");
  puts("STATUS_PROMPT = 中");
  puts("");

  puts("### The Keyboard Layout used by this table. Unset or set to \"Unknown\" to accept any kind of layouts.");
  puts("### KEYBOARD_LAYOUT = US_Default");
  puts("");

  puts("### If true then the first candidate phrase");
  puts("### will be selected automatically during inputing.");
  puts("AUTO_SELECT = TRUE");
  puts("");

  puts("### If true then a multi wildcard will be appended");
  puts("### at the end of inputing string automatically.");
  puts("AUTO_WILDCARD = TRUE");
  puts("");

  puts("### If true then the result string will be committed to client automatically.");
  puts("### This should be used with AUTO_SELECT = TRUE.");
  puts("AUTO_COMMIT = FALSE");
  puts("");

  puts("### If true then the key will be splitted during inputing automatically.");
  puts("AUTO_SPLIT = FALSE");
  puts("");

  puts("### If true then the phrases' frequencies will be adjusted dynamically.");
  puts("DYNAMIC_ADJUST = FALSE ");
  puts("");

  puts("### If true then the preedit area will be filled up by the current candidate phrase automatically.");
  puts("AUTO_FILL = TRUE");
  puts("");

  puts("### If true then the lookup table will always be shown if there is any candidate phrase.");
  puts("### Otherwise the lookup table won't be shown unless the user requires it by moving the preedit caret left.");
  puts("ALWAYS_SHOW_LOOKUP = TRUE");
  puts("");

  puts("### Use full width punctuation by default");
  puts("DEF_FULL_WIDTH_PUNCT = TRUE");
  puts("");

  puts("### Use full width letter by default");
  puts("DEF_FULL_WIDTH_LETTER = FALSE");
  puts("");

  puts("### The maxmium length of a key.");
  puts("MAX_KEY_LENGTH = 5");
  puts("");

  puts("### Valid input chars.");
  puts("VALID_INPUT_CHARS = abcdefghijklmnopqrstuvwxyz");
  puts("");

  puts("### Single wildcard char, can have multiple chars.");
  puts("SINGLE_WILDCARD_CHAR = ?");
  puts("");

  puts("### Multi wildcard char.");
  puts("MULTI_WILDCARD_CHAR = *");
  puts("");

  puts("### The key strokes to split inputted string.");
  puts("SPLIT_KEYS = quoteright");
  puts("");

  puts("### The key strokes to commit the convert result to client.");
  puts("COMMIT_KEYS = space");
  puts("");

  puts("### The keys to forward the inputted string to client.");
  puts("FORWARD_KEYS = Return");
  puts("");

  puts("### The key strokes to select phrases");
  puts("SELECT_KEYS = 1,2,3,4,5,6,7,8,9,0");
  puts("");

  puts("### The key strokes to page up the lookup table.");
  puts("PAGE_UP_KEYS = Page_Up,comma,minus");
  puts("");

  puts("### The key strokes to page down.");
  puts("PAGE_DOWN_KEYS = Page_Down,period,equal");
  puts("");

  puts("### Define the prompts of each valid input char.");
  puts("BEGIN_CHAR_PROMPTS_DEFINITION");
  puts("a 日");
  puts("b 月");
  puts("c 金");
  puts("d 木");
  puts("e 水");
  puts("f 火");
  puts("g 土");
  puts("h 竹");
  puts("i 戈");
  puts("j 十");
  puts("k 大");
  puts("l 中");
  puts("m 一");
  puts("n 弓");
  puts("o 人");
  puts("p 心");
  puts("q 手");
  puts("r 口");
  puts("s 尸");
  puts("t 廿");
  puts("u 山");
  puts("v 女");
  puts("w 田");
  puts("x 难");
  puts("y 卜");
  puts("z 符");
  puts("END_CHAR_PROMPTS_DEFINITION");
  puts("END_DEFINITION");
  puts("");

  puts("### Begin Table data.");
  puts("BEGIN_TABLE");
}


void print_table(const char *filename)
{
  FILE *ifp;
  char line[100];

  ifp = fopen(filename, "r");
  if (!ifp) {
    fprintf(stderr, "Error: Fail to open data file '%s'.\n", filename);
    exit(EXIT_FAILURE);
  }

  /* Skip until the table data */
  while (fgets(line, 100, ifp)) {
    if (!strncmp("[Text]", line, 6)) {
      break;
    }
  }

  if (feof(ifp)) {
    fprintf(stderr, "Error: Fail to locate the table from '%s'.\n", filename);
    exit(EXIT_FAILURE);
  }


  /* Read the interpret the data table              */
  /*------------------------------------------------*/
  char keys[6], keys_prev[6] = "";
  int weight, weight_prev;

  while (fgets(line, 100, ifp)) {

    // Interpret the line
    char *p;
    for (p=line; *p & 0x80; p++) {
      ;
    }
    (void) strtok(p, "\r\n");
    if (strlen(p) > 5) {
      fprintf(stderr, "Error: Number of CangJie keystokes > 5?\n");
      exit(EXIT_FAILURE);
    }
    strcpy(keys, p);
    *p = '\0';

    // Find out the weight
    if (!strcmp(keys, keys_prev)) {
      weight = weight_prev - 5;
    }
    else {
      weight = 500;
      strcpy(keys_prev, keys);
    }
    if (weight <= 0) {
      fprintf(stderr, "Error: Too many duplicated codes?\n");
      exit(EXIT_FAILURE);
    }
    weight_prev = weight;

    // Output the data table according to the SCIM format
    printf("%s\t%s\t%d\n", keys, line, weight);
  }
}


void print_footer(void)
{
  puts("END_TABLE");
}


int main(int argc, char *argv[])
{
  if (argc < 2) {
    fprintf(stderr, "Usage: %s <file_utf8>\n", argv[0]);
    exit(EXIT_SUCCESS);
  }

  print_header();
  print_table(argv[1]);
  print_footer();

  return 0;
}
