/*
 * Terminal_LCD.c
 *
 *  Created on: Jul 11, 2016
 *      Author: Eric
 */
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "IDTDef.h"
#include "LanguageInfo.h"
#include "Terminal_LCD.h"
// #include "libIDTechSDK.h"
#include "libIDT_Device.h"
#include "Terminal_KBInputControl.h"

void
SetOutputTextLCD(char * text[], int lines);
void
showMessageOnLCD(EMV_Callback * emvCallbackInfo, BYTE language[], BYTE message[]);
void
InputSelectNum(EMV_Callback * emvCallbackInfo, int itemSelected);

void
processLCDMenuSelect(EMV_Callback * emvCallbackInfo) {
    int timeWaitingInput = 30;
    int selected         = 0;

    switch (emvCallbackInfo->callbackType) {
        case EMV_CALLBACK_TYPE_LCD:
            switch (emvCallbackInfo->lcd_displayMode) {
                case EMV_LCD_DISPLAY_MODE_CANCEL:
                    // skip

                    break;
                case EMV_LCD_DISPLAY_MODE_MENU:
                    // LCD control should be changed to select the menu
                    showMessageOnLCD(emvCallbackInfo, emvCallbackInfo->language, emvCallbackInfo->lcd_messages);
                    selected = waitInputfor(timeWaitingInput);
                    printf("%d selected\n", selected);
                    InputSelectNum(emvCallbackInfo, selected);
                    break;
                case EMV_LCD_DISPLAY_MODE_PROMPT:
                    showMessageOnLCD(emvCallbackInfo, emvCallbackInfo->language, emvCallbackInfo->lcd_messages);
                    selected = waitInputfor(timeWaitingInput);
                    printf("%d selected\n", selected);
                    InputSelectNum(emvCallbackInfo, selected);
                    break;
                case EMV_LCD_DISPLAY_MODE_MESSAGE:
                    break;
                case EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT:
                    // LCD control should be changed to select the menu
                    showMessageOnLCD(emvCallbackInfo, emvCallbackInfo->language, emvCallbackInfo->lcd_messages);
                    selected = waitInputfor(timeWaitingInput);
                    printf("%d selected\n", selected);
                    InputSelectNum(emvCallbackInfo, selected);
                    break;
                case EMV_LCD_DISPLAY_MODE_PAUSE:
                    showMessageOnLCD(emvCallbackInfo, emvCallbackInfo->language, emvCallbackInfo->lcd_messages);
                    InputSelectNum(emvCallbackInfo, selected);
                    break;
                case EMV_LCD_DISPLAY_MODE_CLEAR_SCREEN:
                    break;
            }
            fflush(stdout);
            break;
        case EMV_CALLBACK_TYPE_PINPAD:
            InputSelectNum(emvCallbackInfo, selected);
            break;
    }
} /* processLCDMenuSelect */

char menuItemList[9][256];
void
showMessageOnLCD(EMV_Callback * emvCallbackInfo, BYTE language[], BYTE message[]) {
    char * messageList[9];
    int lines    = 0;
    int position = 0;
    char * msg   = (char *) message;
    int lengthMsg;
    int currentLine = 0;

    memset(messageList, 0, sizeof(char *) * 9);

    if (message[0] == 0x00 && message[1] != 0) {
        lengthMsg = strlen(msg + 1) + 1;
    } else {
        lengthMsg = strlen(msg);
    }
    while (position < lengthMsg) {
        byte line = message[position++];
        if (position < lengthMsg) {
            if ((line & 0x80) == 0x80) {
                messageList[lines++] = getDisplayMessage(language, message[position++]);
            } else {
                char tmp[256];
                int pos = 0;
                memset(tmp, 0, 256);

                while (position < lengthMsg && message[position] != 0x1C) {
                    tmp[pos++] = message[position++];
                }
                if (emvCallbackInfo->lcd_displayMode == EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT) {
                    currentLine = lines++;
                    memset(menuItemList[currentLine], 0, 256);
                    sprintf(menuItemList[currentLine], "%d : %s", lines, getLanguageCode(tmp));
                    messageList[currentLine] = menuItemList[currentLine];
                } else if (emvCallbackInfo->lcd_displayMode == EMV_LCD_DISPLAY_MODE_MENU) {
                    currentLine = lines++;
                    memset(menuItemList[currentLine], 0, 256);
                    sprintf(menuItemList[currentLine], "%d : %s", lines, tmp);
                    messageList[currentLine] = menuItemList[currentLine];
                } else {
                    messageList[lines++] = tmp;
                }
            }
            position++;
            //	if (position < lengthMsg)
            //		sb.AppendLine();
        }
    }

    int i;
    int exist = 0;
    for (i = 0; i < 9; i++) {
        if (messageList[i] != NULL)
            exist = 1;
    }

    if (emvCallbackInfo->lcd_displayMode == EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT) {
        if (exist) {
            printf("----Select Language----\n");
            SetOutputTextLCD(messageList, lines);
        }
    } else if (emvCallbackInfo->lcd_displayMode == EMV_LCD_DISPLAY_MODE_MENU) {
        if (exist) {
            printf("----Select App----\n");
            SetOutputTextLCD(messageList, lines);
        }
    } else {
        if (exist) {
            SetOutputTextLCD(messageList, lines);
        }
    }
    fflush(stdout);
} /* showMessageOnLCD */

int lastLength = 0;
void
SetOutputTextLCD(char * text[], int lines) {
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns 1.

    int i = 0;
    int backLength = 0;

    if (lines == 1) {
        if (lastLength > 0) {
            for (i = 0; i < lastLength; i++) {
                printf(" ");
            }
            for (i = 0; i != lastLength; i++) {
                putchar('\b');
            }
            fflush(stdout);
        }
        putchar('[');
        printf(text[0]);
        putchar(']');
        backLength = strlen(text[0]);
        for (i = 0; i != backLength + 2; ++i) {
            putchar('\b');
        }
        fflush(stdout);
        lastLength = backLength + 3;
    } else {
        for (i = 0; i < lines; i++) {
            printf(text[i]);
            printf("\n");
        }
    }
    fflush(stdout);
}

void
InputSelectNum(EMV_Callback * emvCallbackInfo, int itemSelected) {
    char * messagePINPad;

    if (emvCallbackInfo == null) {
        return;
    }

    switch (emvCallbackInfo->callbackType) {
        case EMV_CALLBACK_TYPE_LCD:
            switch (emvCallbackInfo->lcd_displayMode) {
                case EMV_LCD_DISPLAY_MODE_MENU:
                    emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_MENU, itemSelected);
                    break;
                case EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT:
                    // LCD control should be changed to select the menu
                    emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT, itemSelected);
                    break;
                case EMV_LCD_DISPLAY_MODE_PROMPT:
                    // LCD control should be changed to select the menu
                    if (itemSelected == 0) {
                        emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_PROMPT, 0x43);
                    } else {
                        emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_PROMPT, 0x45);
                    }
                    break;
                case EMV_LCD_DISPLAY_MODE_PAUSE:
                    emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_PAUSE, itemSelected);
                    break;
            }
            break;

        case EMV_CALLBACK_TYPE_PINPAD:
            switch (emvCallbackInfo->pin_pinMode) {
                case EMV_PIN_MODE_CANCEL:
                    break;
                //				case EMV_PIN_MODE_ONLINE_DUKPT:
                //				case EMV_PIN_MODE_ONLINE_MKSK:
                //				case EMV_PIN_MODE_OFFLINE:
                default:
                    // Show the PIN * in the LCD
                    messagePINPad = getDisplayMessageByID(MSC_ID_ENTER_PIN);
                    SetOutputTextLCD(&messagePINPad, 1);
                    printf("\n");

                    char strPIN[50] = { 0 };
                    int ret         = waitInputforPIN(emvCallbackInfo, strPIN); // if ret == 1 timeout
                    //					printf("%d selected\n", selected);
                    emv_callbackResponsePIN(emvCallbackInfo, strPIN);

                    break;
            }
            break;
    }
} /* InputSelectNum */
