/*---------------------------------------------------------------------------*/
/* Eye-One iSis  C-Style  API                                                */
/* This API provides high-level methods to access the Eye-One iSis device    */
/*                                                                           */
/* Version 1.0                                                               */
/*                                                                           */
/* Copyright (c) 2006 by X-Rite Inc. Switzerland.                            */
/*                                                                           */
/* ALL RIGHTS RESERVED.                                                      */
/*                                                                           */
/* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS         */
/* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED         */
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE        */
/* ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY           */
/* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL        */
/* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE         */
/* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS             */
/* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,              */
/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING                 */
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
/*---------------------------------------------------------------------------*/
#ifndef EYEONE_ISIS_H
#define EYEONE_ISIS_H


#ifdef __cplusplus
  extern "C" {
    namespace ISIS_SDK 
    {
      class Exception
      {
        public:
          virtual ~Exception() = 0;
      };

      inline Exception::~Exception() {}
    }
#endif

#include "MeasurementConditions.h"

/* physical filter */
#define ISIS_PHYSICAL_FILTER                "PhysicalFilter"
#define ISIS_UNDEFINED_FILTER               "0"    
#define ISIS_NO_FILTER                      "1"      
#define ISIS_UV_FILTER                      "2"      // "UVcut" 

#define ISIS_ILLUMINATION_MODE              "IlluminationMode"  // "24060"
#define ISIS_ILLUMINATION_MODE_NO_UV        "0"
#define ISIS_ILLUMINATION_MODE_UV           "1"
#define ISIS_MEASUREMENT_FLOW               "MeasurementFlow"   // "24061"
#define ISIS_MEASUREMENT_FLOW_NORMAL        "0"
#define ISIS_MEASUREMENT_FLOW_COMBINED      "1"


/* definitions for specific ISIS key/values used with ISIS_GetOption() */
/* general key/values */
#define ISIS_LAST_ERROR                     "LastError"
#define ISIS_LAST_ERROR_CODE                "LastErrorCode"
#define ISIS_EXTENDED_ERROR_INFORMATION     "ExtendedErrorInformation"

#define ISIS_YES                            "yes"
#define ISIS_NO                             "no"

/* ISIS key/values */
#define ISIS_VERSION                        "Version"
#define ISIS_VERSION_MAJOR                  "VersionMajor"
#define ISIS_VERSION_MINOR                  "VersionMinor"
#define ISIS_VERSION_REVISION               "VersionRevision"
#define ISIS_VERSION_BUILD                  "VersionBuild"

#define ISIS_FIRMWARE_VERSION               "FirmwareVersion" // "24101" 

#define ISIS_SERIAL_NUMBER                  "SerialNumber"
#define ISIS_WHITE_TILE_ID                  "WhiteTileID"
#define ISIS_CALIBRATION_DATE               "CalibrationDate"

#define ISIS_IS_CONNECTED                   "Connection"
#define ISIS_IS_CHART_INSERTED              "ChartInDevice"
#define ISIS_LAST_AUTO_DENSITY_FILTER       "LastAutoDensityFilter"

#define ISIS_RESET                          "Reset" /*reset command parameters: ISIS_ALL, ISIS_SHORT_INIT*/
#define ISIS_ALL                            "All"

/* ISIS chart key/values */
#define ISIS_CHART_TYPE                     "ChartType"
#define ISIS_CHART_SIZE_X                   "ChartSizeX"
#define ISIS_NUMBER_OF_ROWS                 "NumberOfRows"
#define ISIS_NUMBER_OF_COLUMS               "NumberOfColumns"
#define ISIS_PATCH_SIZE_X                   "PatchSizeX"
#define ISIS_PATCH_SIZE_Y                   "PatchSizeY"
#define ISIS_LARGE_BAR_SIZE_X               "LargeBarSizeX"
#define ISIS_LARGE_BAR_SIZE_Y               "LargeBarSizeY"
#define ISIS_DIST_TO_LARGE_BAR              "DistToLargeBar"

#define ISIS_DIST_TO_BARCODE                "DistToBarcode"

#define ISIS_MARKER_DISTANCE                "MarkerDistance"
#define ISIS_DIST_TO_FIRST_FIELD            "DistToFirstField"
#define ISIS_DIST_TO_FIRST_LINE_Y           "DistToFirstLineY"

#define ISIS_CHART_TYPE_NATIVE                     "0" 

#define ISIS_CHART_BARCODE_WORKFLOW               "40"
#define ISIS_CHART_BARCODE_CHARTINFO              "41"



typedef enum ISIS_ErrorType
{
  isis_NoError,                               /* no error */
  isis_DeviceNotReady,                        /* device not ready	*/
  isis_DeviceNotConnected,                    /* device not connected	*/
  isis_NoDataAvailable,                       /* measurement not triggered, index out	of range (scanning) */
  isis_NoSubstrateWhite,                      /* unable to get substrate white for paper based density */
  isis_WhiteTileDirty,                        /* dirt on the white tile */
  isis_PaperJam,                              /* paper jam in the device, paper must be removed manually */
  isis_NoChartInDevice,                       /* used to test if a chart is inserted */
  isis_IndexOutOfBounds,                      /* the index (row or column) is out of bounds */
  isis_Exception,                             /* internal exception, use GetDeviceInfo(ISIS_LAST_ERROR)	for more details */
  isis_InvalidArgument,                       /* if a	passed method argument is invalid (i.e. NULL) */
  isis_CommunicationError,                    /* communication over the USB channel */
  isis_WorkflowError,                         /* bar not found, marks not found, barcode not detected.. */
  isis_InvalidData,                           /* calculation failed */
  isis_DataOutOfLimit,                        /* data not within tolerance limits */
  isis_HardwareError, 
  isis_UnknownError,                          /* unknown error occurred */
} ISIS_ErrorType;



/*--------------------- prototypes of exported functions --------------------*/
/* General remarks:
The FPtr_ISIS_XXX typedefs (i.e. FPtr_ISIS_IsConnected) are declared to simplify the
process of getting a reference to the desired method(s) while dynamic loading this library
*/


/*------------------------------ error handling -----------------------------*/
/* void MyErrorHandlerFunction(const char *axContext, ISIS_ErrorType axCode, const char *axText); */
typedef void (* FPtr_ISIS_ErrorHandler)(const char*, ISIS_ErrorType, const char*);
FPtr_ISIS_ErrorHandler ISIS_RegisterErrorHandler(FPtr_ISIS_ErrorHandler);
typedef FPtr_ISIS_ErrorHandler (* FPtr_ISIS_RegisterErrorHandler)(FPtr_ISIS_ErrorHandler);


/*-------------------- Information about the state  -------------------------*/
/*
Test if the ISIS is connected
return isis_NoError if connected
return isis_DeviceNotConnected if no ISIS is present
*/
ISIS_ErrorType ISIS_IsConnected(void);
typedef ISIS_ErrorType (* FPtr_ISIS_IsConnected)(void);
/*
Test if a chart is in the ISIS
return isis_NoError if there is a chart in the device
return isis_NoChartInDevice if there is no chart inserted
*/
ISIS_ErrorType ISIS_IsChartInserted(void);
typedef ISIS_ErrorType (* FPtr_ISIS_IsChartInserted)(void);

/*------------------- trigger measurements / calibrations -------------------*/
/*
TriggerPreScan
Triggers a pre scan sequence to find the positions of the Eye-One iSis Chart
defined with ISIS_SetOption
returns isis_DeviceNotConnected if no device is available
*/
ISIS_ErrorType ISIS_TriggerPreScan(void);
typedef ISIS_ErrorType (* FPtr_ISIS_TriggerPreScan)(void);

/*
Trigger measurement

Triggers a meausrement depending on the measurement mode set by ISIS_SetOption

use GetSpectrum(index), ISIS_GetTriStimulus(index) or ISIS_GetDensity(index) to fetch the result

returns isis_DeviceNotConnected if no device is available
*/
ISIS_ErrorType ISIS_TriggerMeasurement(bool wholeChart);
typedef ISIS_ErrorType (* FPtr_ISIS_TriggerMeasurement)(bool);

/*
MoveHome
Returns to white tile position, ejects the chart and sets the device to standby mode
returns isis_DeviceNotConnected if no device is available
*/
ISIS_ErrorType ISIS_MoveHome(void);
typedef ISIS_ErrorType (* FPtr_ISIS_MoveHome)(void);

/*------------------------------- get samples -------------------------------*/
/*General remarks:
Use 0 as Index, to fetch the result of a previously triggered single measurement
To fetch a result of a previously triggered scan, specify an index between 0 - (ISIS_GetNumberOfScannedSamples() - 1)
If no measurement has been triggered or if the specified index is out of range isis_NoDataAvailable is returned
*/

/* 
Get the spectrum of a previous triggered measurement 
*/
ISIS_ErrorType ISIS_GetSpectrum(float spectrum[SPECTRUM_SIZE], long row, long column);
typedef ISIS_ErrorType (* FPtr_ISIS_GetSpectrum)(float[SPECTRUM_SIZE], long, long);

/* 
Get the color vector of a previous triggered measurement 
*/
ISIS_ErrorType ISIS_GetTriStimulus(float tristimulus[TRISTIMULUS_SIZE], long row, long column);
typedef ISIS_ErrorType (* FPtr_ISIS_GetTriStimulus)(float[TRISTIMULUS_SIZE], long, long);

/* 
Get the all densities (cyan, magenta, yellow, black) of a previous triggered measurement 
if pxAutoDensity is not null, *pxAutoDensity will be set accordingly
*/
ISIS_ErrorType ISIS_GetDensities(float densities[DENSITY_SIZE], long *autoDensityIndex, long row, long column);
typedef ISIS_ErrorType (* FPtr_ISIS_GetDensities)(float[DENSITY_SIZE], long*, long, long);

ISIS_ErrorType ISIS_GetDensity(float *density, long row, long column);
typedef ISIS_ErrorType (* FPtr_ISIS_GetDensity)(float*, long, long);

ISIS_ErrorType ISIS_GetSpectralDensity(float densitySpectrum[SPECTRUM_SIZE], long row, long column);
typedef ISIS_ErrorType (* FPtr_ISIS_GetSpectralDensity)(float[SPECTRUM_SIZE], long, long);

const char* ISIS_GetBarcodeText(void);
typedef ISIS_ErrorType (* FPtr_ISIS_GetBarcodeText)(void);


/*------------------ setting measurement mode & conditions ------------------*/
/*
*/
ISIS_ErrorType ISIS_SetOption(const char *key, const char *value);
typedef ISIS_ErrorType (* FPtr_ISIS_SetOption)(const char*, const char*);

const char* ISIS_GetOption(const char *key);
typedef const char* (* FPtr_ISIS_GetOption)(const char*);

#ifdef __cplusplus
}
#endif

#endif /*EYEONE_ISIS_H*/

