
#ifndef DM_PRO_TYPES_H
#define DM_PRO_TYPES_H

// Autentication
//#define twoDTG_AUTHENTICATION

enum CELL_COLOR{
 CL_BLACKONWHITE = 1,
 CL_WHITEONBLACK = 2,
 CL_ANY          = 3
};

enum MIRROR_MODE{
 MM_NORMAL   = 1,
 MM_MIRROR   = 2,
 MM_ANY      = 3
};

enum Decoder_SPEED{
 SP_ROBUST   = 0,
 SP_FAST     = 1,
 SP_GRID_ADJUSTMENT = 2,
 SP_EQUALIZATION    = 3, //!< re-equalization of regions probable Data Matrix
 SP_EQUAL_GRADJ     = 4,
 SP_ACCURATE        = 5,
 SP_ACCURATEPLUS    = 6  
};

#define LABEL_MODE_DEFINED

/// the aliases:
enum DM_SPEED{
 DMSP_ULTIMATEPLUS  = SP_ACCURATEPLUS,//!< most careful and time-expensive
 DMSP_ULTIMATE      = SP_ACCURATE,    //!< more careful and time-expensive
 DMSP_REGULAR       = SP_EQUAL_GRADJ, //!< recommended ratio "speed/quality"
 DMSP_EXPRESS       = SP_ROBUST       //!< basic algorithm (more fast)
};

enum LABEL_MODE{
 LM_STANDARD = 0,      //!<-ISO 16022
 LM_DOTPEEN  = 1,
 LM_FAX      = 2,
 LM_ST_DOT   = 3       //!< Combines Standard & Dotpeen
};

/// \enum QUALITY_MASK bits of mask:
enum QUALITY_MASK {
	DM_QM_NO   = 0X0000,
	DM_QM_AXNU = 0X0001,
	DM_QM_PRGR = 0X0002,
	DM_QM_SYMCTR = 0X0004,
	DM_QM_CELLINFO = 0X0008,
	DM_QM_ALL  = 0x7FFF,
	DM_PQM_ALL_v2 = 0xFFFF
};

#define FILTER_MODE_DEFINED
enum FILTER_MODE{
 FM_NON         = 0, //!< No filter
 FM_SHARP1      = 1, //!< First  Filter Mode (recursive sharpening)
 FM_SHARP2      = 2, //!< Second Filter Mode (recursive sharpening)
 FM_SHARPMASK   = 3, //!< Sharpening Mask Filter
 FM_AUTO        = 4,  //!< Auto selection of sharpening parameters
 FM_BWR         = 5,  //!< Bar Width Reduction (spaces enlargement)
 FM_SM_BWR      = 6  //!< Sharpening Mask + Bar Width Reduction
};

enum DMQZ_MODE
{
 DMQZ_NORMAL   = 0, //!< allows QZ>= 5.7 pixels
 DMQZ_SMALL    = 1 //!< allows QZ>= 4.5 pixels, affects speed and robustness
};


#define DM_REJECTION_REASON_DEFINED
enum DM_REJECTION_REASON
{
	DM_RR_OK               = 0,
	DM_RR_NON              = 1,
	DM_RR_NODATAMATRIX     = 2,
	DM_RR_BYCRIT           = 3,
	DM_RR_REEDSOLOMON      = 5,
	DM_RR_NOMEMORY         = 99,
	DM_RR_UNKNOWN          = 100,
	DM_RR_DISCONNECTED     = 200,
	DM_RR_INVALID_ARGUMENT = 201,
	DM_RR_NOT_SUPPORTED    = 202
};

enum DM_BREAK_REASON
{
	DM_ALL_INSPECTED = 0 //!< no breaks occurred
	, DM_TIMEOUT = 1 //!< termination by time out
	, DM_TERMINATED = 2 //!< termination by user break
};

// Advanced options
enum DM_AdvansedOptions
{
	DM_PQ_APERTURE_PERCENTS = 1001,  // Aperture size as a percentage of the calculated module size.
	DM_PQ_MODULATION_CALCULATE_BY_REAL_CENTER_OF_MODULES = 1002 // Modulation calculations are carried out not for calculated, but for real centers of modules. DISABLED by default.
};


#ifdef twoDTG_AUTHENTICATION
enum SIGNATURE_MODE 
{
	DM_SM_NO = 0,
	DM_SM_USER = 1,   //!< 0x01 User Signature
	DM_SM_PRODUCT = 2,   //!< 0x02 Product Signature
	DM_SM_ALL = 3    //!< 0x03
};

enum UID_VALIDATION 
{
	AU_OK = 0,
	AU_NA = 1, // Not Applicable
	AU_ERR_UID_NF = 3, // File "User_*.txt" not found
	AU_ERR_HEX = 4, // Unresolved hex digit in UserID
	AU_ERR_UID = 5, // Wrong User ID structure/length
};

// Symbol Errors
enum DM_SYMBOL_VALIDATION 
{
	DM_AU_OK = 0,
	DM_AU_NA = 1, // Not Applicable
	DM_AU_FAILURE = 2, // Signature failure
	DM_AU_ERR_PID = 7  // Wrong Product ID structure/length
};
#endif
//=========================================

/// Decoder option modes
struct TDM_OptMode
{
  int maxDMCount;   //!< from 1 to 100. 1 by default
  int cellColor;    //!< CL_ANY by default
  int mirrorMode;   //!< MM_NORMAL by default
  int speedMode;    //!< SP_ROBUST by default
  int qualityMask;  //!< DM_QM_NO by default
  int labelMode;    //!< LM_NORMAL by default
  int timeOut;      //!< timeOut in mls. Timeout <= 0  means infinite timeout
  int filterMode;   //!< FM_NON by default
  int qzMode;
#ifdef twoDTG_AUTHENTICATION
  int signMode;        // Autentication mode
  char productID[128]; // Product ID.  Data - null terminated string. 
#endif
};

/// results of decoding the whole Image
struct TDM_ImageInfo
{
  int DMCount;        //!< number of well decoded symbols within image
  int RejectionReason;//!< not DM_RR_OK if no one matrix has been well decoded
  int BreakReason;    //!< 0 - normal termination, 1 - termination by time-out
  int AF_Mode;        //!< 0 - no Filter, 1 - Small, 2 - Big
 };

/// Data Matrix Print Quality Metrics
struct TDM_Quality
{
    float symbol_contrast;
    float axial_nonuniformity;
    float grid_nonuniformity;
    float fixed_pattern_damage;       //!< the aggregate grade
    float unused_error_correction;
    float vertical_print_growth;
    float horizontal_print_growth;

    float symbol_contrast_grade;
    float axial_nonuniformity_grade;
    float grid_nonuniformity_grade;
    float fixed_pattern_damage_grade;
    float unused_error_correction_grade;
    float modulation_grade;
    float decode_grade;              //!< 4 if DM was successfully decoded
    float overall_grade; //!< minimum of grades
};

// for compatibility with MSVC
/// result of decoding of each Data Matrix symbol in image
struct TDM_Info
{
  float          rowcols[8];	  //!< symbol corner coordinates
  int            pchlen;		     //!< length of decoded byte array
  unsigned char* pch;		        //!< pointer to that array
  int            RSErr;		      //!< number of Reed Solomon errors
  int            VDim, HDim;	//!< vertical and horizontal dimensions of Data Matrix
  int            saTotalSymbolsNumber //!< structured append: total number of matrices
  //!< value 0xff indicates ReaderProgramming - a special case
                ,saSymbolPosition	  //!< current matrix index
                ,saFileID1		   //!< file identifier 1
                ,saFileID2;    //!< file identifier 2
  int            mirrored;     //!< true if mirrored Data Matrix
  int            dotpeenstage; //!< true if dot peened Data Matrix
  int            matrixcolor;  //!< detected color of Data Matrix
  TDM_Quality    quality;      //!< symbol Print Quality Metrics
#ifdef twoDTG_AUTHENTICATION
  int UserSign;
  int ProductSign;
#endif
};

//=========================================
typedef void*           PDM_Decoder;   //!< handler of Data Matrix Decoder
typedef void*           PDM_Options;   //!< handler of Decoder Options
typedef TDM_ImageInfo*  PDM_ImageInfo; //!< pointer to Image Info
typedef TDM_OptMode*    PDM_OptMode;   //!< pointer to Options mode
typedef TDM_Quality*    PDM_Quality;   //!< pointer to symbol Quality
typedef TDM_Info*       PDM_Info;      //!< pointer to symbol Info
typedef unsigned char*  TRow;          //!< pointer to bitmap line
//=========================================

#if (defined WIN32) || (defined _WIN64)
 #define CALL_PREFIX extern "C"
 #define CALL_TYPE __stdcall
#elif defined(__linux__)
 #define CALL_PREFIX extern "C"
 #define CALL_TYPE
#else
 #define CALL_PREFIX extern "C"
 #define CALL_TYPE
#endif 

/// The function creates Data Matrix Decoder and returns Decoder handler
CALL_PREFIX PDM_Decoder   CALL_TYPE  Connect_DM_Decoder    (int maxrow, int maxcol);

/// The function destroys Data Matrix Decoder 
CALL_PREFIX void          CALL_TYPE  Disconnect_DM_Decoder (PDM_Decoder &pDecoder);

/// The function creates Decoder Options and returns Options handler
CALL_PREFIX PDM_Options   CALL_TYPE  Create_DM_Options     (PDM_Decoder pDecoder, TDM_OptMode optmode);
CALL_PREFIX PDM_Options   CALL_TYPE  Create_DM_OptionsP(PDM_Decoder pDecoder
	, int maxDMCount
	, int cellColor
	, int mirrorMode
	, int speedMode
	, int qualityMask
	, int labelMode
	, int timeOut
	, int filterMode
	, int qzMode
);

/// The function destroys Decoder Options 
CALL_PREFIX void          CALL_TYPE  Delete_DM_Options     (PDM_Options &pOptions);

/// The function decodes array ppbits with given Options
CALL_PREFIX int           CALL_TYPE  DecodeDM_Bits         (PDM_Options pOptions, int rowcount, int colcount, TRow* ppbits);
#ifndef ALL_IN_1
CALL_PREFIX int           CALL_TYPE  DecodeBitsF           (PDM_Options pOptions, int rowcount, int colcount, TRow* ppbits);
#endif
/// The function returnes the ImageInfo of last decoded Image
CALL_PREFIX PDM_ImageInfo CALL_TYPE  GetDM_ImageInfo       (PDM_Options pOptions);

/// The function returnes OptMode of current Options
CALL_PREFIX PDM_OptMode   CALL_TYPE  GetDM_OptMode         (PDM_Options pOptions);

/// The function returnes the DM_Info(dmNum)
CALL_PREFIX PDM_Info      CALL_TYPE  GetDM_Info            (PDM_Options pOptions, int dmNum);

CALL_PREFIX const char*   CALL_TYPE  GetDMVersion(void);

// Sets advanced decoder options
CALL_PREFIX int			 CALL_TYPE  SetDM_DecoderOption    (PDM_Decoder decoder, DM_AdvansedOptions optCode, int optValue);


#ifdef twoDTG_AUTHENTICATION
// Add autentication key.
CALL_PREFIX int           CALL_TYPE  AddUserID             (PDM_Decoder decoder, const char* userID);

// Delete all autentication keys
CALL_PREFIX void          CALL_TYPE  RemoveAllUserIDs(PDM_Decoder decoder);
#endif
#endif

