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
17#include "suggest/policyimpl/typing/typing_weighting.h"
18
19#include "suggest/core/dicnode/dic_node.h"
20#include "suggest/policyimpl/typing/scoring_params.h"
21
22namespace latinime {
23
24const TypingWeighting TypingWeighting::sInstance;
25
26ErrorTypeUtils::ErrorType TypingWeighting::getErrorType(const CorrectionType correctionType,
27        const DicTraverseSession *const traverseSession, const DicNode *const parentDicNode,
28        const DicNode *const dicNode) const {
29    switch (correctionType) {
30        case CT_MATCH:
31            if (isProximityDicNode(traverseSession, dicNode)) {
32                return ErrorTypeUtils::PROXIMITY_CORRECTION;
33            } else if (dicNode->isInDigraph()) {
34                return ErrorTypeUtils::MATCH_WITH_DIGRAPH;
35            } else {
36                // Compare the node code point with original primary code point on the keyboard.
37                const ProximityInfoState *const pInfoState =
38                        traverseSession->getProximityInfoState(0);
39                const int primaryOriginalCodePoint = pInfoState->getPrimaryOriginalCodePointAt(
40                        dicNode->getInputIndex(0));
41                const int nodeCodePoint = dicNode->getNodeCodePoint();
42                if (primaryOriginalCodePoint == nodeCodePoint) {
43                    // Node code point is same as original code point on the keyboard.
44                    return ErrorTypeUtils::NOT_AN_ERROR;
45                } else if (CharUtils::toLowerCase(primaryOriginalCodePoint) ==
46                        CharUtils::toLowerCase(nodeCodePoint)) {
47                    // Only cases of the code points are different.
48                    return ErrorTypeUtils::MATCH_WITH_CASE_ERROR;
49                } else if (CharUtils::toBaseCodePoint(primaryOriginalCodePoint) ==
50                        CharUtils::toBaseCodePoint(nodeCodePoint)) {
51                    // Node code point is a variant of original code point.
52                    return ErrorTypeUtils::MATCH_WITH_ACCENT_ERROR;
53                } else {
54                    // Node code point is a variant of original code point and the cases are also
55                    // different.
56                    return ErrorTypeUtils::MATCH_WITH_ACCENT_ERROR
57                            | ErrorTypeUtils::MATCH_WITH_CASE_ERROR;
58                }
59            }
60            break;
61        case CT_ADDITIONAL_PROXIMITY:
62            return  ErrorTypeUtils::PROXIMITY_CORRECTION;
63        case CT_OMISSION:
64            if (parentDicNode->canBeIntentionalOmission()) {
65                return ErrorTypeUtils::INTENTIONAL_OMISSION;
66            } else {
67                return ErrorTypeUtils::EDIT_CORRECTION;
68            }
69            break;
70        case CT_SUBSTITUTION:
71        case CT_INSERTION:
72        case CT_TERMINAL_INSERTION:
73        case CT_TRANSPOSITION:
74            return ErrorTypeUtils::EDIT_CORRECTION;
75        case CT_NEW_WORD_SPACE_OMISSION:
76        case CT_NEW_WORD_SPACE_SUBSTITUTION:
77            return ErrorTypeUtils::NEW_WORD;
78        case CT_TERMINAL:
79            return ErrorTypeUtils::NOT_AN_ERROR;
80        case CT_COMPLETION:
81            return ErrorTypeUtils::COMPLETION;
82        default:
83            return ErrorTypeUtils::NOT_AN_ERROR;
84    }
85}
86}  // namespace latinime
87