#include "Vendor_Interface.h"
#include "TZ_Vendor_tl.h"
#include "TZ_Vendor_debug_tl.h"
#include "tl_tui_bc_error_msg.h"

#include "TuiButton.h"
#include "TuiKeypad.h"
#include "TuiTextBox.h"
#include "TuiImageView.h"
#include "TuiRestoreScreenController.h"
#include "TuiMnemonic.h"
#include "TuiState.h"
#include "TuiScreenResource.h"
#include "SecureObject.h"
#include "TuiPng.h"
#include "TuiLayout.h"
#include "TuiScreen.h"

uint32_t updateMnemonicTextView(uint8_t* text);
bool isLastMnemonic(Node* node);
void disableDeleteButton(void);

static uint8_t emptyString[1] = { '\0' };

ControlGroup gGroupMnemonicList;
ControlGroup gGroupRecommendList;

Node gRestoreScreenControlNode[MAX_CONTROL];

uint32_t initRestoreScreenController() {
	initLayout();
	createMnemonicTree();
	initTextBuffer();
	
	return TIMA_SUCCESS;
}

Node* getRestoreScreenControlNode() {
	return gRestoreScreenControlNode;
}

void drawTextInputActivated() {
	uint32_t resourceSize = 0;
	drawImage(RESTORE_MNEMONIC_TEXTINPUT_START_X, RESTORE_MNEMONIC_TEXTINPUT_LINE_START_Y, getScreenResource(ID_RESOURCE_RESTORE_TEXT_INPUT_ACTIVATED, &resourceSize), resourceSize);
}

void drawTextInputError() {
	uint32_t resourceSize = 0;
	drawImage(RESTORE_MNEMONIC_TEXTINPUT_START_X, RESTORE_MNEMONIC_TEXTINPUT_LINE_START_Y, getScreenResource(ID_RESOURCE_RESTORE_TEXT_INPUT_ERROR, &resourceSize), resourceSize);
}

uint32_t drawRestoreScreen() {
	Control control;
	Location loc;
	uint32_t controlId = 1;
	TextInfo textInfo;
	uint32_t eventImgSize = 0;
	uint32_t originImgSize = 0;
	uint8_t* originImageBuffer;
	uint8_t* eventImageBuffer;

	loc.x1 = RESTORE_MNEMONIC_TEXTINPUT_START_X;
	loc.y1 = RESTORE_MNEMONIC_TEXTINPUT_START_Y;
	textInfo.text = emptyString;
	textInfo.font = getScreenFontType(ID_FONT_TYPE_RESTORE_MNEMONIC_INPUT);
	drawTextInputActivated();
	initTextBox(&control, controlId++, loc, RESTORE_MNEMONIC_TEXTINPUT_WIDTH, RESTORE_MNEMONIC_TEXTINPUT_HEIGHT,
		NULL, 0, getScreenResource(ID_RESOURCE_RESTORE_TEXT_INPUT_CLEAR, &originImgSize), originImgSize, textInfo, LEFT_CONTENT_ALIGN, VERTICAL_CENTER_CONTENT_ALIGN);
	addTextEditBox(&control, executeTextEditMnemonicWord);

	loc.x1 = RESTORE_MNEMONIC_LIST_TEXT_AREA_SIDE_MARGIN;
	loc.y1 = RESTORE_MNEMONIC_LIST_TEXT_AREA_TOP_MARGIN;
	initImageView(&control, controlId++, loc, RESTORE_MNEMONIC_LIST_TEXT_AREA_WIDTH, RESTORE_MNEMONIC_LIST_TEXT_AREA_HEIGHT,
		NULL, 0, getScreenResource(ID_RESOURCE_RESTORE_PHARSE_TEXTAREA, &originImgSize), originImgSize);
	addImageView(&control);

	uint32_t listSize = RESTORE_MNEMONIC_LIST_MAX_COUNT;
	uint32_t listLine, listColumn;
	uint32_t listWidth = SCREEN_WIDTH - (RESTORE_MNEMONIC_LIST_SIDE_MARGIN * 2);
	uint32_t listDistance = (listWidth - (RESTORE_MNEMONIC_TEXTBOX_WIDTH * RESTORE_MNEMONIC_LIST_COLUMN_COUNT)) / (RESTORE_MNEMONIC_LIST_COLUMN_COUNT - 1);
	
	gGroupMnemonicList.startId = controlId;
	gGroupMnemonicList.groupSize = RESTORE_MNEMONIC_LIST_MAX_COUNT;
	for (uint32_t i = 0; i < listSize; i++) {
		if (i == 0) {
			listLine = i;
			listColumn = i;
		} else {
			listLine = i / RESTORE_MNEMONIC_LIST_COLUMN_COUNT;
			listColumn = i % RESTORE_MNEMONIC_LIST_COLUMN_COUNT;
		}
		DBG_LOG("listLine : %d", listLine);
		DBG_LOG("listColumn : %d", listColumn);
		loc.x1 = RESTORE_MNEMONIC_LIST_SIDE_MARGIN + ((RESTORE_MNEMONIC_TEXTBOX_WIDTH + listDistance) * listColumn);
		loc.y1 = RESTORE_MNEMONIC_LIST_TOP_MARGIN + ((RESTORE_MNEMONIC_TEXTBOX_HEIGHT + RESTORE_MNEMONIC_LIST_LINE_DISTANCE) * listLine);
		DBG_LOG("List loc : %d, %d", loc.x1, loc.y1);
		textInfo.text = emptyString;
		textInfo.font = getScreenFontType(ID_FONT_TYPE_RESTORE_MNEMONIC_LIST);

		originImageBuffer = getScreenResource(ID_RESOURCE_RESTORE_WORD_BG, &originImgSize);
		eventImageBuffer = getScreenResource(ID_RESOURCE_RESTORE_WORD_FOCUS_BG, &eventImgSize);

		initTextBox(&control, controlId++, loc, RESTORE_MNEMONIC_TEXTBOX_WIDTH, RESTORE_MNEMONIC_TEXTBOX_HEIGHT, 
			eventImageBuffer, eventImgSize, originImageBuffer, originImgSize, textInfo, CENTER_CONTENT_ALIGN, VERTICAL_CENTER_CONTENT_ALIGN);

		control.isDrawingWhenAdded = 0;
		control.isTouchable = 1;
		addTextViewBox(&control, executeTextViewMnemonicList);
	}

	uint32_t rcmdLine, rcmdColumn;
	uint32_t rcmdWidth = SCREEN_WIDTH - (RESTORE_MNEMONIC_RECOMMEND_SIDE_MARGIN * 2);
	uint32_t rcmdDistance = (rcmdWidth - ((RESTORE_MNEMONIC_RECOMMEND_WIDTH * RESTORE_MNEMONIC_RECOMMEND_COLUMN_COUNT) + RESTORE_MNEMONIC_RECOMMEND_MORE_WIDTH)) / (RESTORE_MNEMONIC_RECOMMEND_COLUMN_COUNT + 1);

	gGroupRecommendList.startId = controlId;
	gGroupRecommendList.groupSize = RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT + 1;
	for (uint32_t i = 0; i < RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT + 1; i++) {
		if (i == 0) {
			rcmdLine = i;
			rcmdColumn = i;
		} else {
			rcmdLine = i / (RESTORE_MNEMONIC_RECOMMEND_COLUMN_COUNT + 1);
			rcmdColumn = i % (RESTORE_MNEMONIC_RECOMMEND_COLUMN_COUNT + 1);
		}
		DBG_LOG("rcmdLine : %d", rcmdLine);
		DBG_LOG("rcmdColumn : %d", rcmdColumn);
		DBG_LOG("rcmdDistance : %d", rcmdDistance);
		loc.x1 = RESTORE_MNEMONIC_RECOMMEND_SIDE_MARGIN + ((RESTORE_MNEMONIC_RECOMMEND_WIDTH + rcmdDistance) * rcmdColumn);
		loc.y1 = RESTORE_MNEMONIC_RECOMMEND_TOP_MARGIN + ((RESTORE_MNEMONIC_RECOMMEND_HEIGHT + RESTORE_MNEMONIC_RECOMMEND_LINE_DISTANCE) * rcmdLine);
		DBG_LOG("Recommend loc : %d, %d", loc.x1, loc.y1);
		textInfo.text = emptyString;
		textInfo.font = getScreenFontType(ID_FONT_TYPE_RESTORE_MNEMONIC_RECOMMEND);

		if (i == RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT) {
            loc.y1 += (RESTORE_MNEMONIC_RECOMMEND_HEIGHT - RESTORE_MNEMONIC_RECOMMEND_MORE_HEIGHT)/2;
			initImageView(&control, controlId++, loc, RESTORE_MNEMONIC_RECOMMEND_MORE_WIDTH, RESTORE_MNEMONIC_RECOMMEND_MORE_HEIGHT,
				getScreenResource(ID_RESOURCE_RESTORE_RECOMMEND_CLEAR, &eventImgSize), eventImgSize, getScreenResource(ID_RESOURCE_RESTORE_RECOMMEND_MORE, &originImgSize), originImgSize);
			control.isDrawingWhenAdded = 0;
			control.isTouchable = 1;
			addImageView(&control);
		} else {
		    initTextBox(&control, controlId++, loc, RESTORE_MNEMONIC_RECOMMEND_WIDTH, RESTORE_MNEMONIC_RECOMMEND_HEIGHT,
			    NULL, 0, getScreenResource(ID_RESOURCE_RESTORE_RECOMMEND_CLEAR, &originImgSize), originImgSize, textInfo, CENTER_CONTENT_ALIGN, VERTICAL_CENTER_CONTENT_ALIGN);
			control.isDrawingWhenAdded = 0;
			control.isTouchable = 1;
			addTextViewBox(&control, executeTextViewRecommendList);
		}
	}

	loc.x1 = RESTORE_KEYPAD_START_X;
	loc.y1 = RESTORE_KEYPAD_START_Y;

	initKeypad(&control, loc);
	addKeypad(&control);

	return TIMA_SUCCESS;
}

void setEnableButtonEnterMnemonic() {
	Node* node = pickingControlById(ID_CONTROL_BUTTON_RESTORE_ENTER);
	if (node == NULL || node->control.state == ENABLE_CONTROL_STATE) {
		return;
	}
	node->control.state = ENABLE_CONTROL_STATE;
	drawButton(&node->control);
}

void setDisableButtonEnterMnemonic() {
	Node* node = pickingControlById(ID_CONTROL_BUTTON_RESTORE_ENTER);
	if (node == NULL || node->control.state == DISABLE_CONTROL_STATE) {
		return;
	}
	node->control.state = DISABLE_CONTROL_STATE;
	drawButton(&node->control);
}

void setEnableButtonNext() {
	Node* node = pickingControlById(ID_CONTROL_BUTTON_RESTORE_NEXT);
	if (node == NULL || node->control.state == ENABLE_CONTROL_STATE) {
		return;
	}
	node->control.state = ENABLE_CONTROL_STATE;
	drawButton(&node->control);
}

void setDisableButtonNext() {
	Node* node = pickingControlById(ID_CONTROL_BUTTON_RESTORE_NEXT);
	if (node == NULL || node->control.state == DISABLE_CONTROL_STATE) {
		return;
	}
	node->control.state = DISABLE_CONTROL_STATE;
	drawButton(&node->control);
}

void updateStateButtonNext() {
	uint32_t strLen = 0;
	uint32_t count = 0;
	Node* mnemonicNode = pickingControlById(gGroupMnemonicList.startId);

	for (count = 0; count < gGroupMnemonicList.groupSize; count++) {
		strLen = strlen((char *)mnemonicNode->control.textInfo.text);
		if (strLen == 0) {
			break;
		}
		mnemonicNode = mnemonicNode->next;
	}
	DBG_LOG("updateStateButtonNext : %d", count);
	if (count >= 12 && count % 3 == 0) {
		setEnableButtonNext();
	} else {
		setDisableButtonNext();
	}
}

//delete word
ResponseControl executeWordDeleteButton(Control *control) {
	DBG_LOG("executeWordDeleteButton");
	Node* node;
	ResponseControl rc;
	initResponseControl(&rc);

	uint8_t* resource;
	uint32_t resourceSize = 0;
	Node* iNode;

	switch (control->state) {
	case RELEASED_CONTROL_STATE:
		node = pickingFocusedControl(TEXT_VIEW_BOX_CONTROL_TYPE);
		if (node == NULL)
			return rc;
		
		//
		deleteControl(ID_RESOURCE_RESTORE_BUTTON_DELETE_WORD);
		resource = getScreenResource(ID_RESOURCE_RESTORE_WORD_CLEAR, &resourceSize);
		setFocus(&node->control, FALSE);
		disableDeleteButton();

		for (iNode = node ; iNode != NULL; iNode = iNode->next) {
			updateText(&iNode->control, emptyString);

			if (strlen((char*)iNode->next->control.textInfo.text) == 0 || isLastMnemonic(iNode)) { // itor next empty or ...
				//last
				updateText(&iNode->control, emptyString);
				iNode->control.originResource = resource;
				iNode->control.originResourceSize = resourceSize;
				drawImage(iNode->control.location.x1, iNode->control.location.y1, iNode->control.originResource, iNode->control.originResourceSize);
				break;
			}
			strcpy((char*)iNode->control.textInfo.text, (char*)iNode->next->control.textInfo.text);
			drawTextBox(&iNode->control);
		}
		
		clearTextEdit(getScreenResource(ID_RESOURCE_RESTORE_TEXT_INPUT_CLEAR, &resourceSize), resourceSize);
		clearRecommendList();
		updateStateButtonNext();
		break;
	case PRESSED_CONTROL_STATE:
		break;
	default:
		TTY_LOG("%s unknown state", LOG_TAG);
		break;
	}
	return rc;
}
void disableDeleteButton() {
	Node* node = pickingControlById(ID_CONTROL_BUTTON_RESTORE_DELETE_WORD);
	if (node != NULL) {
		node->control.state = INVISIBLE_CONTROL_STATE;
	}
}

void enableDeleteButton(Control *textBoxControl) {
	Control control;
	uint32_t resourceWidth, resourceHeight;
	uint32_t resourceSize;
	uint8_t* resource;

	Node* deleteButtonNode = pickingControlById(ID_CONTROL_BUTTON_RESTORE_DELETE_WORD);
	resource = getScreenResource(ID_RESOURCE_RESTORE_BUTTON_DELETE_WORD, &resourceSize);
	getPngWidthAndHeight(resource, &resourceWidth, &resourceHeight);

	if (deleteButtonNode != NULL) {
		deleteButtonNode->control.state = ENABLE_CONTROL_STATE;
		deleteButtonNode->control.location.x1 = textBoxControl->location.x1 + textBoxControl->width - resourceWidth - SCREEN_PIX_PER_DP * 1;
		deleteButtonNode->control.location.y1 = textBoxControl->location.y1;
		drawButton(&deleteButtonNode->control);
	} else {
		control.location.x1 = textBoxControl->location.x1 + textBoxControl->width - resourceWidth - SCREEN_PIX_PER_DP * 1;
		control.location.y1 = textBoxControl->location.y1;
		initButton(&control, ID_CONTROL_BUTTON_RESTORE_DELETE_WORD, control.location, resourceWidth, resourceHeight, resource, resourceSize, resource, resourceSize, NULL, 0, 0);
		addButton(&control, &executeWordDeleteButton);
	}
}

bool isMnemonicTextView(Control* control) {
	if (control != NULL && control->id >= gGroupMnemonicList.startId && control->id < gGroupMnemonicList.startId + gGroupMnemonicList.groupSize) {
		return true;
	}
	return false;
}

bool isLastMnemonic(Node* node) {
	if (node->next == NULL || node->next->control.id >= gGroupMnemonicList.startId + gGroupMnemonicList.groupSize) {
		return true;
	}
	return false;
}

// click word
ResponseControl executeTextViewMnemonicList(Control *control) {
	DBG_LOG("executeTextViewMnemonicList");
	ResponseControl rc;
	initResponseControl(&rc);

	Node* focusViewNode;
	uint32_t resourceSize = 0;

	switch (control->state) {
	case PRESSED_CONTROL_STATE:
		break;
	case RELEASED_CONTROL_STATE:
		if (strcmp((char*)control->textInfo.text, (char *)emptyString) == 0) { //check empty string
			break;
		}

		focusViewNode = pickingFocusedControl(TEXT_VIEW_BOX_CONTROL_TYPE);
		if (focusViewNode != NULL) {
			//check duplicated focus
			if (focusViewNode->control.id == control->id) {
				DBG_LOG("%s Don't need to move focus", LOG_TAG);
				break;
			}
			if (isMnemonicTextView(control) != true) {
				break;
			}
			//unfocusing
			deleteControl(ID_RESOURCE_RESTORE_BUTTON_DELETE_WORD);
			disableDeleteButton();
			setFocus(&focusViewNode->control, FALSE);
			focusViewNode->control.state = RELEASED_CONTROL_STATE;
			drawTextBox(&focusViewNode->control);
		}
		else {
			//check empty view
			if (strlen((char*)control->textInfo.text) == 0) {
				return rc;
			}
		}

		//draw focusView
		setFocus(control, TRUE);
		deleteControl(ID_RESOURCE_RESTORE_BUTTON_DELETE_WORD);
		drawTextBox(control);
		enableDeleteButton(control);
		
		//update editbox control
		if (control->textInfo.text != NULL && ((char *)control->textInfo.text) != 0) {
			Node* textEditNode = pickingFocusedControl(TEXT_EDIT_BOX_CONTROL_TYPE);
			if (textEditNode != NULL) {
				clearTextEdit(getScreenResource(ID_RESOURCE_RESTORE_TEXT_INPUT_CLEAR, &resourceSize), resourceSize);
				bool updated = updateText(&(textEditNode->control), control->textInfo.text);
				drawTextBox(&(textEditNode->control));
				if (updated == true) {
					drawRecommendList(control->textInfo.text);
				}
			} else {
				TTY_LOG("Focused TextEdit is null");
			}
		} else {
			clearTextEdit(getScreenResource(ID_RESOURCE_RESTORE_TEXT_INPUT_CLEAR, &resourceSize), resourceSize);
		}
		break;
	default:
		break;
	}
	return rc;
}

// click recommendList, need to refactoring
void updateMnemonic(uint8_t* text) {
	Node* focusedTextViewNode = pickingFocusedControl(TEXT_VIEW_BOX_CONTROL_TYPE);

	Node* node = NULL;
	Node* TextViewStartNode = pickingControlById(gGroupMnemonicList.startId);
	uint32_t originImgSize = 0;
	uint8_t* originImageBuffer = getScreenResource(ID_RESOURCE_RESTORE_WORD_BG, &originImgSize);

	if (focusedTextViewNode == NULL) {
		for (node = TextViewStartNode; isMnemonicTextView(&node->control); node = node->next) {
			if (strlen((char*)node->control.textInfo.text) == 0) {
				copyTextBuffer(node->control.textInfo.text, text);
				node->control.state = ENABLE_CONTROL_STATE;
				node->control.originResource = originImageBuffer;
				node->control.originResourceSize = originImgSize;
				drawTextBox(&node->control);
				return;
			}
		}
		return;
	}

	//has focus
	setFocus(&focusedTextViewNode->control, FALSE);
	copyTextBuffer(focusedTextViewNode->control.textInfo.text, text);
	focusedTextViewNode->control.state = ENABLE_CONTROL_STATE;
	drawTextBox(&focusedTextViewNode->control);
}

// click recommend list
ResponseControl executeTextViewRecommendList(Control *control) {
	DBG_LOG("executeTextViewRecommendList");
	ResponseControl rc;
	initResponseControl(&rc);
	
	uint32_t resourceSize = 0;
	switch (control->state) {
	case RELEASED_CONTROL_STATE:
		updateMnemonicTextView(control->textInfo.text);
		clearTextEdit(getScreenResource(ID_RESOURCE_RESTORE_TEXT_INPUT_CLEAR, &resourceSize), resourceSize);
		clearRecommendList();
		updateStateButtonNext();
		break;
	default:
		break;
	}
	return rc;
}

void clearWrongInputMnemonicMsg() {
	Node* node = pickingControlById(ID_CONTROL_IMAGE_VIEW_RESTORE_WRONG_INPUT);
	if (node == NULL) {
		DBG_LOG("ID_CONTROL_MSG_WRONG_INPUT_MNEMONIC is NULL");
		return;
	}

	clearImageView(&(node->control));
}

void clearErrorMsg() {
	clearWrongInputMnemonicMsg();
}

ResponseControl executeTextEditMnemonicWord(Control *control) {
	DBG_LOG("executeTextEditMnemonicWord");
	ResponseControl rc;
	initResponseControl(&rc);

	Node* messageNode;
	Node* recommendNode;
	uint32_t recommendCount = 0;
	uint32_t textLen = 0;
	uint32_t textWidth = 0;
	uint32_t textHeight = 0;
	switch (control->state) {
	case UPDATED_CONTROL_STATE:
		setFocus(control, TRUE);
		getTextWidthAndHeight(control->textInfo.text, control->textInfo.font, &textWidth, &textHeight);
		textLen = strlen((char *)control->textInfo.text);
		if (textLen >= RECOMMEND_MNEMONIC_INPUT_CHAR_COUNT) {
			updateBufferCursorWithMargin(control->location.x1 + textWidth, control->location.y1, RESTORE_MNEMONIC_TEXTINPUT_CURSOR_MARGIN);
			recommendCount = drawRecommendList(control->textInfo.text);
			if (recommendCount > 0) {
				drawTextInputActivated();
			} else {
				drawTextInputError();
				messageNode = pickingControlById(ID_CONTROL_IMAGE_VIEW_RESTORE_WRONG_INPUT);
				if (messageNode == NULL || messageNode->control.originResourceSize == 0) {
					changeState(REQUEST_TEXT_RESTORE_WRONG_INPUT_TUI_STATE);
				} else {
					messageNode->control.state = ENABLE_CONTROL_STATE;
					drawImageView(&(messageNode->control));
				}
			}
		} else {
			if (textLen == 0) {
				updateBufferCursor(control->location.x1, control->location.y1);
			} else {
				updateBufferCursorWithMargin(control->location.x1 + textWidth, control->location.y1, RESTORE_MNEMONIC_TEXTINPUT_CURSOR_MARGIN);
			}
			clearErrorMsg();
			clearRecommendList();
			drawTextInputActivated();
		}

		recommendNode = pickingControlById(gGroupRecommendList.startId);
		if (recommendNode != NULL && recommendNode->control.state == ENABLE_CONTROL_STATE 
					&& strcmp((char *)recommendNode->control.textInfo.text, (char *)control->textInfo.text) == 0) {
			setEnableButtonEnterMnemonic();
		} else {
			setDisableButtonEnterMnemonic();
		}
		break;
	default:
		break;
	}

	return rc;
}

uint32_t updateMnemonicTextView(uint8_t* text) {
	disableDeleteButton();
	updateMnemonic(text);

	return SUCCESS_BC_TUI;
}

//click enter(next)
ResponseControl executeButtonEnterMnemonic(Control *control) {
	DBG_LOG("executeButtonEnterMnemonic");
	ResponseControl rc;
	initResponseControl(&rc);

	Node* recommendNode;
	uint32_t resourceSize = 0;
	Node* textEditNode = NULL;

	switch (control->state) {
	case RELEASED_CONTROL_STATE:
		drawButton(control);
		textEditNode = pickingFocusedControl(TEXT_EDIT_BOX_CONTROL_TYPE);

		recommendNode = pickingControlById(gGroupRecommendList.startId);
		if (recommendNode->control.state != DISABLE_CONTROL_STATE && recommendNode->control.state != INVISIBLE_CONTROL_STATE) {
			if (strcmp((char *)recommendNode->control.textInfo.text, (char *)textEditNode->control.textInfo.text) == 0) {
				updateMnemonicTextView(textEditNode->control.textInfo.text);
				clearTextEdit(getScreenResource(ID_RESOURCE_RESTORE_TEXT_INPUT_CLEAR, &resourceSize), resourceSize);
				clearRecommendList();
				updateStateButtonNext();
			}
		}
		break;
	case PRESSED_CONTROL_STATE:
		drawButton(control);
		break;
	default:
		break;
	}
	return rc;
}

//next button.
ResponseControl executeButtonNext(Control *control) {
	DBG_LOG("executeButtonNext");
	ResponseControl rc;
	initResponseControl(&rc);

	Node* mnemonicNode;
	uint8_t mnemonicList[2048];
	uint32_t listIndex = 0;
	uint32_t strLen = 0;
	switch (control->state) {
	case PRESSED_CONTROL_STATE:
		drawButton(control);
		break;

	case RELEASED_CONTROL_STATE:
		drawButton(control);

		memset(mnemonicList, '\0', sizeof(mnemonicList));
		mnemonicNode = pickingControlById(gGroupMnemonicList.startId);
		for (uint32_t i = 0; i < gGroupMnemonicList.groupSize; i++) {
			strLen = strlen((char *)mnemonicNode->control.textInfo.text);
			if (strLen != 0) {
				DBG_LOG("%s mne : %s", LOG_TAG, mnemonicNode->control.textInfo.text);
				if (i != 0) {
					mnemonicList[listIndex++] = ' ';
				}
				memcpy(mnemonicList + listIndex, mnemonicNode->control.textInfo.text, strLen);
				listIndex += strLen;
			}
			mnemonicNode = mnemonicNode->next;
		}

		if (!mnemonicCheck(mnemonicList)) {
			TTY_LOG("Failed checksum for MnemonicList");
			changeScreenState(POPUP_SCREEN_RESTORE_FAILED_CHECKSUM_STATE);
			return rc;
		}
		DBG_LOG("%s mne size : %d, all : %s", LOG_TAG, strlen((char *)mnemonicList), mnemonicList);
		setOutputSoData(mnemonicList, strlen((char *)mnemonicList));
		rc.changeState = RESTORED_TUI_STATE;
		break;
	default:
		break;
	}
	return rc;
}

int32_t drawRecommendList(uint8_t* key) {
	DBG_LOG("drawRecommendList()");
	//uint8_t* recommendList[RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT + 1];
	uint8_t **recommendList = (uint8_t **)TZ_malloc((sizeof(uint8_t *))*(RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT+1));

	if (strlen((char *)key) < RECOMMEND_MNEMONIC_INPUT_CHAR_COUNT) {
		DBG_LOG("Input count is not enough");
		TZ_free(recommendList);
		return 0;
	}

	Node* node = pickingControlById(gGroupRecommendList.startId);
	if (node == NULL) {
		TTY_LOG("RecommendControl is NULL");
		TZ_free(recommendList);
		return 0;
	}

	int32_t count = 0;
	uint32_t resourceSize = 0;
	getRecommendWordList(key, recommendList);

	// handle for MORE icon
	if (recommendList[RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT] != NULL) {
        Node* nodeMore = pickingControlById(gGroupRecommendList.startId + RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT);
        nodeMore->control.state = ENABLE_CONTROL_STATE;
        drawImageView(&nodeMore->control);
	} else if (recommendList[RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT] == NULL) {
        // DELETE MORE ICON USING RECOMMEND_CLEAR
        Node* nodeMore = pickingControlById(gGroupRecommendList.startId + RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT);
        nodeMore->control.state = DISABLE_CONTROL_STATE;
        drawImage(nodeMore->control.location.x1 - RESTORE_MNEMONIC_RECOMMEND_WIDTH + RESTORE_MNEMONIC_RECOMMEND_MORE_WIDTH, nodeMore->control.location.y1, getScreenResource(ID_RESOURCE_RESTORE_RECOMMEND_CLEAR, &resourceSize), resourceSize);
	}

	for (uint32_t i = 0; i < RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT; i++) {
		if (recommendList[i] != NULL) {
			DBG_LOG("%d : %s", count, recommendList[i]);
			node->control.state = ENABLE_CONTROL_STATE;
            if (count == 0) {
                clearErrorMsg();
            }
            node->control.originResource = getScreenResource(ID_RESOURCE_RESTORE_RECOMMEND_BG, &resourceSize);
            node->control.originResourceSize = resourceSize;
            copyTextBuffer(node->control.textInfo.text, recommendList[i]);
            drawTextBox(&node->control);

            count++;
		} else {
			node->control.state = INVISIBLE_CONTROL_STATE;
			if (strlen((char *)node->control.textInfo.text) != 0) {
				copyTextBuffer(node->control.textInfo.text, emptyString);
				drawImage(node->control.location.x1, node->control.location.y1, getScreenResource(ID_RESOURCE_RESTORE_RECOMMEND_CLEAR, &resourceSize), resourceSize);
			}
		}
		node = node->next;
	}

	TZ_free(recommendList);
	//showFrameBuffer();
	DBG_LOG("Recommend Count : %d", count);
	return count;
}

bool clearRecommendList() {
	DBG_LOG("clearRecommendList()");
	Node* node = pickingControlById(gGroupRecommendList.startId);
	uint32_t resourceSize = 0;
	if (node == NULL) {
		TTY_LOG("RecommendControl is NULL");
		return false;
	}

	for (uint32_t i = 0; i < RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT + 1; i++) {
		if (node->control.state != INVISIBLE_CONTROL_STATE) {
			node->control.state = INVISIBLE_CONTROL_STATE;
            copyTextBuffer(node->control.textInfo.text, emptyString);
            if (i == RESTORE_MNEMONIC_RECOMMEND_LIST_COUNT) { // DELETE MORE ICON USING RECOMMEND_CLEAR
                drawImage(node->control.location.x1 - RESTORE_MNEMONIC_RECOMMEND_WIDTH + RESTORE_MNEMONIC_RECOMMEND_MORE_WIDTH, node->control.location.y1, getScreenResource(ID_RESOURCE_RESTORE_RECOMMEND_CLEAR, &resourceSize), resourceSize);
            } else {
                drawImage(node->control.location.x1, node->control.location.y1, getScreenResource(ID_RESOURCE_RESTORE_RECOMMEND_CLEAR, &resourceSize), resourceSize);
            }
		}
		node = node->next;
	}
	//showFrameBuffer();
	return true;
}
