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

extern IDT_DEMO_LIB_DISPLAY_MENU idtech_display_menu_from_lib;
typedef void (* Demo_getMenuFn)(IDT_DEMO_LIB_DISPLAY_MENU * idtech_display_menu_from_lib);

extern Demo_getMenuFn demo_getMenuFn;

void
printMSRData(IDTMSRData * cardData);
void
printTags(IDTMSRData * cardData);
void
printCoreDumpData(IDTMSRData * cardData);

void
MSR_callBack(int type, IDTMSRData cardData1) {
    printf("\nMSR Callback\n");
    switch (type) {
        case MSR_callBack_type_ERR:
            printf("MSR Callback: Card Swipe/Tap Cancelled\n");
            break;
        case MSR_callBack_type_TERMINATED:
            printf("MSR Callback: Terminated\n");
        case MSR_callBack_type_RETURN_CODE:
            printMSRData(&cardData1);
            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;
        case MSR_callBack_type_FALLBACK_TO_CONTACT:
            printf("MSR Callback: Fallback to contact\n");
            printMSRData(&cardData1);
            break;
        case MSR_callBack_type_ERR_CODE: {
            printf("MSR Error Code: %04X\n", cardData1.errorCode);
            printf("card data length %d\n", cardData1.cardDataLen);
            int i;
            for (i = 0; i < cardData1.cardDataLen; i++)
                printf("%02X", cardData1.cardData[i]);
            printf("\n");
        }
        break;
        case MSR_callBack_type_CORE_DUMP:
            printCoreDumpData(&cardData1);
            break;
        default:
            break;
    }
    fflush(stdout);
    //    if (ApplicationMode == CLIENT)
    //      return;
    switch (device_getCurrentDeviceType()) {
        case IDT_DEVICE_SPECTRUM_PRO:
        case IDT_DEVICE_SPECTRUM_PRO_COM:
            idtech_display_menu_from_lib.pDisplay_Menu_msr();
            printf("Please Input your Selection. (0 - exit current menu)\n");
            break;
        case IDT_DEVICE_KIOSK_III:
        case IDT_DEVICE_KIOSK_III_COM:
        case IDT_DEVICE_PIP_READER:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_KIOSK_III_S:
        case IDT_DEVICE_KIOSK_III_S_COM:
            idtech_display_menu_from_lib.pDisplay_Menu_ctls();
            printf("Please Input your Selection. (0 - exit current menu)\n");
            break;
        case IDT_DEVICE_VP3300_USB:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_VP3300_COM:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_VP3300_AJ:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_VP3300_BT:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            if (idtech_display_menu_from_lib.pDisplay_Menu_current) {
                printf("Please Input your Selection. (0 - exit current menu)\n");
                idtech_display_menu_from_lib.pDisplay_Menu_current();
            }
            break;
        case IDT_DEVICE_VP8800:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_NEO2:
        case IDT_DEVICE_NEO2 + 1:
        case IDT_DEVICE_NEO2 + 2:
        case IDT_DEVICE_NEO2 + 3:
        case IDT_DEVICE_NEO2 + 4:
        case IDT_DEVICE_NEO2_COM:
        case IDT_DEVICE_NEO2_COM + 1:
        case IDT_DEVICE_NEO2_COM + 2:
        case IDT_DEVICE_NEO2_COM + 3:
        case IDT_DEVICE_NEO2_COM + 4:
        case IDT_DEVICE_NEO2_TCPIP:
        case IDT_DEVICE_NEO2_TCPIP + 1:
        case IDT_DEVICE_NEO2_TCPIP + 2:
        case IDT_DEVICE_NEO2_TCPIP + 3:
        case IDT_DEVICE_NEO2_TCPIP + 4:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_VENDI:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_UNIPAY_I_V:
        case IDT_DEVICE_UNIPAY_I_V_TTK:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_AUGUSTA_HID:
        case IDT_DEVICE_AUGUSTA_KB:
        case IDT_DEVICE_AUGUSTA_S_HID:
        case IDT_DEVICE_AUGUSTA_S_KB:
        case IDT_DEVICE_AUGUSTA_S_TTK_HID:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            //			idtech_display_menu_from_lib.pDisplay_Menu_msr();
            break;
        default:
            break;
    }
} /* MSR_callBack */

void
MSR_callBackp(int type, IDTMSRData * cardData1) {
    printf("\nMSR Callback with card data pointer\n");
    switch (type) {
        case MSR_callBack_type_ERR:
            printf("MSR Callback: Card Swipe/Tap Cancelled\n");
            break;
        case MSR_callBack_type_TERMINATED:
            printf("MSR Callback: Terminated\n");
        case MSR_callBack_type_RETURN_CODE:
            printMSRData(cardData1);
            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;
        case MSR_callBack_type_FALLBACK_TO_CONTACT:
            printf("MSR Callback: Fallback to contact\n");
            printMSRData(cardData1);
            break;
        case MSR_callBack_type_ERR_CODE: {
            printf("MSR Error Code: %04X\n", cardData1->errorCode);
            printf("card data length %d\n", cardData1->cardDataLen);
            int i;
            for (i = 0; i < cardData1->cardDataLen; i++) {
                printf("%02X", cardData1->cardData[i]);
            }
            printf("\n");
        }
        break;
        case MSR_callBack_type_CORE_DUMP:
            printCoreDumpData(cardData1);
            break;
        default:
            break;
    }
    fflush(stdout);
    //    if (ApplicationMode == CLIENT)
    //        return;
    switch (device_getCurrentDeviceType()) {
        case IDT_DEVICE_SPECTRUM_PRO:
        case IDT_DEVICE_SPECTRUM_PRO_COM:
            idtech_display_menu_from_lib.pDisplay_Menu_msr();
            printf("Please Input your Selection. (0 - exit current menu)\n");
            break;
        case IDT_DEVICE_KIOSK_III:
        case IDT_DEVICE_KIOSK_III_COM:
        case IDT_DEVICE_PIP_READER:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_KIOSK_III_S:
        case IDT_DEVICE_KIOSK_III_S_COM:
            idtech_display_menu_from_lib.pDisplay_Menu_ctls();
            printf("Please Input your Selection. (0 - exit current menu)\n");
            break;
        case IDT_DEVICE_VP3300_USB:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_VP3300_COM:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_VP3300_AJ:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_VP3300_BT:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_VP8800:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_NEO2:
        case IDT_DEVICE_NEO2 + 1:
        case IDT_DEVICE_NEO2 + 2:
        case IDT_DEVICE_NEO2 + 3:
        case IDT_DEVICE_NEO2 + 4:
        case IDT_DEVICE_NEO2_COM:
        case IDT_DEVICE_NEO2_COM + 1:
        case IDT_DEVICE_NEO2_COM + 2:
        case IDT_DEVICE_NEO2_COM + 3:
        case IDT_DEVICE_NEO2_COM + 4:
        case IDT_DEVICE_NEO2_TCPIP:
        case IDT_DEVICE_NEO2_TCPIP + 1:
        case IDT_DEVICE_NEO2_TCPIP + 2:
        case IDT_DEVICE_NEO2_TCPIP + 3:
        case IDT_DEVICE_NEO2_TCPIP + 4:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_VENDI:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_UNIPAY_I_V:
        case IDT_DEVICE_UNIPAY_I_V_TTK:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            break;
        case IDT_DEVICE_AUGUSTA_HID:
        case IDT_DEVICE_AUGUSTA_KB:
        case IDT_DEVICE_AUGUSTA_S_HID:
        case IDT_DEVICE_AUGUSTA_S_KB:
        case IDT_DEVICE_AUGUSTA_S_TTK_HID:
            demo_getMenuFn(&idtech_display_menu_from_lib);
            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");
            }
            //			idtech_display_menu_from_lib.pDisplay_Menu_msr();
            break;
        default:
            break;
    }
} /* MSR_callBackp */

void
printMSRData(IDTMSRData * cardData) {
    BYTE xmlStart[] = { 0x3C, 0x44, 0x76, 0x63, 0x4D, 0x73, 0x67 };

    if (cardData->cardDataLen > 7 && !memcmp(cardData->cardData, xmlStart, 7)) {
        printf("cardData:\n");
        int i;
        for (i = 0; i < cardData->cardDataLen; i++) {
            printf("%c", cardData->cardData[i]);
        }
        printf("\n");
        return;
    }
    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 (cardData->encTrack1Len + cardData->encTrack2Len + cardData->encTrack3Len > 0) {
        if (cardData->captureEncryptType == CAPTURE_ENCRYPT_TYPE_TDES) {
            printf("captureEncryptType: TDES\n");
        } else if (cardData->captureEncryptType == CAPTURE_ENCRYPT_TYPE_AES) {
            printf("captureEncryptType: AES\n");
        } else if (cardData->captureEncryptType == CAPTURE_ENCRYPT_TYPE_TRANSARMOR) {
            printf("captureEncryptType: TRANSARMOR\n");
        } else if (cardData->captureEncryptType == CAPTURE_ENCRYPT_TYPE_VOLTAGE) {
            printf("captureEncryptType: VOLTAGE\n");
        } else if (cardData->captureEncryptType == CAPTURE_ENCRYPT_TYPE_VISA_FPE) {
            printf("captureEncryptType: VISA_FPE\n");
        } else if (cardData->captureEncryptType == CAPTURE_ENCRYPT_TYPE_VERIFONE_FPE) {
            printf("captureEncryptType: VERIFONE_FPE\n");
        } else if (cardData->captureEncryptType == CAPTURE_ENCRYPT_TYPE_VERIFONE_FPE) {
            printf("captureEncryptType: VERIFONE_FPE\n");
        } else {
            printf("captureEncryptType: NONE\n");
        }
        if (cardData->isDataVariant == 1) {
            printf("Key Type: Data Variant\n");
        } else if (cardData->isDataVariant == 0) {
            printf("Key Type: PIN Variant\n");
        } else {
            printf("Key Type: Unknown\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("Section/Transaction ID:\n");
    printData(cardData->sessionID, cardData->sessionIDLen, 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/Key ID:\n");
    printData(cardData->KSN, cardData->KSNLen, 0);

    printf("MAC:\n");
    printData(cardData->mac, cardData->macLen, 0);

    printf("MAC KSN:\n");
    printData(cardData->macKSN, cardData->macKSNLen, 0);

    printf("\n");
    fflush(stdout);
    printTags(cardData);
} /* printMSRData */

void
printCoreDumpData(IDTMSRData * cardData) {
    printf("Core Dump Data:\n");
    int i;
    printf("Core Dump File Name %s\n", cardData->track1);
    printf("Core Dump Data Length %d\n", cardData->track1Length);
    if (cardData->track1Length > 0) {
        FILE * fp;
        if (NULL == (fp = fopen(cardData->track1, "rb"))) {
            printf("Could not open file %s\n", cardData->track1);
            fflush(stdout);
            exit(1);
        }

        char *data = (char *)malloc(cardData->track1Length);
        if (data == NULL) {
            printf("Cannot open file %s to read\n", cardData->track1);
            exit(1);
        }

        memset(data, 0, cardData->track1Length);
        fread(data, cardData->track1Length, 1, fp);
        fclose(fp);

        for (i = 0; i < cardData->track1Length; i++) {
            printf("%c", data[i]);
        }
        printf("\n");
        printf("Core Dumped Occurred!!!  Please exit the demo and reboot the reader.\n");
        free(data);
        fflush(stdout);
    }
}

void
printTransactionData(IDTTransactionData * cardData) {
    printf("cardType: %02X\n", cardData->msr_cardType);
    printf("cardData Len: %d\ncardData:\n", cardData->msr_rawDataLen);
    printData(cardData->msr_rawData, cardData->msr_rawDataLen, 0);

    printf("Track1:\n");
    printData((BYTE *) cardData->msr_track1, cardData->msr_track1Length, 1);

    printf("Track2:\n");
    printData((BYTE *) cardData->msr_track2, cardData->msr_track2Length, 1);

    printf("Track3:\n");
    printData((BYTE *) cardData->msr_track3, cardData->msr_track3Length, 1);

    if (cardData->msr_encTrack1Len + cardData->msr_encTrack2Len + cardData->msr_encTrack3Len > 0) {

        if (cardData->msr_captureEncryptType == CAPTURE_ENCRYPT_TYPE_TDES) {
            printf("captureEncryptType: TDES\n");
        } else if (cardData->msr_captureEncryptType == CAPTURE_ENCRYPT_TYPE_AES) {
            printf("captureEncryptType: AES\n");
        } else if (cardData->msr_captureEncryptType == CAPTURE_ENCRYPT_TYPE_TRANSARMOR) {
            printf("captureEncryptType: TRANSARMOR\n");
        } else if (cardData->msr_captureEncryptType == CAPTURE_ENCRYPT_TYPE_VOLTAGE) {
            printf("captureEncryptType: VOLTAGE\n");
        } else if (cardData->msr_captureEncryptType == CAPTURE_ENCRYPT_TYPE_VISA_FPE) {
            printf("captureEncryptType: VISA_FPE\n");
        } else if (cardData->msr_captureEncryptType == CAPTURE_ENCRYPT_TYPE_VERIFONE_FPE) {
            printf("captureEncryptType: VERIFONE_FPE\n");
        } else if (cardData->msr_captureEncryptType == CAPTURE_ENCRYPT_TYPE_VERIFONE_FPE) {
            printf("captureEncryptType: VERIFONE_FPE\n");
        } else {
            printf("captureEncryptType: NONE\n");
        }

        if (cardData->msr_isDataVariant == 1) {
            printf("Key Type: Data Variant\n");
        } else if (cardData->msr_isDataVariant == 0) {
            printf("Key Type: PIN Variant\n");
        } else {
            printf("Key Type: Unknown\n");
        }
    }
    printf("iccPresent: %02X\n", cardData->iccPresent);

    // encrypted data
    printf("encTrack1:\n");
    printData(cardData->msr_encTrack1, cardData->msr_encTrack1Len, 0);

    printf("encTrack2:\n");
    printData(cardData->msr_encTrack2, cardData->msr_encTrack2Len, 0);

    printf("encTrack3:\n");
    printData(cardData->msr_encTrack3, cardData->msr_encTrack3Len, 0);

    printf("Track 1 hash:\n");
    printData(cardData->msr_hashTrack1, cardData->msr_hashTrack1Len, 0);

    printf("Track 2 hash:\n");
    printData(cardData->msr_hashTrack2, cardData->msr_hashTrack2Len, 0);

    printf("Track 3 hash:\n");
    printData(cardData->msr_hashTrack3, cardData->msr_hashTrack3Len, 0);

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

    printf("KSN/Key ID:\n");
    printData(cardData->msr_KSN, cardData->msr_KSNLen, 0);

    printf("MAC:\n");
    printData(cardData->mac, cardData->macLen, 0);

    printf("\n");
    fflush(stdout);
    //	printTags(cardData);
} /* printTransactionData */

void
printTags(IDTMSRData * cardData) {
    // print all tags
    if (cardData->unencryptedTagCount > 0) {
        printf("Unencrypted Tags Count %d:\n", cardData->unencryptedTagCount);
        int i;
        for (i = 0; i < cardData->unencryptedTagCount; i++) {
            //			printf("Tag %d: ", i);
            int j;
            for (j = 0; j < cardData->unencryptedTagArray[i].tagLen; j++) {
                printf("%02X", cardData->unencryptedTagArray[i].Tag[j]);
            }
            printf(": ");
            for (j = 0; j < cardData->unencryptedTagArray[i].valueLen; j++) {
                printf("%02X", cardData->unencryptedTagArray[i].value[j]);
            }
            printf("\n");
        }
    }
    printf("\n");

    if (cardData->maskedTagCount > 0) {
        printf("Masked Tags Count %d:\n", cardData->maskedTagCount);
        int i;
        for (i = 0; i < cardData->maskedTagCount; i++) {
            //			printf("Tag %d: ", i);
            int j;
            for (j = 0; j < cardData->maskedTagArray[i].tagLen; j++) {
                printf("%02X", cardData->maskedTagArray[i].Tag[j]);
            }
            printf(": ");
            for (j = 0; j < cardData->maskedTagArray[i].valueLen; j++) {
                printf("%02X", cardData->maskedTagArray[i].value[j]);
            }
            printf("\n");
        }
    }
    printf("\n");

    if (cardData->encryptedTagCount > 0) {
        printf("Encrypted Tags Count %d:\n", cardData->encryptedTagCount);
        int i;
        for (i = 0; i < cardData->encryptedTagCount; i++) {
            //			printf("Tag %d: ", i);
            int j;
            for (j = 0; j < cardData->encryptedTagArray[i].tagLen; j++) {
                printf("%02X", cardData->encryptedTagArray[i].Tag[j]);
            }
            printf(": ");
            for (j = 0; j < cardData->encryptedTagArray[i].valueLen; j++) {
                printf("%02X", cardData->encryptedTagArray[i].value[j]);
            }
            printf("\n");
        }
    }
    printf("\n");
    fflush(stdout);
} /* printTags */
