1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.inputmethod.keyboard.internal;
18
19import android.text.TextUtils;
20
21import com.android.inputmethod.event.Event;
22import com.android.inputmethod.latin.common.Constants;
23import com.android.inputmethod.latin.utils.RecapitalizeStatus;
24
25public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
26    public interface MockConstants {
27        // Argument for {@link KeyboardState#onPressKey} and {@link KeyboardState#onReleaseKey}.
28        public static final boolean NOT_SLIDING = false;
29        public static final boolean SLIDING = true;
30        // Argument for {@link KeyboardState#onEvent}.
31        public static final boolean SINGLE = true;
32        public static final boolean MULTI = false;
33        public static final int CAP_MODE_OFF = Constants.TextUtils.CAP_MODE_OFF;
34        public static final int CAP_MODE_WORDS = TextUtils.CAP_MODE_WORDS;
35        public static final int CAP_MODE_CHARACTERS = TextUtils.CAP_MODE_CHARACTERS;
36
37        public static final int CODE_SHIFT = Constants.CODE_SHIFT;
38        public static final int CODE_SYMBOL = Constants.CODE_SWITCH_ALPHA_SYMBOL;
39        public static final int CODE_SPACE = Constants.CODE_SPACE;
40        public static final int CODE_AUTO_CAPS_TRIGGER = Constants.CODE_SPACE;
41
42        public static final int ALPHABET_UNSHIFTED = 0;
43        public static final int ALPHABET_MANUAL_SHIFTED = 1;
44        public static final int ALPHABET_AUTOMATIC_SHIFTED = 2;
45        public static final int ALPHABET_SHIFT_LOCKED = 3;
46        public static final int ALPHABET_SHIFT_LOCK_SHIFTED = 4;
47        public static final int SYMBOLS_UNSHIFTED = 5;
48        public static final int SYMBOLS_SHIFTED = 6;
49    }
50
51    private int mLayout = MockConstants.ALPHABET_UNSHIFTED;
52
53    private int mAutoCapsMode = MockConstants.CAP_MODE_OFF;
54    // Following InputConnection's behavior. Simulating InputType.TYPE_TEXT_FLAG_CAP_WORDS.
55    private int mAutoCapsState = MockConstants.CAP_MODE_OFF;
56
57    private boolean mIsInDoubleTapShiftKeyTimeout;
58    private int mLongPressTimeoutCode;
59
60    private final KeyboardState mState = new KeyboardState(this);
61
62    public int getLayoutId() {
63        return mLayout;
64    }
65
66    public static String getLayoutName(final int layoutId) {
67        switch (layoutId) {
68        case MockConstants.ALPHABET_UNSHIFTED: return "ALPHABET_UNSHIFTED";
69        case MockConstants.ALPHABET_MANUAL_SHIFTED: return "ALPHABET_MANUAL_SHIFTED";
70        case MockConstants.ALPHABET_AUTOMATIC_SHIFTED: return "ALPHABET_AUTOMATIC_SHIFTED";
71        case MockConstants.ALPHABET_SHIFT_LOCKED: return "ALPHABET_SHIFT_LOCKED";
72        case MockConstants.ALPHABET_SHIFT_LOCK_SHIFTED: return "ALPHABET_SHIFT_LOCK_SHIFTED";
73        case MockConstants.SYMBOLS_UNSHIFTED: return "SYMBOLS_UNSHIFTED";
74        case MockConstants.SYMBOLS_SHIFTED: return "SYMBOLS_SHIFTED";
75        default: return "UNKNOWN<" + layoutId + ">";
76        }
77    }
78
79    public void setAutoCapsMode(final int autoCaps) {
80        mAutoCapsMode = autoCaps;
81        mAutoCapsState = autoCaps;
82    }
83
84    public void expireDoubleTapTimeout() {
85        mIsInDoubleTapShiftKeyTimeout = false;
86    }
87
88    @Override
89    public void setAlphabetKeyboard() {
90        mLayout = MockConstants.ALPHABET_UNSHIFTED;
91    }
92
93    @Override
94    public void setAlphabetManualShiftedKeyboard() {
95        mLayout = MockConstants.ALPHABET_MANUAL_SHIFTED;
96    }
97
98    @Override
99    public void setAlphabetAutomaticShiftedKeyboard() {
100        mLayout = MockConstants.ALPHABET_AUTOMATIC_SHIFTED;
101    }
102
103    @Override
104    public void setAlphabetShiftLockedKeyboard() {
105        mLayout = MockConstants.ALPHABET_SHIFT_LOCKED;
106    }
107
108    @Override
109    public void setAlphabetShiftLockShiftedKeyboard() {
110        mLayout = MockConstants.ALPHABET_SHIFT_LOCK_SHIFTED;
111    }
112
113    @Override
114    public void setSymbolsKeyboard() {
115        mLayout = MockConstants.SYMBOLS_UNSHIFTED;
116    }
117
118    @Override
119    public void setSymbolsShiftedKeyboard() {
120        mLayout = MockConstants.SYMBOLS_SHIFTED;
121    }
122
123    @Override
124    public void setEmojiKeyboard() {
125        // Just ignore.
126    }
127
128    @Override
129    public void requestUpdatingShiftState(final int currentAutoCapsState,
130            final int currentRecapitalizeState) {
131        mState.onUpdateShiftState(currentAutoCapsState, currentRecapitalizeState);
132    }
133
134    @Override
135    public void startDoubleTapShiftKeyTimer() {
136        mIsInDoubleTapShiftKeyTimeout = true;
137    }
138
139    @Override
140    public void cancelDoubleTapShiftKeyTimer() {
141        mIsInDoubleTapShiftKeyTimeout = false;
142    }
143
144    @Override
145    public boolean isInDoubleTapShiftKeyTimeout() {
146        return mIsInDoubleTapShiftKeyTimeout;
147    }
148
149    public void updateShiftState() {
150        mState.onUpdateShiftState(mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
151    }
152
153    public void loadKeyboard() {
154        mState.onLoadKeyboard(mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
155    }
156
157    public void saveKeyboardState() {
158        mState.onSaveKeyboardState();
159    }
160
161    public void onPressKey(final int code, final boolean isSinglePointer) {
162        mState.onPressKey(code, isSinglePointer, mAutoCapsState,
163                RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
164    }
165
166    public void onReleaseKey(final int code, final boolean withSliding) {
167        onReleaseKey(code, withSliding, mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
168    }
169
170    public void onReleaseKey(final int code, final boolean withSliding,
171            final int currentAutoCapsState, final int currentRecapitalizeState) {
172        mState.onReleaseKey(code, withSliding, currentAutoCapsState, currentRecapitalizeState);
173        if (mLongPressTimeoutCode == code) {
174            mLongPressTimeoutCode = 0;
175        }
176    }
177
178    public void onCodeInput(final int code) {
179        if (mAutoCapsMode == MockConstants.CAP_MODE_WORDS) {
180            if (Constants.isLetterCode(code)) {
181                mAutoCapsState = (code == MockConstants.CODE_AUTO_CAPS_TRIGGER)
182                        ? mAutoCapsMode : MockConstants.CAP_MODE_OFF;
183            }
184        } else {
185            mAutoCapsState = mAutoCapsMode;
186        }
187        final Event event =
188                Event.createSoftwareKeypressEvent(code /* codePoint */, code /* keyCode */,
189                        Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
190                        false /* isKeyRepeat */);
191        mState.onEvent(event, mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
192    }
193
194    public void onFinishSlidingInput() {
195        mState.onFinishSlidingInput(mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);
196    }
197}
198