/*
eis * Copyright (C) 2008,2009  OMRON SOFTWARE Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.

 * test message
 */

package net.gorry.android.input.nicownng.JAJP;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import net.gorry.android.input.nicownng.ComposingText;
import net.gorry.android.input.nicownng.DefaultSoftKeyboard;
import net.gorry.android.input.nicownng.MyHeightKeyboard;
import net.gorry.android.input.nicownng.NicoWnnG;
import net.gorry.android.input.nicownng.NicoWnnGEvent;
import net.gorry.android.input.nicownng.NicoWnnGJAJP;
import net.gorry.android.input.nicownng.R;
import android.content.SharedPreferences;
import android.inputmethodservice.Keyboard;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;

/**
 * The default Software Keyboard class for Japanese IME.
 *
 * @author Copyright (C) 2009 OMRON SOFTWARE CO., LTD.  All Rights Reserved.
 */
public class DefaultSoftKeyboardNico2 extends DefaultSoftKeyboard {
	/** new keycode **/
	private static final int KEYCODE_NEWKEY_0 = -410;
	private static final int KEYCODE_NEWKEY_1 = -411;
	private static final int KEYCODE_NEWKEY_2 = -412;
	private static final int KEYCODE_NEWKEY_3 = -413;
	private static final int KEYCODE_NEWKEY_4 = -414;

	/** Enable English word prediction on half-width alphabet mode */
	private static final boolean USE_ENGLISH_PREDICT = true;

	/** Key code for case toggle key */
	private static final int KEYCODE_SELECT_CASE = -309;

	/** Key code for EISU-KANA conversion */
	// private static final int KEYCODE_EISU_KANA = -305;

	/** Key code for switching to full-width Nicotouch mode */
	private static final int KEYCODE_SWITCH_FULL_NICO = -400;

	/** Key code for switching to full-width Nicotouch katakana mode */
	private static final int KEYCODE_SWITCH_FULL_NICO_KATAKANA = -401;

	/** Key code for switching to half-width Nicotouch katakana mode */
	private static final int KEYCODE_SWITCH_HALF_NICO_KATAKANA = -402;

	/** Key code for NOP (no-operation) */
	private static final int KEYCODE_NOP = -310;

	/** Key code for preference setting */
	private static final int KEYCODE_PREFERENCE_SETTING = -999;

	/** Key code for help */
	private static final int KEYCODE_SHOW_HELP = -998;

	/** Key code for Mushroom */
	private static final int KEYCODE_MUSHROOM = -997;

	private NicoWnnG mNicoWnnG;


	/** Input mode toggle cycle table */
	private static final int[] JP_MODE_CYCLE_TABLE = {
		KEYMODE_JA_FULL_NICO,
	};

	/** Definition for {@code mInputType} (toggle) */
	private static final int INPUT_TYPE_TOGGLE = 1;

	/** Definition for {@code mInputType} (commit instantly) */
	private static final int INPUT_TYPE_INSTANT = 2;

	/** Max key number of the 12 key keyboard (depends on the definition of keyboards) */
	private static final int KEY_NUMBER_12KEY = 20;

	/* */
	SetupKeyboard              mSetupKeyboard;
	String[][][][]             mCycleTable;
	// HashMap<String, String>    mReplaceTable;

	/** Character table for full-width number */
	private static final char[] INSTANT_CHAR_CODE_FULL_NUMBER =
		"\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19\uff10\uff03\uff0a".toCharArray();

	/** Character table for half-width number */
	private static final char[] INSTANT_CHAR_CODE_HALF_NUMBER =
		"1234567890#*".toCharArray();

	/** The constant for mFixedKeyMode. It means that input mode is not fixed. */
	private static final int INVALID_KEYMODE = -1;

	/** KeyIndex of "Moji" key on 12 keyboard (depends on the definition of keyboards) */
	private static final int KEY_INDEX_CHANGE_MODE_12KEY = 15;

	/** KeyIndex of "Moji" key on QWERTY keyboard (depends on the definition of keyboards) */
	private static final int KEY_INDEX_CHANGE_MODE_QWERTY = 29;

	/** Type of input mode */
	private int mInputType = INPUT_TYPE_TOGGLE;

	private static final NicoWnnGEvent mEventTouchOtherKey    = new NicoWnnGEvent(NicoWnnGEvent.TOUCH_OTHER_KEY);
	private static final NicoWnnGEvent mEventCommitText       = new NicoWnnGEvent(NicoWnnGEvent.COMMIT_COMPOSING_TEXT);
	private static final NicoWnnGEvent mEventConvert          = new NicoWnnGEvent(NicoWnnGEvent.CONVERT);
	private static final NicoWnnGEvent mEventConvertPredict   = new NicoWnnGEvent(NicoWnnGEvent.CONVERT_PREDICT);
	private static final NicoWnnGEvent mEventConvertPredictBackward   = new NicoWnnGEvent(NicoWnnGEvent.CONVERT_PREDICT_BACKWARD);

	private static final NicoWnnGEvent mEventChangeMode12Key    = new NicoWnnGEvent(NicoWnnGEvent.CHANGE_MODE, NicoWnnGJAJP.ENGINE_MODE_OPT_TYPE_12KEY);
	private static final NicoWnnGEvent mEventChangeModeQwerty   = new NicoWnnGEvent(NicoWnnGEvent.CHANGE_MODE, NicoWnnGJAJP.ENGINE_MODE_OPT_TYPE_QWERTY);
	private static final NicoWnnGEvent mEventChangeModeSymbol   = new NicoWnnGEvent(NicoWnnGEvent.CHANGE_MODE, NicoWnnGJAJP.ENGINE_MODE_SYMBOL);
	private static final NicoWnnGEvent mEventChangeModeDocomo   = new NicoWnnGEvent(NicoWnnGEvent.CHANGE_MODE, NicoWnnGJAJP.ENGINE_MODE_DOCOMOSYMBOL);
	private static final NicoWnnGEvent mEventChangeModeEisuKana = new NicoWnnGEvent(NicoWnnGEvent.CHANGE_MODE, NicoWnnGJAJP.ENGINE_MODE_EISU_KANA);

	private static final NicoWnnGEvent mEventInputShiftLeft   = new NicoWnnGEvent(NicoWnnGEvent.INPUT_SOFT_KEY, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SHIFT_LEFT));

	private static final NicoWnnGEvent mEventInputKeyDel      = new NicoWnnGEvent(NicoWnnGEvent.INPUT_SOFT_KEY, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
	private static final NicoWnnGEvent mEventInputEnter       = new NicoWnnGEvent(NicoWnnGEvent.INPUT_SOFT_KEY, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
	private static final NicoWnnGEvent mEventInputBack        = new NicoWnnGEvent(NicoWnnGEvent.INPUT_KEY, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
	private static final NicoWnnGEvent mEventInputDpadLeft    = new NicoWnnGEvent(NicoWnnGEvent.INPUT_SOFT_KEY, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT));
	private static final NicoWnnGEvent mEventInputDpadRight   = new NicoWnnGEvent(NicoWnnGEvent.INPUT_SOFT_KEY, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT));
	private static final NicoWnnGEvent mEventInputDpadUp      = new NicoWnnGEvent(NicoWnnGEvent.INPUT_SOFT_KEY, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP));
	private static final NicoWnnGEvent mEventInputDpadDown    = new NicoWnnGEvent(NicoWnnGEvent.INPUT_SOFT_KEY, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN));


	/**
	 * Character table to input when mInputType becomes INPUT_TYPE_INSTANT.
	 * (Either INSTANT_CHAR_CODE_FULL_NUMBER or INSTANT_CHAR_CODE_HALF_NUMBER)
	 */
	private final char[] mCurrentInstantTable = null;

	/** Input mode that is not able to be changed. If ENABLE_CHANGE_KEYMODE is set, input mode can change. */
	private int[] mLimitedKeyMode = null;

	/** Input mode that is given the first priority. If ENABLE_CHANGE_KEYMODE is set, input mode can change. */
	private int mPreferenceKeyMode = INVALID_KEYMODE;

	/** The last input type */
	private int mLastInputType = 0;

	/** Auto caps mode */
	private boolean mEnableAutoCaps = true;

	/** PopupResId of "Moji" key (this is used for canceling long-press) */
	private int mPopupResId = 0;

	/** Whether the InputType is null */
	private boolean mIsInputTypeNull = false;

	/** {@code SharedPreferences} for save the keyboard type */
	private SharedPreferences.Editor mPrefEditor = null;

	/** "Moji" key (this is used for canceling long-press) */
	private Keyboard.Key mChangeModeKey = null;

	private MyHeightKeyboard[][][] mNicoKeyboard;
	private int mNicoKeyMode = 0;

	/** option bell type **/
	private final int ALPHAMODE_SMALL = 0;
	private final int ALPHAMODE_BIG   = 1;
	private int mChangeAlphaBigMode = ALPHAMODE_SMALL;

	/** Default constructor */
	public DefaultSoftKeyboardNico2(final SetupKeyboard keyboard) {
		mSetupKeyboard       = keyboard;
		mCycleTable   = keyboard.SetupCycleTable();

		mCurrentLanguage     = LANG_JA;
		mShiftOn             = KEYBOARD_SHIFT_OFF;
		mCurrentKeyMode      = KEYMODE_JA_FULL_NICO;
		mCurrentSlide        = NICO_SLIDE_MODE_TOP;
	}

	/** @see com.hiroshica.android.input.nicownn2.DefaultSoftKeyboard#createKeyboards */
	@Override protected void createKeyboards(final NicoWnnG parent) {
		mNicoWnnG = parent;

		/* Keyboard[# of Languages][portrait/landscape][# of keyboard type][shift off/on][max # of key-modes][noinput/input] */
		mKeyboard = new MyHeightKeyboard[LANG_MAX][PORTRAIT_LANDSCAPE][KEYBOARD_MAX][KEYBOARD_SHIFT_MAX][KEYMODE_JA_MAX][2];

		final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(parent);
		mQwertyMatrixMode      = mWnn.getOrientPrefBoolean(pref, "qwerty_matrix_mode", false);
		mNoAlphaMode           = mWnn.getOrientPrefBoolean(pref, "change_noalpha_qwerty", false);
		mNoNumberMode          = mWnn.getOrientPrefBoolean(pref, "change_nonumber_qwerty", false);
		final boolean getalphamode  = mWnn.getOrientPrefBoolean(pref, "change_alphamode", false);
		mFlickNicoInput        = Integer.valueOf(mWnn.getOrientPrefString(pref, "nicoflick_mode", "0"));
		mFlickGuide            = mWnn.getOrientPrefBoolean(pref, "flick_guide", true);
		mHiddenSoftKeyboard    = Integer.valueOf(mWnn.getOrientPrefString(pref, "hidden_softkeyboard2", "0"));

		if (false == getalphamode) {
			mChangeAlphaBigMode = ALPHAMODE_SMALL;
		}
		else{
			mChangeAlphaBigMode = ALPHAMODE_BIG;
		}

		mKana12Key = mWnn.getOrientPrefBoolean(pref, "change_kana_12key", false);
		mAnum12Key = mWnn.getOrientPrefBoolean(pref, "change_alphanum_12key", false);
		setM12KeyTable();

		/* Create the suitable keyboard object */
		if (mDisplayMode == DefaultSoftKeyboard.PORTRAIT) {
			createKeyboardsPortrait(parent);
		} else {
			createKeyboardsLandscape(parent);
		}

		if (m12keyTable[mCurrentKeyMode] == KEYBOARD_12KEY) {
			mWnn.onEvent(mEventChangeMode12Key);
			NicoWnnGJAJP.getInstance().setSpecialCandidateOnKana12KeyToggleMode((mFlickNicoInput > 0) ? 2 : 0);
		} else {
			mWnn.onEvent(mEventChangeModeQwerty);
			NicoWnnGJAJP.getInstance().setSpecialCandidateOnKana12KeyToggleMode(0);
		}
	}

	public void setM12KeyTable() {
		m12keyTable[KEYMODE_JA_FULL_NICO]          = mKana12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_FULL_HIRAGANA]      = mKana12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_FULL_ALPHABET]      = mAnum12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_FULL_NUMBER]        = mAnum12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_FULL_KATAKANA]      = mKana12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_HALF_ALPHABET]      = mAnum12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_HALF_NUMBER]        = mAnum12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_HALF_KATAKANA]      = mKana12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_HALF_PHONE]         = mAnum12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_FULL_NICO_KATAKANA] = mKana12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
		m12keyTable[KEYMODE_JA_HALF_NICO_KATAKANA] = mKana12Key ? KEYBOARD_12KEY : KEYBOARD_QWERTY;
	}

	/**
	 *
	 */
	@Override public void checkHiddenKeyboard() {
		super.checkHiddenKeyboard();
	}

	/**
	 * Commit the pre-edit string for committing operation that is not explicit
	 * (ex. when a candidate is selected)
	 */
	private void commitText() {
		if (!mNoInput) {
			mWnn.onEvent(mEventCommitText);
		}
	}

	/**
	 * Change input mode
	 * <br>
	 * @param keyMode   The type of input mode
	 */
	@Override
	public void changeKeyMode(final int keyMode) {
		final int targetMode = filterKeyMode(keyMode);
		if (targetMode == INVALID_KEYMODE) {
			return;
		}

		commitText();

		if (mCapsLock) {
			mWnn.onEvent(mEventInputShiftLeft);
			mCapsLock = false;
		}
		mShiftOn = KEYBOARD_SHIFT_OFF;
		final MyHeightKeyboard kbd = getModeChangeKeyboard(targetMode);
		mCurrentKeyMode = targetMode;
		mPrevInputKeyCode = 0;
		mCurrentSlide = 0;
		mNicoKeyMode = NICO_MODE_FULL_HIRAGANA;

		int mode = NicoWnnGEvent.Mode.DIRECT;

		switch (targetMode) {

			case KEYMODE_JA_FULL_NICO:
				mInputType = INPUT_TYPE_TOGGLE;
				mode = NicoWnnGEvent.Mode.DEFAULT;
				mNicoFirst = false;
				break;

			default:
				break;
		}

		setStatusIcon();
		changeKeyboard(kbd);
		mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.CHANGE_MODE, mode));
		changeKeyboardType(m12keyTable[targetMode]);
	}

	/** @see com.hiroshica.android.input.nicownn2.DefaultSoftKeyboard#initView */
	@Override public View initView(final NicoWnnG parent, final int width, final int height) {
		final View view = super.initView(parent, width, height);
		changeKeyboard(mKeyboard[mCurrentLanguage][mDisplayMode][m12keyTable[mCurrentKeyMode]][mShiftOn][mCurrentKeyMode][0]);
		return view;
	}

	/** @see com.hiroshica.android.input.nicownn2.DefaultSoftKeyboard#changeKeyboard */
	@Override protected boolean changeKeyboard(final MyHeightKeyboard keyboard) {
		resetKeyRepeat();

		if (keyboard != null) {
			if (mIsInputTypeNull) {
				if (mChangeModeKey != null) {
					mChangeModeKey.popupResId = mPopupResId;
				}
			}

			final List<Keyboard.Key> keys = keyboard.getKeys();
			final int keyIndex = (KEY_NUMBER_12KEY < keys.size())
			? KEY_INDEX_CHANGE_MODE_QWERTY : KEY_INDEX_CHANGE_MODE_12KEY;
			mChangeModeKey = keys.get(keyIndex);

			if (mIsInputTypeNull) {
				if (mChangeModeKey != null) {
					mPopupResId = mChangeModeKey.popupResId;
					mChangeModeKey.popupResId = 0;
				}
			}
		}
		return super.changeKeyboard(keyboard);
	}

	/** @see com.hiroshica.android.input.nicownn2.DefaultSoftKeyboard#changeKeyboardType */
	@Override public void changeKeyboardType(final int type) {
		commitText();
		m12keyTable[mCurrentKeyMode] = type;
		final MyHeightKeyboard kbd = getTypeChangeKeyboard(type);
		if (kbd != null) {
			/*
			mPrefEditor.putBoolean("opt_enable_qwerty", type == KEYBOARD_QWERTY);
			mPrefEditor.commit();
			 */
			changeKeyboard(kbd);
		}
		if (m12keyTable[mCurrentKeyMode] == KEYBOARD_12KEY) {
			mWnn.onEvent(mEventChangeMode12Key);
		} else {
			mWnn.onEvent(mEventChangeModeQwerty);
		}
	}
	/** @see com.hiroshica.android.input.nicownn2.DefaultSoftKeyboard#setPreferences */
	@Override public void setPreferences(final SharedPreferences pref, final EditorInfo editor) {
		mPrefEditor = pref.edit();
		/*
		final boolean isQwerty = pref.getBoolean("opt_enable_qwerty", false);
		if (isQwerty && (mCurrentKeyboardType != KEYBOARD_QWERTY)) {
			changeKeyboardType(KEYBOARD_QWERTY);
		}
		 */

		super.setPreferences(pref, editor);

		final int inputType = editor.inputType;
		if (mHardKeyboardHidden) {
			if (inputType == InputType.TYPE_NULL) {
				if (!mIsInputTypeNull) {
					mIsInputTypeNull = true;
					if (mChangeModeKey != null) {
						mPopupResId = mChangeModeKey.popupResId;
						mChangeModeKey.popupResId = 0;
					}
				}
				return;
			}

			if (mIsInputTypeNull) {
				mIsInputTypeNull = false;
				if (mChangeModeKey != null) {
					mChangeModeKey.popupResId = mPopupResId;
				}
			}
		}

		mEnableAutoCaps = mWnn.getOrientPrefBoolean(pref, "auto_caps", false);
		mLimitedKeyMode = null;
		mPreferenceKeyMode = INVALID_KEYMODE;
		mNoInput = true;
		mDisableKeyInput = false;
		mCapsLock = false;

		switch (inputType & InputType.TYPE_MASK_CLASS) {

			case InputType.TYPE_CLASS_NUMBER:
			case InputType.TYPE_CLASS_DATETIME:
				mPreferenceKeyMode = KEYMODE_JA_HALF_NUMBER;
				break;

			case InputType.TYPE_CLASS_PHONE:
				if (mHardKeyboardHidden) {
					//mLimitedKeyMode = new int[] {KEYMODE_JA_FULL_NICO};
					mPreferenceKeyMode = KEYMODE_JA_FULL_NICO;
				} else {
					//mLimitedKeyMode = new int[] {KEYMODE_JA_HALF_ALPHABET};
					mPreferenceKeyMode = KEYMODE_JA_FULL_NICO;
				}
				break;

			case InputType.TYPE_CLASS_TEXT:
				switch (inputType & InputType.TYPE_MASK_VARIATION) {

					case InputType.TYPE_TEXT_VARIATION_PASSWORD:
						//mLimitedKeyMode = new int[] {KEYMODE_JA_HALF_ALPHABET, KEYMODE_JA_HALF_NUMBER};
						break;

					case InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS:
						//mLimitedKeyMode = new int[] {KEYMODE_JA_HALF_ALPHABET, KEYMODE_JA_HALF_NUMBER};
						break;
					case InputType.TYPE_TEXT_VARIATION_URI:
						//mPreferenceKeyMode = KEYMODE_JA_HALF_ALPHABET;
						mPreferenceKeyMode = KEYMODE_JA_FULL_NICO;
						break;

					default:
						break;
				}
				break;

			default:
				break;
		}

		boolean restartkey = false;
		final boolean oldKana12key = mKana12Key;
		final boolean oldAnum12key = mAnum12Key;

		mQwertyMatrixMode      = mWnn.getOrientPrefBoolean(pref, "qwerty_matrix_mode", false);
		mKana12Key = mWnn.getOrientPrefBoolean(pref, "change_kana_12key", false);
		mAnum12Key = mWnn.getOrientPrefBoolean(pref, "change_alphanum_12key", false);
		mNoAlphaMode           = mWnn.getOrientPrefBoolean(pref, "change_noalpha_qwerty", false);
		mNoNumberMode          = mWnn.getOrientPrefBoolean(pref, "change_nonumber_qwerty", false);
		final boolean getalphamode  = mWnn.getOrientPrefBoolean(pref, "change_alphamode", false);
		mFlickNicoInput        = Integer.valueOf(mWnn.getOrientPrefString(pref, "nicoflick_mode", "0"));
		mFlickGuide            = mWnn.getOrientPrefBoolean(pref, "flick_guide", true);
		mHiddenSoftKeyboard    = Integer.valueOf(mWnn.getOrientPrefString(pref, "hidden_softkeyboard2", "0"));

		if (false == getalphamode) {
			mChangeAlphaBigMode = ALPHAMODE_SMALL;
		}
		else{
			mChangeAlphaBigMode = ALPHAMODE_BIG;
		}

		if ((oldKana12key != mKana12Key) || (oldAnum12key != mAnum12Key)) {
			restartkey = true;
			setM12KeyTable();
		}
		if (inputType != mLastInputType) {
			setDefaultKeyboard();
			mLastInputType = inputType;
		}
		else if (true == restartkey) {
			setDefaultKeyboard();
		}

		setStatusIcon();
		setShiftByEditorInfo();
	}

	/** @see com.hiroshica.android.input.nicownn2.DefaultSoftKeyboard#onUpdateState */
	@Override public void onUpdateState(final NicoWnnG parent) {
		super.onUpdateState(parent);
		if (!mCapsLock) {
			setShiftByEditorInfo();
			if ((true == mNoInput) && (true == mNicoFirst)) {
				resetNicoKeyboard();
			}
		}
	}
	/**
	 * Change the keyboard to default
	 */
	@Override public void setDefaultKeyboard() {
		final Locale locale = Locale.getDefault();
		int keymode = KEYMODE_JA_FULL_NICO;


		if (mPreferenceKeyMode != INVALID_KEYMODE) {
			keymode = mPreferenceKeyMode;
		} else if (mLimitedKeyMode != null) {
			keymode = mLimitedKeyMode[0];
		} else {
			if (!locale.getLanguage().equals(Locale.JAPANESE.getLanguage())) {
				keymode = KEYMODE_JA_HALF_ALPHABET;
			}
		}
		changeKeyMode(keymode);
	}


	/**
	 * Change to the next input mode
	 */
	@Override public void nextKeyMode() {
		/* Search the current mode in the toggle table */
		boolean found = false;
		int index;
		for (index = 0; index < JP_MODE_CYCLE_TABLE.length; index++) {
			if (JP_MODE_CYCLE_TABLE[index] == mCurrentKeyMode) {
				found = true;
				break;
			}
		}

		if (!found) {
			/* If the current mode not exists, set the default mode */
			setDefaultKeyboard();
		} else {
			/* If the current mode exists, set the next input mode */
			final int size = JP_MODE_CYCLE_TABLE.length;
			int keyMode = INVALID_KEYMODE;
			for (int i = 0; i < size; i++) {
				index = (++index) % size;
				if (keyMode == INVALID_KEYMODE) {
					continue;
				}
				if (m12keyTable[keyMode] == KEYBOARD_QWERTY) {
					if (mNoAlphaMode) {
						if (JP_MODE_CYCLE_TABLE[index] == KEYMODE_JA_HALF_ALPHABET) {
							continue;
						}
					}
					if (mNoNumberMode) {
						if (JP_MODE_CYCLE_TABLE[index] == KEYMODE_JA_HALF_NUMBER) {
							continue;
						}
					}
				}
				break;
			}

			if (keyMode != INVALID_KEYMODE) {
				changeKeyMode(keyMode);
			}
		}
	}

	/**
	 * Create the keyboard for portrait mode
	 * <br>
	 * @param parent  The context
	 */
	private void createKeyboardsPortrait(final NicoWnnG parent) {
		mNicoKeyboard = mSetupKeyboard.SetupSoftKeyboard(parent, PORTRAIT, mInputViewHeightIndex, mFlickNicoInput, mFlickGuide);

		if (true == isHideSoftKeyboardByHardKeyboard()) {
			return;				// not create soft keyboard
		}

		int[] keyTable = selectQwertyPortKeyTable;
		if (mQwertyMatrixMode) {
			keyTable = selectQwertyPortKeyTable;
		} else {
			keyTable = selectQwertySlantKeyTable;
		}

		MyHeightKeyboard[][] keyList;
		/* qwerty shift_off (portrait) */
		keyList = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_QWERTY][KEYBOARD_SHIFT_OFF];
		keyList[KEYMODE_JA_FULL_NICO][0]     = new MyHeightKeyboard(parent, keyTable[0], mInputViewHeightIndex, KEYTYPE_NICO2, true);

		/* qwerty shift_on (portrait) */
		keyList = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_QWERTY][KEYBOARD_SHIFT_ON];
		keyList[KEYMODE_JA_FULL_NICO][0]     = new MyHeightKeyboard(parent, keyTable[1], mInputViewHeightIndex, KEYTYPE_NICO2, true);

		/* 12-keys shift_off (portrait) */
		keyList = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF];

		/* 12-keys shift_on (portrait) */
		keyList = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_ON];

		MyHeightKeyboard[][] keyListOn;
		keyList   = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF];
		keyListOn = mKeyboard[LANG_JA][PORTRAIT][KEYBOARD_12KEY][KEYBOARD_SHIFT_ON];
		keyList[KEYMODE_JA_FULL_NICO]     = mNicoKeyboard[NICO_MODE_FULL_HIRAGANA][NICO_SLIDE_MODE_TOP];
		keyList[KEYMODE_JA_FULL_NICO_KATAKANA]     = mNicoKeyboard[NICO_MODE_FULL_KATAKANA][NICO_SLIDE_MODE_TOP];
		keyList[KEYMODE_JA_HALF_NICO_KATAKANA]     = mNicoKeyboard[NICO_MODE_HALF_KATAKANA][NICO_SLIDE_MODE_TOP];
		keyListOn[KEYMODE_JA_FULL_NICO]   = mNicoKeyboard[NICO_MODE_FULL_HIRAGANA][NICO_SLIDE_MODE_A];
		keyListOn[KEYMODE_JA_FULL_NICO_KATAKANA]   = mNicoKeyboard[NICO_MODE_FULL_KATAKANA][NICO_SLIDE_MODE_A];
		keyListOn[KEYMODE_JA_HALF_NICO_KATAKANA]   = mNicoKeyboard[NICO_MODE_HALF_KATAKANA][NICO_SLIDE_MODE_A];
		mCreateKeyboard = true;
	}

	/**
	 * Create the keyboard for landscape mode
	 * <br>
	 * @param parent  The context
	 */
	private void createKeyboardsLandscape(final NicoWnnG parent) {
		mNicoKeyboard = mSetupKeyboard.SetupSoftKeyboard(parent, LANDSCAPE, mInputViewHeightIndex, mFlickNicoInput, mFlickGuide);

		if (true == isHideSoftKeyboardByHardKeyboard()) {
			return;				// not create soft keyboard
		}

		int[] keyTable = selectQwertyLandKeyTable;
		if (mQwertyMatrixMode) {
			keyTable = selectQwertyLandKeyTable;
		} else {
			keyTable = selectQwertyLandSlantKeyTable;
		}

		MyHeightKeyboard[][] keyList;
		/* qwerty shift_off (landscape) */
		keyList = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_QWERTY][KEYBOARD_SHIFT_OFF];
		keyList[KEYMODE_JA_FULL_NICO][0]     = new MyHeightKeyboard(parent, keyTable[0], mInputViewHeightIndex, KEYTYPE_NICO2, false);

		/* qwerty shift_on (landscape) */
		keyList = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_QWERTY][KEYBOARD_SHIFT_ON];
		keyList[KEYMODE_JA_FULL_NICO][0]     = new MyHeightKeyboard(parent, keyTable[1], mInputViewHeightIndex, KEYTYPE_NICO2, false);

		/* 12-keys shift_off (landscape) */
		keyList = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF];

		/* 12-keys shift_on (landscape) */
		keyList = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_ON];

		MyHeightKeyboard[][] keyListOn;
		keyList   = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_OFF];
		keyListOn = mKeyboard[LANG_JA][LANDSCAPE][KEYBOARD_12KEY][KEYBOARD_SHIFT_ON];
		keyList[KEYMODE_JA_FULL_NICO]     = mNicoKeyboard[NICO_MODE_FULL_HIRAGANA][NICO_SLIDE_MODE_TOP];
		keyList[KEYMODE_JA_FULL_NICO_KATAKANA]     = mNicoKeyboard[NICO_MODE_FULL_KATAKANA][NICO_SLIDE_MODE_TOP];
		keyList[KEYMODE_JA_HALF_NICO_KATAKANA]     = mNicoKeyboard[NICO_MODE_HALF_KATAKANA][NICO_SLIDE_MODE_TOP];
		keyListOn[KEYMODE_JA_FULL_NICO]   = mNicoKeyboard[NICO_MODE_FULL_HIRAGANA][NICO_SLIDE_MODE_A];
		keyListOn[KEYMODE_JA_FULL_NICO_KATAKANA]   = mNicoKeyboard[NICO_MODE_FULL_KATAKANA][NICO_SLIDE_MODE_A];
		keyListOn[KEYMODE_JA_HALF_NICO_KATAKANA]   = mNicoKeyboard[NICO_MODE_HALF_KATAKANA][NICO_SLIDE_MODE_A];
		mCreateKeyboard = true;
	}

	/**
	 * Convert the key code to the index of table
	 * <br>
	 * @param index     The key code
	 * @return          The index of the toggle table for input
	 */
	@Override public int getTableIndex(final int keyCode) {
		final int index =
			(keyCode == KEYCODE_JP12_1)     ?  0 :
				(keyCode == KEYCODE_JP12_2)     ?  1 :
					(keyCode == KEYCODE_JP12_3)     ?  2 :
						(keyCode == KEYCODE_JP12_4)     ?  3 :
							(keyCode == KEYCODE_JP12_5)     ?  4 :
								(keyCode == KEYCODE_JP12_6)     ?  5 :
									(keyCode == KEYCODE_JP12_7)     ?  6 :
										(keyCode == KEYCODE_JP12_8)     ?  7 :
											(keyCode == KEYCODE_JP12_9)     ?  8 :
												(keyCode == KEYCODE_JP12_0)     ?  9 :
													(keyCode == KEYCODE_NEWKEY_0)   ? 10 :
														(keyCode == KEYCODE_NEWKEY_1)   ? 11 :
															(keyCode == KEYCODE_NEWKEY_2)   ? 12 :
																(keyCode == KEYCODE_NEWKEY_3)   ? 13 :
																	(keyCode == KEYCODE_NEWKEY_4)   ? 14 :
																		0;
		return index;
	}
	private int checkTableIndex(final int keyCode) {
		final int index =
			(keyCode == KEYCODE_JP12_1)     ?  0 :
				(keyCode == KEYCODE_JP12_2)     ?  1 :
					(keyCode == KEYCODE_JP12_3)     ?  2 :
						(keyCode == KEYCODE_JP12_4)     ?  3 :
							(keyCode == KEYCODE_JP12_5)     ?  4 :
								(keyCode == KEYCODE_JP12_6)     ?  5 :
									(keyCode == KEYCODE_JP12_7)     ?  6 :
										(keyCode == KEYCODE_JP12_8)     ?  7 :
											(keyCode == KEYCODE_JP12_9)     ?  8 :
												(keyCode == KEYCODE_JP12_0)     ?  9 :
													-1;
		return index;
	}

	/**
	 * Get the toggle table for input that is appropriate in current mode.
	 *
	 * @return      The toggle table for input
	 */
	private String[][] getCycleTable() {
		final String[][] cycleTable = mCycleTable[mNicoKeyMode][mChangeAlphaBigMode];
		return cycleTable;
	}

	/**
	 * Get the replace table that is appropriate in current mode.
	 *
	 * @return      The replace table
	 */
	private HashMap<String,String> getReplaceTable() {
		HashMap<String,String> hashTable = null;
		switch (mCurrentKeyMode) {
			case KEYMODE_JA_FULL_NICO:
				hashTable = mSetupKeyboard.SetupReplaceTable(mTsuMode);
				break;

			default:
				break;
		}
		return hashTable;
	}

	/**
	 * Set the status icon that is appropriate in current mode
	 */
	private void setStatusIcon() {
		int icon = 0;

		switch (mCurrentKeyMode) {
			case KEYMODE_JA_FULL_NICO:
				icon = mSetupKeyboard.SetupIcon();
				break;

			default:
				break;
		}

		mWnn.showStatusIcon(icon);
	}

	/**
	 * Get the shift key state from the editor.
	 * <br>
	 * @param editor    The editor information
	 * @return          The state id of the shift key (0:off, 1:on)
	 */
	protected int getShiftKeyState(final EditorInfo editor) {
		final InputConnection connection = mWnn.getCurrentInputConnection();
		if (connection != null) {
			final int caps = connection.getCursorCapsMode(editor.inputType);
			return (caps == 0) ? 0 : 1;
		} else {
			return 0;
		}
	}

	/**
	 * Set the shift key state from {@link EditorInfo}.
	 */
	private void setShiftByEditorInfo() {
	}

	/** @see com.hiroshica.android.input.nicownn2.DefaultSoftKeyboard#setHardKeyboardHidden */
	@Override public void setHardKeyboardHidden(final boolean hidden, final boolean hardkey) {
		if (mWnn != null) {
			if (!hidden) {
				mWnn.onEvent(mEventChangeModeQwerty);
			}

			if (mHardKeyboardHidden != hidden) {
				if ((mLimitedKeyMode != null) || ((mCurrentKeyMode != KEYMODE_JA_FULL_NICO))) {

					mLastInputType = InputType.TYPE_NULL;
					if (mWnn.isInputViewShown()) {
						setDefaultKeyboard();
					}
				}
			}
		}
		super.setHardKeyboardHidden(hidden, hardkey);
	}

	/**
	 * Change the key-mode to the allowed one which is restricted
	 *  by the text input field or the type of the keyboard.
	 * @param keyMode The key-mode
	 * @return the key-mode allowed
	 */
	private int filterKeyMode(final int keyMode) {
		int targetMode = keyMode;
		final int[] limits = mLimitedKeyMode;
		/* restrict by the type of the text field */
		if (limits != null) {
			boolean hasAccepted = false;
			boolean hasRequiredChange = true;
			final int size = limits.length;
			final int nowMode = mCurrentKeyMode;

			for (int i = 0; i < size; i++) {
				if (targetMode == limits[i]) {
					hasAccepted = true;
					break;
				}
				if (nowMode == limits[i]) {
					hasRequiredChange = false;
				}
			}

			if (!hasAccepted) {
				if (hasRequiredChange) {
					targetMode = mLimitedKeyMode[0];
				} else {
					targetMode = INVALID_KEYMODE;
				}
			}
		}

		return targetMode;
	}

	@Override public String[] convertFlickToKeyString(int flickdir) {
		final int col = getTableIndex(mPrevInputKeyCode);
		final int row = flickdir;
		final String[][] cycleTable = getCycleTable();

		if (null != cycleTable) {
			return cycleTable[col * 15 + row];
		}
		return null;
	}

	/*****************************************
	 * onkey (normal)
	 */
	/** @see com.hiroshica.android.input.nicownn2.DefaultSoftKeyboard#onKey */
	@Override public void onKey(final int primaryCode2, final int[] keyCodes) {
		int primaryCode = primaryCode2;
		boolean changeShiftLock = true;

		MyHeightKeyboard newKeyboard = null;
		if (mDisableKeyInput) {
			return;
		}
		final int getFlickCode = checkFlickKeyCode(false, false);
		if (getFlickCode >= 0) {
			// get flick keydata
			final String keyString[] = convertFlickToKeyString(getFlickCode);
			if (null != keyString) {
				mWnn.onEvent(mEventTouchOtherKey);
				mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.TOGGLE_CHAR, keyString));
			}
			mNicoFirst = false;
			mNicoFlick = false;
			return;
		} else if (getFlickCode < -1) {
			switch (primaryCode) {
			case KEYCODE_JP12_CONVPREDICT:
			case KEYCODE_JP12_CONVPREDICT_BACKWARD:
				break;
			default:
				primaryCode = getFlickCode;
			}
		}

		switch (primaryCode) {
			case KEYCODE_JP12_TOGGLE_MODE:
			case KEYCODE_QWERTY_TOGGLE_MODE:
				if (!mNoInput) {
					final NicoWnnGJAJP wnn = NicoWnnGJAJP.getInstance();
					wnn.changeKanaDirectPhase();
					break;
				}
				if (!mIsInputTypeNull) {
					nextKeyMode();
				}
				break;

			case DefaultSoftKeyboard.KEYCODE_QWERTY_BACKSPACE:
			case KEYCODE_JP12_BACKSPACE:
				if (mNicoFirst == true) {
					resetNicoKeyboard();
				}
				else {
					mWnn.onEvent(mEventInputKeyDel);
				}
				changeShiftLock = false;
				break;

			case DefaultSoftKeyboard.KEYCODE_QWERTY_SHIFT:
				toggleShiftLock(1);
				changeShiftLock = false;
				break;

			case DefaultSoftKeyboard.KEYCODE_QWERTY_ALT:
				processAltKey();
				break;

			case KEYCODE_QWERTY_ENTER:
			case KEYCODE_JP12_ENTER:
				if (mNicoFirst == false) {
					mWnn.onEvent(mEventInputEnter);
				}
				break;

			case KEYCODE_QWERTY_KBD:
			case KEYCODE_JP12_KBD:
				resetNicoKeyboard();
				break;

			case KEYCODE_JP12_EMOJI:
			case KEYCODE_QWERTY_EMOJI:
				if (mNicoFirst == false) {
					commitText();
					mWnn.onEvent(mEventChangeModeSymbol);
				}
				break;

			case KEYCODE_EISU_KANA:
				if (mNicoFirst == false) {
					mWnn.onEvent(mEventChangeModeEisuKana);
				}
				break;

			case KEYCODE_JP12_SHARP:
				if ((mNicoFirst == false) && mNoInput) {
					commitText();
					mWnn.onEvent(mEventChangeModeDocomo);
				}
				break;

			case KEYCODE_JP12_1:
			case KEYCODE_JP12_2:
			case KEYCODE_JP12_3:
			case KEYCODE_JP12_4:
			case KEYCODE_JP12_5:
			case KEYCODE_JP12_6:
			case KEYCODE_JP12_7:
			case KEYCODE_JP12_8:
			case KEYCODE_JP12_9:
			case KEYCODE_JP12_0:
			case KEYCODE_NEWKEY_0:
			case KEYCODE_NEWKEY_1:
			case KEYCODE_NEWKEY_2:
			case KEYCODE_NEWKEY_3:
			case KEYCODE_NEWKEY_4:
				if (mNicoFirst == false) {
					mWnn.onEvent(mEventTouchOtherKey);
					if (NICOFLICK_NONE == mFlickNicoInput) {
						mPrevInputKeyCode = primaryCode;
					}
					else{
						if (-1 == checkTableIndex(mPrevInputKeyCode)) {
							mPrevInputKeyCode = primaryCode;
						}
					}
					mNicoFirst = true;

					/* change keymap */
					final int index = getTableIndex(mPrevInputKeyCode);
					final MyHeightKeyboard[][] keyList = mKeyboard[LANG_JA][mDisplayMode][KEYBOARD_12KEY][KEYBOARD_SHIFT_ON];

					keyList[KEYMODE_JA_FULL_NICO] = mNicoKeyboard[mNicoKeyMode][index+1];
					newKeyboard = getShiftChangeKeyboard(KEYBOARD_SHIFT_ON);
					mShiftOn = KEYBOARD_SHIFT_ON;
					changeKeyboard(newKeyboard);
				}
				else{
					/* change keyboard */
					newKeyboard = getShiftChangeKeyboard(KEYBOARD_SHIFT_OFF);
					mShiftOn = KEYBOARD_SHIFT_OFF;
					changeKeyboard(newKeyboard);
					/* set input char & update text */
					final int col = getTableIndex(mPrevInputKeyCode);
					final int row = getTableIndex(primaryCode);
					final String[][] cycleTable = getCycleTable();
					mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.TOGGLE_CHAR, cycleTable[col * 15 + row]));
					mNicoFirst = false;
					mNicoFlick = false;
				}
				break;

			case KEYCODE_JP12_ASTER:
				if (mNicoFirst == true) {
					resetNicoKeyboard();
				} else {
					if (!mNoInput) {
						/* Processing to toggle Dakuten, Handakuten, and capital */
						final HashMap<String,String> replaceTable = getReplaceTable();
						if (replaceTable == null) {
							Log.e("NicoWnnG", "not founds replace table");
						} else {
							mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.REPLACE_CHAR, replaceTable));
							mPrevInputKeyCode = primaryCode;
						}
					} else {
						mWnn.onEvent(mEventInputEnter);
					}
				}
				break;

			case KEYCODE_JP12_SPACE:
				if (mNicoFirst == false) {
					if (NicoWnnGJAJP.getInstance().isRenbun()||NicoWnnGJAJP.getInstance().isPredict()) {
						mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.INPUT_KEY, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SPACE)));
						mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.INPUT_CHAR, ' '));
					} else if (!mNoInput) {
						mWnn.onEvent(mEventConvert);
					} else {
						mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.INPUT_CHAR, ' '));
					}
				}
				break;

			case KEYCODE_JP12_ZEN_SPACE:
				if (mNicoFirst == false) {
					if (NicoWnnGJAJP.getInstance().isRenbun()||NicoWnnGJAJP.getInstance().isPredict()) {
						mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.INPUT_KEY, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SPACE)));
					} else if (!mNoInput) {
						mWnn.onEvent(mEventConvert);
					} else {
						mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.INPUT_CHAR, '\u3000'));
					}
				}
				break;

			case KEYCODE_SWITCH_FULL_NICO:
				/* Change mode to Full width nicotouch */
				changeKeyMode(KEYMODE_JA_FULL_NICO);
				break;

			case KEYCODE_SELECT_CASE:
				final int shifted = (mShiftOn == 0) ? 1 : 0;
				newKeyboard = getShiftChangeKeyboard(shifted);
				if (newKeyboard != null) {
					mShiftOn = shifted;
					changeKeyboard(newKeyboard);
				}
				break;

			case KEYCODE_JP12_CLOSE:
				mWnn.onEvent(mEventInputBack);
				break;

			case KEYCODE_JP12_LEFT:
				mWnn.onEvent(mEventInputDpadLeft);
				changeShiftLock = false;
				break;

			case KEYCODE_JP12_RIGHT:
				mWnn.onEvent(mEventInputDpadRight);
				changeShiftLock = false;
				break;

			case KEYCODE_JP12_UP:
				mWnn.onEvent(mEventInputDpadUp);
				changeShiftLock = false;
				break;

			case KEYCODE_JP12_DOWN:
				mWnn.onEvent(mEventInputDpadDown);
				changeShiftLock = false;
				break;

			case KEYCODE_NOP:
				break;

			case KEYCODE_PREFERENCE_SETTING:
				if (mNicoWnnG != null) {
					try {
						mNicoWnnG.openPreferenceSetting();
					} catch (final Exception e) {
						//
					}
				}
				break;

			case KEYCODE_SHOW_HELP:
				if (mNicoWnnG != null) {
					//try {
					mNicoWnnG.openHelp();
					//} catch (final Exception e) {
					//
					//}
				}
				break;

			case KEYCODE_MUSHROOM:
				if (mWnn != null) {
					final String str = mWnn.getComposingText(ComposingText.LAYER2);
					mWnn.onEvent(mEventInputBack);
					mWnn.invokeMushroom(str);
				}
				break;

			case KEYCODE_JP12_CONVPREDICT:
				mWnn.onEvent(mEventConvertPredict);
				break;

			case KEYCODE_JP12_CONVPREDICT_BACKWARD:
				mWnn.onEvent(mEventConvertPredictBackward);
				break;

			default:
				if (primaryCode >= 0) {
					if (mKeyboardView.isShifted()) {
						primaryCode = Character.toUpperCase(primaryCode);
					}
					mWnn.onEvent(new NicoWnnGEvent(NicoWnnGEvent.INPUT_CHAR, (char)primaryCode));
				}
				break;
		}

		if (changeShiftLock) {
			toggleShiftLock(2);
		}

		/* update shift key's state */
		if (!mCapsLock && (primaryCode != DefaultSoftKeyboard.KEYCODE_QWERTY_SHIFT)) {
			setShiftByEditorInfo();
		}
	}

	/*
	 * reset nicotouch keyboard
	 */
	@Override public void resetNicoKeyboard() {
		final MyHeightKeyboard newKeyboard = getShiftChangeKeyboard(KEYBOARD_SHIFT_OFF);
		if (newKeyboard != null) {
			mShiftOn = KEYBOARD_SHIFT_OFF;
			changeKeyboard(newKeyboard);
		}
		mNicoFirst = false;
		mNicoFlick = false;
	} // resetNicoKeyboard

	/**
	 */
	@Override public void onPress(final int primaryCode) {
		super.onPress(primaryCode);
	}
	/**
	 */
	@Override public void onRelease(final int primaryCode) {
		super.onRelease(primaryCode);
	} // onRelease
	/**
	 */
	@Override public int convertModeFlick(final int prev, final int key) {
		return mSetupKeyboard.GetFlickKeyCode(prev, key);
	}



	private static int selectQwertyLandKeyTable[] = {
		R.xml.keyboard_qwerty_jp_0,
		R.xml.keyboard_qwerty_jp_shift_0,
	};

	private static int selectQwertyPortKeyTable[] = {
		R.xml.keyboard_qwerty_jp_0,
		R.xml.keyboard_qwerty_jp_shift_0,
	};

	private static int selectQwertySlantKeyTable[] = {
		R.xml.keyboard_qwerty_jp_s0,
		R.xml.keyboard_qwerty_jp_shift_s0,
	};

	private static int selectQwertyLandSlantKeyTable[] = {
		R.xml.keyboard_qwerty_jp_s0,
		R.xml.keyboard_qwerty_jp_shift_s0,
	};


}
