/* All of these C functions start with libspectrometer_ to prevent namespace
 * collisions.
 */
#ifndef LIB_SPECTROMETER
#define LIB_SPECTROMETER


#define DLL_DECL extern "C" _declspec(dllexport) 




 /////////////////////////////////////////////////////////////////
 // typedef 
 /////////////////////////////////////////////////////////////////
//PROTOCOL_TYPE;
//	PROTOCOL_JUMP = 0
//  Other protocol check with support engineer


//errorCode
//ERR_CODE_NONE=1;
//ERR_CODE_DEVICE_NOT_CONNECTED=2;
//ERR_CODE_PARAMETER_INVALID=3;
//ERR_CODE_FEATURE_NOT_SUPPORT=4;



 /////////////////////////////////////////////////////////////////
 // SPECTROMETER open close function
 /////////////////////////////////////////////////////////////////
/**
 * This function opened specified spectrometer attached to the PC via USB.
 * @param Index is started from 0, and to N-1, eg, we have 3 spectrometer, the index is 0,1,2
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param protocol means, this SDK supported spectrometers from different vendor,
 * By default we use protocol=0, to open default spectrometer using default protocol
 * more spectrometer supported please check with technical support engineer.
 * @return int Return value to indicate if the specified spectrometer we opened successfully or not, 1=successfully, 0=not opened
 
 
 * Note that the index used to open a device with this function should also
 * be used to communicate with that same device in the other functions
 * provided here. 
 */
DLL_DECL int libspectrometer_open_spectrometer(int protocol, int index, int* error_code);

/**
 * @brief This function closes specified spectrometer attached to the PC.
 * @param index , position of spectrometer connected to the PC
 * @param error_code please see above
 * @return int: This function will return 1 no matter what!
 */
DLL_DECL int libspectrometer_close_spectrometer(int index, int* error_code);

/**
 * @brief This function opens ALL detected spectrometer attached to the system.
 * @param protocol means, this SDK supported spectrometers from different vendor,
 * By default we use protocol=0, to open default spectrometer using default protocol
 * more spectrometer supported please check with technical support engineer.
 * @param error_code please see above
 * @param indexSpec (Input) if not -1 only open the first detected device
 * @return int: The function will return an integer of number it opened
 * device successfully, or 0 if no device was opened 
 */
DLL_DECL int libspectrometer_open_all_spectrometers(int protocol, int* error_code, int indexSpec = -1);

/**
 * @brief This function closes all spectrometers attached to the system.
 * @param error_code please see above
 * @return int: This function will return 1 no matter what!
 */
DLL_DECL int libspectrometer_close_all_spectrometers(int* error_code);

/////////////////////////////////////////////////////////////////
// SPECTROMETER main function
/////////////////////////////////////////////////////////////////
/**
 * @brief This function returns a string indicate the model type of the spectrometer.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param buffer A character buffer muset be allocated by Upper Layer Application
 * @param buffer_length (Input) allocated size of the buffer, count in byte
 * @return int: return 1 when success, return 0 if has error
 */
DLL_DECL int libspectrometer_get_model(int index, int* error_code, char* buffer, int buffer_length);


/**
 * @brief This function returns a string indicate the serial number of the spectrometer.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param buffer A character buffer muset be allocated by Upper Layer Application
 * @param buffer_length (Input) allocated size of the buffer, count in byte
 * @return int: return 1 when success, return 0 if has error
 */
DLL_DECL int libspectrometer_get_serial_number(int index, int* error_code, char* buffer, int buffer_length);


/**
 * @brief This function sets the trigger mode for the specified device.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param mode (Input) a trigger mode
 *  mode=1 (software trigger, PC software start one command , and spectrometer will do one acquisition)
 *  mode=2 (external signal trigger spectrometer， trigger signal is posted by remote device)
 *	mode=3(free, always running mode, never stop, this mode will always acquisition data from CCD)
 * @return int: return 1 when success, return 0 if has error
 * please be noted, it is not allow to set trigger mode while acquisition is on going
 */
DLL_DECL int libspectrometer_set_trigger_mode(int index, int* error_code, int mode);


/**
 * @brief This function sets the timeout when in external mode for the specified device.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param timeout ,specify the timeout for external trigger
 * @return int: return 1 when success, return 0 if has error
 * please be noted, it is not allow to set trigger mode while acquisition is on going
 */
DLL_DECL int libspectrometer_set_external_trigger_timeout(int index, int* error_code, long timeout);


/**
 * @brief This function sets the running mode for the specified device. With running mode, we need
 * to save dark spectrum and reference spectrum first (by sending relatived command). With help of this running mode, we can
 * read processed data directly from spectrometer
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param mode (Input) a running mode
 
		#define RUNNING_MODE_RAW_DATA 0
		#define RUNNING_MODE_TRANS 1
		#define RUNNING_MODE_REFLEX 2
		#define RUNNING_MODE_RADIA 3
		#define RUNNING_MODE_ABSORB 4

 * @return int: return 1 when success, return 0 if has error
 * please be noted, it is not allow to set trigger mode while acquisition is on going
*/
DLL_DECL int libspectrometer_set_running_mode(int index, int* error_code, int mode);


/**
 * @brief This function sets the integration time for the specified device (by index).
 * this command has two behaviour,
	1: when spectrometer is not in acquisition, we can change the integration time
	2: when spectrometer is in acquisition, we will stop previous acquisition, and set the
	new integration time to the spectrometer.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param integration_time_micros (Input) The new integration time in units of
 *      microseconds
 *
 * @return int: return 1 when success, return 0 if has error
 */
DLL_DECL int libspectrometer_set_integration_time_microsec(int index, int* error_code,
	unsigned long integration_time_micros);

/**
 * @brief This function returns the smallest integration time setting,
 *        in microseconds, that is valid for the spectrometer.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return Returns minimum legal integration time in microseconds , here always be 1ms
 */
DLL_DECL long libspectrometer_get_min_integration_time_microsec(int index, int* error_code);

/**
 * @brief This computes the wavelengths range of the spectrometer 
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param wavelengths (Output) A array of doubles which memory is allocated by Upper Layer Application
 * @param length (Input) The number of array (count in double) 
 * @return int: An integer of pixel count of this spectrometer
 */
DLL_DECL int libspectrometer_get_wavelengths(int index, int* error_code, double* wavelengths, int length);



/**
 * @brief This acquires a spectrum and returns raw spectrum
 *
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param buffer (Output) A buffer (with memory allocated by Upper Layer Application) to hold the
 *        spectral data
 * @param buffer_length (Input) The length of the buffer in double (count in double)
 * @return int: The number of double read into the buffer
 *
 * A formatted spectrum returns exactly one double-precision floating-point IEEE value
 * per pixel, The spectrometer has also had gain control (gain control)
 * applied, meaning it has been scaled up to the spectrometer's full dynamic range using
 * the gain setting recorded in that spectrometer’s EEPROM. user can't change the gain control value
 */
DLL_DECL int libspectrometer_get_raw_spectrum(int index, int* error_code,
	double* buffer, int buffer_length);


/**
 * @brief This acquires a spectrum and returns (raw - dark) spectrum
 *        floats(spectrum minues dark spectrum which stored in the EEPROM during factory calibration. 
		  In this mode, gain control should be automatically
 *        performed for devices that support it.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param buffer (Output) A buffer (with memory allocated by Upper Layer Application) to hold the
 *        spectral data
 * @param buffer_length (Input) The length of the buffer in double (count in double)
 * @return int: The number of double read into the buffer
 *
 */
DLL_DECL int libspectrometer_get_reduced_spectrum(int index, int* error_code,
	double* buffer, int buffer_length);



/**
 * @brief This return a processed spectrum data to host
 * 		  in raw mode, return raw spectral
 *		  in transmit mode, return transmit ratio
 *		  in reflex mode, return reflex ratio
 *		  in absorb mode, return absorb ratio
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param buffer (Output) A buffer (with memory allocated by Upper Layer Application) to hold the
 *        spectral data
 * @param buffer_length (Input) The length of the buffer in double (count in double)
 * @return int: The number of double read into the buffer
 */
DLL_DECL int libspectrometer_get_processed_spectrum(int index, int* error_code,
	double* buffer, int buffer_length);


/**
 * @brief This returns the number of pixels in the spectrometer     
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: An integer denoting the length of a formatted spectrum (in pixels)
 */
DLL_DECL int libspectrometer_get_raw_spectrum_length(int index, int* error_code);


/**
 * @brief set hardware average count, spectrometer will do the average automatically, 
 * and hardware only return only one spectrum(after average), which contains averaged data
 * upper software can also do the average by upload the several packages from spectrometer to PC, 
 * but upper layer application average will cost too much time
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 */
DLL_DECL int libspectrometer_set_average(int index, int* error_code, int value);


/**
 * @brief set the boxcar of the spectrometer, 
 * be noted : must be in odd number
 *  ABCD X EFGH, where X is current pixel, and AAAA BBBB means value = 4;
 *  X = X + D/2 + C/4 + B/8 + A/16 + E/2 + F/4 + G/8 + H/16
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 */
DLL_DECL int libspectrometer_set_boxcar(int index, int* error_code, int value);


/**
 * @brief save current collected spectrum as reference spectrum in the RAM of spectrometer
 * this data will be lost after spectrometer lost power
 * user can also save the reference spectrum in the EEPROM by using special factory tool
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 *
 * Save last collected spectrum in the cache of spectrometer as reference spectrum
 * further spectrum can be use processed_spectrum function to get processed data
 */
DLL_DECL int libspectrometer_save_as_reference_spectrum(int index, int* error_code);


/** 
 * @brief save current collect spectrum as dark spectrum in the eeprom
 * this data will be lost after spectrometer lost power
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 * Save last collected spectrum in the cache of spectrometer as dark spectrum
 * further spectrum can be use processed_spectrum function to get processed data
 */
DLL_DECL int libspectrometer_save_as_dark_spectrum(int index, int* error_code);

/**
 * @brief This function sets the shutter state on the spectrometer if system has shutter outside,
   and this shutter connected to GPIO of spectrometer.
 * @param index (Input) The index of a device previously opened with open_spectrometer().
 * @param error_code (Output) A pointer to an integer that can be used for storing
 *        error codes.
 * @param opened (Input)  1=open, 0=close
 * @return int: return 1 when success, return 0 if has error

 */
DLL_DECL int libspectrometer_set_shutter_open(int index, int* error_code, int opened);



/**
 * @brief spectrometer can connect a XNEON light outside, Spectrometer has the capability to
 * tunr on the XNEON ligh sychronized with the spectrum acquisition,
 * Normally the XNEON need 6ms to get charged, and flash in 1us after charge is full.
 * Higher charge voltage (12V), smaller charger time needed.
 * We can specify the High period and low period of the XNEON flash time, so that we can control the XNEON to 
 * flash more than one time in one spectrum acquisiton period, This will cause more brighter of the light
 * This will be very helpful, it means we can control the brightness of the light, this usage is popular
 * when the liquid measurement. Low concentration liquid we can flash less, while High concentration liquid, we can flash 
 * more times to get the proper absorbance.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 * @param mode (Input) 
 *			mode = 0 (xneon always off, default value)
 *			mode = 1 (xneon always on)
 *			mode = 2 (xneon flash for one time when collect spectrum)
 * @param  flash_count when enable ligh, how many times XNEON will flash in one spectrum acquisition
 * please remember , integration time should be 8ms * flash_count, eg, flash_count=10, integration_time should be 
 * at least 80ms. Otherwise the XNEON will not get sufficient charged.
 */
DLL_DECL int libspectrometer_set_light_mode(int index, int* error_code, int mode, int flash_count);


/**
 * @brief This function sets watch dog enable or disable, we not recommend to enable this function in USB mode
 * normally this function is enabled in the serial connection mode, and used in 7X24hour usage in the industry area.
 * Because usb connection we need to enumerate device after reboot, while in serial mode, not enumerate needed
 * Plese be noted, total_time = maximum_integration_time * maximum_average, total_time should be smaller than watchdog period
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 * @param mode (Input)
 *			mode = 0 (watchdog disable, default)
 *			mode = 1 (watchdog enable	
 * @param timeout count unit is second.
 */
DLL_DECL int libspectrometer_set_watchdog(int index, int* error_code, int mode, int timeout);


/**
 * @brief This function reads a string out of the spectrometer's EEPROM slot
 *        and returns the result. Each slot is a 16 byte data. 
 * It is not recommend to write data to EEPROM slot frequently, since the SLOT is a progammable area.
 * User can read data from EEPROM slot frequently. 
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 * @param slot_number (Input) The number of the slot to read out. each slot is a 16 character array 
 * @param slot_number after 100 is drak spectrum embedded. each dark spectrum is 8192 byte, total 3 dark spectrum
 * @param buffer (Output)  A buffer (with memory already allocated by upper layer application) to hold the
 *        value read out of the EEPROM slot
 * @param buffer_length (Input) The length of the allocated output buffer (typically 16)
 *

/* SLOT 0 serial number
 * SLOT 1 model number
 * SLOT 9 serial baudrate
 * SLOT 10 gainBaseline
 * SLOT 11 gainHigh
 * SLOT 12 watchdog enable



 * SLOT 21 wavelength coef0
 * SLOT 22 wavelength coef1
 * SLOT 23 wavelength coef2
 * SLOT 24 wavelength coef3
 * SLOT 25 wavelength coef4
 * SLOT 26 wavelength coef5
 * SLOT 27 wavelength coef6
 * SLOT 28 wavelength coef7
 
 *
 * SLOT 44 ip address
 * SLOT 45 DNS
 * SLOT 46 NETWORK MASK


 * SLOT 1000 -  reference spectrum
 * SLOT 2000 -  dark spectrum
 * SLOT 3000 -  1ms dark spectrum
 * SLOT 4000 -  10ms dark spectrum
 * SLOT 5000 -  100ms dark spectrum
 * SLOT 6000 -  500ms dark spectrum
 *

 * 
 * Other space is reserved by factory used,
 * It is strongly recommended that end user not to touch unknown eeprom area
 */
DLL_DECL int libspectrometer_read_eeprom_slot(int index, int* error_code, int slot_number, unsigned char* buffer,
	int buffer_length);
 
 
 
 /** @brief This function write a string into the spectrometer's EEPROM slot
 * Each slot is a 16 byte data. 
 * It is not recommend to write data to EEPROM slot frequently, since the SLOT is a progammable area.
 * User can read data from EEPROM slot frequently. 
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 * @param slot_number (Input) The number of the slot to read out. each slot is a 16 character array 
 * @param slot_number after SLOT 1000 is drak spectrum embedded. each dark spectrum is 8192 byte, total 3 dark spectrum
 * @param buffer (Input)  A buffer contrains data to write of the EEPROM slot
 * @param buffer_length (Input) The length of the allocated output buffer (typically 16)
 *

/* SLOT 0 serial number
 * SLOT 1 model number
 * SLOT 9 serial baudrate
 * SLOT 10 gainBaseline
 * SLOT 11 gainHigh
 * SLOT 12 watchdog enable



 * SLOT 21 wavelength coef0
 * SLOT 22 wavelength coef1
 * SLOT 23 wavelength coef2
 * SLOT 24 wavelength coef3
 * SLOT 25 wavelength coef4
 * SLOT 26 wavelength coef5
 * SLOT 27 wavelength coef6
 * SLOT 28 wavelength coef7
 
 *
 * SLOT 44 ip address
 * SLOT 45 DNS
 * SLOT 46 NETWORK MASK


 * SLOT 1000 -  reference spectrum
 * SLOT 2000 -  dark spectrum
 * SLOT 3000 -  1ms dark spectrum
 * SLOT 4000 -  10ms dark spectrum
 * SLOT 5000 -  100ms dark spectrum
 * SLOT 6000 -  500ms dark spectrum
 *

 * 
 * Other space is reserved by factory used,
 * It is strongly recommended that end user not to touch unknown eeprom area
 */
DLL_DECL int libspectrometer_write_eeprom_slot(int index, int* error_code, int slot_number, unsigned char* buffer,
	int buffer_length);


/**
 * This function is reserved by factory internal used 
 * read all the eeprom from device, this command should not be used by end customer, to avoid the mistake in the spectrometer
*/
DLL_DECL int libspectrometer_read_all_eeprom(int index, int* error_code,  unsigned char* buffer,
	int buffer_length);

/** 
 * This function is reserved by factory internal used 
 * this function to push all the data into eeprom
 */
DLL_DECL int libspectrometer_flush_all_eeprom(int index, int* error_code);

/**
 * @brief This function reads the value of the TEC and returns the value in
 *        degrees celsius.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return double: The TEC temperature in degrees Celsius.
 */
DLL_DECL double libspectrometer_read_tec_current_temperature(int index, int* error_code);

/**
 * @brief This function sets the TEC temperature.
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 * @param temperature_degrees_celsius (Input) The desired temperature, in degrees
 *        Celsius.
 */
DLL_DECL int libspectrometer_set_tec_temperature(int index, int* error_code,
	double temperature_degrees_celsius);


/**
*  @brief read TEC set point only support TEC enabled device
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return double: The setting point of TEC temperature in degrees Celsius.
*/
DLL_DECL double libspectrometer_read_tec_set_point(int index, int* error_code);


/**
 * @brief This fills in the provided array (up to the given length) with the indices
 *        of the pixels that are electrically active but optically masked
 *        (a.k.a. electric dark pixels).
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @param indices (Output) A pre-allocated array of ints into which the pixel indices
 *        will be copied
 * @param length (Input) The number of values to copy into the indices array (count in size of int(4byte))
  *
 * Note that not all detectors have optically masked pixels; in that case,
 * this function will return zero.
 */
DLL_DECL int libspectrometer_get_electric_dark_pixel_indices(int index, int* error_code,
	int* indices, int length);




/////////////////////////////////////////////////////////////////
// SPECTROMETER HW and GPIO related
/////////////////////////////////////////////////////////////////
/**
 * @brief set external trigger parameter
 * external trigger timing can be defined by end user
 *
 * --SPECTROMETER -------------------------------||starting integration <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<||---
 *                     ^                                                      |
 *                     |<-delay before collect-> | <-delay after collect->  | V
 *           external trigger coming                          output signal to external device such as XNEON/laser light on 
 * ---------------------------------------------------------------------------------------------------------------------------
 *
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
*/
DLL_DECL int libspectrometer_set_external_trigger_parameter(int index, int* error_code,
	unsigned long delayBeforeAcquisitonUS, unsigned long delayAfterAcquisitonUS);

/**
 * @brief get stm32 version 
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 */
DLL_DECL int libspectrometer_get_stm32_version(int index, int* error_code, char* string, int length);

/**
 * @brief get fpga version
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
 *///, if return is null, need to be called several times
DLL_DECL int libspectrometer_get_fpga_version(int index, int* error_code, char* string, int length);

/**
 * @brief set state of GPIO pin, gpioId is index of GPIO,
 * currently only 0 (GPIO0)  or 1 (GPIO1) supported, state=1,
 * set GPIO to high, state=0 set GPIO to low
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
*/
DLL_DECL int libspectrometer_set_gpiox(int index, int* error_code, int gpioId, int state);


/**
 * @brief get input voltage of GPIO input,
 * currently only 0 (GPIO0)  or 1 (GPIO1) supported, state=1,
 * set GPIO to high, state=0 set GPIO to low
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
*/
DLL_DECL int libspectrometer_read_gpio_input(int index, int* error_code, int gpioId);

/**
 * @brief automatically set the integration time, user can specfied the min Y intensity of spectrum he wanted, typical min=40000
 * currently only 0 (GPIO0)  or 1 (GPIO1) supported, state=1,
 * set GPIO to high, state=0 set GPIO to low
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
*/
DLL_DECL long libspectrometer_set_auto_integration_time(int index, int* error_code, double min);



/////////////////////////////////////////////////////////////////
// LASER related
/////////////////////////////////////////////////////////////////
/**
 * @brief  state = 1 open laser, state = 0 close laser
 *
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
*/
DLL_DECL int libspectrometer_set_laser_switch(int index, int* error_code, int laser_id, int state);



/**
 * @brief  set power of laser, 785laser range from 1 - 500mw, 532laser range from 1 - 100mw
 *
 * @param index the position of the spectrometer, if only one spectrometer connected to PC,
 * please use index=0, to open the spectromter. If we have more than one spectrometer, we can use 
 * index = 0.... N-1 to open specfied spectrometer.
 * please be noted, if spectrometer is changed to different PC USB port , the index of the spectrometer may be also changed
 * @param error_code please see above
 * @return int: return 1 when success, return 0 if has error
*/
DLL_DECL int libspectrometer_set_laser_power(int index, int* error_code, int laser_id, int power);




#endif