#include <Windows.h>
#include "SFC5xxxDevice.h"

/***************************************
* Function pointers from ShdlcDriver.dll
***************************************/

Shdlc_FctOpenPort              Shdlc_OpenPort;
Shdlc_FctClosePort             Shdlc_ClosePort;
Shdlc_FctGetPortInformation    Shdlc_GetPortInformation;
Shdlc_FctGetDeviceInfo         Shdlc_GetDeviceInfo;
Shdlc_FctGetVersionString      Shdlc_GetVersionString;
Shdlc_FctGetVersionNbr         Shdlc_GetVersionNbr;
Shdlc_FctGetDeviceErrorState   Shdlc_GetDeviceErrorState;
Shdlc_FctDeviceReset           Shdlc_DeviceReset;
Shdlc_FctGetDeviceAddress      Shdlc_GetDeviceAddress;
Shdlc_FctSetDeviceAddress      Shdlc_SetDeviceAddress;
Shdlc_FctFactoryReset          Shdlc_FactoryReset;
Shdlc_FctGetBaudrate           Shdlc_GetBaudrate;
Shdlc_FctSetBaudrate           Shdlc_SetBaudrate;

/***************************************
* Function pointers from SFC5xxxDriver.dll
***************************************/
SFC5xxx_FctTranslateErrorCode                         SFC5xxx_TranslateErrorCode;
SFC5xxx_FctReadMeasuredValue                          SFC5xxx_ReadMeasuredValue;
SFC5xxx_FctReadMeasuredValueBuffered                  SFC5xxx_ReadMeasuredValueBuffered;
SFC5xxx_FctGetCurrentCalibInfo                        SFC5xxx_GetCurrentCalibInfo;
SFC5xxx_FctLoadAndSelectCalibration                   SFC5xxx_LoadAndSelectCalibration;
SFC5xxx_FctSetSetpoint                                SFC5xxx_SetSetpoint;
SFC5xxx_FctGetSetpoint                                SFC5xxx_GetSetpoint;
SFC5xxx_FctSetSetpointAndReadMeasuredValue            SFC5xxx_SetSetpointAndReadMeasuredValue;
SFC5xxx_FctSetSetpointAndReadMeasuredValues2Sensors   SFC5xxx_SetSetpointAndReadMeasuredValues2Sensors;
SFC5xxx_FctValveSetInputSource                        SFC5xxx_ValveSetInputSource;
SFC5xxx_FctValveGetInputSource                        SFC5xxx_ValveGetInputSource;
SFC5xxx_FctValveSetUserDefinedValue                   SFC5xxx_ValveSetUserDefinedValue;
SFC5xxx_FctValveGetUserDefinedValue                   SFC5xxx_ValveGetUserDefinedValue;
SFC5xxx_FctSetUserDefinedMediumUnit                   SFC5xxx_SetUserDefinedMediumUnit;
SFC5xxx_FctGetUserDefinedMediumUnit                   SFC5xxx_GetUserDefinedMediumUnit;
SFC5xxx_FctGetUserDefinedMediumFullscale              SFC5xxx_GetUserDefinedMediumFullscale;
SFC5xxx_FctGetSensorTemperatureInCelsius              SFC5xxx_GetSensorTemperatureInCelsius;
SFC5xxx_FctGetUserControllerGain                      SFC5xxx_GetUserControllerGain;
SFC5xxx_FctSetUserControllerGain                      SFC5xxx_SetUserControllerGain;
SFC5xxx_FctGetUsePressureDependentGain                SFC5xxx_GetUsePressureDependentGain;
SFC5xxx_FctSetUsePressureDependentGain                SFC5xxx_SetUsePressureDependentGain;
SFC5xxx_FctGetInletPressure                           SFC5xxx_GetInletPressure;
SFC5xxx_FctSetInletPressure                           SFC5xxx_SetInletPressure;
SFC5xxx_FctGetUseGasTemperatureCompensation           SFC5xxx_GetUseGasTemperatureCompensation;
SFC5xxx_FctSetUseGasTemperatureCompensation           SFC5xxx_SetUseGasTemperatureCompensation;
SFC5xxx_FctGetInletGasTemperature                     SFC5xxx_GetInletGasTemperature;
SFC5xxx_FctSetInletGasTemperature                     SFC5xxx_SetInletGasTemperature;

/***************************************
* Handles to DLL files
***************************************/
static HINSTANCE _ShdlcDriverHandle = NULL;
static HINSTANCE _SFC5xxxDriverHandle = NULL;

/***************************************
* Library Functions
***************************************/

int32_t SFC5xxxDevice_LoadLibrary()
{
  // load libraries
  _ShdlcDriverHandle = LoadLibrary(TEXT("ShdlcDriver.dll"));
  if(_ShdlcDriverHandle == NULL) return -2;
  _SFC5xxxDriverHandle = LoadLibrary(TEXT("SFC5xxxDriver.dll"));
  if(_SFC5xxxDriverHandle == NULL) return -2;

  // load ShdlcDriver functions
  Shdlc_OpenPort = (Shdlc_FctOpenPort)GetProcAddress(_ShdlcDriverHandle, "OpenPort");
  if(Shdlc_OpenPort == NULL) return -1;

  Shdlc_ClosePort = (Shdlc_FctClosePort)GetProcAddress(_ShdlcDriverHandle, "ClosePort");
  if(Shdlc_ClosePort == NULL) return -1;

  Shdlc_GetDeviceInfo = (Shdlc_FctGetDeviceInfo)GetProcAddress(_ShdlcDriverHandle, "GetDeviceInfo");
  if(Shdlc_GetDeviceInfo == NULL) return -1;

  Shdlc_GetPortInformation = (Shdlc_FctGetPortInformation)GetProcAddress(_ShdlcDriverHandle, "GetPortInformation");
  if(Shdlc_GetPortInformation == NULL) return -1;

  Shdlc_GetVersionString = (Shdlc_FctGetVersionString)GetProcAddress(_ShdlcDriverHandle, "GetVersionString");
  if(Shdlc_GetVersionString == NULL) return -1;

  Shdlc_GetVersionNbr = (Shdlc_FctGetVersionNbr)GetProcAddress(_ShdlcDriverHandle, "GetVersionNbr");
  if(Shdlc_GetVersionNbr == NULL) return -1;

  Shdlc_GetDeviceErrorState = (Shdlc_FctGetDeviceErrorState)GetProcAddress(_ShdlcDriverHandle, "GetDeviceErrorState");
  if(Shdlc_GetDeviceErrorState == NULL) return -1;

  Shdlc_DeviceReset = (Shdlc_FctDeviceReset)GetProcAddress(_ShdlcDriverHandle, "DeviceReset");
  if(Shdlc_DeviceReset == NULL) return -1;

  Shdlc_FactoryReset = (Shdlc_FctFactoryReset)GetProcAddress(_ShdlcDriverHandle, "FactoryReset");
  if(Shdlc_FactoryReset == NULL) return -1;

  Shdlc_GetDeviceAddress = (Shdlc_FctGetDeviceAddress)GetProcAddress(_ShdlcDriverHandle, "GetDeviceAddress");
  if(Shdlc_GetDeviceAddress == NULL) return -1;

  Shdlc_SetDeviceAddress = (Shdlc_FctSetDeviceAddress)GetProcAddress(_ShdlcDriverHandle, "SetDeviceAddress");
  if(Shdlc_SetDeviceAddress == NULL) return -1;

  Shdlc_GetBaudrate = (Shdlc_FctGetBaudrate)GetProcAddress(_ShdlcDriverHandle, "GetBaudrate");
  if(Shdlc_GetBaudrate == NULL) return -1;

  Shdlc_SetBaudrate = (Shdlc_FctSetBaudrate)GetProcAddress(_ShdlcDriverHandle, "SetBaudrate");
  if(Shdlc_SetBaudrate == NULL) return -1;

  // load SFC5xxxDriver functions
  SFC5xxx_TranslateErrorCode = (SFC5xxx_FctTranslateErrorCode)GetProcAddress(_SFC5xxxDriverHandle, "TranslateErrorCode");
  if(SFC5xxx_TranslateErrorCode == NULL) return -1;

  SFC5xxx_ReadMeasuredValue = (SFC5xxx_FctReadMeasuredValue)GetProcAddress(_SFC5xxxDriverHandle, "ReadMeasuredValue");
  if(SFC5xxx_ReadMeasuredValue == NULL) return -1;

  SFC5xxx_SetSetpoint = (SFC5xxx_FctSetSetpoint)GetProcAddress(_SFC5xxxDriverHandle, "SetSetpoint");
  if(SFC5xxx_SetSetpoint == NULL) return -1;

  SFC5xxx_GetSetpoint = (SFC5xxx_FctGetSetpoint)GetProcAddress(_SFC5xxxDriverHandle, "GetSetpoint");
  if(SFC5xxx_GetSetpoint == NULL) return -1;

  SFC5xxx_ReadMeasuredValueBuffered = (SFC5xxx_FctReadMeasuredValueBuffered)GetProcAddress(_SFC5xxxDriverHandle, "ReadMeasuredValueBuffered");
  if(SFC5xxx_ReadMeasuredValueBuffered == NULL) return -1;

  SFC5xxx_GetCurrentCalibInfo = (SFC5xxx_FctGetCurrentCalibInfo)GetProcAddress(_SFC5xxxDriverHandle, "GetCurrentCalibInfo");
  if(SFC5xxx_GetCurrentCalibInfo == NULL) return -1;

  SFC5xxx_LoadAndSelectCalibration = (SFC5xxx_FctLoadAndSelectCalibration)GetProcAddress(_SFC5xxxDriverHandle, "LoadAndSelectCalibration");
  if(SFC5xxx_LoadAndSelectCalibration == NULL) return -1;

  SFC5xxx_SetSetpointAndReadMeasuredValue = (SFC5xxx_FctSetSetpointAndReadMeasuredValue)GetProcAddress(_SFC5xxxDriverHandle, "SetSetpointAndReadMeasuredValue");
  if(SFC5xxx_SetSetpointAndReadMeasuredValue == NULL) return -1;

  SFC5xxx_SetSetpointAndReadMeasuredValues2Sensors = (SFC5xxx_FctSetSetpointAndReadMeasuredValues2Sensors)GetProcAddress(_SFC5xxxDriverHandle, "SetSetpointAndReadMeasuredValues2Sensors");
  if(SFC5xxx_SetSetpointAndReadMeasuredValues2Sensors == NULL) return -1;

  SFC5xxx_ValveSetInputSource = (SFC5xxx_FctValveSetInputSource)GetProcAddress(_SFC5xxxDriverHandle, "ValveSetInputSource");
  if(SFC5xxx_ValveSetInputSource == NULL) return -1;

  SFC5xxx_ValveSetUserDefinedValue = (SFC5xxx_FctValveSetUserDefinedValue)GetProcAddress(_SFC5xxxDriverHandle, "ValveSetUserDefinedValue");
  if(SFC5xxx_ValveSetUserDefinedValue == NULL) return -1;

  SFC5xxx_ValveGetUserDefinedValue = (SFC5xxx_FctValveGetUserDefinedValue)GetProcAddress(_SFC5xxxDriverHandle, "ValveGetUserDefinedValue");
  if(SFC5xxx_ValveGetUserDefinedValue == NULL) return -1;

  SFC5xxx_SetUserDefinedMediumUnit = (SFC5xxx_FctSetUserDefinedMediumUnit)GetProcAddress(_SFC5xxxDriverHandle, "SetUserDefinedMediumUnit");
  if(SFC5xxx_SetUserDefinedMediumUnit == NULL) return -1;

  SFC5xxx_GetUserDefinedMediumUnit = (SFC5xxx_FctGetUserDefinedMediumUnit)GetProcAddress(_SFC5xxxDriverHandle, "GetUserDefinedMediumUnit");
  if(SFC5xxx_GetUserDefinedMediumUnit == NULL) return -1;

  SFC5xxx_GetUserDefinedMediumFullscale = (SFC5xxx_FctGetUserDefinedMediumFullscale)GetProcAddress(_SFC5xxxDriverHandle, "GetUserDefinedMediumFullscale");
  if(SFC5xxx_GetUserDefinedMediumFullscale == NULL) return -1;

  SFC5xxx_GetSensorTemperatureInCelsius = (SFC5xxx_FctGetSensorTemperatureInCelsius)GetProcAddress(_SFC5xxxDriverHandle, "GetSensorTemperatureInCelsius");
  if(SFC5xxx_GetSensorTemperatureInCelsius == NULL) return -1;

  SFC5xxx_GetUserControllerGain = (SFC5xxx_FctGetUserControllerGain)GetProcAddress(_SFC5xxxDriverHandle, "GetUserControllerGain");
  if(SFC5xxx_GetUserControllerGain == NULL) return -1;

  SFC5xxx_SetUserControllerGain = (SFC5xxx_FctSetUserControllerGain)GetProcAddress(_SFC5xxxDriverHandle, "SetUserControllerGain");
  if(SFC5xxx_SetUserControllerGain == NULL) return -1;

  SFC5xxx_GetUsePressureDependentGain = (SFC5xxx_FctGetUsePressureDependentGain)GetProcAddress(_SFC5xxxDriverHandle, "GetUsePressureDependentGain");
  if(SFC5xxx_GetUsePressureDependentGain == NULL) return -1;

  SFC5xxx_SetUsePressureDependentGain = (SFC5xxx_FctSetUsePressureDependentGain)GetProcAddress(_SFC5xxxDriverHandle, "SetUsePressureDependentGain");
  if(SFC5xxx_SetUsePressureDependentGain == NULL) return -1;

  SFC5xxx_GetInletPressure = (SFC5xxx_FctGetInletPressure)GetProcAddress(_SFC5xxxDriverHandle, "GetInletPressure");
  if(SFC5xxx_GetInletPressure == NULL) return -1;

  SFC5xxx_SetInletPressure = (SFC5xxx_FctSetInletPressure)GetProcAddress(_SFC5xxxDriverHandle, "SetInletPressure");
  if(SFC5xxx_SetInletPressure == NULL) return -1;

  SFC5xxx_GetUseGasTemperatureCompensation = (SFC5xxx_FctGetUseGasTemperatureCompensation)GetProcAddress(_SFC5xxxDriverHandle, "GetUseGasTemperatureCompensation");
  if(SFC5xxx_GetUseGasTemperatureCompensation == NULL) return -1;

  SFC5xxx_SetUseGasTemperatureCompensation = (SFC5xxx_FctSetUseGasTemperatureCompensation)GetProcAddress(_SFC5xxxDriverHandle, "SetUseGasTemperatureCompensation");
  if(SFC5xxx_SetUseGasTemperatureCompensation == NULL) return -1;

  SFC5xxx_GetInletGasTemperature = (SFC5xxx_FctGetInletGasTemperature)GetProcAddress(_SFC5xxxDriverHandle, "GetInletGasTemperature");
  if(SFC5xxx_GetInletGasTemperature == NULL) return -1;

  SFC5xxx_SetInletGasTemperature = (SFC5xxx_FctSetInletGasTemperature)GetProcAddress(_SFC5xxxDriverHandle, "SetInletGasTemperature");
  if(SFC5xxx_SetInletGasTemperature == NULL) return -1;

  return 0;
}

void SFC5xxxDevice_ReleaseLibrary()
{
  if(_ShdlcDriverHandle != NULL)
  {
    FreeLibrary(_ShdlcDriverHandle);
    _ShdlcDriverHandle = NULL;
  }
  if(_SFC5xxxDriverHandle != NULL)
  {
    FreeLibrary(_SFC5xxxDriverHandle);
    _SFC5xxxDriverHandle = NULL;
  }
}
