#pragma once

#ifndef DOXYGEN_SHOULD_SKIP_THIS
#if defined(WIN32)
#ifdef WHALETEQ_API

#else
#define WHALETEQ_API extern "C" __declspec(dllimport)
#endif
#elif defined(LINUX) || defined(OSX)
#define WHALETEQ_API extern "C"
#endif
#endif


typedef enum  {
    OutputOff = 0,         //!< Stop output
    OutputSine,            //!< Sine
    OutputTriangle,        //!< Triangle
    OutputSquare,          //!< Square
    OutputRectanglePulse,  //!< Rectangle Pulse
    OutputTrianglePulse,   //!< Triangle Pulse
    OutputExponential,     //!< Exponential
    OutputECG2_27,         //!< ECG 2-27 waveform	
    OutputCustomECG,       //!< ECG customized waveform
    OutputRawData = 18     //!< Play Raw Data
} OutputFunction;

typedef enum {
    Lead_RA,                //!< RA
    Lead_LA                 //!< LA
} OutputLead;

typedef enum {
    SinglePulse = 0,            //!< Single Pulse
    DoublePulse_150ms,          //!< Double Pulse with interval 150ms
    DoublePulse_250ms           //!< Double Pulse with interval 250ms
} PacingPulse;

/// @anchor structMODEL_INFORMATION
/// @brief Define a structure of the device model; for C code, you can get the serial number by the format:
///        ("W%c%c%02x%02x-%02d%04d", ProductName[0], ProductName[1], GenerationNumber, ModelNumber, Year, SerialNumber)
typedef struct {
    char			ProductName[2];
    unsigned char	GenerationNumber;
    unsigned char	ModelNumber;
    int				SerialNumber;       //!< device serial number
    int				Year;               //!< 0x11 = 2017
} MODEL_INFORMATION;

/// @anchor structHW_INFORMATION
/// @brief Define a structure of device hw and fw information
/// @details <B>FW version:</B> x.y (ex: version 1.2)\n
///          <B>HW version:</B> x (ex: version 9)
typedef struct {
    int         FWMajorVersion;    //!< FW major version
    int         FWMinorVersion;    //!< FW minor version
    int         FWBuildVersion;    //!< FW build version
    int         HWMajorVersion;    //!< HW version
    int			HWMinorVersion;    //!< PCB version
} HW_INFORMATION;

/// @anchor structPLAY_RAW_DATA
/// @brief Define a structure of ac and dc raw data
///          <B>HW version:</B> x (ex: version 9)
typedef struct {
    double  SampleRate;   //!< sampling frequency
    int     Size;         //!< the number of points for AC and DC
    double  *AC;          //!< the array of AC data; unit: mV
    double  *DC;          //!< the array of DC data; unit: mV
} PLAY_RAW_DATA;


/// \fn DeviceConnectedCB
/// \brief Called when the device is connected or disconnected
/// @param connected    true if connected; otherwise, it's false
typedef void (*ConnectedCallback) (bool connected);

/// \fn TimeAmplitudeCB
/// \brief Callback the time and amplitude of every sampling points
/// @param  time from the output signal changed, in second
/// @param  amplitude of the output voltage, in mV
///
typedef void (*SignalOutputCallback) (double time, double amplitude);

/// @fn OutputFunctionCallback(OutputFunction_E func)
/// @brief Callback main function during frequency scanning
/// @param function to callback current main function in type ::OutputFunction_E
/// @see ::RegisterSyncMainFuncCB
typedef void (*OutputFunctionCallback) (OutputFunction function);

/// @fn FrequencyCallback
/// @brief Callback frequency value during "Baseline Reset Test" or "Frequency Scanning"
/// @param frequency frequency to callback in <strong> Hz </strong>
/// @see ::RegisterSyncFreqCB
typedef void (*FrequencyCallback) (double frequency);

//
// Initialization & Cleanup
//

///
/// Initialization; register connection event listener
///
/// During initialization, it will try to connect a device. If a device is found,
/// the cb function will be called. After then, if a device is disconnected,
/// the cb will be called again to notify the disconnection event. 
///
/// @param[in] cb  A callback function that is used to receive the connection or disconnection event
///
WHALETEQ_API 
bool 
WECGInit (
    ConnectedCallback cb
);

///
/// Connect the device.
///
/// @param[in] portNumber            Device COM port number; -1 means the port number is automatically selected
/// @param[in] millisecondsTimeout   Connection timeout; the number of milliseconds to connect, or -1 to wait indefinitely
/// @return true if the device is connected; false if the time-out interval elapsed and 
///         the device is still not connected
///
WHALETEQ_API 
bool 
WECGConnect (
    unsigned int portNumber, 
    unsigned int millisecondsTimeout
);

///
/// Disconnect the device and clean up library resource
///
WHALETEQ_API 
void 
WECGFree (
    void
);


///
/// Get device information
/// @param[out] modelInfo     A pointer to a ::MODEL_INFORMATION structure
/// @return true if success, or false if failed
///
WHALETEQ_API 
bool 
WECGGetDeviceInformation (
    MODEL_INFORMATION *modelInfo
);

///
/// Get device serial number (main module)
///
/// @return a null-terminated string of serial number text; DO NOT free the returned string
///
WHALETEQ_API 
char* 
WECGGetSerialNumber (
    void
);

///
/// Get device FW/HW information
/// @param[out] hwInfo     A pointer to a ::HW_INFORMATION structure
/// @return true if success, or false if failed
///
WHALETEQ_API 
bool 
WECGGetHWInformation (
    HW_INFORMATION *hwInfo
);

///
/// Reset all parameters to default value, and close all leads
///
WHALETEQ_API 
void 
WECGReset (
    void
);

///
/// Check if device is connected
/// @return true if the device is connected, or false otherwise
///
WHALETEQ_API 
bool 
WECGIsConnected (
    void
);

///
/// Check if the device is playing
/// @return     true if playing, or false otherwise
///
WHALETEQ_API 
bool 
WECGIsPlaying (
    void
);

///
/// Register a AC output callback <br>
/// The cb function will be called with every AC sampling points when playing
/// @param cb   the function to callback AC output.
/// @note the divider is synchronized with the one in DC callback, and if the value is invalid, 
/// it will be set to default.
/// 
WHALETEQ_API 
void 
WECGRegisterSignalOutputCallback (
    SignalOutputCallback cb
);

///
/// Register a DC output callback <br>
/// The cb function will be called with every DC sampling points when playing and DC enabled
/// @note the divider is synchronized with the one in AC callback, and if the value is invalid, 
/// it will be set to default.
/// 
WHALETEQ_API 
void 
WECGRegisterPacingOutputCallback (
    SignalOutputCallback cb
);

///
/// Register a callback function to get main function during frequency scanning
/// @param cb callback function in type ::SyncMainFuncCB
///
WHALETEQ_API 
void 
WECGRegisterOutputFunctionCallback (
    OutputFunctionCallback cb
);

///
/// Register a callback function to receive frequency value during "Baseline Reset Test" or "Frequency Scanning"
/// @param cb a callback function in type ::SyncFreqCB
/// @see ::SetBaselineResetTest
/// @see ::SetFreqScanSine
/// @see ::SetFreqScanECG
///
WHALETEQ_API 
void 
WECGRegisterFrequencyCallback (
    FrequencyCallback cb
);

///
/// Change the state of leads. Default: only ::Lead_RA on
/// @param channel  the channel number; the supported channel is 0~3
/// @param lead     the lead to control
//
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized 
/// -2: unknown error @endverbatim
///
WHALETEQ_API 
int 
WECGSetOutputLead (
    int channel, 
    OutputLead lead
);

///
/// Set output function (play raw mode)
/// @param function output function type @note if <tt>function</tt> is not ::Output_Off, the device will start output
/// @return 0 if success, or -1 if failed
///
WHALETEQ_API 
int 
WECGSetOutputFunction (
    OutputFunction function
);


///
/// Set output function (standalooe mode)
/// @param function output function type @note if <tt>function</tt> is not ::Output_Off, the device will start output
/// @return 0 if success, or -1 if failed
///
WHALETEQ_API
int
WECGOutputSignal (
	OutputFunction function
);

///
/// Get current output function
/// @return enum ::OutputFunction_E as current output function
/// @see ::SetOutputFunc
///
WHALETEQ_API 
OutputFunction 
WECGGetOutputFunction (
    void
);

//
// Amplitude (mV)
//

#define DefaultAmplitude    1.0			 //!< mV
#define MaxAmplitude        5.0		 //!< mV
#define MinAmplitude        -5.0		 //!< mV
#define MaxAmplitudeECG     5.0		     //!< mV
#define MinAmplitudeECG     -5.0		 //!< mV

///
/// Set AC output voltage amplitude
/// @param amplitude	amplitude of AC output in <strong> mV </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
///	-2: value out of range
///	-3: "Baseline Reset Test" is working @endverbatim
/// @see ::DefaultAmplitude
/// @see ::MaxAmplitude
/// @see ::MinAmplitude
/// @see ::MaxAmplitudePulse
/// @see ::MinAmplitudePulse
/// @see ::MaxAmplitudeECG
/// @see ::MinAmplitudeECG
///
WHALETEQ_API 
int 
WECGSetAmplitude (
    double amplitude
);

///
/// Get current AC output voltage amplitude
/// @return amplitude of AC output in <strong> mV </strong>
/// @see ::SetAmplitude
///
WHALETEQ_API 
double 
WECGGetAmplitude (
    void
);

//
// Frequency (Hz)
//

#define DefaultFrequency        1.0			//!< Hz
#define MaxFrequency            500.0		//!< Hz
#define MinFrequency			0.05		//!< Hz
#define MaxFrequencyECG			6.0			//!< Hz, for ::Output_ECG2_27 and ::Output_Custom_ECG
#define MinFrequencyECG			0.017		//!< Hz, for ::Output_ECG2_27 and ::Output_Custom_ECG
#define MaxFrequencyPulseWave	5.0			//!< Hz, for ::Output_RectanglePulse and ::Output_TrianglePulse

///
/// Set frequency of waveform
/// @param frequency	frequency of output function in <strong> Hz </strong>
/// @note If failed, try to ::SetOutputFunc first
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
///	-2: value out of range
///	-3: "Frequency Scan" is working
///	-4: "Baseline Reset Test" is working @endverbatim
/// @see ::DefaultFrequency
/// @see ::MaxFrequency
/// @see ::MinFrequency
/// @see ::MaxFrequencyECG
/// @see ::MinFrequencyECG
/// @see ::MaxFrequencyPulseWave
///
WHALETEQ_API 
int 
WECGSetFrequency (
    double frequency
);

///
/// Get current frequency setting
/// @return frequency of AC output in <strong> mV </strong>
/// @see ::SetFrequency
///
WHALETEQ_API 
double 
WECGGetFrequency (
    void
);


//
// Fixed/Variable DC Offset (mV)
//
#define DefaultDCOffset			0			//!< mV
#define MaxDCOffset				300			//!< mV, fixed mode
#define MinDCOffset				-300		//!< mV, fixed mode
#define MaxDCOffsetVarMode		1000		//!< mV
#define MinDCOffsetVarMode		-1000		//!< mV

///
/// Set DC offset
/// @param dcOffset	DC offset on output function in <strong> mV </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
///	-2: value out of range @endverbatim
/// @see ::DefaultDCOffset
/// @see ::MaxDCOffset
/// @see ::MinDCOffset
/// @see ::MaxDCOffsetVarMode
/// @see ::MinDCOffsetVarMode
///
WHALETEQ_API 
int 
WECGSetDCOffset (
    int channel,
    int dcOffset
);

///
/// Get current DC offset setting
/// @return current DC offset setting in <strong> mV </strong>
/// @see ::SetDCOffset
///
WHALETEQ_API 
int 
WECGGetDCOffset (
    void
);


///
/// Set DC offset variable mode <br>
/// Default: <tt> true </tt>
/// @param onOff	true to set DC offset variable mode, otherwise fixed mode
/// @note The fixed mode is valid only when DC offset is ::MaxDCOffset or ::MinDCOffset
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized @endverbatim
/// @see ::MaxDCOffset
/// @see ::MinDCOffset
/// @see ::MaxDCOffsetVarMode
/// @see ::MinDCOffsetVarMode
///
WHALETEQ_API 
int 
WECGSetDCOffsetVariableMode (
    int channel,
    bool onOff
);

///
/// Get current DC offset variable mode setting
/// @return true if the setting is on variable mode, or false on fixed mode
/// @see ::SetDCOffsetVariableMode
///
WHALETEQ_API 
bool 
WECGGetDCOffsetVariableMode (
    void
);


//
// Pulse Width (ms)
//

#define DefaultPulseWidth    100            //!< ms
#define MaxPulseWidth        300            //!< ms
#define MinPulseWidth        1              //!< ms

///
/// Set the pulse width of pulse function
/// @param pulseWidth the pulse width to set in <strong> ms </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
///	-2: value out of range @endverbatim
/// @see ::DefaultPulseWidth
/// @see ::MaxPulseWidth
/// @see ::MinPulseWidth
///
WHALETEQ_API 
int 
WECGSetPulseWidth (
    double pulseWidth
);

///
/// Get current pulse width setting
/// @return the current pulse width setting in <strong> ms </strong>
///
WHALETEQ_API 
double 
WECGGetPulseWidth (
    void
);


//
// PR Interval (ms)
//
#define DefaultPRInterval    160            //!< ms
#define MaxPRInterval        200            //!< ms
#define MinPRInterval        0              //!< ms

///
/// Set PR interval of customized ECG waveform
/// @param time PR interval in <strong> ms </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultPRInterval
/// @see ::MaxPRInterval
/// @see ::MinPRInterval
/// @see ::Output_Custom_ECG
///
WHALETEQ_API 
int 
WECGSetPRInterval (
    double time
);

///
/// Get current PR interval setting of customized ECG waveform
/// @return current PR interval setting in <strong> ms </strong>
/// @see ::SetPRInterval
///
WHALETEQ_API 
double 
WECGGetPRInterval (
    void
);


//
// QT Interval (ms)
//

#define DefaultQTInterval    350			//!< ms
#define MaxQTInterval        900			//!< ms
#define MinQTInterval        100			//!< ms

///
/// Set QT interval of customized ECG waveform
/// @param time QT interval in <strong> ms </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultQTInterval
/// @see ::MaxQTInterval
/// @see ::MinQTInterval
/// @see ::Output_Custom_ECG
///
WHALETEQ_API 
int 
WECGSetQTInterval (
    double time
);

///
/// Get current QT interval setting of customized ECG waveform
/// @return current QT interval setting in <strong> ms </strong>
/// @see ::SetQTInterval
///
WHALETEQ_API 
double 
WECGGetQTInterval (
    void
);

//
// P Duration (ms)
//

#define DefaultPDuration    100         //!< ms
#define MaxPDuration        100         //!< ms
#define MinPDuration        50          //!< ms
///
/// Set P duration of customized ECG waveform
/// @param time P duration in <strong> ms </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultPDuration
/// @see ::MaxPDuration
/// @see ::MinPDuration
/// @see ::Output_Custom_ECG
///
WHALETEQ_API 
int 
WECGSetPDuration (
    double time
);

///
/// Get current P duration setting of customized ECG waveform
/// @return current P duration setting in <strong> ms </strong>
/// @see ::SetPDuration
///
WHALETEQ_API 
double 
WECGGetPDuration (
    void
);


//
// P Wave (mV)
//

#define DefaultPWave    0.2         //!< mV
#define MaxPWave        2           //!< mV
#define MinPWave        0           //!< mV

///
/// Set P wave of customized ECG waveform
/// @param amplitude amplitude of P wave in <strong> mV </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultPWave
/// @see ::MaxPWave
/// @see ::MinPWave
/// @see ::Output_Custom_ECG
///
WHALETEQ_API 
int 
WECGSetPWave (
    double amplitude
);

///
/// Get current P wave setting of customized ECG waveform
/// @return current P wave setting in <strong> mV </strong>
/// @see ::SetPWave
///
WHALETEQ_API 
double 
WECGGetPWave (
    void
);

//
// QRS Duration (ms)
//

#define DefaultQRSDuration  100         //!< ms
#define MaxQRSDuration      200         //!< ms
#define MinQRSDuration      5           //!< ms

///
/// Set QRS duration of ECG waveform
/// @param time QRS duration in <strong> ms </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultQRSDuration
/// @see ::MaxQRSDuration
/// @see ::MinQRSDuration
///
WHALETEQ_API 
int 
WECGSetQRSDuration (
    double time
);

///
/// Get current QRS duration setting of ECG waveform
/// @return current QRS duration setting in <strong> ms </strong>
/// @see ::SetQRSDuration
///
WHALETEQ_API 
double 
WECGGetQRSDuration (
    void
);

//
// ST Deviation (mV)
//

#define DefaultSTDeviation    0             //!< mV
#define MaxSTDeviation        2.00          //!< mV
#define MinSTDeviation        -2.00         //!< mV

///
/// Set ST deviation of customized ECG waveform
/// @param amplitude amplitude of ST deviation in <strong> mV </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultSTDeviation
/// @see ::MaxSTDeviation
/// @see ::MinSTDeviation
/// @see ::Output_Custom_ECG
///
WHALETEQ_API 
int 
WECGSetSTDeviation (
    double amplitude
);

///
/// Get current ST deviation setting of customized ECG waveform
/// @return current ST deviation setting in <strong> mV </strong>
/// @see ::SetSTDeviation
///
WHALETEQ_API 
double 
WECGGetSTDeviation (
    void
);


//
// T Wave (mV)
//

#define DefaultTWave    0.2         //!< mV
#define MaxTWave        5           //!< mV
#define MinTWave        0           //!< mV

///
/// Set T wave of ECG waveform
/// @param amplitude amplitude of T wave in <strong> mV </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultTWave
/// @see ::MaxTWave
/// @see ::MinTWave
///
WHALETEQ_API 
int 
WECGSetTWave (
    double amplitude
);

///
/// Get current T wave setting of ECG waveform
/// @return current T wave setting in <strong> mV </strong>
/// @see ::SetTWave
///
WHALETEQ_API 
double 
WECGGetTWave (
    void
);


//
// ST Segment (ms)
//
#define DefaultSTSegment    70			//!< ms

///
/// Set ST Segment of customized ECG waveform
/// @param time ST Segment in <strong> ms </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultSTSegment
/// @see ::Output_Custom_ECG
///
WHALETEQ_API 
int 
WECGSetSTSegment (
    double time
);

///
/// Get current ST Segment setting of customized ECG waveform
/// @return current ST Segment setting in <strong> ms </strong>
/// @see ::SetCustomizedSTSegment
///
WHALETEQ_API 
double 
WECGGetSTSegment (
    void
);

//
// T Duration (ms)
//
#define DefaultTDuration    180			//!< ms

///
/// Set T duration of customized ECG waveform
/// @param time T duration in <strong> ms </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultTDuration
/// @see ::Output_Custom_ECG
///
WHALETEQ_API 
int 
WECGSetTDuration (
    double time
);

///
/// Get current T duration setting of customized ECG waveform
/// @return current T duration setting in <strong> ms </strong>
/// @see ::SetCustomizedTDuration
///
WHALETEQ_API 
double 
WECGGetTDuration (
    void
);


///
/// Set the input impedance mode
///
/// @param channel  the channel number; the supported channel is 0~2
/// @param mode    0: 100ohm; 1: 620Kohm; 2: 10Mohm
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized @endverbatim
/// -2: no such mode
/// 
WHALETEQ_API 
int 
WECGSetInputImpedanceMode (
    int channel,
    int mode
);

///
/// Get the input impedance mode
/// 
/// @param channel  the channel number; the supported channel is 0~2
/// @return true if the impedance is shorted
/// @see ::SetInputImpedanceMode
///
WHALETEQ_API 
int 
WECGGetInputImpedanceMode (
    int channel
);

//
// Connection between Signal Ground and GND Ground
//
WHALETEQ_API
int
WECGSetSignalGroundToGNDGround (
    int channel,
    bool connect
);

WHALETEQ_API
bool
WECGGetSignalGroundToGNDGround (
    int channel    
);


//
// Pacing
//

///
/// Set the mode of pacing pulse.
/// <p> Default: ::SinglePulse </p>
/// @param mode pulse mode in type ::PacingPulse_E
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized @endverbatim
///
WHALETEQ_API 
int 
WECGSetPacingPulseMode (
    PacingPulse mode
);

///
/// Get current pulse mode
/// @return current pulse mode setting
/// @see ::SetPacingPulseMode
///
WHALETEQ_API 
PacingPulse 
WECGGetPacingPulseMode (
    void
);

//
// Pacing Amplitude (mV)
//

#define DefaultPacingAmplitude    0			//!< mV
#define MaxPacingAmplitude        700		//!< mV
#define MinPacingAmplitude        -700		//!< mV

///
/// Set amplitude of pacing pulse
/// If the pacing amplitude is not zero, the variable mode will be auto enabled
/// @param amplitude amplitude of pacing pulse in <strong> mV </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
///
WHALETEQ_API 
int 
WECGSetPacingAmplitude (
    double amplitude
);

///
/// Get current amplitude of pacing pulse
/// @return current amplitude setting of pacing pulse
/// @see ::SetPacingAmplitude
///
WHALETEQ_API 
double 
WECGGetPacingAmplitude (
    void
);

//
// Pacing Duration (ms)
//
#define DefaultPacingDuration    2.0			//!< ms
#define MaxPacingDuration        3.0			//!< ms
#define MinPacingDuration        0.1			//!< ms

///
/// Set duration of pacing pulse
/// @param time pulse duration in <strong> ms </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultPacingDuration
/// @see ::MaxPacingDuration
/// @see ::MinPacingDuration
///
WHALETEQ_API 
int 
WECGSetPacingDuration (
    double time
);

///
/// Get current duration setting of pacing pulse
/// @return current duration of pacing pulse in <strong> ms </strong>
/// @see ::SetPacingDuration
///
WHALETEQ_API 
double 
WECGGetPacingDuration (
    void
);

//
// Pacing Rate (BPM)
//
#define DefaultPacingRate    60				//!< BPM
#define MaxPacingRate        360			//!< BPM
#define MinPacingRate        10				//!< BPM

///
/// Set pacing rate
/// @note If success, the synchronized state of pcaing will be off
/// @param BPM pacing rate in <strong> BPM </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::DefaultPacingRate
/// @see ::MaxPacingRate
/// @see ::MinPacingRate
/// @see ::SetPacingRateSynchronized
///
WHALETEQ_API 
int 
WECGSetPacingRate (
    unsigned int BPM
);

///
/// Get current pacing rate setting
/// @return current pacing rate in <strong> BPM </strong>
///
WHALETEQ_API 
unsigned int 
WECGGetPacingRate (
    void
);


///
/// Make pacing rate synchronized with the frequency of main function <br>
/// Default: <tt>true</tt>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::SetPacingRate
/// @see ::SetFrequency
///
WHALETEQ_API 
int 
WECGSetPacingRateSynchronized (
    void
);


//
// Overshoot Time Constant (ms)
//

#define DefaultOvershootTimeConstant    0           //!< ms
#define MaxOvershootTimeConstant        100         //!< ms
#define MinOvershootTimeConstant        0           //!< ms

///
/// Set time constant of pacing overshooting
/// @param time time constant in <strong> ms </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::SetOvershootAmplitude
///
WHALETEQ_API 
int 
WECGSetOvershootTimeConstant (
    unsigned int time
);

///
/// Get time constant of pacing overshooting
/// @return time constant in <strong> ms </strong>
/// @see ::SetOvershootTimeConstant
///
WHALETEQ_API 
unsigned int 
WECGGetOvershootTimeConstant (
    void
);

//
// Overshoot Amplitude (mV)
//

#define DefaultOvershootAmplitude        0          //!< mV
#define MaxOvershootAmplitude            5.00       //!< mV
#define MinOvershootAmplitude            0          //!< mV

///
/// Set amplitude of pacing overshooting
/// @param amplitude amplitude of pacing overshooting in <strong> mV </strong>
/// @return state of result:
///@verbatim
///	 0: success
///	-1: device isn't initialized
/// -2: value out of range @endverbatim
/// @see ::SetOvershootTimeConstant
///
WHALETEQ_API 
int 
WECGSetOvershootAmplitude (
    double amplitude
);

///
/// Get amplitude of pacing overshooting
/// @return amplitude of pacing overshooting in <strong> mV </strong>
/// @see ::SetOvershootAmplitude
///
WHALETEQ_API 
double 
WECGGetOvershootAmplitude (
    void
);


//
// Dynamic Range Test
//

#define DefaultDynamicRangeTestAmp    1.0			//!< mV
#define MaxDynamicRangeTestAmp       10.0			//!< mV
#define MinDynamicRangeTestAmp        	0			//!< mV
#define DefaultDynamicRangeTestFreq    40			//!< Hz
#define MaxDynamicRangeTestFreq        60			//!< Hz
#define MinDynamicRangeTestFreq         1			//!< Hz

///
/// Set dynamic range test
/// @param onOff		true to start test; otherwise, stop test
/// @param useTriangle	true to use <strong>triangle wave</strong> as main function;
/// 					otherwise, use <strong>square wave</strong> instead
/// @param amplitude	amplitude of the sine wave in <strong> mV </strong>
/// @param frequency	frequency of the <strong>sine wave</strong> in <strong> Hz </Strong>
////@verbatim
///	 0: success
///	-1: device isn't initialized
///	-2: amplitude out of range
///	-3: frequency out of range @endverbatim
/// @see ::DefaultDynamicRangeTestAmp
/// @see ::MaxDynamicRangeTestAmp
/// @see ::MinDynamicRangeTestAmp
/// @see ::DefaultDynamicRangeTestFreq
/// @see ::MaxDynamicRangeTestFreq
/// @see ::MinDynamicRangeTestFreq
///
WHALETEQ_API 
int 
WECGSetDynamicRangeTest (
    bool onOff, 
    bool useTriangle, 
    double amplitude, 
    double frequency
);

///
/// Check if dynamic range test is enabled
/// @return true if dynamic range test is enabled
///
WHALETEQ_API 
bool 
WECGGetDynamicRangeTest (
    void
);

///
/// Save the current settings to standalone mode
/// 
WHALETEQ_API
bool
WECGSaveToStandaloneMode (
    OutputFunction function
);

//
// Frequenc Scan
//

#define DefaultScanSineStartFreq    0.67            //!< Hz
#define DefaultScanSineStopFreq     150             //!< Hz
#define MaxScanSineFreq             500.0           //!< Hz
#define MinScanSineFreq             0.67            //!< Hz
#define DefaultScanSineDuration     30              //!< second
#define MaxScanSineDuration         180             //!< second
#define MinScanSineDuration         10              //!< second

///
/// Set sine wave frequency scan
/// @note "Output Function" would be set to "Output_Sine" when setting "OnOff" as true,
/// then "Frequency" would be locked(SetFrequency() return -3) for periodic scanning <br>
/// "Output Function" would be set to "Output_Off" when setting "OnOff" as false.
/// @param onOff             true to start, false to stop
/// @param startFrequency    the first value of frequency in <strong> Hz </strong>
/// @param stopFrequency     the last value of frequency in <strong> Hz </strong>
/// @param duration          total duration of frequency scan
////@verbatim
///	 0: success
///	-1: device isn't initialized
///	-2: start frequency out of range
///	-3: stop frequency out of range
/// -4: duration out of range @endverbatim
/// @see ::DefaultScanSineStartFreq
/// @see ::DefaultScanSineStopFreq
/// @see ::MaxScanSineFreq
/// @see ::MinScanSineFreq
/// @see ::DefaultScanSineDuration
/// @see ::MaxScanSineDuration
/// @see ::MinScanSineDuration
///
WHALETEQ_API 
int 
WECGSetFrequencyScan (
    bool onOff, 
    double startFrequency, 
    double stopFrequency, 
    int duration
);

//
//Load Raw Data
//
WHALETEQ_API
int
WECGLoadRawData (
    PLAY_RAW_DATA *rawData
);

WHALETEQ_API
void
WECGEnableLoop (
    bool enable
);

//
// DLL Version
//
/// Get DLL file version
/// \return The version is 4-digits and are saved in each byte of unsigned int value.\n
///         For example, if the return value is 0x01020304, the dll version is 1.2.3.4.
WHALETEQ_API
unsigned int
WECGGetVersion (
	void
);
