#include <stdio.h>
#include <string.h>
#include "demo_common.h"

#define ENABLE_LOG 0

extern IDT_DEMO_LIB_DISPLAY_MENU idtech_display_menu_from_lib;

void
printCMRData(IDTCMRData * cmrData);

void
CMR_callBack(int type, IDTCMRData * cmrData) {
    printf("\nCMR Callback\n");
    switch (type) {
        case CMR_callBack_type_ERR:
            printf("Callback Camera Function Error\n");
            break;
        case CMR_callBack_type_Cancelled:
            printf("Callback Camera Cancelled\n");
            break;
        case CMR_callBack_type_RETURN_CODE:
            printCMRData(cmrData);
            break;
        case CMR_callBack_type_TIMEOUT:
            printf("Camera Callback Timeout\n");
            break;
        default:
            break;
    }

    #ifndef WIN32
    if (idtech_display_menu_from_lib.pDisplay_Menu_current) {
        idtech_display_menu_from_lib.pDisplay_Menu_current();
        printf("Please Input your Selection. (0 - exit current menu)\n");
    }
    #endif
    fflush(stdout);
} /* CMR_callBack */

void
CSFS_callBack(BYTE status) {
    printf("\nCSFS Callback\n");

    if ((status & 0x04) == 0) {
        printf("Front Switch Not Detected\n");
    } else {
        printf("Front Switch Detected\n");
    }
    if ((status & 0x02) == 0) {
        printf("Card Not Seated\n");
    } else {
        printf("Card Seated\n");
    }
    #ifndef WIN32
    if (idtech_display_menu_from_lib.pDisplay_Menu_current) {
        idtech_display_menu_from_lib.pDisplay_Menu_current();
        printf("Please Input your Selection. (0 - exit current menu)\n");
    }
    #endif
    fflush(stdout);
}

void
SendDataLog(BYTE * data, int dataLen) {
    if (ENABLE_LOG) {
        printf("\nSend Command\n");
        int i;
        for (i = 0; i < dataLen; i++) {
            printf("%02X ", data[i]);
        }
        printf("\n");
        fflush(stdout);
    }
}

void
ReadDataLog(BYTE * data, int dataLen) {
    if (ENABLE_LOG) {
        printf("\nRead Response\n");
        int i;
        for (i = 0; i < dataLen; i++) {
            printf("%02X ", data[i]);
        }
        printf("\n");
        fflush(stdout);
    }
}

void
printCMRData(IDTCMRData * cmrData) {
    printf("Camera Data Length: %d\n", cmrData->cameraDataLen);
    int i;
    for (i = 0; i < cmrData->cameraDataLen; i++) {
        if (i == 0) {
            printf("{ %02X ", cmrData->cameraData[0]);
        } else {
            printf("%02X ", cmrData->cameraData[i]);
        }
    }
    printf("}\n");
}

void
getDUKPT(int type) {
    int rt = 0;
    BYTE KSN[10];

    memset(KSN, 0, 10);
    rt = device_getSpectrumProKSN(type, KSN);
    if (rt == RETURN_CODE_DO_SUCCESS) {
        char str2[100];
        memset(str2, 0, 100);
        convertBytesIntoHexStr(KSN, 10, 1, str2);

        printf("DUKPT KSN = %s\r\n", str2);
    } else {
        char strErr[200] = { 0 };
        memset(strErr, 0, 200);
        device_getResponseCodeString(rt, strErr);
        printf("DUKPT KSN failed: %s\r\n", strErr);
    }
    fflush(stdout);
}

int
inputSelection() {
    char buffer[50] = { 0 };

    while (1) {
        printf("Please Input your Selection. (0 - exit current menu)\n");
        fflush(stdout);
        char * str = fgets(buffer, sizeof(buffer), stdin);
        if (str != NULL) {
            char * end;
            long num = strtol(str, &end, 10);
            if (str != end) {
                return (int) num;
            }
        }
        printf("Invalid entry\n");
        fflush(stdout);
    }
}

void
libraryPathSelection(char * libraryPath) {
    char buffer[512];

    while (1) {
        printf("Please enter an absolute library path:\n");

        fflush(stdout);

        char * str = fgets(buffer, sizeof(buffer), stdin);

        if (str != NULL) {
            strncpy(libraryPath, str, strlen(str) - 1); // Exclude newline character
            return;
        }

        printf("Invalid entry\n");
        fflush(stdout);
    }
}

void
FW_callBack(int deviceType, int state, int currentBlock, int totalBlocks, int ResultCode) {
    //	printf("\nFW Callback\n");
    if (ResultCode == RETURN_CODE_BLOCK_TRANSFER_SUCCESS) {
        if (deviceType == IDT_DEVICE_KIOSK_III ||
            deviceType == IDT_DEVICE_KIOSK_III_S ||
            deviceType == IDT_DEVICE_KIOSK_III_COM ||
            deviceType == IDT_DEVICE_KIOSK_III_S_COM ||
            deviceType == IDT_DEVICE_PIP_READER ||
            deviceType == IDT_DEVICE_VP3300_AJ ||
            deviceType == IDT_DEVICE_UNIPAY_I_V ||
            deviceType == IDT_DEVICE_UNIPAY_I_V_TTK ||
            deviceType == IDT_DEVICE_VP3300_BT ||
            deviceType == IDT_DEVICE_VP3300_USB ||
            deviceType == IDT_DEVICE_VP3300_COM) {
            printf("Wrote %d of %d %%\r", currentBlock, totalBlocks);
        } else {
            if (totalBlocks == 100) {
                printf("Wrote %d of %d %%\r", currentBlock, totalBlocks);
            } else {
                printf("Wrote block %d of %d\r", currentBlock, totalBlocks);
            }
        }
        fflush(stdout);
    }
}

void
RKI_callBack(int ResultCode, char * macValue) {
    //	printf("\nPIN Callback\n");
    if (ResultCode == RETURN_CODE_RKI_TIMEOUT) {
        printf("RKI Timeout\n");

        fflush(stdout);
    } else if (ResultCode == RETURN_CODE_RKI_INITIALIZATION_ERROR) {
        printf("RKI Initialization Error\n");
        fflush(stdout);
    } else if (ResultCode == RETURN_CODE_RKI_AUTHENTICATION_ERROR) {
        printf("RKI Authentication Error\n");
        fflush(stdout);
    } else if (ResultCode == RETURN_CODE_RKI_TR31_ERROR) {
        printf("RKI TR31 Error\n");
        fflush(stdout);
    } else if (ResultCode == IDG_P2_STATUS_CODE_DO_SUCCESS) {
        printf("RKI Succeeded\n");
        if (macValue != NULL) {
            printf("Mac: %s\n", macValue);
        }
        fflush(stdout);
    }

    #ifndef WIN32
    if (idtech_display_menu_from_lib.pDisplay_Menu_current) {
        idtech_display_menu_from_lib.pDisplay_Menu_current();
        printf("Please Input your Selection. (0 - exit current menu)\n");
    }
    #endif
}

void
process_exit() {
    device_close();
}
