#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#include <Windows.h>

#include "DMPro_Types.h"

#include "LoadBmp.cpp"

const int   // the images maximum dimensions
  maxrowQ = 5000,
  maxcolQ = 8192;

int main(int argc, char **argv)
{
	TRow*    pbits;
	TRow     pmembits;  // Image in Memory

	char*   files[] =
	{
	  "samples\\1.bmp",
	  "samples\\2.bmp",
	  "samples\\3.bmp",
	  "samples\\4.bmp",
	  "samples\\5.bmp",
	  "samples\\6.bmp",
	  "samples\\7.bmp",
	  "samples\\8.bmp",
	  NULL
	};
	int 	   ResLoadBMP;
	int	    rowcount, colcount, row, result;
	int     i;
	int     k;
	int     rr;

	PDM_Decoder pDecoder;
	PDM_Options dec1;
	TDM_OptMode opt;
	TDM_ImageInfo* pdm_imageinfo;
	TDM_Info* pdm_info;

	int fn = 0;
	int dmq;
	int welldec;
	char endrun;
	char Symbology_Identifier[4];

	pmembits = (TRow)malloc(maxrowQ*maxcolQ);      //  Image in Memory
	pbits = (TRow*)malloc(maxrowQ * sizeof(TRow)); // pointers to ScanLines
	for (row = 0; row < maxrowQ; row++) {
		pbits[row] = &pmembits[maxcolQ*row];
	}
	welldec = 0;
	if (Connect_DM_Decoder == NULL)
		goto doExit;
	pDecoder = Connect_DM_Decoder(maxcolQ, maxrowQ);
	if (pDecoder != NULL) 
	{
		opt.maxDMCount = 1;
		opt.cellColor = CL_ANY; // equal to default value
		opt.mirrorMode = MM_ANY;
		opt.speedMode = DMSP_ULTIMATEPLUS; // DMSP_REGULAR;

		// Legacy QP
		//opt.qualityMask = DM_QM_ALL;

		// Print Quality Metrics
		opt.qualityMask = DM_PQM_ALL_v2;

		opt.labelMode = LM_ST_DOT;
		opt.timeOut = 0;
		opt.filterMode = FM_AUTO;
		opt.qzMode = DMQZ_SMALL;

		dec1 = Create_DM_Options(pDecoder, opt);

		for (int j = 0; files[j] != NULL; j++) 
		{
			if (files[j] == NULL)
				break;
			printf("\n\n");
			printf("%s ", files[j]);

			rowcount = maxrowQ;
			colcount = maxcolQ;
			ResLoadBMP = LoadBMP(files[j], pbits, rowcount, colcount);
			if (ResLoadBMP == 0) 
			{
				result = DecodeDM_Bits(dec1, rowcount, colcount, pbits);

				pdm_imageinfo = GetDM_ImageInfo(dec1);
				dmq = pdm_imageinfo->DMCount;
				printf("\n DM count = %4d", dmq);
				rr = pdm_imageinfo->RejectionReason;
				if (dmq > 0) 
				{
					for (i = 0; i <= dmq - 1; i++)
					{
						pdm_info = GetDM_Info(dec1, i);
						printf("\n rowcols: ");
						for (k = 0; k < 4; k++)
						{
							printf("(%4d,%4d),   ", int(pdm_info->rowcols[2 * k]), int(pdm_info->rowcols[2 * k + 1]));
						}
						printf("\n");
						if (pdm_info->pchlen > 0)
						{
							welldec++;
							printf("\n Decoded array: %s", pdm_info->pch);
							strncpy(Symbology_Identifier, (char*)&(pdm_info->pch[-3]), 3);
							Symbology_Identifier[3] = 0;
							printf("\n Symbology_Id = %s,  RSErr = %4d", Symbology_Identifier, pdm_info->RSErr);
						}
						printf("\n Dimensions: %4d * %4d",
							pdm_info->VDim, pdm_info->HDim);
						printf("\n axial_nonuniformity (grade)  = %7.2f  (%d)"
							, pdm_info->quality.axial_nonuniformity
							, int(pdm_info->quality.axial_nonuniformity_grade));
						printf("\n grid_nonuniformity  (grade)  = %7.2f  (%d)"
							, pdm_info->quality.grid_nonuniformity
							, int(pdm_info->quality.grid_nonuniformity_grade));
						printf("\n symbol_contrast     (grade)  = %7.2f  (%d)"
							, pdm_info->quality.symbol_contrast
							, int(pdm_info->quality.symbol_contrast_grade));
						printf("\n unused_error_corr.  (grade)  = %7.2f  (%d)"
							, pdm_info->quality.unused_error_correction
							, int(pdm_info->quality.unused_error_correction_grade));
						printf("\n vert. & horiz. print_growth  = %7.2f,%7.2f"
							, pdm_info->quality.vertical_print_growth
							, pdm_info->quality.horizontal_print_growth);
						printf("\n fixed_patt_damage.  (grade)  = %7.2f  (%d)"
							, pdm_info->quality.fixed_pattern_damage
							, int(pdm_info->quality.fixed_pattern_damage_grade));
						printf("\n (modulation grade)           =          (%d)"
							, int(pdm_info->quality.modulation_grade));
						printf("\n (decode grade)               =          (%d)"
							, int(pdm_info->quality.decode_grade));
						printf("\n (overall grade)              =          (%d)"
							, int(pdm_info->quality.overall_grade));
					}
				}
				fn++;
			}
			else 
			{
				printf("\n\nLoadBMP !=0\n");
			}
		}
		Delete_DM_Options(dec1);
		Disconnect_DM_Decoder(pDecoder);
	}

doExit:
	free(pbits);
	free(pmembits);

	printf("\n\n  Matrices OK: %d", welldec);
	printf("\nPush 'Enter' to exit>");
	scanf("%c", &endrun);
	return 0;
}
