
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <locale.h>
#include <iconv.h>

#include "LoadBMP.c"
#include "QRPro_Types.h"
#include "twodtg_license.h"

// the images size
const int maxrowQ = 4000;       // maximum of image rows
const int maxcolQ = 4000;

const char GRADE[] = "FDCBA";

void printParamQuality(TQR_Info* pqrinfo);

int main(int argc, char **argv)
{
   TRow* pbits = NULL;
   TRow pmembits = NULL;  // Image in Memory
   int	rowcount = maxrowQ;
   int colcount = maxcolQ;
   void* hndlQr = NULL; // decoder
   void* hoptQr = NULL; // options
   iconv_t conv = NULL;
   char dataBuf[4000] = "";

   printf("Lib v%s\n", Get_QR_Version());

   setlocale(LC_ALL,"");
   conv = iconv_open("UTF-8", "UTF-16");

   if(argc != 2)
   {
    printf("Usage:\n");
    printf("demo.out MyImageName.bmp\n");
    return 0;
   }
   
   // Check License
   if(IsActivated())
   {
       printf("License status: Fully licensed.\n");
   }else if(EvaluationDayCount() > 0)
   {
       printf("License status: Evaluation expires in %d days.\n.", EvaluationDayCount());
   }else if(RequredRootAcess())
   {
       printf("ATTENTION: ROOT rights are required to initialize a license!\nUse 'sudo' for first run.\n");
       return 0;
   }else
   {
       printf("License status: Evaluation expired!\n");
       return 0;
   }
   

   pmembits = (TRow) malloc(maxrowQ*maxcolQ);       //  Image in Memory
   pbits    = (TRow*) malloc(maxrowQ*sizeof(TRow)); // pointers to ScanLines
   for(int row = 0; row < maxrowQ; row++)
     pbits[row] = &pmembits[maxcolQ*row];

   // Load the image
   if(LoadBMP (argv[1], pbits, &rowcount, &colcount) != 0)
   {
    free(pmembits); free(pbits);
    printf("Failed Load file: %s\n", argv[1]);
    return 0;
   }

   // create decoder
   hndlQr = Connect_QR_Decoder(rowcount, colcount);
   //hndlQr = Connect_QR_Decoder(maxrowQ, maxcolQ);
   if(hndlQr == NULL)
   {
     free(pmembits); free(pbits);
     printf("Failed Connect_QR_Decoder\n");
     return 0;
   }

   // create the options
   TQR_OptMode    opt;
   opt.maxQRCount  = 1;
   opt.qualityMask = QR_QM_ALL;
   opt.symbology   = QRC_ANY;
   opt.cellColor   = QRCL_ANY;
   opt.qzMode      = QRQZ_SMALL;
   opt.filterMode = QRFM_NON;
   opt.mirrorMode  = QRMM_ANY;

   //opt.filterMode = QRFM_DOT_PEEN;


   if((hoptQr = Create_QR_Options(hndlQr, opt)) == NULL)
   {
     free(pmembits);
     free(pbits);
     Disconnect_QR_Decoder(hndlQr);
     printf("Failed Create_QR_Options\n");
     return 0;
   }

   // decode
   DecodeQR_Bits(hoptQr, rowcount, colcount, pbits);

   TQR_ImageInfo* infImg = GetQR_ImageInfo(hoptQr);

   if((infImg->QRCount > 0) && (infImg->RejectionReason == 0))
   {
    printf("Barcodes count: %d\n\n", infImg->QRCount);
    for(int i=0; i < infImg->QRCount; i++)
    {
     printf("Barcode %d\n", i + 1);

     TQR_Info* inf = GetQR_Info(hoptQr, i);
     printf("Dim: %2d  Version: %2d  Level: %c\n", inf->Dim, inf->Version, inf->level);
     // Convert data to utf-8
     char* out = dataBuf;
     size_t bufSize = 4000;
     size_t pchSize = inf->pchlen*2;
     char* in = (char*)(inf->pch2);
     int res = iconv(conv, &in, &pchSize, &out, &bufSize);

     printf("Data: %s\n", dataBuf);

     printParamQuality(inf);
    }
   }
   else
   {
    if(QR_NO_IMAGE_FOUND == infImg->RejectionReason)
     printf("NO_IMAGE_FOUND\n");
    else if(QR_POOR_IMAGE_QUALITY == infImg->RejectionReason)
     printf("POOR_IMAGE_QUALITY\n");
    else if(QR_ERROR_OF_RS_CODE == infImg->RejectionReason)
     printf("ERROR_OF_RS_CODE\n");
    else if(QR_ERR_DECODE == infImg->RejectionReason)
     printf("ERR_DECODE\n");
    else if(QR_ERR_MODE == infImg->RejectionReason)
     printf("ERR_MODE\n");
    else
     printf("Not Found\n");
   }

   Delete_QR_Options(hoptQr);
   Disconnect_QR_Decoder(hndlQr);

   free(pbits);
   free(pmembits);

   iconv_close(conv);

   //char str[16]; scanf("%c", str);
   return 0;
}

void printParamQuality(TQR_Info* pqrinfo)
{
  printf("\nParam Quality:\n");
  printf("SC    = %7.2f (%c)\n"  , pqrinfo->quality.sc, GRADE[int(pqrinfo->quality.scG)]);
  printf("AxNU  = %7.2f (%c)\n", pqrinfo->quality.an, GRADE[int(pqrinfo->quality.anG)]);
  printf("GrNU  = %7.2f (%c)\n", pqrinfo->quality.gn, GRADE[int(pqrinfo->quality.gnG)]);
  printf("UEC   = %7.2f (%c)\n",  pqrinfo->quality.uec, GRADE[int(pqrinfo->quality.uecG)]);
  printf("FPD   = (%c)\n" ,  GRADE[int(pqrinfo->quality.fpdG)]);
  printf("ModG  = (%c)\n",  GRADE[int(pqrinfo->quality.modG)]);
  printf("DecG  = (%c)\n",  GRADE[int(pqrinfo->quality.deG)]);
  printf("FrmG  = (%c)\n",  GRADE[int(pqrinfo->quality.frmG)]);
  printf("VerG  = (%c)\n",  GRADE[int(pqrinfo->quality.verG)]);
  printf("ScanG = (%c)\n", GRADE[int(pqrinfo->quality.scanG)]);

  printf("\n\n");
}
