#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "IDTDef.h"
#include "libIDT_VP8800.h"

void
printMSRData(IDTMSRData cardData);
void
process_exit();
void
display_main_menu();
void
programLoop();
void
MSR_callBack(int type, IDTMSRData cardData) {
    printf("\nMSR Callback\n");
    switch (type) {
        case MSR_callBack_type_ERR:
            printf("MSR Callback: Card Swipe Cancelled\n");
            break;
        case MSR_callBack_type_RETURN_CODE:
            printMSRData(cardData);
            break;
        case MSR_callBack_type_CARD_READ_ERR:
            printf("MSR Callback: Card Read Error\n");
            break;
        case MSR_callBack_type_TIMEOUT:
            printf("MSR Callback: Timeout\n");
            break;
        default:
            break;
    }
    display_main_menu();
}

void
printMSRData(IDTMSRData cardData) {
    printf("cardType: %02X\n", cardData.cardType);
    printf("cardData Len: %d\ncardData:\n", cardData.cardDataLen);
    printData(cardData.cardData, cardData.cardDataLen, 0);

    printf("Track1:\n");
    printData((BYTE *) cardData.track1, cardData.track1Length, 1);

    printf("Track2:\n");
    printData((BYTE *) cardData.track2, cardData.track2Length, 1);

    printf("Track3:\n");
    printData((BYTE *) cardData.track3, cardData.track3Length, 1);

    if (CAPTURE_ENCODE_TYPE_ISOABA == cardData.cardType) {
        if (cardData.captureEncryptType == CAPTURE_ENCRYPT_TYPE_AES) {
            printf("captureEncryptType: AES\n");
        } else {
            printf("captureEncryptType: TDES\n");
        }
        if (cardData.isDataVariant) {
            printf("Key Type: Data Variant\n");
        } else {
            printf("Key Type: PIN Variant\n");
        }
    }
    printf("Optional Bytes:\n");
    printData(cardData.optionalBytes, cardData.optionalBytesLen, 0);
    printf("iccPresent: %02X\n", cardData.iccPresent);

    // encrypted data
    printf("encTrack1:\n");
    printData(cardData.encTrack1, cardData.encTrack1Len, 0);

    printf("encTrack2:\n");
    printData(cardData.encTrack2, cardData.encTrack2Len, 0);

    printf("encTrack3:\n");
    printData(cardData.encTrack3, cardData.encTrack3Len, 0);

    printf("Track 1 hash:\n");
    printData(cardData.track1Hash, cardData.track1HashLen, 0);

    printf("Track 2 hash:\n");
    printData(cardData.track2Hash, cardData.track2HashLen, 0);

    printf("Track 3 hash:\n");
    printData(cardData.track3Hash, cardData.track3HashLen, 0);

    printf("serialNumber:\n");
    printData((BYTE *) cardData.serialNumber, cardData.serialNumberLen, 0);

    printf("KSN:\n");
    printData(cardData.KSN, cardData.KSNLen, 0);
} /* printMSRData */

int
main(void) {
    int device = IDT_DEVICE_VP8800;

    if (!device_setCurrentDevice(device)) {
        printf("  Fail to Init VP8800!\n");
        device = IDT_DEVICE_UNKNOWN;
    }

    if (device == IDT_DEVICE_UNKNOWN) {
        return 0;
    }

    msr_registerCallBk(MSR_callBack);

    programLoop();
    device_close();
    return 0;
}

void
display_main_menu() {
    printf("\t\t************* VP8800 Simple Demo **************\n");
    printf("\t\t0. Exit\n");
    printf("\t\t1. Firmware Version\n");
    printf("\t\t2. Start Slide Show\n");
    printf("\t\t3. Capture MSR Data\n");
    printf("\t\t4. Reset Display / Stop Slide Show\n");
    printf("\t\t***********************************************\n");
}

void
process_exit() {
    printf("Application Exit.\n");
}

void
programLoop() {
    int choice;
    char inputParameter1[256];
    int r = 0;
    char str1[256] = { 0 };
    int len        = 512;

    memset(inputParameter1, 0, 256);

    do {
        display_main_menu();
        printf("Please Input your Selection\n");
        scanf("%d", &choice);
        switch (choice) {
            case 1:
                printf(">>1. Get Firmware Version\n");

                r = device_getFirmwareVersion(str1);
                if (r != RETURN_CODE_DO_SUCCESS) {
                    printf("  Do device_getFirmwareVersion(), failed!\n");
                } else {
                    char str2[200] = { 0 };
                    sprintf(str2, "Firmware version: %s\n", str1);
                    printf(str2);
                }

                break;

            case 2: {
                printf(">>2. Start Default Slideshow\n");
                fflush(stdout);

                char directory[_DATA_BUF_LEN];
                int directoryLen = _DATA_BUF_LEN;
                r = device_listDirectory(NULL, 0, 1, 0, directory, &directoryLen);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- List Directory Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                    fflush(stdout);
                    break;
                }

                if (NULL == strstr(directory, "DefaultSlideShow/")) {
                    // create folder
                    device_createDirectory("DefaultSlideShow", 16);
                    // transfer files
                    int i;
                    int failed = 0;
                    for (i = 1; i <= 8; i++) {
                        char out_filename[50];
                        sprintf(out_filename, "DefaultSlideShow/img%d.png", i);
                        char in_filename[50];
                        sprintf(in_filename, "../Resources/%3d.png", i);
                        BYTE fileData[166000];
                        int fileDataLen;
                        FILE * fp;
                        if (NULL == (fp = fopen(in_filename, "rb"))) {
                            printf("Could not open file %s\n", in_filename);
                            fflush(stdout);
                            failed = 1;
                            break;
                        }
                        fseek(fp, 0, SEEK_END);
                        fileDataLen = ftell(fp);
                        if (fileDataLen > 166000) {
                            printf("Not enough buffer\n");
                            fflush(stdout);
                            failed = 1;
                            break;
                        }

                        fseek(fp, 0, SEEK_SET);
                        fread(fileData, fileDataLen, 1, fp);
                        fclose(fp);

                        r = device_transferFile(out_filename, strlen(out_filename), fileData, fileDataLen);
                        if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                            char strErr[200] = { 0 };
                            memset(strErr, 0, 200);
                            device_getIDGStatusCodeString(r, strErr);
                            printf(
                                ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Transfer File Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                                strErr);
                            fflush(stdout);
                            failed = 1;
                            break;
                        }
                    }
                    if (failed == 1) {
                        break;
                    }
                } else {
                    int i;
                    int failed = 0;
                    for (i = 1; i <= 8; i++) {
                        char out_filename[50];
                        sprintf(out_filename, "DefaultSlideShow/img%d.png", i);
                        char in_filename[50];
                        sprintf(in_filename, "../Resources/%3d.png", i);
                        if (NULL == strstr(directory, out_filename)) {
                            //						device_createDirectory("DefaultBackground");
                            // Read in the file
                            BYTE fileData[166000];
                            int fileDataLen;
                            FILE * fp;
                            if (NULL == (fp = fopen(in_filename, "rb"))) {
                                printf("Could not open file %s\n", in_filename);
                                fflush(stdout);
                                failed = 1;
                                break;
                            }

                            fseek(fp, 0, SEEK_END);
                            fileDataLen = ftell(fp);
                            if (fileDataLen > 35000) {
                                printf("Not enough buffer\n");
                                fflush(stdout);
                                failed = 1;
                                break;
                            }
                            fseek(fp, 0, SEEK_SET);
                            fread(fileData, fileDataLen, 1, fp);
                            fclose(fp);
                            r = device_transferFile(out_filename, strlen(out_filename), fileData, fileDataLen);
                            if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                                char strErr[200] = { 0 };
                                memset(strErr, 0, 200);
                                device_getIDGStatusCodeString(r, strErr);
                                printf(
                                    ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Transfer File Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                                    strErr);
                                fflush(stdout);
                                failed = 1;
                                break;
                            }
                        }
                    }
                    if (failed == 1)
                        break;
                }
                lcd_customDisplayMode(0);
                lcd_customDisplayMode(1);
                r = lcd_startSlideShow("DefaultSlideShow", strlen("DefaultSlideShow"), 0, 0, 2, 1, 0, 1, 3, 0, 1);
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Start Default Slideshow failed!! ErrorCode:0x%02x ,Info: %s ----- \n", r,
                        strErr);
                    fflush(stdout);
                    break;
                } else {
                    printf("Start Default Slideshow Succeeded\n");
                }
                fflush(stdout);
            }
            break;

            case 3:
                printf(">>3. Start MSR\n");
                msr_registerCallBk(MSR_callBack);
                r = msr_startMSRSwipe(30);
                if (r != RETURN_CODE_DO_SUCCESS) {
                    printf("  Do msr_startMSRSwipe(), failed! Error Code: %04X\n", r);
                } else {
                    printf("MSR Start MSR Swipe Succeeded\n");
                    printf("Please Swipe Card...\n");
                }

                break;

            case 4:
                printf(">>4. Reset Initial State\n");
                fflush(stdout);
                r = lcd_resetInitialState();
                if (r != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                    char strErr[200] = { 0 };
                    memset(strErr, 0, 200);
                    device_getIDGStatusCodeString(r, strErr);
                    printf(
                        ">>>>>>>>>>>>FAIL<<<<<<<<<<<<< \n   ----- Reset Initial State Failed! ErrorCode:0x%02x, Info: %s ----- \n", r,
                        strErr);
                } else {
                    printf("Reset Initial State Succeeded\n");
                }
                fflush(stdout);
                break;

            case 0:
                process_exit();
                break;
        }
    } while (choice != 0);
} /* programLoop */
