/*******************************************************************************
 * Copyright (c) 2008 IGA Tosiki, NTT DATA BUSINESS BRAINS Corp.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IGA Tosiki (NTT DATA BUSINESS BRAINS Corp.) - initial API and implementation
 *******************************************************************************/
/*
 * blanco Framework
 * Copyright (C) 2008 NTT DATA BUSINESS BRAINS CORPORATION
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.nlpack.generator.dictionary;

import jp.sourceforge.mergedoc.pleiades.resource.TranslationDictionary;
import jp.sourceforge.mergedoc.pleiades.resource.TranslationResult;
import blanco.nlpack.generator.message.BlancoNLpackGeneratorMessage;

/**
 * Pleiades および その辞書を利用して、与えられた値を「英語→日本語」などへ変換するためのクラス。
 * 
 * @author IGA Tosiki
 */
public class BlancoNLpackGeneratorPleiadesDictionary {
    /**
     * ステータス無し。
     */
    public static final int STATUS_NONE = -1;

    /**
     * 辞書から発見できなかった。
     */
    public static final int STATUS_NOT_FOUND = 0;

    /**
     * 辞書から発見できなかったがニモーニック変換だけは実施された。
     */
    public static final int STATUS_MNEMONIC_CHANGED = 2;

    /**
     * 辞書から発見できた。
     */
    public static final int STATUS_FOUND = 1;

    /**
     * メッセージオブジェクト。
     */
    private final BlancoNLpackGeneratorMessage fMsg = new BlancoNLpackGeneratorMessage();

    /**
     * Pleiades 辞書 のインスタンス。
     */
    private TranslationDictionary fDictionary = null;

    /**
     * 直前の lookup の結果を保持。
     */
    private int fFoundStatus = STATUS_NONE;

    /**
     * 直前の lookupの際に 辞書から検索できたのかどうか。
     * 
     * @return 発見状況ステータス。
     */
    public int getFoundStatus() {
        return fFoundStatus;
    }

    /**
     * Pleiades 辞書 のロード。
     * 
     * @throws Throwable
     *             実行時例外が発生した場合。
     */
    private void load() throws Throwable {
        System.out.println("babel: Pleiades dictionary: load: begin.");

        // 辞書インスタンスの取得。
        fDictionary = new TranslationDictionary();

        System.out.println("babel: Pleiades dictionary: load: end.");

    }

    /**
     * Pleiades および その辞書を利用して、与えられた値を「英語→日本語」へ変換します。
     * 
     * @param argString
     *            英語文字列。
     * @return 日本語文字列。
     */
    public String lookup(final String argString) {
        if (argString == null) {
            // TODO 文字列の外部化！
            throw new IllegalArgumentException(
                    "IllegalArgument: BlancoNLpackGeneratorPleiadesDictionary#lookup(null)");
        }

        // ステータスを初期化。
        fFoundStatus = STATUS_NONE;

        if (fDictionary == null) {
            try {
                load();
            } catch (Throwable e) {
                throw new IllegalArgumentException(fMsg.getMbebp001(e
                        .toString()));
            }
        }

        String result = lookupInternal(argString);

        // 他のパターンの可能性に対する悪あがき。
        if (fFoundStatus == STATUS_NOT_FOUND) {
            if (argString.endsWith(" ") || argString.endsWith(":")) {
                // 後方に空白やコロンが付いただけの文字列であると仮定して再検索。
                result = lookupInternal(argString.substring(0, argString
                        .length() - 1))
                        + argString.charAt(argString.length() - 1);
            }
        }
        if (fFoundStatus == STATUS_NOT_FOUND) {
            if (argString.startsWith(" ") || argString.startsWith(":")) {
                // 前方に空白が付いただけの文字列であると仮定して再検索。
                result = argString.charAt(0)
                        + lookupInternal(argString.substring(1));
            }
        }
        if (fFoundStatus == STATUS_NOT_FOUND) {
            // 実験用。
            // 空白だったらコロンに置き換えてためしに検索してみる案。
            if (argString.endsWith(" ")) {
                final String result2 = lookupInternal(argString.substring(0,
                        argString.length() - 1)
                        + ":");
                if (fFoundStatus == STATUS_FOUND) {
                    result = result2.substring(0, result2.length() - 1)
                            + argString.charAt(argString.length() - 1);
                }
            }
        }

        if (false) {
            // 気合いで翻訳する実験的コーナー。
            // 通常は利用しないこととします。
            String result2 = experimentalLookup(argString);
            if (fFoundStatus == STATUS_FOUND) {
                result = result2;
            }
        }

        return result;
    }

    private String experimentalLookup(final String argString) {
        String result = "";
        if (fFoundStatus == STATUS_NOT_FOUND) {
            // 実験用。
            if (argString.startsWith("Create ")) {
                final String result2 = lookupInternal(argString.substring(
                        "Create ".length(), argString.length() - 1));
                if (fFoundStatus == STATUS_FOUND) {
                    result = result2 + "の作成";
                }
            }
        }
        if (fFoundStatus == STATUS_NOT_FOUND) {
            // 実験用。
            if (argString.startsWith("Edit ")) {
                final String result2 = lookupInternal(argString.substring(
                        "Edit ".length(), argString.length() - 1));
                if (fFoundStatus == STATUS_FOUND) {
                    result = result2 + "の編集";
                }
            }
        }
        if (fFoundStatus == STATUS_NOT_FOUND) {
            // 実験用。
            if (argString.startsWith("Delete ")) {
                final String result2 = lookupInternal(argString.substring(
                        "Delete ".length(), argString.length() - 1));
                if (fFoundStatus == STATUS_FOUND) {
                    result = result2 + "の削除";
                }
            }
        }
        if (fFoundStatus == STATUS_NOT_FOUND) {
            // 実験用。
            if (argString.startsWith("Remove ")) {
                final String result2 = lookupInternal(argString.substring(
                        "Remove ".length(), argString.length() - 1));
                if (fFoundStatus == STATUS_FOUND) {
                    result = result2 + "の除去";
                }
            }
        }
        if (fFoundStatus == STATUS_NOT_FOUND) {
            // 実験用。
            if (argString.startsWith("Open ")) {
                final String result2 = lookupInternal(argString.substring(
                        "Open ".length(), argString.length() - 1));
                if (fFoundStatus == STATUS_FOUND) {
                    result = result2 + "を開く";
                }
            }
        }

        return result;
    }

    private String lookupInternal(final String argString) {
        final TranslationResult result = fDictionary.lookup(argString);

        // 辞書に見つかったかどうかを記憶します。
        if (result.isFound()) {
            fFoundStatus = STATUS_FOUND;
        } else {
            if (argString.equals(result.getValue())) {
                fFoundStatus = STATUS_NOT_FOUND;
            } else {
                fFoundStatus = STATUS_MNEMONIC_CHANGED;
            }
        }

        return result.getValue();
    }
}
