1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "normal_scene.h"
17
18#include "tree_manager.h"
19
20namespace OHOS {
21namespace WuKong {
22namespace {
23const int MAXINPUTNUM = 3;
24const int ONEHUNDRED = 100;
25const int NEWPERCENT = 75;
26const int OLDPERCENT = 20;
27}  // namespace
28NormalScene::NormalScene()
29{
30}
31
32NormalScene::~NormalScene()
33{
34}
35ErrCode NormalScene::SetInputComponentList(std::vector<std::shared_ptr<ComponentTree>> &componentList)
36{
37    ErrCode result = OHOS::ERR_OK;
38    int randomNumber = rand() % ONEHUNDRED;
39    uint32_t count = 0;
40    DEBUG_LOG_STR("randomNumber: %d", randomNumber);
41    std::vector<uint32_t> indexList;
42    auto util = WuKongUtil::GetInstance();
43    std::vector<std::string> compIdBlock = util->GetCompIdBlockList();
44    std::vector<std::string> compTypeBlock = util->GetCompTypeBlockList();
45    if (randomNumber < NEWPERCENT) {
46        for (auto it = componentList.begin(); it != componentList.end(); it++) {
47            TRACK_LOG_STR("component inputcount: %d", (*it)->GetInputCount());
48            if ((*it)->GetInputCount() > MAXINPUTNUM || IsComponentBlock((*it), compIdBlock, compTypeBlock)) {
49                indexList.push_back((*it)->GetIndex());
50                TRACK_LOG_STR("index0: %d", distance(componentList.begin(), it));
51            }
52        }
53    } else if (randomNumber < (NEWPERCENT + OLDPERCENT)) {
54        for (auto it = componentList.begin(); it != componentList.end(); it++) {
55            TRACK_LOG_STR("component inputcount: %d", (*it)->GetInputCount());
56            if ((*it)->GetInputCount() <= MAXINPUTNUM || IsComponentBlock((*it), compIdBlock, compTypeBlock)) {
57                count++;
58                TRACK_LOG_STR("inputed count: %d, componentList size: %d", count, componentList.size());
59                indexList.push_back((*it)->GetIndex());
60                TRACK_LOG_STR("index: %d", distance(componentList.begin(), it));
61            }
62        }
63    }
64    if (count >= componentList.size()) {
65        if ((componentList.size() == 0) || (randomNumber < ONEHUNDRED && randomNumber >= (NEWPERCENT + OLDPERCENT))) {
66            isBack_ = true;
67        } else {
68            SubtractComponent(componentList, indexList);
69        }
70        indexList.clear();
71        return OHOS::ERR_OK;
72    }
73    TRACK_LOG_STR("componentList size: %d", componentList.size());
74    TRACK_LOG_STR("indexList size: %d", indexList.size());
75    SubtractComponent(componentList, indexList);
76    if ((componentList.size() == 0) || (randomNumber < ONEHUNDRED && randomNumber >= (NEWPERCENT + OLDPERCENT))) {
77        isBack_ = true;
78    }
79    indexList.clear();
80    return result;
81}
82
83ErrCode NormalScene::SetInputComponent(std::vector<std::shared_ptr<ComponentTree>> &componentList,
84                                       std::shared_ptr<ComponentTree> &componentinfo)
85{
86    auto util = WuKongUtil::GetInstance();
87    std::vector<std::string> compIdBlock = util->GetCompIdBlockList();
88    std::vector<std::string> compTypeBlock = util->GetCompTypeBlockList();
89    ErrCode result = OHOS::ERR_OK;
90    if (!componentList.empty()) {
91        auto treemanager = TreeManager::GetInstance();
92        bool hasDialog = treemanager->HasDialog();
93        bool meetDialog = false;
94        for (auto it : componentList) {
95            if (it->GetType() == "Dialog") {
96                meetDialog = true;
97            }
98            if (hasDialog && !meetDialog) {
99                continue;
100            }
101            DEBUG_LOG_STR("component inputcount: %d, node id: %016llX", it->GetInputCount(), it->GetNodeId());
102            if (it->GetInputCount() < 1 && !IsComponentBlock(it, compIdBlock, compTypeBlock)) {
103                componentinfo = it;
104                break;
105            }
106        }
107    }
108    if (componentinfo == nullptr) {
109        isBack_ = true;
110    }
111    return result;
112}
113
114ErrCode NormalScene::SetInputComponentListForFocusInput(std::vector<std::shared_ptr<ComponentTree>> &componentList)
115{
116    ErrCode result = OHOS::ERR_OK;
117    uint32_t count = 0;
118    std::vector<uint32_t> indexList;
119    auto treemanager = TreeManager::GetInstance();
120    uint32_t focusNum = treemanager->GetFocusNum();
121    auto util = WuKongUtil::GetInstance();
122    std::vector<std::string> compIdBlock = util->GetCompIdBlockList();
123    std::vector<std::string> compTypeBlock = util->GetCompTypeBlockList();
124    for (auto it = componentList.begin(); it != componentList.end(); it++) {
125        TRACK_LOG_STR("component inputcount: %d", (*it)->GetInputCount());
126        std::string type = (*it)->GetType();
127        bool needFocus = treemanager->NeedFocus(type);
128        uint32_t limit = needFocus ? focusNum : MAXINPUTNUM;
129        if ((*it)->GetInputCount() >= limit || IsComponentBlock((*it), compIdBlock, compTypeBlock)) {
130            indexList.push_back((*it)->GetIndex());
131            count++;
132            TRACK_LOG_STR("index0: %d", distance(componentList.begin(), it));
133        }
134    }
135    if (count >= componentList.size()) {
136        isBack_ = true;
137        indexList.clear();
138        return OHOS::ERR_OK;
139    }
140    // just determine back or not, can not remove component because of locating component after
141    if (componentList.size() == 0) {
142        isBack_ = true;
143    }
144    indexList.clear();
145    return result;
146}
147
148void NormalScene::SubtractComponent(std::vector<std::shared_ptr<ComponentTree>> &componentList,
149    std::vector<uint32_t> &indexList)
150{
151    for (auto index : indexList) {
152        for (auto it = componentList.begin(); it != componentList.end(); it++) {
153            if ((*it)->GetIndex() == index) {
154                componentList.erase(it);
155                it--;
156            }
157        }
158    }
159}
160
161bool NormalScene::IsComponentBlock(std::shared_ptr<ComponentTree> &comp, std::vector<std::string> &compIdBlock,
162    std::vector<std::string> &compTypeBlock)
163{
164    std::string id = comp->GetInspectorKey();
165    std::string type = comp->GetType();
166    auto util = WuKongUtil::GetInstance();
167    if (util->ContainsElement(compIdBlock, id)) {
168        DEBUG_LOG_STR("Block Id: %s", id.c_str());
169        return true;
170    }
171    if (util->ContainsElement(compTypeBlock, type)) {
172        DEBUG_LOG_STR("Block type: %s", type.c_str());
173        return true;
174    }
175    DEBUG_LOG_STR("UnBlock Id: %s, type: %s", id.c_str(), type.c_str());
176    return false;
177}
178}  // namespace WuKong
179}  // namespace OHOS
180