/*******************************************************************************
 * 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) {
                e.printStackTrace();
                throw new IllegalArgumentException(fMsg.getMbebp001(e
                        .toString()));
            }
        }

        String result = lookupInternal(argString);

        // Pleiades 1.3.0 の機能強化に伴い、他のパターンの可能性に対する悪あがき (空白およびコロン) は実施しないように変更。

        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();
    }
}
