/*
 * 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.
 */

package jp.co.omronsoft.openwnn;

import jp.co.omronsoft.openwnn.EN.*;
import android.content.SharedPreferences;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Message;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.MetaKeyKeyListener;
import android.text.style.BackgroundColorSpan;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;

/**
 * The OpenWnn English IME class.
 *
 * @author Copyright (C) 2009 OMRON SOFTWARE CO., LTD.  All Rights Reserved.
 */
public class OpenWnnEN extends OpenWnn {
    /** A space character */
    private static final char[] SPACE = {' '};
    
    /** Character style of underline */
    private static final CharacterStyle SPAN_UNDERLINE   = new UnderlineSpan();
    /** Highlight color style for the selected string  */
    private static final CharacterStyle SPAN_EXACT_BGCOLOR_HL     = new BackgroundColorSpan(0xFF66CDAA);
    /** Highlight color style for the composing text */
    private static final CharacterStyle SPAN_REMAIN_BGCOLOR_HL    = new BackgroundColorSpan(0xFFF0FFFF);
    /** Highlight text color */
    private static final CharacterStyle SPAN_TEXTCOLOR  = new ForegroundColorSpan(0xFF000000);

    /** A private area code(ALT+SHIFT+X) to be ignore (G1 specific). */
    private static final int PRIVATE_AREA_CODE = 61184;
    /** Never move cursor in to the composing text (adapting to IMF's specification change) */
    private static final boolean FIX_CURSOR_TEXT_END = true;

    /** Spannable string for the composing text */
    protected SpannableStringBuilder mDisplayText;

    /** Characters treated as a separator */
    private String mWordSeparators;
    /** Previous event's code */
    private int mPreviousEventCode;

    /** Array of words from the user dictionary */
    private WnnWord[] mUserDictionaryWords = null;

    /** The converter for English prediction/spell correction */
    private OpenWnnEngineEN mConverterEN;
    /** The symbol list generator */
    private SymbolList mSymbolList;
    /** Whether it is displaying symbol list */
    private boolean mSymbolMode;
    /** Whether prediction is enabled */
    private boolean mOptPrediction;
    /** Whether spell correction is enabled */
    private boolean mOptSpellCorrection;
    /** Whether learning is enabled */
    private boolean mOptLearning;
    
    /** SHIFT key state */
    private int mHardShift;
    /** SHIFT key state (pressing) */
    private boolean mShiftPressing;
    /** ALT key state */
    private int mHardAlt;
    /** ALT key state (pressing) */
    private boolean mAltPressing;

    /** Instance of this service */
    private static OpenWnnEN mSelf = null;

    /** Shift lock toggle definition */
    private static final int[] mShiftKeyToggle = {0, MetaKeyKeyListener.META_SHIFT_ON, MetaKeyKeyListener.META_CAP_LOCKED};
    /** ALT lock toggle definition */
    private static final int[] mAltKeyToggle = {0, MetaKeyKeyListener.META_ALT_ON, MetaKeyKeyListener.META_ALT_LOCKED};
    /** Auto caps mode */
    private boolean mAutoCaps = false;
    
    /** Whether dismissing the keyboard when the enter key is pressed */
    private boolean mEnableAutoHideKeyboard = true;
    
    /** Tutorial */
    private TutorialEN mTutorial;

    /** Whether tutorial mode or not */
    private boolean mEnableTutorial;

    /** Message for {@code mHandler} (execute prediction) */
    private static final int MSG_PREDICTION = 0;

    /** Message for {@code mHandler} (execute tutorial) */
    private static final int MSG_START_TUTORIAL = 1;

    /** Message for {@code mHandler} (close) */
    private static final int MSG_CLOSE = 2;

    /** Delay time(msec.) to start prediction after key input when the candidates view is not shown. */
    private static final int PREDICTION_DELAY_MS_1ST = 200;

    /** Delay time(msec.) to start prediction after key input when the candidates view is shown. */
    private static final int PREDICTION_DELAY_MS_SHOWING_CANDIDATE = 200;
    
    /** {@code Handler} for drawing candidates/displaying tutorial */
    Handler mHandler = new Handler() {
            @Override public void handleMessage(Message msg) {
                switch (msg.what) {
                case MSG_PREDICTION:
                    updatePrediction();
                    break;
                case MSG_START_TUTORIAL:
                    if (mTutorial == null) {
                        if (isInputViewShown()) {
                            DefaultSoftKeyboardEN inputManager = ((DefaultSoftKeyboardEN) mInputViewManager);
                            View v = inputManager.getKeyboardView();
                            mTutorial = new TutorialEN(OpenWnnEN.this, v, inputManager);
                                                         
                            mTutorial.start();
                        } else {
                            /* Try again soon if the view is not yet showing */
                            sendMessageDelayed(obtainMessage(MSG_START_TUTORIAL), 100);
                        }
                    }
                    break;
                case MSG_CLOSE:
                    if (mConverterEN != null) mConverterEN.close();
                    if (mSymbolList != null) mSymbolList.close();
                    break;
                }
            }
        };

    /**
     * Constructor
     */
    public OpenWnnEN() {
        super();
        mSelf = this;

        /* used by OpenWnn */
        mComposingText = new ComposingText();
        mCandidatesViewManager = new TextCandidatesViewManager(-1);
        mInputViewManager = new DefaultSoftKeyboardEN();
        mConverterEN = new OpenWnnEngineEN("/data/data/jp.co.omronsoft.openwnn/writableEN.dic");
        mConverter = mConverterEN;
        mSymbolList = null;

        /* etc */
        mDisplayText = new SpannableStringBuilder();
        mAutoHideMode = false;
        mSymbolMode = false;
        mOptPrediction = true;
        mOptSpellCorrection = true;
        mOptLearning = true;
    }

    /**
     * Constructor
     *
     * @param context       The context
     */
    public OpenWnnEN(Context context) {
        this();
        attachBaseContext(context);
    }
    /**
     * Get the instance of this service.
     * <br>
     * Before using this method, the constructor of this service must be invoked.
     * 
     * @return      The instance of this object
     */
    public static OpenWnnEN getInstance() {
        return mSelf;
    }

    /**
     * Insert a character into the composing text.
     *
     * @param chars     A array of character
     */
    private void insertCharToComposingText(char[] chars) {
        StrSegment seg = new StrSegment(chars);

        if (chars[0] == SPACE[0] || chars[0] == '\u0009') {
            /* if the character is a space, commit the composing text */
            commitText(1);
            commitText(seg.string);
            mComposingText.clear();
        } else if (mWordSeparators.contains(seg.string)) {
            /* if the character is a separator, remove an auto-inserted space and commit the composing text. */
            if (mPreviousEventCode == OpenWnnEvent.SELECT_CANDIDATE) {
                mInputConnection.deleteSurroundingText(1, 0);
            }
            commitText(1);
            commitText(seg.string);
            mComposingText.clear();
        } else {
            mComposingText.insertStrSegment(0, 1, seg);
            updateComposingText(1);
        }
    }

    /**
     * Insert a character into the composing text.
     *
     * @param charCode      A character code
     * @return              {@code true} if success; {@code false} if an error occurs.
     */
    private boolean insertCharToComposingText(int charCode) {
        if (charCode == 0) {
            return false;
        }
        insertCharToComposingText(Character.toChars(charCode));
        return true;
    }

    /**
     * Get the shift key state from the editor.
     *
     * @param editor    Editor
     *
     * @return          State ID of the shift key (0:off, 1:on)
     */
    protected int getShiftKeyState(EditorInfo editor) {
        return (getCurrentInputConnection().getCursorCapsMode(editor.inputType) == 0) ? 0 : 1;
    }

    /**
     * Set the mode of the symbol list.
     * 
     * @param mode      {@code SymbolList.SYMBOL_ENGLISH} or {@code null}.
     */
    private void setSymbolMode(String mode) {
        if (mode != null) {
            mHandler.removeMessages(MSG_PREDICTION);
            mSymbolMode = true;
            mSymbolList.setDictionary(mode);
            mConverter = mSymbolList;
        } else {
            if (!mSymbolMode) {
                return;
            }
            mHandler.removeMessages(MSG_PREDICTION);
            mSymbolMode = false;
            mConverter = mConverterEN;
        }
    }

    /***********************************************************************
     * InputMethodServer
     ***********************************************************************/
    /** @see jp.co.omronsoft.openwnn.OpenWnn#onCreate */
    @Override public void onCreate() {
        super.onCreate();
        mWordSeparators = getResources().getString(R.string.en_word_separators);

        if (mSymbolList == null) {
            mSymbolList = new SymbolList(this, SymbolList.LANG_EN);
        }
    }
    
    /** @see jp.co.omronsoft.openwnn.OpenWnn#onCreateInputView */
    @Override public View onCreateInputView() {
        int hiddenState = getResources().getConfiguration().hardKeyboardHidden;
        boolean hidden = (hiddenState == Configuration.HARDKEYBOARDHIDDEN_YES);
        ((DefaultSoftKeyboardEN) mInputViewManager).setHardKeyboardHidden(hidden);
        mEnableTutorial = hidden;

        return super.onCreateInputView();
    }

    /** @see jp.co.omronsoft.openwnn.OpenWnn#onStartInputView */
    @Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
        super.onStartInputView(attribute, restarting);

        /* initialize views */
        mCandidatesViewManager.clearCandidates();
        mCandidatesViewManager.setViewType(CandidatesViewManager.VIEW_TYPE_CLOSE);

        mHardShift = 0;
        mHardAlt   = 0;
        updateMetaKeyStateDisplay();

        /* load preferences */
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);

        /* auto caps mode */
        mAutoCaps = pref.getBoolean("auto_caps", true);

        /* set TextCandidatesViewManager's option */
        ((TextCandidatesViewManager)mCandidatesViewManager).setAutoHide(true);
        
        /* display status icon */
        showStatusIcon(R.drawable.immodeic_half_alphabet);

        if (mComposingText != null) {
            mComposingText.clear();
        }
        /* initialize the engine's state */
        fitInputType(pref, attribute);
        
        ((DefaultSoftKeyboard) mInputViewManager).resetCurrentKeyboard();
    }

    /** @see jp.co.omronsoft.openwnn.OpenWnn#hideWindow */
    @Override public void hideWindow() {
        mComposingText.clear();
        mInputViewManager.onUpdateState(this);
        mHandler.removeMessages(MSG_START_TUTORIAL);
        mInputViewManager.closing();
        if (mTutorial != null) {
            mTutorial.close();
            mTutorial = null;
        }

        super.hideWindow();
    }

    /** @see jp.co.omronsoft.openwnn.OpenWnn#onUpdateSelection */
    @Override public void onUpdateSelection(int oldSelStart, int oldSelEnd,
            int newSelStart, int newSelEnd, int candidatesStart,
            int candidatesEnd) {

        boolean isNotComposing = ((candidatesStart < 0) && (candidatesEnd < 0));
        if (isNotComposing) {
            mComposingText.clear();
            updateComposingText(1);
        } else {
            if (mComposingText.size(1) != 0) {
                updateComposingText(1);
            }
        }
    }

    /** @see jp.co.omronsoft.openwnn.OpenWnn#onConfigurationChanged */
    @Override public void onConfigurationChanged(Configuration newConfig) {
        try {
            super.onConfigurationChanged(newConfig);
            if (mInputConnection != null) {
                updateComposingText(1);
            }
            /* Hardware keyboard */
            int hiddenState = newConfig.hardKeyboardHidden;
            boolean hidden = (hiddenState == Configuration.HARDKEYBOARDHIDDEN_YES);
            mEnableTutorial = hidden;
        } catch (Exception ex) {
        }
    }

    /** @see jp.co.omronsoft.openwnn.OpenWnn#onEvaluateFullscreenMode */
    @Override public boolean onEvaluateFullscreenMode() {
        return false;
    }

    /** @see jp.co.omronsoft.openwnn.OpenWnn#onEvaluateInputViewShown */
    @Override public boolean onEvaluateInputViewShown() {
        return true;
    }

    /***********************************************************************
     * OpenWnn
     ***********************************************************************/
    /** @see jp.co.omronsoft.openwnn.OpenWnn#onEvent */
    @Override synchronized public boolean onEvent(OpenWnnEvent ev) {
        /* handling events which are valid when InputConnection is not active. */
        switch (ev.code) {
        
        case OpenWnnEvent.KEYUP:
            onKeyUpEvent(ev.keyEvent);
            return true;
            
        case OpenWnnEvent.INITIALIZE_LEARNING_DICTIONARY:
            return mConverterEN.initializeDictionary( WnnEngine.DICTIONARY_TYPE_LEARN );

        case OpenWnnEvent.INITIALIZE_USER_DICTIONARY:
            return mConverterEN.initializeDictionary( WnnEngine.DICTIONARY_TYPE_USER );

        case OpenWnnEvent.LIST_WORDS_IN_USER_DICTIONARY:
            mUserDictionaryWords = mConverterEN.getUserDictionaryWords( );
            return true;

        case OpenWnnEvent.GET_WORD:
            if( mUserDictionaryWords != null ) {
                ev.word = mUserDictionaryWords[ 0 ];
                for( int i = 0 ; i < mUserDictionaryWords.length-1 ; i++ ) {
                    mUserDictionaryWords[ i ] = mUserDictionaryWords[ i + 1 ];
                }
                mUserDictionaryWords[ mUserDictionaryWords.length-1 ] = null;
                if( mUserDictionaryWords[ 0 ] == null ) {
                    mUserDictionaryWords = null;
                }
                return true;
            }
            break;

        case OpenWnnEvent.ADD_WORD:
            mConverterEN.addWord(ev.word);
            return true;

        case OpenWnnEvent.DELETE_WORD:
            mConverterEN.deleteWord(ev.word);
            return true;

        case OpenWnnEvent.CHANGE_MODE:
            return false;
            
        case OpenWnnEvent.UPDATE_CANDIDATE:
            updateComposingText(ComposingText.LAYER1);
            return true;

        case OpenWnnEvent.CHANGE_INPUT_VIEW:
            setInputView(onCreateInputView());
            return true;

        case OpenWnnEvent.CANDIDATE_VIEW_TOUCH:
            boolean ret;
                ret = ((TextCandidatesViewManager)mCandidatesViewManager).onTouchSync();
            return ret;

        default:
            break;
        }

        dismissPopupKeyboard();
        KeyEvent keyEvent = ev.keyEvent;
        int keyCode = 0;
        if (keyEvent != null) {
            keyCode = keyEvent.getKeyCode();
        }
        if (mDirectInputMode) {
            if (ev.code == OpenWnnEvent.INPUT_SOFT_KEY && mInputConnection != null) {
                mInputConnection.sendKeyEvent(keyEvent);
                mInputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
                                                           keyEvent.getKeyCode()));
            }
            return false;
        }

        if (ev.code == OpenWnnEvent.LIST_CANDIDATES_FULL) {
            mCandidatesViewManager.setViewType(CandidatesViewManager.VIEW_TYPE_FULL);
            return true;
        } else if (ev.code == OpenWnnEvent.LIST_CANDIDATES_NORMAL) {
            mCandidatesViewManager.setViewType(CandidatesViewManager.VIEW_TYPE_NORMAL);
            return true;
        }

        boolean ret = false;
        switch (ev.code) {
        case OpenWnnEvent.INPUT_CHAR:
             ((TextCandidatesViewManager)mCandidatesViewManager).setAutoHide(false);
            EditorInfo edit = getCurrentInputEditorInfo();
            if( edit.inputType == EditorInfo.TYPE_CLASS_PHONE){
                commitText(new String(ev.chars));           
            }else{
                setSymbolMode(null);
                insertCharToComposingText(ev.chars);
                ret = true;
                mPreviousEventCode = ev.code;
            }
            break;

        case OpenWnnEvent.INPUT_KEY:
            keyCode = ev.keyEvent.getKeyCode();
            /* update shift/alt state */
            switch (keyCode) {
            case KeyEvent.KEYCODE_ALT_LEFT:
            case KeyEvent.KEYCODE_ALT_RIGHT:
                if (ev.keyEvent.getRepeatCount() == 0) {
                    if (++mHardAlt > 2) { mHardAlt = 0; }
                }
                mAltPressing   = true;
                updateMetaKeyStateDisplay();
                return true;

            case KeyEvent.KEYCODE_SHIFT_LEFT:
            case KeyEvent.KEYCODE_SHIFT_RIGHT:
                if (ev.keyEvent.getRepeatCount() == 0) {
                    if (++mHardShift > 2) { mHardShift = 0; }
                }
                mShiftPressing = true;
                updateMetaKeyStateDisplay();
                return true;
            }
            setSymbolMode(null);
            updateComposingText(1);
            /* handle other key event */
            ret = processKeyEvent(ev.keyEvent);
            mPreviousEventCode = ev.code;
            break;

        case OpenWnnEvent.INPUT_SOFT_KEY:
            setSymbolMode(null);
            updateComposingText(1);
            ret = processKeyEvent(ev.keyEvent);
            if (!ret) {
            	int code = keyEvent.getKeyCode();
            	if (code == KeyEvent.KEYCODE_ENTER) {
                    sendKeyChar('\n');
            	} else {
                    mInputConnection.sendKeyEvent(keyEvent);
                    mInputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, code));
            	}
                ret = true;
            }
            mPreviousEventCode = ev.code;
            break;

        case OpenWnnEvent.SELECT_CANDIDATE:
            if (mSymbolMode) {
                commitText(ev.word, false);
            } else {
                if (mWordSeparators.contains(ev.word.candidate) && 
                    mPreviousEventCode == OpenWnnEvent.SELECT_CANDIDATE) {
                    mInputConnection.deleteSurroundingText(1, 0);
                }
                commitText(ev.word, true);
            }
            mComposingText.clear();
            mPreviousEventCode = ev.code;
            updateComposingText(1);
            break;

        case OpenWnnEvent.LIST_SYMBOLS:
            commitText(1);
            mComposingText.clear();
            setSymbolMode(SymbolList.SYMBOL_ENGLISH);
            updateComposingText(1);
            break;

        default:
            break;
        }

        if (mCandidatesViewManager.getViewType() == CandidatesViewManager.VIEW_TYPE_FULL) {
        	mCandidatesViewManager.setViewType(CandidatesViewManager.VIEW_TYPE_NORMAL);
        }

        return ret;
    }

    /***********************************************************************
     * OpenWnnEN
     ***********************************************************************/
    /**
     * Handling KeyEvent
     * <br>
     * This method is called from {@link #onEvent()}.
     *
     * @param ev   A key event
     * @return      {@code true} if the event is processed in this method; {@code false} if the event is not processed in this method
     */
    private boolean processKeyEvent(KeyEvent ev) {

        int key = ev.getKeyCode();
        EditorInfo edit = getCurrentInputEditorInfo();
        /* keys which produce a glyph */
        if (ev.isPrintingKey()) {
            /* do nothing if the character is not able to display or the character is dead key */
            if ((mHardShift > 0 && mHardAlt > 0) || (ev.isAltPressed() && ev.isShiftPressed())) {
                int charCode = ev.getUnicodeChar(MetaKeyKeyListener.META_SHIFT_ON | MetaKeyKeyListener.META_ALT_ON);
                if (charCode == 0 || (charCode & KeyCharacterMap.COMBINING_ACCENT) != 0 || charCode == PRIVATE_AREA_CODE) {
                    if(mHardShift == 1){
                        mShiftPressing = false;
                    }
                    if(mHardAlt == 1){
                        mAltPressing   = false;
                    }
                    if(!ev.isAltPressed()){
                        if (mHardAlt == 1) {
                            mHardAlt = 0;
                        }
                    }
                    if(!ev.isShiftPressed()){
                        if (mHardShift == 1) {
                            mHardShift = 0;
                        }
                    }
                    if(!ev.isShiftPressed() && !ev.isAltPressed()){
                        updateMetaKeyStateDisplay();
                    }
                    return true;
                }
            }
            
            ((TextCandidatesViewManager)mCandidatesViewManager).setAutoHide(false);

            /* get the key character */
            if (mHardShift== 0  && mHardAlt == 0) {
                /* no meta key is locked */
                int shift = (mAutoCaps) ? getShiftKeyState(edit) : 0;
                if (shift != mHardShift && (key >= KeyEvent.KEYCODE_A && key <= KeyEvent.KEYCODE_Z)) {
                    /* handling auto caps for a alphabet character */
                    insertCharToComposingText(ev.getUnicodeChar(MetaKeyKeyListener.META_SHIFT_ON));
                } else {
                    insertCharToComposingText(ev.getUnicodeChar());
                }
            } else {
                insertCharToComposingText(ev.getUnicodeChar(mShiftKeyToggle[mHardShift]
                                                            | mAltKeyToggle[mHardAlt]));
                if(mHardShift == 1){
                    mShiftPressing = false;
                }
                if(mHardAlt == 1){
                    mAltPressing   = false;
                }
                /* back to 0 (off) if 1 (on/not locked) */
                if(!ev.isAltPressed()){
                    if (mHardAlt == 1) {
                        mHardAlt = 0;
                    }
                }
                if(!ev.isShiftPressed()){
                    if (mHardShift == 1) {
                        mHardShift = 0;
                    }
                }
                if(!ev.isShiftPressed() && !ev.isAltPressed()){
                    updateMetaKeyStateDisplay();
                }
            }

            if (edit.inputType == EditorInfo.TYPE_CLASS_PHONE) {
                commitText(1);
                mComposingText.clear();
                return true;
            }
            return true;

        } else if (key == KeyEvent.KEYCODE_SPACE) {
            if (ev.isAltPressed()) {
                /* display the symbol list (G1 specific. same as KEYCODE_SYM) */
                commitText(1);
                mComposingText.clear();
                setSymbolMode(SymbolList.SYMBOL_ENGLISH);
                updateComposingText(1);     
                mHardAlt = 0;
                updateMetaKeyStateDisplay();
            } else {
                insertCharToComposingText(SPACE);   
            }
            return true;
        } else if (key == KeyEvent.KEYCODE_SYM) {
            /* display the symbol list */
            commitText(1);
            mComposingText.clear();
            setSymbolMode(SymbolList.SYMBOL_ENGLISH);
            updateComposingText(1);     
            mHardAlt = 0;
            updateMetaKeyStateDisplay();
        } 


        /* Functional key */
        if (mComposingText.size(1) > 0) {
            switch (key) {
            case KeyEvent.KEYCODE_DEL:
                mComposingText.delete(1, false);
                updateComposingText(1);
                return true;

            case KeyEvent.KEYCODE_BACK:
                if (mCandidatesViewManager.getViewType() == CandidatesViewManager.VIEW_TYPE_FULL) {
                    mCandidatesViewManager.setViewType(CandidatesViewManager.VIEW_TYPE_NORMAL);
                } else {
                    mComposingText.clear();
                    updateComposingText(1);
                }
                return true;

            case KeyEvent.KEYCODE_DPAD_LEFT:
                mComposingText.moveCursor(1, -1);
                updateComposingText(1);
                return true;

            case KeyEvent.KEYCODE_DPAD_RIGHT:
                mComposingText.moveCursor(1, 1);
                updateComposingText(1);
                return true;

            case KeyEvent.KEYCODE_ENTER:
            case KeyEvent.KEYCODE_DPAD_CENTER:
                commitText(1);
                mComposingText.clear();
                if (mEnableAutoHideKeyboard) {
                    mInputViewManager.closing();
                    requestHideSelf(0);
                }
                return true;

            default:
                break;
            }
        } else {
            /* if there is no composing string. */
            if (mCandidatesViewManager.getCurrentView().isShown()) {
            	if (key == KeyEvent.KEYCODE_BACK) {
            		if (mCandidatesViewManager.getViewType() == CandidatesViewManager.VIEW_TYPE_FULL) {
            			mCandidatesViewManager.setViewType(CandidatesViewManager.VIEW_TYPE_NORMAL);
            		} else {
            			mCandidatesViewManager.setViewType(CandidatesViewManager.VIEW_TYPE_CLOSE);
            		}
            		return true;
            	}
            } else {
                switch (key) {
                case KeyEvent.KEYCODE_DPAD_CENTER:
                case KeyEvent.KEYCODE_ENTER:
                    if (mEnableAutoHideKeyboard) {
                        mInputViewManager.closing();
                        requestHideSelf(0);
                        return true;
                    }
                    break;
                case KeyEvent.KEYCODE_BACK:
                    /*
                     * If 'BACK' key is pressed when the SW-keyboard is shown
                     * and the candidates view is not shown, dismiss the SW-keyboard.
                     */
                    if (isInputViewShown()) {
                        mInputViewManager.closing();
                        requestHideSelf(0);
                        return true;
                    }
                    break;
                default:
                    break;
                }
            }
        }

        return false;
    }

    /**
     * Thread for updating the candidates view
     */
    private void updatePrediction() {
        int candidates = 0;
        if (mConverter != null) {
            /* normal prediction */
            candidates = mConverter.predict(mComposingText, 0, -1);
        }
        /* update the candidates view */
        if (candidates > 0) {
            mCandidatesViewManager.displayCandidates(mConverter);
        } else {
            mCandidatesViewManager.clearCandidates();
        }
    }

    /**
     * Update the composing text.
     *
     * @param layer  {@link mComposingText}'s layer to display
     */
    private void updateComposingText(int layer) {
        /* update the candidates view */
        if (!mOptPrediction) {
            commitText(1);
            mComposingText.clear();
            if (mSymbolMode) {
                mHandler.removeMessages(MSG_PREDICTION);
                mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PREDICTION), 0);
            }
        } else {
            if (mComposingText.size(1) != 0) {
                mHandler.removeMessages(MSG_PREDICTION);
                if (mCandidatesViewManager.getCurrentView().isShown()) {
                    mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PREDICTION),
                                                PREDICTION_DELAY_MS_SHOWING_CANDIDATE);
                } else {
                    mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PREDICTION),
                                                PREDICTION_DELAY_MS_1ST);
                }
            } else {
                mHandler.removeMessages(MSG_PREDICTION);
                mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PREDICTION), 0);
            }

            /* notice to the input view */
            this.mInputViewManager.onUpdateState(this);

            /* set the text for displaying as the composing text */
            SpannableStringBuilder disp = mDisplayText;
            disp.clear();
            disp.insert(0, mComposingText.toString(layer));

            /* add decoration to the text */
            int cursor = mComposingText.getCursor(layer);
            if (disp.length() != 0) {
                if (cursor > 0 && cursor < disp.length()) {
                    disp.setSpan(SPAN_EXACT_BGCOLOR_HL, 0, cursor,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                if (cursor < disp.length()) {
                    mDisplayText.setSpan(SPAN_REMAIN_BGCOLOR_HL, cursor, disp.length(),
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    mDisplayText.setSpan(SPAN_TEXTCOLOR, 0, disp.length(),
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 
                }
                
                disp.setSpan(SPAN_UNDERLINE, 0, disp.length(),
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            
            int displayCursor = cursor;
            if (FIX_CURSOR_TEXT_END) {
                displayCursor = (cursor == 0) ?  0 : 1;
            } 
            /* update the composing text on the EditView */
            mInputConnection.setComposingText(disp, displayCursor);
        }
    }

    /**
     * Commit the composing text.
     *
     * @param layer  {@link mComposingText}'s layer to commit.
     */
    private void commitText(int layer) {
        String tmp = mComposingText.toString(layer);

        if (mOptLearning && mConverter != null && tmp.length() > 0) {
            WnnWord word = new WnnWord(tmp, tmp);
            mConverter.learn(word);
        }

        mInputConnection.commitText(tmp, (FIX_CURSOR_TEXT_END ? 1 : tmp.length()));
        mCandidatesViewManager.clearCandidates();
    }

    /**
     * Commit a word
     *
     * @param word          A word to commit
     * @param withSpace     Append a space after the word if {@code true}.
     */
    private void commitText(WnnWord word, boolean withSpace) {

        if (mOptLearning && mConverter != null) {
            mConverter.learn(word);
        }

        mInputConnection.commitText(word.candidate, (FIX_CURSOR_TEXT_END ? 1 : word.candidate.length()));

        if (withSpace) {
            commitText(" ");
        }       
    }

    /**
     * Commit a string
     * <br>
     * The string is not registered into the learning dictionary.
     *
     * @param str  A string to commit
     */
    private void commitText(String str) {
        mInputConnection.commitText(str, (FIX_CURSOR_TEXT_END ? 1 : str.length()));
        mCandidatesViewManager.clearCandidates();
    }

    /**
     * Dismiss the pop-up keyboard
     */
    protected void dismissPopupKeyboard() {
        DefaultSoftKeyboardEN kbd = (DefaultSoftKeyboardEN)mInputViewManager;
        if (kbd != null) {
            kbd.dismissPopupKeyboard();
        }
    }

    /**
     * Display current meta-key state.
     */
    private void updateMetaKeyStateDisplay() {
        int mode = 0;
        if(mHardShift == 0 && mHardAlt == 0){
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_OFF_ALT_OFF;
        }else if(mHardShift == 1 && mHardAlt == 0){
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_ON_ALT_OFF;
        }else if(mHardShift == 2  && mHardAlt == 0){
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_LOCK_ALT_OFF;
        }else if(mHardShift == 0 && mHardAlt == 1){
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_OFF_ALT_ON;
        }else if(mHardShift == 0 && mHardAlt == 2){
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_OFF_ALT_LOCK;
        }else if(mHardShift == 1 && mHardAlt == 1){
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_ON_ALT_ON;
        }else if(mHardShift == 1 && mHardAlt == 2){
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_ON_ALT_LOCK;
        }else if(mHardShift == 2 && mHardAlt == 1){
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_LOCK_ALT_ON;
        }else if(mHardShift == 2 && mHardAlt == 2){
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_LOCK_ALT_LOCK;
        }else{
            mode = DefaultSoftKeyboard.HARD_KEYMODE_SHIFT_OFF_ALT_OFF;
        }

        ((DefaultSoftKeyboard) mInputViewManager).updateIndicator(mode);
    }

    /**
     * Handling KeyEvent(KEYUP)
     * <br>
     * This method is called from {@link #onEvent()}.
     *
     * @param ev   An up key event
     */
    private void onKeyUpEvent(KeyEvent ev) {
        int key = ev.getKeyCode();
        if(!mShiftPressing){
            if(key == KeyEvent.KEYCODE_SHIFT_LEFT || key == KeyEvent.KEYCODE_SHIFT_RIGHT){
                mHardShift = 0;
                mShiftPressing = true;
                updateMetaKeyStateDisplay();
            }
        }
        if(!mAltPressing ){
            if(key == KeyEvent.KEYCODE_ALT_LEFT || key == KeyEvent.KEYCODE_ALT_RIGHT){
                mHardAlt = 0;
                mAltPressing   = true;
                updateMetaKeyStateDisplay();
            }
        }
    }
    /**
     * Fits an editor info.
     * 
     * @param preferences  The preference data.
     * @param info          The editor info.
     */
    private void fitInputType(SharedPreferences preference, EditorInfo info) {
        if (info.inputType == EditorInfo.TYPE_NULL) {
            mDirectInputMode = true;
            return;
        }

        mEnableAutoHideKeyboard = false;
        
        /* set prediction & spell correction mode */
        mOptPrediction      = preference.getBoolean("opt_en_prediction", true);
        mOptSpellCorrection = preference.getBoolean("opt_en_spell_correction", true);
        mOptLearning        = preference.getBoolean("opt_en_enable_learning", true);

        /* prediction on/off */
        switch (info.inputType & EditorInfo.TYPE_MASK_CLASS) {
        case EditorInfo.TYPE_CLASS_NUMBER:
        case EditorInfo.TYPE_CLASS_DATETIME:
        case EditorInfo.TYPE_CLASS_PHONE:
            mOptPrediction = false;
            mOptLearning = false;
            break;

        case EditorInfo.TYPE_CLASS_TEXT:
            switch (info.inputType & EditorInfo.TYPE_MASK_VARIATION) {
            case EditorInfo.TYPE_TEXT_VARIATION_PASSWORD:
            case EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD:
                mOptLearning = false;
                mOptPrediction = false;
                break;

            case EditorInfo.TYPE_TEXT_VARIATION_PHONETIC:
                mOptLearning = false;
                mOptPrediction = false;
                break;
            default:
                break;
            }
        }

        /* doesn't learn any word if it is not prediction mode */
        if (!mOptPrediction) {
            mOptLearning = false;
        }

        /* set engine's mode */
        if (mOptSpellCorrection) {
            mConverterEN.setDictionary(OpenWnnEngineEN.DICT_FOR_CORRECT_MISTYPE);
        } else {
            mConverterEN.setDictionary(OpenWnnEngineEN.DICT_DEFAULT);
        }
        checkTutorial(info.privateImeOptions);
    }

    /**
     * Check and start the tutorial if it is the tutorial mode.
     * 
     * @param privateImeOptions IME's options
     */
    private void checkTutorial(String privateImeOptions) {
        if (privateImeOptions == null) return;
        if (privateImeOptions.equals("com.google.android.setupwizard:ShowTutorial")) {
            if ((mTutorial == null) && mEnableTutorial) startTutorial();
        } else if (privateImeOptions.equals("com.google.android.setupwizard:HideTutorial")) {
            if (mTutorial != null) {
                if (mTutorial.close()) {
                    mTutorial = null;
                }
            }
        }
    }

    /**
     * Start the tutorial
     */
    private void startTutorial() {
        DefaultSoftKeyboardEN inputManager = ((DefaultSoftKeyboardEN) mInputViewManager);
        View v = inputManager.getKeyboardView();
        v.setOnTouchListener(new View.OnTouchListener() {
				public boolean onTouch(View v, MotionEvent event) {
					return true;
				}});
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_TUTORIAL), 500);
    }

    /**
     * Close the tutorial
     */
    public void tutorialDone() {
        mTutorial = null;
    }

    /** @see OpenWnn#close */
    @Override protected void close() {
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLOSE), 0);
    }
}
