/**
 * @file
 * @brief PassportBox API Include File
 * 
 * Copyright (c) 2012-2016, Smart Engines. All rights reserved.
 */

/**
 * @mainpage Overview
 * The Smart PassportBox API Library allows to recognize Internal passport of Russia
 * using Smart PassportBox device.
 *
 * This file contains a brief description of all members of the Library.
 * Sample usage is shown in the @c passport_box_api_sample.cpp.
 *
 * Feel free to send any questions about the Library on support@smartengines.biz.

 * @example passport_box_api_sample.cpp
 */

#ifndef PASSPORT_BOX_API_INCLUDED
#define PASSPORT_BOX_API_INCLUDED

#if defined _WIN32 && PASSPORT_BOX_API_EXPORTS
#  define PBAPI_EXPORT   __declspec( dllexport )
#else
# if defined(__clang__) || defined(__GNUC__)
#  define PBAPI_EXPORT __attribute__ ((visibility ("default")))
# else
#  define PBAPI_EXPORT
# endif
#endif 

#define PBAPI_NO_ERROR           0   ///< No error has occurred. It indicates that the function completed successfully
#define PBAPI_BAD_ARGS          -1   ///< This error indicates that one or more arguments passed to the function are not correct
#define PBAPI_INTERNAL_ERROR    -2   ///< An internal error has occurred. This error indicates that something went wrong
#define PBAPI_CAPTURE_ERROR     -3   ///< A capture error has occurred. This error indicates problems with capture device
#define PBAPI_ENGINE_ERROR      -4   ///< A common recognition engine problem (not configured, not loaded and etc.)

#include <QSharedPointer>

 /// The structure represents last error description
typedef struct
{
  int  err_code;            ///< Error code
  char err_message[1024];   ///< Error description
} PBAPI_ErrorInfo;

/// The structure represents document info
typedef struct
{
  char doc_type[256];             ///< Type of recognized document(empty if document wasn't recognized)
  int field_count;                ///< Number of text fields in recognized document
  int image_count;                ///< Number of image fields in recognized document
} PBAPI_DocInfo;

/// The structure represents field info
typedef struct
{
  char field_name[256];           ///< Name of text field
  char field_value[4096];         ///< Value of text field
  char field_coordinates[4096];   ///< Text field coordinates in format: [(,), (,), (,), (,)]|[(,)...
  char field_raw_coordinates[4096];   ///< Text field raw coordinates in format: [(,), (,), (,), (,)]|[(,)...
  bool is_accepted;               ///< Bool flag tells is system sure in result
} PBAPI_FieldInfo;

/// The structure represents the capture document settings
typedef struct
{
  int timeout;                    ///< Specifies maximum recognition time in milliseconds
  char doc_classes[4096];         ///< Specifies the list of document classes for recognition separated via semicolon
  bool compete_doc_classes;       ///< Specifies whether the documents should be compete in recognition process
  int thread_count;               ///< Specifies maximum threads count for recognition, 0 for max thread
} PBAPI_CaptureSettings;

typedef struct  
{
  unsigned char *data;
  int stride;
  int width;
  int height;
} PBAPI_ImageData;

typedef struct
{
  int points[4][2];

} PBAPI_CalibrateQuad;

/// The structure represents settings for auto capture mode
typedef struct
{
  int interval;                 ///< Time interval (in milliseconds) to check the document on the working surface
} PBAPI_AutoCaptureSettings;

#define PBAPI_CB_ERROR                    0
#define PBAPI_CB_DOCUMENT_DETECTED        1
#define PBAPI_CB_DOCUMENT_RECOGNIZED      2
#define PBAPI_CB_DOCUMENT_REMOVED         3   
#define PBAPI_CB_FRAME_RECOGNIZED         4

/// Specifies the signature of callback recognition function
typedef void(*PBAPI_CaptureDocumentCB)(int, void *cb_data);

#define PBAPI_ALL_FIELDS_FLAG 0x0FFFFFFF
const PBAPI_CaptureSettings PBAPI_DEFAULT_CAPTURESETTINGS = { 5000, {0}, true, 0 };

/// Specifies default auto capture settings
const PBAPI_AutoCaptureSettings PBAPI_DEFAULT_AUTOCAPTURESETTINGS = { 1000 };

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/**
* @brief  Returns library version
* @param  version_buf       Buffer for version
* @param  version_buf       Size of passed buffer
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetVersion(char *version_buf, int version_buf_size);

/**
* @brief  Configures the recognition engines
* @param  config_path       Configuration file path
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* Configuration file contains the following options:
* * Capture device name (should be changed only by experts)
* * Capture frame size and FPS (should be changed only by experts)
* * Key points for cropping capture frames (should be changed only by experts)
* * Cropped frame size (should be changed only by experts)
* * Engine configurations (should be changed only by experts)
*/
int PBAPI_EXPORT PBAPI_Configure(const char *config_path);

/**
* @brief  Configures the recognition engines
* @param  config_json_string       Configuration string
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* Configuration string contains the following options:
* * Capture device name (should be changed only by experts)
* * Capture frame size and FPS (should be changed only by experts)
* * Key points for cropping capture frames (should be changed only by experts)
* * Cropped frame size (should be changed only by experts)
* * Engine configurations (should be changed only by experts)
*/
int PBAPI_EXPORT PBAPI_ConfigureFromString(const char *config_json_string);

/**
* @brief  Dumps current engine state
* @param  config_path       Configuration file path
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* Configuration file contains the following options:
* * Capture device name (should be changed only by experts)
* * Capture frame size and FPS (should be changed only by experts)
* * Key points for cropping capture frames (should be changed only by experts)
* * Cropped frame size (should be changed only by experts)
* * Engine configurations (should be changed only by experts)
*/
int PBAPI_EXPORT PBAPI_DumpConfigure(const char *config_path);

/**
* @brief  Dumps current engine state
* @param  config_json_buf       Configuration string
* @param  config_json_buf_size     Size of passed buffer
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* Configuration file contains the following options:
* * Capture device name (should be changed only by experts)
* * Capture frame size and FPS (should be changed only by experts)
* * Key points for cropping capture frames (should be changed only by experts)
* * Cropped frame size (should be changed only by experts)
* * Engine configurations (should be changed only by experts)
*/
int PBAPI_EXPORT PBAPI_DumpConfigureToString(char *config_json_buf, int config_json_buf_size);

/**
* @brief  Returns the list of supported document classes as a text string separated via semicolon
* @param  doc_classes_buf       Buffer for document classes 
* @param  doc_classes_buf_size  Size of passed buffer
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetDocumentClasses(char *doc_classes_buf, int doc_classes_buf_size);

/**
* @brief  Opens capture device
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* The capture name to be open is specified in configuration file. Opening capture device for a long time reduces device life cycle.
*/
int PBAPI_EXPORT PBAPI_OpenCaptureDevice();

/**
* @brief  Closes capture device
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_CloseCaptureDevice();

int PBAPI_EXPORT PBAPI_SkipFrames(int frames);

/**
* @brief  Returns last error information
* @param  error The pointer to error description structure
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetLastError(PBAPI_ErrorInfo *error);

/**
* @brief  Recognizes document on the working surface in synchronous mode
* @param  capture_settings   The pointer to capture settings
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* The function returns control when either document on the working surface is confidently recognized or break condition arises.
*/
int PBAPI_EXPORT PBAPI_CaptureDocument( 
  const PBAPI_CaptureSettings *capture_settings = &PBAPI_DEFAULT_CAPTURESETTINGS);

/**
* @brief  Recognizes document on the working surface in asynchronous mode
* @param  cb               The pointer to callback function
* @param  cb_data          The pointer to user defined callback parameter
* @param  capture_settings The pointer to capture settings
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* The function returns control and call callback function when either document on the working surface is confidently recognized or break condition arises.
*/
int PBAPI_EXPORT PBAPI_CaptureDocumentAsync(
  PBAPI_CaptureDocumentCB cb, void *cb_data = 0,
  const PBAPI_CaptureSettings *capture_settings = &PBAPI_DEFAULT_CAPTURESETTINGS);

/**
* @brief  Begins auto capture mode.
* @param  cb               The pointer to callback function
* @param  cb_data          The pointer to user defined callback parameter
* @param  auto_settings    The pointer to auto capture mode settings
* @param  capture_settings The pointer to capture settings
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* In auto capture recognition mode the working surface is analyzed for the presence of the document.
* When the document is detected and recognized the function call specified callback function.
*/
int PBAPI_EXPORT PBAPI_StartAutoCaptureDocument( 
  PBAPI_CaptureDocumentCB cb, void *cb_data = 0,
  const PBAPI_AutoCaptureSettings *auto_settings = &PBAPI_DEFAULT_AUTOCAPTURESETTINGS,
  const PBAPI_CaptureSettings *capture_settings = &PBAPI_DEFAULT_CAPTURESETTINGS);

/**
* @brief  Stops auto capture mode.
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_StopAutoCaptureDocument();

/**
* @brief  Process current frame from opened capture device.
* @param  new_session      Flag shows should recognition engine use old or new sessions(when sessions reset all previous results loses) 
* @param  capture_settings The pointer to capture settings
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* The function returns control when frame is recognized
*/
int PBAPI_EXPORT PBAPI_RecognizeCurrentFrame(bool new_session = false,
  const PBAPI_CaptureSettings *capture_settings = &PBAPI_DEFAULT_CAPTURESETTINGS);

/**
* @brief  PBAPI_IsTerminal Specifies whether the recognition should stop. It must be called together with PBAPI_RecognizeCurrentFrame
* @param  is_terminal      The pointer to is_terminal flag
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_IsTerminal(bool *is_terminal);

/**
* @brief  Returns document info
* @param  doc_info          The pointer to document info structure
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/    
int PBAPI_EXPORT PBAPI_GetDocumentInfo(PBAPI_DocInfo *doc_info);

/**
* @brief  Returns field info
* @param  field_info       The pointer to field info structure
* @param  field_index      Index number of field in doc
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetFieldInfo(int field_index, PBAPI_FieldInfo *field_info);

/**
* @brief  Returns image name
* @param  image_index       The inside index (should be from 0 to image_count-1) of image
* @param  image_name        The pointer to string buffer for image name
* @param  size              Size of preallocated image_name
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetImageName(int image_index, char *image_name, int size);

/**
* @brief  Returns image size
* @param  image_index       The inside index (should be from 0 to image_count-1) of image
* @param  size              Demanded size of buffer
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetImageBase64Size(int image_index, int *size);

/**
* @brief  Returns image
* @param  image_index       The inside index (should be from 0 to image_count-1) of image
* @param  data_buffer       The pointer to data buffer with image in base64 (data buffer should be preallocated)
* @param  size              Size of preallocated data_buffer
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
*/
int PBAPI_EXPORT PBAPI_GetImageBase64(int image_index, char *data_buffer, int size);

/**
* @brief  Saves image to specified path
* @param  image_index       The inside index(should be from 0 to image_count-1) of image
* @param  image_path        Image file path
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_SaveImage(int image_index, const char *image_path);

/**
* @brief  Takes snapshot and saves it in internal buffer.
* @param  is_src            Specifies which snapshot should be returned (source or projective cropped)
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
* Use PBAPI_GetSnapshotBase64() or PBAPI_SaveSnapshot() to obtain saved snapshot.
*/
int PBAPI_EXPORT PBAPI_TakeSnapshot(bool is_src = false);

/**
* @brief  Returns snapshot size
* @param  size              Demanded size of buffer
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetSnapshotSize(int *size);

/**
* @brief  Returns snapshot
* @param  data_buffer       The unique_ptr pointer to data buffer with image (data buffer should be preallocated)
* @param  size              Size of preallocated data_buffer
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*
*/
int PBAPI_EXPORT PBAPI_GetSnapshot(QSharedPointer<char> data_buffer, int size);

/**
* @brief  Returns snapshot size
* @param  size              Demanded size of buffer
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetSnapshotBase64Size(int *size);

/**
* @brief  Returns snapshot
* @param  data_buffer       The pointer to data buffer with image in base64 (data buffer should be preallocated)
* @param  size              Size of preallocated data_buffer
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetSnapshotBase64(char *data_buffer, int size);

/**
* @brief  Returns snapshot in bitmap presence
* @param  image_data       The pointer to PBAPI_ImageData structure
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetSnapshotData(PBAPI_ImageData *image_data);

/**
* @brief  Takes snapshot and saves it to specified path
* @param  file_path         Snapshot file path
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_SaveSnapshot(const char *file_path);

/**
* @brief  Updates document quadrangle
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_Calibrate(PBAPI_CalibrateQuad * arg_quad = nullptr);

/**
* @brief  Calculates focus ratio
* @param  ratio        Returned focus ratio
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_FocusRatio(int *ratio);

/**
* @brief  Specifying document types to recognition
* @param  doc_masks        Semicolon-separated document masks
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_SpecifyDocumentMask(const char *doc_masks);

/**
* @brief  Display current enabled doctypes
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetCurrentDocsBufSize(int *size);

/**
* @brief  Display current enabled doctypes
* @return Returns error code. To obtain error description see PBAPI_GetLastError() function
*/
int PBAPI_EXPORT PBAPI_GetCurrentDocs(char* buf, int size);

#ifdef __cplusplus
}
#endif // __cplusplus

#endif  // PASSPORT_BOX_API_INCLUDED
