1/*
2 * Copyright (C) 2008-2012  OMRON SOFTWARE Co., Ltd.
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 jp.co.omronsoft.openwnn.JAJP;
18
19import java.text.DecimalFormat;
20import java.util.ArrayList;
21import java.util.HashMap;
22import java.util.List;
23import java.util.Locale;
24import jp.co.omronsoft.openwnn.WnnDictionary;
25import jp.co.omronsoft.openwnn.WnnPOS;
26import jp.co.omronsoft.openwnn.WnnWord;
27
28/**
29 * The EISU-KANA converter class for Japanese IME.
30 *
31 * @author Copyright (C) 2009 OMRON SOFTWARE CO., LTD.  All Rights Reserved.
32 */
33public class KanaConverter {
34
35	/** Conversion rule for half-width numeric */
36    private static final HashMap<String,String> mHalfNumericMap = new HashMap<String,String>() {{
37        put( "\u3042", "1");
38        put( "\u3044", "11");
39        put( "\u3046", "111");
40        put( "\u3048", "1111");
41        put( "\u304a", "11111");
42        put( "\u3041", "111111");
43        put( "\u3043", "1111111");
44        put( "\u3045", "11111111");
45        put( "\u3047", "111111111");
46        put( "\u3049", "1111111111");
47        put( "\u304b", "2");
48        put( "\u304d", "22");
49        put( "\u304f", "222");
50        put( "\u3051", "2222");
51        put( "\u3053", "22222");
52        put( "\u3055", "3");
53        put( "\u3057", "33");
54        put( "\u3059", "333");
55        put( "\u305b", "3333");
56        put( "\u305d", "33333");
57        put( "\u305f", "4");
58        put( "\u3061", "44");
59        put( "\u3064", "444");
60        put( "\u3066", "4444");
61        put( "\u3068", "44444");
62        put( "\u3063", "444444");
63        put( "\u306a", "5");
64        put( "\u306b", "55");
65        put( "\u306c", "555");
66        put( "\u306d", "5555");
67        put( "\u306e", "55555");
68        put( "\u306f", "6");
69        put( "\u3072", "66");
70        put( "\u3075", "666");
71        put( "\u3078", "6666");
72        put( "\u307b", "66666");
73        put( "\u307e", "7");
74        put( "\u307f", "77");
75        put( "\u3080", "777");
76        put( "\u3081", "7777");
77        put( "\u3082", "77777");
78        put( "\u3084", "8");
79        put( "\u3086", "88");
80        put( "\u3088", "888");
81        put( "\u3083", "8888");
82        put( "\u3085", "88888");
83        put( "\u3087", "888888");
84        put( "\u3089", "9");
85        put( "\u308a", "99");
86        put( "\u308b", "999");
87        put( "\u308c", "9999");
88        put( "\u308d", "99999");
89        put( "\u308f", "0");
90        put( "\u3092", "00");
91        put( "\u3093", "000");
92        put( "\u308e", "0000");
93        put( "\u30fc", "00000");
94    }};
95
96    /** Conversion rule for full-width numeric */
97    private static final HashMap<String,String> mFullNumericMap = new HashMap<String,String>() {{
98        put( "\u3042", "\uff11");
99        put( "\u3044", "\uff11\uff11");
100        put( "\u3046", "\uff11\uff11\uff11");
101        put( "\u3048", "\uff11\uff11\uff11\uff11");
102        put( "\u304a", "\uff11\uff11\uff11\uff11\uff11");
103        put( "\u3041", "\uff11\uff11\uff11\uff11\uff11\uff11");
104        put( "\u3043", "\uff11\uff11\uff11\uff11\uff11\uff11\uff11");
105        put( "\u3045", "\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11");
106        put( "\u3047", "\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11");
107        put( "\u3049", "\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11");
108        put( "\u304b", "\uff12");
109        put( "\u304d", "\uff12\uff12");
110        put( "\u304f", "\uff12\uff12\uff12");
111        put( "\u3051", "\uff12\uff12\uff12\uff12");
112        put( "\u3053", "\uff12\uff12\uff12\uff12\uff12");
113        put( "\u3055", "\uff13");
114        put( "\u3057", "\uff13\uff13");
115        put( "\u3059", "\uff13\uff13\uff13");
116        put( "\u305b", "\uff13\uff13\uff13\uff13");
117        put( "\u305d", "\uff13\uff13\uff13\uff13\uff13");
118        put( "\u305f", "\uff14");
119        put( "\u3061", "\uff14\uff14");
120        put( "\u3064", "\uff14\uff14\uff14");
121        put( "\u3066", "\uff14\uff14\uff14\uff14");
122        put( "\u3068", "\uff14\uff14\uff14\uff14\uff14");
123        put( "\u3063", "\uff14\uff14\uff14\uff14\uff14\uff14");
124        put( "\u306a", "\uff15");
125        put( "\u306b", "\uff15\uff15");
126        put( "\u306c", "\uff15\uff15\uff15");
127        put( "\u306d", "\uff15\uff15\uff15\uff15");
128        put( "\u306e", "\uff15\uff15\uff15\uff15\uff15");
129        put( "\u306f", "\uff16");
130        put( "\u3072", "\uff16\uff16");
131        put( "\u3075", "\uff16\uff16\uff16");
132        put( "\u3078", "\uff16\uff16\uff16\uff16");
133        put( "\u307b", "\uff16\uff16\uff16\uff16\uff16");
134        put( "\u307e", "\uff17");
135        put( "\u307f", "\uff17\uff17");
136        put( "\u3080", "\uff17\uff17\uff17");
137        put( "\u3081", "\uff17\uff17\uff17\uff17");
138        put( "\u3082", "\uff17\uff17\uff17\uff17\uff17");
139        put( "\u3084", "\uff18");
140        put( "\u3086", "\uff18\uff18");
141        put( "\u3088", "\uff18\uff18\uff18");
142        put( "\u3083", "\uff18\uff18\uff18\uff18");
143        put( "\u3085", "\uff18\uff18\uff18\uff18\uff18");
144        put( "\u3087", "\uff18\uff18\uff18\uff18\uff18\uff18");
145        put( "\u3089", "\uff19");
146        put( "\u308a", "\uff19\uff19");
147        put( "\u308b", "\uff19\uff19\uff19");
148        put( "\u308c", "\uff19\uff19\uff19\uff19");
149        put( "\u308d", "\uff19\uff19\uff19\uff19\uff19");
150        put( "\u308f", "\uff10");
151        put( "\u3092", "\uff10\uff10");
152        put( "\u3093", "\uff10\uff10\uff10");
153        put( "\u308e", "\uff10\uff10\uff10\uff10");
154        put( "\u30fc", "\uff10\uff10\uff10\uff10\uff10");
155    }};
156
157    /** Conversion rule for half-width Katakana */
158    private static final HashMap<String,String> mHalfKatakanaMap = new HashMap<String,String>() {{
159        put( "\u3042", "\uff71");
160        put( "\u3044", "\uff72");
161        put( "\u3046", "\uff73");
162        put( "\u3048", "\uff74");
163        put( "\u304a", "\uff75");
164        put( "\u3041", "\uff67");
165        put( "\u3043", "\uff68");
166        put( "\u3045", "\uff69");
167        put( "\u3047", "\uff6a");
168        put( "\u3049", "\uff6b");
169        put( "\u30f4\u3041", "\uff73\uff9e\uff67");
170        put( "\u30f4\u3043", "\uff73\uff9e\uff68");
171        put( "\u30f4", "\uff73\uff9e");
172        put( "\u30f4\u3047", "\uff73\uff9e\uff6a");
173        put( "\u30f4\u3049", "\uff73\uff9e\uff6b");
174        put( "\u304b", "\uff76");
175        put( "\u304d", "\uff77");
176        put( "\u304f", "\uff78");
177        put( "\u3051", "\uff79");
178        put( "\u3053", "\uff7a");
179        put( "\u304c", "\uff76\uff9e");
180        put( "\u304e", "\uff77\uff9e");
181        put( "\u3050", "\uff78\uff9e");
182        put( "\u3052", "\uff79\uff9e");
183        put( "\u3054", "\uff7a\uff9e");
184        put( "\u3055", "\uff7b");
185        put( "\u3057", "\uff7c");
186        put( "\u3059", "\uff7d");
187        put( "\u305b", "\uff7e");
188        put( "\u305d", "\uff7f");
189        put( "\u3056", "\uff7b\uff9e");
190        put( "\u3058", "\uff7c\uff9e");
191        put( "\u305a", "\uff7d\uff9e");
192        put( "\u305c", "\uff7e\uff9e");
193        put( "\u305e", "\uff7f\uff9e");
194        put( "\u305f", "\uff80");
195        put( "\u3061", "\uff81");
196        put( "\u3064", "\uff82");
197        put( "\u3066", "\uff83");
198        put( "\u3068", "\uff84");
199        put( "\u3063", "\uff6f");
200        put( "\u3060", "\uff80\uff9e");
201        put( "\u3062", "\uff81\uff9e");
202        put( "\u3065", "\uff82\uff9e");
203        put( "\u3067", "\uff83\uff9e");
204        put( "\u3069", "\uff84\uff9e");
205        put( "\u306a", "\uff85");
206        put( "\u306b", "\uff86");
207        put( "\u306c", "\uff87");
208        put( "\u306d", "\uff88");
209        put( "\u306e", "\uff89");
210        put( "\u306f", "\uff8a");
211        put( "\u3072", "\uff8b");
212        put( "\u3075", "\uff8c");
213        put( "\u3078", "\uff8d");
214        put( "\u307b", "\uff8e");
215        put( "\u3070", "\uff8a\uff9e");
216        put( "\u3073", "\uff8b\uff9e");
217        put( "\u3076", "\uff8c\uff9e");
218        put( "\u3079", "\uff8d\uff9e");
219        put( "\u307c", "\uff8e\uff9e");
220        put( "\u3071", "\uff8a\uff9f");
221        put( "\u3074", "\uff8b\uff9f");
222        put( "\u3077", "\uff8c\uff9f");
223        put( "\u307a", "\uff8d\uff9f");
224        put( "\u307d", "\uff8e\uff9f");
225        put( "\u307e", "\uff8f");
226        put( "\u307f", "\uff90");
227        put( "\u3080", "\uff91");
228        put( "\u3081", "\uff92");
229        put( "\u3082", "\uff93");
230        put( "\u3084", "\uff94");
231        put( "\u3086", "\uff95");
232        put( "\u3088", "\uff96");
233        put( "\u3083", "\uff6c");
234        put( "\u3085", "\uff6d");
235        put( "\u3087", "\uff6e");
236        put( "\u3089", "\uff97");
237        put( "\u308a", "\uff98");
238        put( "\u308b", "\uff99");
239        put( "\u308c", "\uff9a");
240        put( "\u308d", "\uff9b");
241        put( "\u308f", "\uff9c");
242        put( "\u3092", "\uff66");
243        put( "\u3093", "\uff9d");
244        put( "\u308e", "\uff9c");
245        put( "\u30fc", "\uff70");
246    }};
247
248    /** Conversion rule for full-width Katakana */
249    private static final HashMap<String,String> mFullKatakanaMap = new HashMap<String,String>() {{
250        put( "\u3042", "\u30a2");
251        put( "\u3044", "\u30a4");
252        put( "\u3046", "\u30a6");
253        put( "\u3048", "\u30a8");
254        put( "\u304a", "\u30aa");
255        put( "\u3041", "\u30a1");
256        put( "\u3043", "\u30a3");
257        put( "\u3045", "\u30a5");
258        put( "\u3047", "\u30a7");
259        put( "\u3049", "\u30a9");
260        put( "\u30f4\u3041", "\u30f4\u30a1");
261        put( "\u30f4\u3043", "\u30f4\u30a3");
262        put( "\u30f4", "\u30f4");
263        put( "\u30f4\u3047", "\u30f4\u30a7");
264        put( "\u30f4\u3049", "\u30f4\u30a9");
265        put( "\u304b", "\u30ab");
266        put( "\u304d", "\u30ad");
267        put( "\u304f", "\u30af");
268        put( "\u3051", "\u30b1");
269        put( "\u3053", "\u30b3");
270        put( "\u304c", "\u30ac");
271        put( "\u304e", "\u30ae");
272        put( "\u3050", "\u30b0");
273        put( "\u3052", "\u30b2");
274        put( "\u3054", "\u30b4");
275        put( "\u3055", "\u30b5");
276        put( "\u3057", "\u30b7");
277        put( "\u3059", "\u30b9");
278        put( "\u305b", "\u30bb");
279        put( "\u305d", "\u30bd");
280        put( "\u3056", "\u30b6");
281        put( "\u3058", "\u30b8");
282        put( "\u305a", "\u30ba");
283        put( "\u305c", "\u30bc");
284        put( "\u305e", "\u30be");
285        put( "\u305f", "\u30bf");
286        put( "\u3061", "\u30c1");
287        put( "\u3064", "\u30c4");
288        put( "\u3066", "\u30c6");
289        put( "\u3068", "\u30c8");
290        put( "\u3063", "\u30c3");
291        put( "\u3060", "\u30c0");
292        put( "\u3062", "\u30c2");
293        put( "\u3065", "\u30c5");
294        put( "\u3067", "\u30c7");
295        put( "\u3069", "\u30c9");
296        put( "\u306a", "\u30ca");
297        put( "\u306b", "\u30cb");
298        put( "\u306c", "\u30cc");
299        put( "\u306d", "\u30cd");
300        put( "\u306e", "\u30ce");
301        put( "\u306f", "\u30cf");
302        put( "\u3072", "\u30d2");
303        put( "\u3075", "\u30d5");
304        put( "\u3078", "\u30d8");
305        put( "\u307b", "\u30db");
306        put( "\u3070", "\u30d0");
307        put( "\u3073", "\u30d3");
308        put( "\u3076", "\u30d6");
309        put( "\u3079", "\u30d9");
310        put( "\u307c", "\u30dc");
311        put( "\u3071", "\u30d1");
312        put( "\u3074", "\u30d4");
313        put( "\u3077", "\u30d7");
314        put( "\u307a", "\u30da");
315        put( "\u307d", "\u30dd");
316        put( "\u307e", "\u30de");
317        put( "\u307f", "\u30df");
318        put( "\u3080", "\u30e0");
319        put( "\u3081", "\u30e1");
320        put( "\u3082", "\u30e2");
321        put( "\u3084", "\u30e4");
322        put( "\u3086", "\u30e6");
323        put( "\u3088", "\u30e8");
324        put( "\u3083", "\u30e3");
325        put( "\u3085", "\u30e5");
326        put( "\u3087", "\u30e7");
327        put( "\u3089", "\u30e9");
328        put( "\u308a", "\u30ea");
329        put( "\u308b", "\u30eb");
330        put( "\u308c", "\u30ec");
331        put( "\u308d", "\u30ed");
332        put( "\u308f", "\u30ef");
333        put( "\u3092", "\u30f2");
334        put( "\u3093", "\u30f3");
335        put( "\u308e", "\u30ee");
336        put( "\u30fc", "\u30fc");
337    }};
338
339    /** Conversion rule for half-width alphabet */
340    private static final HashMap<String,String> mHalfAlphabetMap = new HashMap<String,String>() {{
341        put( "\u3042", ".");
342        put( "\u3044", "@");
343        put( "\u3046", "-");
344        put( "\u3048", "_");
345        put( "\u304a", "/");
346        put( "\u3041", ":");
347        put( "\u3043", "~");
348        put( "\u304b", "A");
349        put( "\u304d", "B");
350        put( "\u304f", "C");
351        put( "\u3055", "D");
352        put( "\u3057", "E");
353        put( "\u3059", "F");
354        put( "\u305f", "G");
355        put( "\u3061", "H");
356        put( "\u3064", "I");
357        put( "\u306a", "J");
358        put( "\u306b", "K");
359        put( "\u306c", "L");
360        put( "\u306f", "M");
361        put( "\u3072", "N");
362        put( "\u3075", "O");
363        put( "\u307e", "P");
364        put( "\u307f", "Q");
365        put( "\u3080", "R");
366        put( "\u3081", "S");
367        put( "\u3084", "T");
368        put( "\u3086", "U");
369        put( "\u3088", "V");
370        put( "\u3089", "W");
371        put( "\u308a", "X");
372        put( "\u308b", "Y");
373        put( "\u308c", "Z");
374        put( "\u308f", "-");
375    }};
376
377    /** Conversion rule for full-width alphabet */
378    private static final HashMap<String,String> mFullAlphabetMap = new HashMap<String,String>() {{
379        put( "\u3042", "\uff0e");
380        put( "\u3044", "\uff20");
381        put( "\u3046", "\u30fc");
382        put( "\u3048", "\uff3f");
383        put( "\u304a", "\uff0f");
384        put( "\u3041", "\uff1a");
385        put( "\u3043", "\u301c");
386        put( "\u304b", "\uff21");
387        put( "\u304d", "\uff22" );
388        put( "\u304f", "\uff23");
389        put( "\u3055", "\uff24" );
390        put( "\u3057", "\uff25" );
391        put( "\u3059", "\uff26" );
392        put( "\u305f", "\uff27");
393        put( "\u3061", "\uff28" );
394        put( "\u3064", "\uff29");
395        put( "\u306a", "\uff2a");
396        put( "\u306b", "\uff2b" );
397        put( "\u306c", "\uff2c" );
398        put( "\u306f", "\uff2d");
399        put( "\u3072", "\uff2e");
400        put( "\u3075", "\uff2f");
401        put( "\u307e", "\uff30");
402        put( "\u307f", "\uff31");
403        put( "\u3080", "\uff32");
404        put( "\u3081", "\uff33" );
405        put( "\u3084", "\uff34" );
406        put( "\u3086", "\uff35" );
407        put( "\u3088", "\uff36" );
408        put( "\u3089", "\uff37" );
409        put( "\u308a", "\uff38" );
410        put( "\u308b", "\uff39");
411        put( "\u308c", "\uff3a" );
412        put( "\u308f", "\u30fc" );
413    }};
414
415    /** Conversion rule for full-width alphabet (QWERTY mode) */
416    private static final HashMap<String,String> mFullAlphabetMapQwety = new HashMap<String,String>() {{
417        put( "a", "\uff41");
418        put( "b", "\uff42");
419        put( "c", "\uff43");
420        put( "d", "\uff44");
421        put( "e", "\uff45");
422        put( "f", "\uff46");
423        put( "g", "\uff47");
424        put( "h", "\uff48");
425        put( "i", "\uff49");
426        put( "j", "\uff4a");
427        put( "k", "\uff4b");
428        put( "l", "\uff4c");
429        put( "m", "\uff4d");
430        put( "n", "\uff4e");
431        put( "o", "\uff4f");
432        put( "p", "\uff50");
433        put( "q", "\uff51");
434        put( "r", "\uff52");
435        put( "s", "\uff53");
436        put( "t", "\uff54");
437        put( "u", "\uff55");
438        put( "v", "\uff56");
439        put( "w", "\uff57");
440        put( "x", "\uff58");
441        put( "y", "\uff59");
442        put( "z", "\uff5a");
443
444        put( "A", "\uff21");
445        put( "B", "\uff22");
446        put( "C", "\uff23");
447        put( "D", "\uff24");
448        put( "E", "\uff25");
449        put( "F", "\uff26");
450        put( "G", "\uff27");
451        put( "H", "\uff28");
452        put( "I", "\uff29");
453        put( "J", "\uff2a");
454        put( "K", "\uff2b");
455        put( "L", "\uff2c");
456        put( "M", "\uff2d");
457        put( "N", "\uff2e");
458        put( "O", "\uff2f");
459        put( "P", "\uff30");
460        put( "Q", "\uff31");
461        put( "R", "\uff32");
462        put( "S", "\uff33");
463        put( "T", "\uff34");
464        put( "U", "\uff35");
465        put( "V", "\uff36");
466        put( "W", "\uff37");
467        put( "X", "\uff38");
468        put( "Y", "\uff39");
469        put( "Z", "\uff3a");
470    }};
471
472    /** Decimal format using comma */
473    private static final DecimalFormat mFormat = new DecimalFormat("###,###");
474
475    /** List of the generated candidates */
476    private List<WnnWord> mAddCandidateList;
477    /** Work area for generating string */
478    private StringBuffer mStringBuff;
479
480    /** part of speech (default) */
481    private WnnPOS mPosDefault;
482    /** part of speech (number) */
483    private WnnPOS mPosNumber;
484    /** part of speech (symbol) */
485    private WnnPOS mPosSymbol;
486
487    /**
488     * Constructor
489     */
490    public KanaConverter() {
491        mAddCandidateList = new ArrayList<WnnWord>();
492        mStringBuff = new StringBuffer();
493    }
494
495    /**
496     * Set The dictionary.
497     * <br>
498     * {@link KanaConverter} gets part-of-speech tags from the dictionary.
499     *
500     * @param dict  The dictionary
501     */
502    public void setDictionary(WnnDictionary dict) {
503        /* get part of speech tags */
504        mPosDefault  = dict.getPOS(WnnDictionary.POS_TYPE_MEISI);
505        mPosNumber   = dict.getPOS(WnnDictionary.POS_TYPE_SUUJI);
506        mPosSymbol   = dict.getPOS(WnnDictionary.POS_TYPE_KIGOU);
507    }
508
509    /**
510     * Create the pseudo candidate list
511     * <br>
512     * @param inputHiragana     The input string (Hiragana)
513     * @param inputRomaji       The input string (Romaji)
514     * @param keyBoardMode      The mode of keyboard
515     * @return                  The candidate list
516     */
517    public List<WnnWord> createPseudoCandidateList(String inputHiragana, String inputRomaji, int keyBoardMode) {
518        List<WnnWord> list = mAddCandidateList;
519
520        list.clear();
521        if (inputHiragana.length() == 0) {
522        	return list;
523        }
524
525        /* Create pseudo candidates for all keyboard type */
526        /* Hiragana(reading) / Full width katakana / Half width katakana */
527        list.add(new WnnWord(inputHiragana, inputHiragana));
528        if (createCandidateString(inputHiragana, mFullKatakanaMap, mStringBuff)) {
529            list.add(new WnnWord(mStringBuff.toString(), inputHiragana, mPosDefault));
530        }
531        if (createCandidateString(inputHiragana, mHalfKatakanaMap, mStringBuff)) {
532            list.add(new WnnWord(mStringBuff.toString(), inputHiragana, mPosDefault));
533        }
534
535        if (keyBoardMode == OpenWnnEngineJAJP.KEYBOARD_QWERTY) {
536            /* Create pseudo candidates for Qwerty keyboard */
537            createPseudoCandidateListForQwerty(inputHiragana, inputRomaji);
538        } else {
539            /* Create pseudo candidates for 12key */
540
541        	/* Create pseudo candidates for half width numeric */
542            if (createCandidateString(inputHiragana, mHalfNumericMap, mStringBuff)) {
543                String convHanSuuji = mStringBuff.toString();
544                String convNumComma = convertNumber(convHanSuuji);
545                list.add(new WnnWord(convHanSuuji, inputHiragana, mPosNumber));
546                if (convNumComma != null) {
547                    list.add(new WnnWord(convNumComma, inputHiragana, mPosNumber));
548                }
549            }
550
551            /* Create pseudo candidates for full width numeric */
552            if (createCandidateString(inputHiragana, mFullNumericMap, mStringBuff)) {
553                list.add(new WnnWord(mStringBuff.toString(), inputHiragana, mPosNumber));
554            }
555
556            /* Create pseudo candidates for half width alphabet */
557            if (createCandidateString(inputHiragana, mHalfAlphabetMap, mStringBuff)) {
558                String convHanEiji = mStringBuff.toString();
559                String convHanEijiLower = convHanEiji.toLowerCase();
560                list.add(new WnnWord(convHanEijiLower, inputHiragana, mPosSymbol));
561                list.add(new WnnWord(convertCaps(convHanEijiLower), inputHiragana, mPosSymbol));
562                list.add(new WnnWord(convHanEiji, inputHiragana, mPosSymbol));
563            }
564
565            /* Create pseudo candidates for full width alphabet */
566            if (createCandidateString(inputHiragana, mFullAlphabetMap, mStringBuff)) {
567                String convZenEiji = mStringBuff.toString();
568                String convZenEijiLower = convZenEiji.toLowerCase(Locale.JAPAN);
569                list.add(new WnnWord(convZenEijiLower, inputHiragana, mPosSymbol));
570                list.add(new WnnWord(convertCaps(convZenEijiLower), inputHiragana, mPosSymbol));
571                list.add(new WnnWord(convZenEiji, inputHiragana, mPosSymbol));
572            }
573        }
574        return list;
575    }
576
577    /**
578     * Create the pseudo candidate list for Qwerty keyboard
579     * <br>
580     * @param inputHiragana     The input string (Hiragana)
581     * @param inputRomaji       The input string (Romaji)
582     */
583    private void createPseudoCandidateListForQwerty(String inputHiragana, String inputRomaji) {
584        List<WnnWord> list = mAddCandidateList;
585
586        /* Create pseudo candidates for half width alphabet */
587        String convHanEijiLower = inputRomaji.toLowerCase();
588        list.add(new WnnWord(inputRomaji, inputHiragana, mPosDefault));
589        list.add(new WnnWord(convHanEijiLower, inputHiragana, mPosSymbol));
590        list.add(new WnnWord(convertCaps(convHanEijiLower), inputHiragana, mPosSymbol));
591        list.add(new WnnWord(inputRomaji.toUpperCase(), inputHiragana, mPosSymbol));
592
593        /* Create pseudo candidates for the full width alphabet */
594        if (createCandidateString(inputRomaji, mFullAlphabetMapQwety, mStringBuff)) {
595            String convZenEiji = mStringBuff.toString();
596            String convZenEijiLower = convZenEiji.toLowerCase(Locale.JAPAN);
597            list.add(new WnnWord(convZenEiji, inputHiragana, mPosSymbol));
598            list.add(new WnnWord(convZenEijiLower, inputHiragana, mPosSymbol));
599            list.add(new WnnWord(convertCaps(convZenEijiLower), inputHiragana, mPosSymbol));
600            list.add(new WnnWord(convZenEiji.toUpperCase(Locale.JAPAN), inputHiragana, mPosSymbol));
601        }
602    }
603
604    /**
605     * Create the candidate string
606     * <br>
607     * @param input     The input string
608     * @param map       The hash map
609     * @param outBuf    The output string
610     * @return          {@code true} if success
611     */
612    private boolean createCandidateString(String input, HashMap<String,String> map, StringBuffer outBuf) {
613        if (outBuf.length() > 0) {
614            outBuf.delete(0, outBuf.length());
615        }
616        for (int index = 0; index < input.length(); index++) {
617            String convChar = map.get(input.substring(index, index + 1));
618            if (convChar == null) {
619                return false;
620            }
621            outBuf.append(convChar);
622        }
623        return true;
624    }
625
626    /**
627     * Convert into both small and capital letter
628     * <br>
629     * @param moji  The input string
630     * @return      The converted string
631     */
632    private String convertCaps(String moji) {
633        String tmp = "";
634        if (moji != null && moji.length() > 0) {
635            tmp = moji.substring(0, 1).toUpperCase(Locale.JAPAN)
636                    + moji.substring(1).toLowerCase(Locale.JAPAN);
637        }
638        return tmp;
639    }
640
641    /**
642     * Convert the numeric into formatted string
643     * <br>
644     * @param numComma  The value
645     * @return          {@code true} if success
646     */
647    private String convertNumber(String numComma) {
648        try {
649            return mFormat.format(Double.parseDouble(numComma));
650        } catch (NumberFormatException e) {
651            return null;
652        }
653    }
654}
655