/****************************************
 * ArtemisCCDAPI.cpp
 *
 * This file is autogenerated.
  * ...and modified by BM 20070811
 ****************************************/
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#if defined(_WXMSW_)

#include <windows.h>

#include <comdef.h>

#define NFUNCS 64
static FARPROC pFuncs[NFUNCS];
static HINSTANCE hArtemisDLL=NULL;

//////////////////////////////////////////////////////////////////////////
//
// Interface functions for Artemis CCD Camera Library
//

//Error codes

enum ARTEMISERROR
{
	ARTEMIS_OK = 0,
	ARTEMIS_INVALID_PARAMETER,
	ARTEMIS_NOT_CONNECTED,
	ARTEMIS_NOT_IMPLEMENTED,
	ARTEMIS_NO_RESPONSE,
};

//Other enumeration types
enum ARTEMISPRECHARGEMODE
{
	PRECHARGE_NONE = 0,		// Precharge ignored
	PRECHARGE_ICPS,			// In-camera precharge subtraction
	PRECHARGE_FULL,			// Precharge sent with image data
};

// Camera State
enum ARTEMISCAMERASTATE
{
	CAMERA_ERROR = -1,
	CAMERA_IDLE = 0,
	CAMERA_WAITING,
	CAMERA_EXPOSING,
	CAMERA_READING,
	CAMERA_DOWNLOADING,
	CAMERA_FLUSHING,
};

// Parameters for ArtemisSendMessage
enum ARTEMISSENDMSG
{
	ARTEMIS_LE_LOW				=0,
	ARTEMIS_LE_HIGH				=1,
	ARTEMIS_GUIDE_NORTH			=10,
	ARTEMIS_GUIDE_SOUTH			=11,
	ARTEMIS_GUIDE_EAST			=12,
	ARTEMIS_GUIDE_WEST			=13,
	ARTEMIS_GUIDE_STOP			=14,
};

// Parameters for ArtemisGet/SetProcessing
// These must be powers of 2.
enum ARTEMISPROCESSING
{
	ARTEMIS_PROCESS_NULL    	=0,	// using none sometimes
	ARTEMIS_PROCESS_LINEARISE	=1,	// compensate for JFET nonlinearity
	ARTEMIS_PROCESS_VBE			=2, // adjust for 'Venetian Blind effect'
};

enum ARTEMISPROPERTIESCCDFLAGS
{
	ARTEMIS_PROPERTIES_CCDFLAGS_NULL =0, // no flag
	ARTEMIS_PROPERTIES_CCDFLAGS_INTERLACED =1, // CCD is interlaced type
	ARTEMIS_PROPERTIES_CCDFLAGS_DUMMY=0x7FFFFFFF // force size to 4 bytes
};
enum ARTEMISPROPERTIESCAMERAFLAGS
{
	ARTEMIS_PROPERTIES_CAMERAFLAGS_NULL =0, // no flag
	ARTEMIS_PROPERTIES_CAMERAFLAGS_FIFO =1, // Camera has readout FIFO fitted
	ARTEMIS_PROPERTIES_CAMERAFLAGS_EXT_TRIGGER =2, // Camera has external trigger capabilities
	ARTEMIS_PROPERTIES_CAMERAFLAGS_DUMMY=0x7FFFFFFF // force size to 4 bytes
};

//Structures

// camera/CCD properties
struct ARTEMISPROPERTIES
{
	int Protocol;
	int nPixelsX;
	int nPixelsY;
	float PixelMicronsX;
	float PixelMicronsY;
	int ccdflags;
	int cameraflags;
	char Description[40];
	char Manufacturer[40];
};

typedef void* ArtemisHandle;

// interface functions

// Return API version. XYY X=major, YY=minor
typedef int (__stdcall * TYPE_ARTEMISAPIVERSION)();
int ArtemisAPIVersion()
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[0])
			pFuncs[0]=GetProcAddress(hArtemisDLL, "ArtemisAPIVersion");
		TYPE_ARTEMISAPIVERSION pArtemisAPIVersion=(TYPE_ARTEMISAPIVERSION)pFuncs[0];
		if (NULL != pArtemisAPIVersion)
			return pArtemisAPIVersion();
	}
	return (int)NULL;
}


// ** Deprecated - use ArtemisDeviceName instead
// Get USB Identifier of Nth FTDI device. Return false if no such device.
// pName must be at least 40 chars long.
typedef bool (__stdcall * TYPE_ARTEMISFTNAME)(int Device, char * pName);
bool ArtemisFTName(int Device, char * pName)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[1])
			pFuncs[1]=GetProcAddress(hArtemisDLL, "ArtemisFTName");
		TYPE_ARTEMISFTNAME pArtemisFTName=(TYPE_ARTEMISFTNAME)pFuncs[1];
		if (NULL != pArtemisFTName)
			return pArtemisFTName(Device, pName);
	}
	return (bool)NULL;
}


// ** Deprecated - use ArtemisDeviceSerial instead
// Get USB Serial number of Nth FTDI device. Return false if no such device.
// pName must be at least 40 chars long.
typedef bool (__stdcall * TYPE_ARTEMISFTSERIAL)(int Device, char * pName);
bool ArtemisFTSerial(int Device, char * pName)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[2])
			pFuncs[2]=GetProcAddress(hArtemisDLL, "ArtemisFTSerial");
		TYPE_ARTEMISFTSERIAL pArtemisFTSerial=(TYPE_ARTEMISFTSERIAL)pFuncs[2];
		if (NULL != pArtemisFTSerial)
			return pArtemisFTSerial(Device, pName);
	}
	return (bool)NULL;
}


// ** Deprecated - use ArtemisDeviceIsCamera instead
// Return true if Nth FTDI device exists and is a camera.
typedef bool (__stdcall * TYPE_ARTEMISISCAMERA)(int Device);
bool ArtemisIsCamera(int Device)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[3])
			pFuncs[3]=GetProcAddress(hArtemisDLL, "ArtemisIsCamera");
		TYPE_ARTEMISISCAMERA pArtemisIsCamera=(TYPE_ARTEMISISCAMERA)pFuncs[3];
		if (NULL != pArtemisIsCamera)
			return pArtemisIsCamera(Device);
	}
	return (bool)NULL;
}


// Get USB Identifier of Nth USB device. Return false if no such device.
// pName must be at least 40 chars long.
typedef bool (__stdcall * TYPE_ARTEMISDEVICENAME)(int Device, char * pName);
bool ArtemisDeviceName(int Device, char * pName)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[4])
			pFuncs[4]=GetProcAddress(hArtemisDLL, "ArtemisDeviceName");
		TYPE_ARTEMISDEVICENAME pArtemisDeviceName=(TYPE_ARTEMISDEVICENAME)pFuncs[4];
		if (NULL != pArtemisDeviceName)
			return pArtemisDeviceName(Device, pName);
	}
	return (bool)NULL;
}


// Get USB Serial number of Nth USB device. Return false if no such device.
// pName must be at least 40 chars long.
typedef bool (__stdcall * TYPE_ARTEMISDEVICESERIAL)(int Device, char * pName);
bool ArtemisDeviceSerial(int Device, char * pName)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[5])
			pFuncs[5]=GetProcAddress(hArtemisDLL, "ArtemisDeviceSerial");
		TYPE_ARTEMISDEVICESERIAL pArtemisDeviceSerial=(TYPE_ARTEMISDEVICESERIAL)pFuncs[5];
		if (NULL != pArtemisDeviceSerial)
			return pArtemisDeviceSerial(Device, pName);
	}
	return (bool)NULL;
}


// Return true if Nth USB device exists and is a camera.
typedef bool (__stdcall * TYPE_ARTEMISDEVICEISCAMERA)(int Device);
bool ArtemisDeviceIsCamera(int Device)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[6])
			pFuncs[6]=GetProcAddress(hArtemisDLL, "ArtemisDeviceIsCamera");
		TYPE_ARTEMISDEVICEISCAMERA pArtemisDeviceIsCamera=(TYPE_ARTEMISDEVICEISCAMERA)pFuncs[6];
		if (NULL != pArtemisDeviceIsCamera)
			return pArtemisDeviceIsCamera(Device);
	}
	return (bool)NULL;
}


// Disconnect from given device.
// Returns true if disconnected as requested
typedef bool (__stdcall * TYPE_ARTEMISDISCONNECT)(ArtemisHandle hCam);
bool ArtemisDisconnect(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[7])
			pFuncs[7]=GetProcAddress(hArtemisDLL, "ArtemisDisconnect");
		TYPE_ARTEMISDISCONNECT pArtemisDisconnect=(TYPE_ARTEMISDISCONNECT)pFuncs[7];
		if (NULL != pArtemisDisconnect)
			return pArtemisDisconnect(hCam);
	}
	return (bool)NULL;
}


// Connect to given device. If Device=-1, connect to first available
// Returns handle if connected as requested, else NULL
typedef ArtemisHandle (__stdcall * TYPE_ARTEMISCONNECT)(int Device);
ArtemisHandle ArtemisConnect(int Device)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[8])
			pFuncs[8]=GetProcAddress(hArtemisDLL, "ArtemisConnect");
		TYPE_ARTEMISCONNECT pArtemisConnect=(TYPE_ARTEMISCONNECT)pFuncs[8];
		if (NULL != pArtemisConnect)
			return pArtemisConnect(Device);
	}
	return (ArtemisHandle)NULL;
}


// Disconnect all connected devices
typedef bool (__stdcall * TYPE_ARTEMISDISCONNECTALL)();
bool ArtemisDisconnectAll()
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[9])
			pFuncs[9]=GetProcAddress(hArtemisDLL, "ArtemisDisconnectAll");
		TYPE_ARTEMISDISCONNECTALL pArtemisDisconnectAll=(TYPE_ARTEMISDISCONNECTALL)pFuncs[9];
		if (NULL != pArtemisDisconnectAll)
			return pArtemisDisconnectAll();
	}
	return (bool)NULL;
}


// Returns TRUE if currently connected to a device
typedef bool (__stdcall * TYPE_ARTEMISISCONNECTED)(ArtemisHandle hCam);
bool ArtemisIsConnected(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[10])
			pFuncs[10]=GetProcAddress(hArtemisDLL, "ArtemisIsConnected");
		TYPE_ARTEMISISCONNECTED pArtemisIsConnected=(TYPE_ARTEMISISCONNECTED)pFuncs[10];
		if (NULL != pArtemisIsConnected)
			return pArtemisIsConnected(hCam);
	}
	return (bool)NULL;
}


// Fills in pProp with camera properties
typedef int (__stdcall * TYPE_ARTEMISPROPERTIES)(ArtemisHandle hCam, struct ARTEMISPROPERTIES * pProp);
int ArtemisProperties(ArtemisHandle hCam, struct ARTEMISPROPERTIES * pProp)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[11])
			pFuncs[11]=GetProcAddress(hArtemisDLL, "ArtemisProperties");
		TYPE_ARTEMISPROPERTIES pArtemisProperties=(TYPE_ARTEMISPROPERTIES)pFuncs[11];
		if (NULL != pArtemisProperties)
			return pArtemisProperties(hCam, pProp);
	}
	return (int)NULL;
}


// Displays the Artemis setup dialog, if any
typedef int (__stdcall * TYPE_ARTEMISSETUPDIALOG)();
int ArtemisSetupDialog()
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[12])
			pFuncs[12]=GetProcAddress(hArtemisDLL, "ArtemisSetupDialog");
		TYPE_ARTEMISSETUPDIALOG pArtemisSetupDialog=(TYPE_ARTEMISSETUPDIALOG)pFuncs[12];
		if (NULL != pArtemisSetupDialog)
			return pArtemisSetupDialog();
	}
	return (int)NULL;
}


// Abort exposure, if one is in progress
typedef int (__stdcall * TYPE_ARTEMISABORTEXPOSURE)(ArtemisHandle hCam);
int ArtemisAbortExposure(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[13])
			pFuncs[13]=GetProcAddress(hArtemisDLL, "ArtemisAbortExposure");
		TYPE_ARTEMISABORTEXPOSURE pArtemisAbortExposure=(TYPE_ARTEMISABORTEXPOSURE)pFuncs[13];
		if (NULL != pArtemisAbortExposure)
			return pArtemisAbortExposure(hCam);
	}
	return (int)NULL;
}


// Set the start x,y coords for imaging subframe.
// X,Y in unbinned coordinates
typedef int (__stdcall * TYPE_ARTEMISSUBFRAMEPOS)(ArtemisHandle hCam, int x, int y);
int ArtemisSubframePos(ArtemisHandle hCam, int x, int y)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[14])
			pFuncs[14]=GetProcAddress(hArtemisDLL, "ArtemisSubframePos");
		TYPE_ARTEMISSUBFRAMEPOS pArtemisSubframePos=(TYPE_ARTEMISSUBFRAMEPOS)pFuncs[14];
		if (NULL != pArtemisSubframePos)
			return pArtemisSubframePos(hCam, x, y);
	}
	return (int)NULL;
}


// Set the width and height of imaging subframe
// W,H in unbinned coordinates
typedef int (__stdcall * TYPE_ARTEMISSUBFRAMESIZE)(ArtemisHandle hCam, int w, int h);
int ArtemisSubframeSize(ArtemisHandle hCam, int w, int h)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[15])
			pFuncs[15]=GetProcAddress(hArtemisDLL, "ArtemisSubframeSize");
		TYPE_ARTEMISSUBFRAMESIZE pArtemisSubframeSize=(TYPE_ARTEMISSUBFRAMESIZE)pFuncs[15];
		if (NULL != pArtemisSubframeSize)
			return pArtemisSubframeSize(hCam, w, h);
	}
	return (int)NULL;
}


// set the pos and size of imaging subframe inunbinned coords
typedef int (__stdcall * TYPE_ARTEMISSUBFRAME)(ArtemisHandle hCam, int x, int y, int w, int h);
int ArtemisSubframe(ArtemisHandle hCam, int x, int y, int w, int h)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[16])
			pFuncs[16]=GetProcAddress(hArtemisDLL, "ArtemisSubframe");
		TYPE_ARTEMISSUBFRAME pArtemisSubframe=(TYPE_ARTEMISSUBFRAME)pFuncs[16];
		if (NULL != pArtemisSubframe)
			return pArtemisSubframe(hCam, x, y, w, h);
	}
	return (int)NULL;
}


// Get the pos and size of imaging subframe
typedef int (__stdcall * TYPE_ARTEMISGETSUBFRAME)(ArtemisHandle hCam, int * x, int * y, int * w, int * h);
int ArtemisGetSubframe(ArtemisHandle hCam, int * x, int * y, int * w, int * h)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[17])
			pFuncs[17]=GetProcAddress(hArtemisDLL, "ArtemisGetSubframe");
		TYPE_ARTEMISGETSUBFRAME pArtemisGetSubframe=(TYPE_ARTEMISGETSUBFRAME)pFuncs[17];
		if (NULL != pArtemisGetSubframe)
			return pArtemisGetSubframe(hCam, x, y, w, h);
	}
	return (int)NULL;
}


// Set the x,y binning factors
typedef int (__stdcall * TYPE_ARTEMISBIN)(ArtemisHandle hCam, int x, int y);
int ArtemisBin(ArtemisHandle hCam, int x, int y)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[18])
			pFuncs[18]=GetProcAddress(hArtemisDLL, "ArtemisBin");
		TYPE_ARTEMISBIN pArtemisBin=(TYPE_ARTEMISBIN)pFuncs[18];
		if (NULL != pArtemisBin)
			return pArtemisBin(hCam, x, y);
	}
	return (int)NULL;
}


// Get the x,y binning factors
typedef int (__stdcall * TYPE_ARTEMISGETBIN)(ArtemisHandle hCam, int * x, int * y);
int ArtemisGetBin(ArtemisHandle hCam, int * x, int * y)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[19])
			pFuncs[19]=GetProcAddress(hArtemisDLL, "ArtemisGetBin");
		TYPE_ARTEMISGETBIN pArtemisGetBin=(TYPE_ARTEMISGETBIN)pFuncs[19];
		if (NULL != pArtemisGetBin)
			return pArtemisGetBin(hCam, x, y);
	}
	return (int)NULL;
}


// Set the Precharge mode
typedef int (__stdcall * TYPE_ARTEMISPRECHARGEMODE)(ArtemisHandle hCam, int mode);
int ArtemisPrechargeMode(ArtemisHandle hCam, int mode)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[20])
			pFuncs[20]=GetProcAddress(hArtemisDLL, "ArtemisPrechargeMode");
		TYPE_ARTEMISPRECHARGEMODE pArtemisPrechargeMode=(TYPE_ARTEMISPRECHARGEMODE)pFuncs[20];
		if (NULL != pArtemisPrechargeMode)
			return pArtemisPrechargeMode(hCam, mode);
	}
	return (int)NULL;
}


// Clear the VRegs
typedef int (__stdcall * TYPE_ARTEMISCLEARVREGS)(ArtemisHandle hCam);
int ArtemisClearVRegs(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[21])
			pFuncs[21]=GetProcAddress(hArtemisDLL, "ArtemisClearVRegs");
		TYPE_ARTEMISCLEARVREGS pArtemisClearVRegs=(TYPE_ARTEMISCLEARVREGS)pFuncs[21];
		if (NULL != pArtemisClearVRegs)
			return pArtemisClearVRegs(hCam);
	}
	return (int)NULL;
}


// Set the FIFO usage flag
typedef int (__stdcall * TYPE_ARTEMISFIFO)(ArtemisHandle hCam, bool bEnable);
int ArtemisFIFO(ArtemisHandle hCam, bool bEnable)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[22])
			pFuncs[22]=GetProcAddress(hArtemisDLL, "ArtemisFIFO");
		TYPE_ARTEMISFIFO pArtemisFIFO=(TYPE_ARTEMISFIFO)pFuncs[22];
		if (NULL != pArtemisFIFO)
			return pArtemisFIFO(hCam, bEnable);
	}
	return (int)NULL;
}


// Start an exposure
typedef int (__stdcall * TYPE_ARTEMISSTARTEXPOSURE)(ArtemisHandle hCam, float Seconds);
int ArtemisStartExposure(ArtemisHandle hCam, float Seconds)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[23])
			pFuncs[23]=GetProcAddress(hArtemisDLL, "ArtemisStartExposure");
		TYPE_ARTEMISSTARTEXPOSURE pArtemisStartExposure=(TYPE_ARTEMISSTARTEXPOSURE)pFuncs[23];
		if (NULL != pArtemisStartExposure)
			return pArtemisStartExposure(hCam, Seconds);
	}
	return (int)NULL;
}


// Prematurely end an exposure, collecting image data.
typedef int (__stdcall * TYPE_ARTEMISSTOPEXPOSURE)(ArtemisHandle hCam);
int ArtemisStopExposure(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[24])
			pFuncs[24]=GetProcAddress(hArtemisDLL, "ArtemisStopExposure");
		TYPE_ARTEMISSTOPEXPOSURE pArtemisStopExposure=(TYPE_ARTEMISSTOPEXPOSURE)pFuncs[24];
		if (NULL != pArtemisStopExposure)
			return pArtemisStopExposure(hCam);
	}
	return (int)NULL;
}


// Retrieve the downloaded image as a 2D array of type VARIANT
typedef int (__stdcall * TYPE_ARTEMISGETIMAGEARRAY)(ArtemisHandle hCam, VARIANT * pImageArray);
int ArtemisGetImageArray(ArtemisHandle hCam, VARIANT * pImageArray)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[25])
			pFuncs[25]=GetProcAddress(hArtemisDLL, "ArtemisGetImageArray");
		TYPE_ARTEMISGETIMAGEARRAY pArtemisGetImageArray=(TYPE_ARTEMISGETIMAGEARRAY)pFuncs[25];
		if (NULL != pArtemisGetImageArray)
			return pArtemisGetImageArray(hCam, pImageArray);
	}
	return (int)NULL;
}


// Retrieve image dimensions and binning factors.
// x,y are actual CCD locations. w,h are pixel dimensions of image
typedef int (__stdcall * TYPE_ARTEMISGETIMAGEDATA)(ArtemisHandle hCam, int * x, int * y, int * w, int * h, int * binx, int * biny);
int ArtemisGetImageData(ArtemisHandle hCam, int * x, int * y, int * w, int * h, int * binx, int * biny)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[26])
			pFuncs[26]=GetProcAddress(hArtemisDLL, "ArtemisGetImageData");
		TYPE_ARTEMISGETIMAGEDATA pArtemisGetImageData=(TYPE_ARTEMISGETIMAGEDATA)pFuncs[26];
		if (NULL != pArtemisGetImageData)
			return pArtemisGetImageData(hCam, x, y, w, h, binx, biny);
	}
	return (int)NULL;
}


// Upload a compressed object file to the Artemis PIC
typedef int (__stdcall * TYPE_ARTEMISREFLASH)(ArtemisHandle hCam , char * objfile);
int ArtemisReflash(ArtemisHandle hCam , char * objfile)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[27])
			pFuncs[27]=GetProcAddress(hArtemisDLL, "ArtemisReflash");
		TYPE_ARTEMISREFLASH pArtemisReflash=(TYPE_ARTEMISREFLASH)pFuncs[27];
		if (NULL != pArtemisReflash)
			return pArtemisReflash(hCam , objfile);
	}
	return (int)NULL;
}


// Return true if amp switched off during exposures
typedef bool (__stdcall * TYPE_ARTEMISGETAMPLIFIERSWITCHED)(ArtemisHandle hCam);
bool ArtemisGetAmplifierSwitched(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[28])
			pFuncs[28]=GetProcAddress(hArtemisDLL, "ArtemisGetAmplifierSwitched");
		TYPE_ARTEMISGETAMPLIFIERSWITCHED pArtemisGetAmplifierSwitched=(TYPE_ARTEMISGETAMPLIFIERSWITCHED)pFuncs[28];
		if (NULL != pArtemisGetAmplifierSwitched)
			return pArtemisGetAmplifierSwitched(hCam);
	}
	return (bool)NULL;
}


// Set whether amp is switched off during exposures
typedef int (__stdcall * TYPE_ARTEMISSETAMPLIFIERSWITCHED)(ArtemisHandle hCam, bool bSwitched);
int ArtemisSetAmplifierSwitched(ArtemisHandle hCam, bool bSwitched)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[29])
			pFuncs[29]=GetProcAddress(hArtemisDLL, "ArtemisSetAmplifierSwitched");
		TYPE_ARTEMISSETAMPLIFIERSWITCHED pArtemisSetAmplifierSwitched=(TYPE_ARTEMISSETAMPLIFIERSWITCHED)pFuncs[29];
		if (NULL != pArtemisSetAmplifierSwitched)
			return pArtemisSetAmplifierSwitched(hCam, bSwitched);
	}
	return (int)NULL;
}


// Return duration of last exposure, in seconds
typedef float (__stdcall * TYPE_ARTEMISLASTEXPOSUREDURATION)(ArtemisHandle hCam);
float ArtemisLastExposureDuration(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[30])
			pFuncs[30]=GetProcAddress(hArtemisDLL, "ArtemisLastExposureDuration");
		TYPE_ARTEMISLASTEXPOSUREDURATION pArtemisLastExposureDuration=(TYPE_ARTEMISLASTEXPOSUREDURATION)pFuncs[30];
		if (NULL != pArtemisLastExposureDuration)
			return pArtemisLastExposureDuration(hCam);
	}
	return (float)NULL;
}


// Return time remaining in current exposure, in seconds
typedef float (__stdcall * TYPE_ARTEMISEXPOSURETIMEREMAINING)(ArtemisHandle hCam);
float ArtemisExposureTimeRemaining(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[31])
			pFuncs[31]=GetProcAddress(hArtemisDLL, "ArtemisExposureTimeRemaining");
		TYPE_ARTEMISEXPOSURETIMEREMAINING pArtemisExposureTimeRemaining=(TYPE_ARTEMISEXPOSURETIMEREMAINING)pFuncs[31];
		if (NULL != pArtemisExposureTimeRemaining)
			return pArtemisExposureTimeRemaining(hCam);
	}
	return (float)NULL;
}


// Return ptr to static buffer containing time of start of last exposure
typedef char* (__stdcall * TYPE_ARTEMISLASTSTARTTIME)(ArtemisHandle hCam);
char* ArtemisLastStartTime(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[32])
			pFuncs[32]=GetProcAddress(hArtemisDLL, "ArtemisLastStartTime");
		TYPE_ARTEMISLASTSTARTTIME pArtemisLastStartTime=(TYPE_ARTEMISLASTSTARTTIME)pFuncs[32];
		if (NULL != pArtemisLastStartTime)
			return pArtemisLastStartTime(hCam);
	}
	return (char*)NULL;
}


// Return true if an image is ready to be retrieved
typedef bool (__stdcall * TYPE_ARTEMISIMAGEREADY)(ArtemisHandle hCam);
bool ArtemisImageReady(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[33])
			pFuncs[33]=GetProcAddress(hArtemisDLL, "ArtemisImageReady");
		TYPE_ARTEMISIMAGEREADY pArtemisImageReady=(TYPE_ARTEMISIMAGEREADY)pFuncs[33];
		if (NULL != pArtemisImageReady)
			return pArtemisImageReady(hCam);
	}
	return (bool)NULL;
}


// Switch off all guide relays
typedef int (__stdcall * TYPE_ARTEMISSTOPGUIDING)(ArtemisHandle hCam);
int ArtemisStopGuiding(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[34])
			pFuncs[34]=GetProcAddress(hArtemisDLL, "ArtemisStopGuiding");
		TYPE_ARTEMISSTOPGUIDING pArtemisStopGuiding=(TYPE_ARTEMISSTOPGUIDING)pFuncs[34];
		if (NULL != pArtemisStopGuiding)
			return pArtemisStopGuiding(hCam);
	}
	return (int)NULL;
}


// Activate a guide relay for a short interval
typedef int (__stdcall * TYPE_ARTEMISPULSEGUIDE)(ArtemisHandle hCam, int axis, int milli);
int ArtemisPulseGuide(ArtemisHandle hCam, int axis, int milli)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[35])
			pFuncs[35]=GetProcAddress(hArtemisDLL, "ArtemisPulseGuide");
		TYPE_ARTEMISPULSEGUIDE pArtemisPulseGuide=(TYPE_ARTEMISPULSEGUIDE)pFuncs[35];
		if (NULL != pArtemisPulseGuide)
			return pArtemisPulseGuide(hCam, axis, milli);
	}
	return (int)NULL;
}


// Activate a guide relay
typedef int (__stdcall * TYPE_ARTEMISGUIDE)(ArtemisHandle hCam, int axis);
int ArtemisGuide(ArtemisHandle hCam, int axis)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[36])
			pFuncs[36]=GetProcAddress(hArtemisDLL, "ArtemisGuide");
		TYPE_ARTEMISGUIDE pArtemisGuide=(TYPE_ARTEMISGUIDE)pFuncs[36];
		if (NULL != pArtemisGuide)
			return pArtemisGuide(hCam, axis);
	}
	return (int)NULL;
}


// Set download thread to high or normal priority
typedef int (__stdcall * TYPE_ARTEMISHIGHPRIORITY)(ArtemisHandle hCam, bool bHigh);
int ArtemisHighPriority(ArtemisHandle hCam, bool bHigh)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[37])
			pFuncs[37]=GetProcAddress(hArtemisDLL, "ArtemisHighPriority");
		TYPE_ARTEMISHIGHPRIORITY pArtemisHighPriority=(TYPE_ARTEMISHIGHPRIORITY)pFuncs[37];
		if (NULL != pArtemisHighPriority)
			return pArtemisHighPriority(hCam, bHigh);
	}
	return (int)NULL;
}


// Retrieve the current camera state
typedef int (__stdcall * TYPE_ARTEMISCAMERASTATE)(ArtemisHandle hCam);
int ArtemisCameraState(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[38])
			pFuncs[38]=GetProcAddress(hArtemisDLL, "ArtemisCameraState");
		TYPE_ARTEMISCAMERASTATE pArtemisCameraState=(TYPE_ARTEMISCAMERASTATE)pFuncs[38];
		if (NULL != pArtemisCameraState)
			return pArtemisCameraState(hCam);
	}
	return (int)NULL;
}


// Percentage downloaded
typedef int (__stdcall * TYPE_ARTEMISDOWNLOADPERCENT)(ArtemisHandle hCam);
int ArtemisDownloadPercent(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[39])
			pFuncs[39]=GetProcAddress(hArtemisDLL, "ArtemisDownloadPercent");
		TYPE_ARTEMISDOWNLOADPERCENT pArtemisDownloadPercent=(TYPE_ARTEMISDOWNLOADPERCENT)pFuncs[39];
		if (NULL != pArtemisDownloadPercent)
			return pArtemisDownloadPercent(hCam);
	}
	return (int)NULL;
}


// Return pointer to internal image buffer (actually unsigned shorts)
typedef void* (__stdcall * TYPE_ARTEMISIMAGEBUFFER)(ArtemisHandle hCam);
void* ArtemisImageBuffer(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[40])
			pFuncs[40]=GetProcAddress(hArtemisDLL, "ArtemisImageBuffer");
		TYPE_ARTEMISIMAGEBUFFER pArtemisImageBuffer=(TYPE_ARTEMISIMAGEBUFFER)pFuncs[40];
		if (NULL != pArtemisImageBuffer)
			return pArtemisImageBuffer(hCam);
	}
	return (void*)NULL;
}


// Set the CCD amplifier on or off
typedef int (__stdcall * TYPE_ARTEMISAMPLIFIER)(ArtemisHandle hCam, bool bOn);
int ArtemisAmplifier(ArtemisHandle hCam, bool bOn)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[41])
			pFuncs[41]=GetProcAddress(hArtemisDLL, "ArtemisAmplifier");
		TYPE_ARTEMISAMPLIFIER pArtemisAmplifier=(TYPE_ARTEMISAMPLIFIER)pFuncs[41];
		if (NULL != pArtemisAmplifier)
			return pArtemisAmplifier(hCam, bOn);
	}
	return (int)NULL;
}


// Set the webcam Long Exposure control
typedef int (__stdcall * TYPE_ARTEMISWEBCAMLE)(ArtemisHandle hCam, bool bHigh);
int ArtemisWebcamLE(ArtemisHandle hCam, bool bHigh)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[42])
			pFuncs[42]=GetProcAddress(hArtemisDLL, "ArtemisWebcamLE");
		TYPE_ARTEMISWEBCAMLE pArtemisWebcamLE=(TYPE_ARTEMISWEBCAMLE)pFuncs[42];
		if (NULL != pArtemisWebcamLE)
			return pArtemisWebcamLE(hCam, bHigh);
	}
	return (int)NULL;
}


// Reset the camera PIC
typedef int (__stdcall * TYPE_ARTEMISRESET)(ArtemisHandle hCam);
int ArtemisReset(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[43])
			pFuncs[43]=GetProcAddress(hArtemisDLL, "ArtemisReset");
		TYPE_ARTEMISRESET pArtemisReset=(TYPE_ARTEMISRESET)pFuncs[43];
		if (NULL != pArtemisReset)
			return pArtemisReset(hCam);
	}
	return (int)NULL;
}


// Get current image processing options
typedef int (__stdcall * TYPE_ARTEMISGETPROCESSING)(ArtemisHandle hCam);
int ArtemisGetProcessing(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[44])
			pFuncs[44]=GetProcAddress(hArtemisDLL, "ArtemisGetProcessing");
		TYPE_ARTEMISGETPROCESSING pArtemisGetProcessing=(TYPE_ARTEMISGETPROCESSING)pFuncs[44];
		if (NULL != pArtemisGetProcessing)
			return pArtemisGetProcessing(hCam);
	}
	return (int)NULL;
}


// Set current image processing options
typedef int (__stdcall * TYPE_ARTEMISSETPROCESSING)(ArtemisHandle hCam, int options);
int ArtemisSetProcessing(ArtemisHandle hCam, int options)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[45])
			pFuncs[45]=GetProcAddress(hArtemisDLL, "ArtemisSetProcessing");
		TYPE_ARTEMISSETPROCESSING pArtemisSetProcessing=(TYPE_ARTEMISSETPROCESSING)pFuncs[45];
		if (NULL != pArtemisSetProcessing)
			return pArtemisSetProcessing(hCam, options);
	}
	return (int)NULL;
}


// Set External Trigger mode. True=wait for trigger.
typedef int (__stdcall * TYPE_ARTEMISTRIGGEREDEXPOSURE)(ArtemisHandle hCam, bool bAwaitTrigger);
int ArtemisTriggeredExposure(ArtemisHandle hCam, bool bAwaitTrigger)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[46])
			pFuncs[46]=GetProcAddress(hArtemisDLL, "ArtemisTriggeredExposure");
		TYPE_ARTEMISTRIGGEREDEXPOSURE pArtemisTriggeredExposure=(TYPE_ARTEMISTRIGGEREDEXPOSURE)pFuncs[46];
		if (NULL != pArtemisTriggeredExposure)
			return pArtemisTriggeredExposure(hCam, bAwaitTrigger);
	}
	return (int)NULL;
}


// Send a packet of data to a peripheral, and receive a reply.
// pSendData points to an 8 byte array which is sent to the peripheral.
// pRecvData points to an 8 byte array which is filled with the peripheral's response.
// Returns ARTEMIS_OK if the peripheral responds, in which case pRecvData contains its reply.
// Returns ARTEMIS_NO_RESPONSE if the peripheral doesn't respond.
// If the peripheral does not respond, pRecvData is not guaranteed to be preserved.
// pSendData and pRecvData may be the same but must not be NULL.
typedef int (__stdcall * TYPE_ARTEMISPERIPHERAL)(ArtemisHandle hCam, int PeripheralID, unsigned char * pSendData, unsigned char * pRecvData);
int ArtemisPeripheral(ArtemisHandle hCam, int PeripheralID, unsigned char * pSendData, unsigned char * pRecvData)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[47])
			pFuncs[47]=GetProcAddress(hArtemisDLL, "ArtemisPeripheral");
		TYPE_ARTEMISPERIPHERAL pArtemisPeripheral=(TYPE_ARTEMISPERIPHERAL)pFuncs[47];
		if (NULL != pArtemisPeripheral)
			return pArtemisPeripheral(hCam, PeripheralID, pSendData, pRecvData);
	}
	return (int)NULL;
}


typedef int (__stdcall * TYPE_ARTEMISTEMPERATURESENSORINFO)(ArtemisHandle hCam, int sensor, int* temperature);
int ArtemisTemperatureSensorInfo(ArtemisHandle hCam, int sensor, int* temperature)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[48])
			pFuncs[48]=GetProcAddress(hArtemisDLL, "ArtemisTemperatureSensorInfo");
		TYPE_ARTEMISTEMPERATURESENSORINFO pArtemisTemperatureSensorInfo=(TYPE_ARTEMISTEMPERATURESENSORINFO)pFuncs[48];
		if (NULL != pArtemisTemperatureSensorInfo)
			return pArtemisTemperatureSensorInfo(hCam, sensor, temperature);
	}
	return (int)NULL;
}


typedef int (__stdcall * TYPE_ARTEMISCOOLINGINFO)(ArtemisHandle hCam, int* flags, int* level, int* minlvl, int* maxlvl, int* setpoint);
int ArtemisCoolingInfo(ArtemisHandle hCam, int* flags, int* level, int* minlvl, int* maxlvl, int* setpoint)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[49])
			pFuncs[49]=GetProcAddress(hArtemisDLL, "ArtemisCoolingInfo");
		TYPE_ARTEMISCOOLINGINFO pArtemisCoolingInfo=(TYPE_ARTEMISCOOLINGINFO)pFuncs[49];
		if (NULL != pArtemisCoolingInfo)
			return pArtemisCoolingInfo(hCam, flags, level, minlvl, maxlvl, setpoint);
	}
	return (int)NULL;
}


typedef int (__stdcall * TYPE_ARTEMISSETCOOLING)(ArtemisHandle hCam, int setpoint);
int ArtemisSetCooling(ArtemisHandle hCam, int setpoint)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[50])
			pFuncs[50]=GetProcAddress(hArtemisDLL, "ArtemisSetCooling");
		TYPE_ARTEMISSETCOOLING pArtemisSetCooling=(TYPE_ARTEMISSETCOOLING)pFuncs[50];
		if (NULL != pArtemisSetCooling)
			return pArtemisSetCooling(hCam, setpoint);
	}
	return (int)NULL;
}


typedef int (__stdcall * TYPE_ARTEMISCOOLERWARMUP)(ArtemisHandle hCam);
int ArtemisCoolerWarmUp(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[51])
			pFuncs[51]=GetProcAddress(hArtemisDLL, "ArtemisCoolerWarmUp");
		TYPE_ARTEMISCOOLERWARMUP pArtemisCoolerWarmUp=(TYPE_ARTEMISCOOLERWARMUP)pFuncs[51];
		if (NULL != pArtemisCoolerWarmUp)
			return pArtemisCoolerWarmUp(hCam);
	}
	return (int)NULL;
}


typedef int (__stdcall * TYPE_ARTEMISRECONNECTUSB)(ArtemisHandle hCam);
int ArtemisReconnectUSB(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[52])
			pFuncs[52]=GetProcAddress(hArtemisDLL, "ArtemisReconnectUSB");
		TYPE_ARTEMISRECONNECTUSB pArtemisReconnectUSB=(TYPE_ARTEMISRECONNECTUSB)pFuncs[52];
		if (NULL != pArtemisReconnectUSB)
			return pArtemisReconnectUSB(hCam);
	}
	return (int)NULL;
}


/////////////////////////////////////////////////
// Diagnostic Functions

// Ping the camera, return the result. -1 on error.
typedef int (__stdcall * TYPE_ARTEMISDIAGNOSTICPING)(ArtemisHandle hCam, int send);
int ArtemisDiagnosticPing(ArtemisHandle hCam, int send)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[53])
			pFuncs[53]=GetProcAddress(hArtemisDLL, "ArtemisDiagnosticPing");
		TYPE_ARTEMISDIAGNOSTICPING pArtemisDiagnosticPing=(TYPE_ARTEMISDIAGNOSTICPING)pFuncs[53];
		if (NULL != pArtemisDiagnosticPing)
			return pArtemisDiagnosticPing(hCam, send);
	}
	return (int)NULL;
}


// Ping the FIFO, return the result. -1 on error.
typedef int (__stdcall * TYPE_ARTEMISDIAGNOSTICPINGFIFO)(ArtemisHandle hCam, int send);
int ArtemisDiagnosticPingFIFO(ArtemisHandle hCam, int send)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[54])
			pFuncs[54]=GetProcAddress(hArtemisDLL, "ArtemisDiagnosticPingFIFO");
		TYPE_ARTEMISDIAGNOSTICPINGFIFO pArtemisDiagnosticPingFIFO=(TYPE_ARTEMISDIAGNOSTICPINGFIFO)pFuncs[54];
		if (NULL != pArtemisDiagnosticPingFIFO)
			return pArtemisDiagnosticPingFIFO(hCam, send);
	}
	return (int)NULL;
}


// Set the CCD clocks running (firmware doesn't return!)
typedef int (__stdcall * TYPE_ARTEMISDIAGNOSTICRUNCCD)(ArtemisHandle hCam);
int ArtemisDiagnosticRunCCD(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[55])
			pFuncs[55]=GetProcAddress(hArtemisDLL, "ArtemisDiagnosticRunCCD");
		TYPE_ARTEMISDIAGNOSTICRUNCCD pArtemisDiagnosticRunCCD=(TYPE_ARTEMISDIAGNOSTICRUNCCD)pFuncs[55];
		if (NULL != pArtemisDiagnosticRunCCD)
			return pArtemisDiagnosticRunCCD(hCam);
	}
	return (int)NULL;
}


// Measure the precharge level
typedef int (__stdcall * TYPE_ARTEMISDIAGNOSTICPRECHARGE)(ArtemisHandle hCam);
int ArtemisDiagnosticPrecharge(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[56])
			pFuncs[56]=GetProcAddress(hArtemisDLL, "ArtemisDiagnosticPrecharge");
		TYPE_ARTEMISDIAGNOSTICPRECHARGE pArtemisDiagnosticPrecharge=(TYPE_ARTEMISDIAGNOSTICPRECHARGE)pFuncs[56];
		if (NULL != pArtemisDiagnosticPrecharge)
			return pArtemisDiagnosticPrecharge(hCam);
	}
	return (int)NULL;
}


// Connects to kernel only, safe to use before firmware
// has been uploaded.
// Returns handle if connected as requested
typedef ArtemisHandle (__stdcall * TYPE_ARTEMISDIAGNOSTICCONNECT)(int Device);
ArtemisHandle ArtemisDiagnosticConnect(int Device)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[57])
			pFuncs[57]=GetProcAddress(hArtemisDLL, "ArtemisDiagnosticConnect");
		TYPE_ARTEMISDIAGNOSTICCONNECT pArtemisDiagnosticConnect=(TYPE_ARTEMISDIAGNOSTICCONNECT)pFuncs[57];
		if (NULL != pArtemisDiagnosticConnect)
			return pArtemisDiagnosticConnect(Device);
	}
	return (ArtemisHandle)NULL;
}


// Miscellaneous commands to set voltages etc.
// Not to be called if the CCD is installed!
typedef int (__stdcall * TYPE_ARTEMISDIAGNOSTICCOMMAND)(ArtemisHandle hCam, int cmd);
int ArtemisDiagnosticCommand(ArtemisHandle hCam, int cmd)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[58])
			pFuncs[58]=GetProcAddress(hArtemisDLL, "ArtemisDiagnosticCommand");
		TYPE_ARTEMISDIAGNOSTICCOMMAND pArtemisDiagnosticCommand=(TYPE_ARTEMISDIAGNOSTICCOMMAND)pFuncs[58];
		if (NULL != pArtemisDiagnosticCommand)
			return pArtemisDiagnosticCommand(hCam, cmd);
	}
	return (int)NULL;
}


// Return the last FT USB error condition seen
// Calling this function clears the internal error state
typedef int (__stdcall * TYPE_ARTEMISDIAGNOSTICUSBERROR)(ArtemisHandle hCam);
int ArtemisDiagnosticUSBError(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[59])
			pFuncs[59]=GetProcAddress(hArtemisDLL, "ArtemisDiagnosticUSBError");
		TYPE_ARTEMISDIAGNOSTICUSBERROR pArtemisDiagnosticUSBError=(TYPE_ARTEMISDIAGNOSTICUSBERROR)pFuncs[59];
		if (NULL != pArtemisDiagnosticUSBError)
			return pArtemisDiagnosticUSBError(hCam);
	}
	return (int)NULL;
}


/////////////////////////////////////////////////
// Access LE/Guide ports from 3rd-party software
// msg is the command to execute
// unit is the camera number
// returns:
//  0  OK
//  1  camera busy
//  2  no camera active
//  3  invalid command
typedef int (__stdcall * TYPE_ARTEMISSENDMESSAGE)(int msg, int unit);
int ArtemisSendMessage(int msg, int unit)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[60])
			pFuncs[60]=GetProcAddress(hArtemisDLL, "ArtemisSendMessage");
		TYPE_ARTEMISSENDMESSAGE pArtemisSendMessage=(TYPE_ARTEMISSENDMESSAGE)pFuncs[60];
		if (NULL != pArtemisSendMessage)
			return pArtemisSendMessage(msg, unit);
	}
	return (int)NULL;
}


/////////////////////////////////////////////////
// Access peripherals from 3rd-party software
// peripheral is the peripheral's device ID
// send and recv are 8-byte buffers for message-passing
// unit is the camera number
// returns:
//  0  OK
//  1  camera busy
//  2  no camera active
//  3  invalid command
//  4  no response fropm peripheral
typedef int (__stdcall * TYPE_ARTEMISSENDPERIPHERALMESSAGE)(int peripheral, char * send, char * recv, int unit);
int ArtemisSendPeripheralMessage(int peripheral, char * send, char * recv, int unit)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[61])
			pFuncs[61]=GetProcAddress(hArtemisDLL, "ArtemisSendPeripheralMessage");
		TYPE_ARTEMISSENDPERIPHERALMESSAGE pArtemisSendPeripheralMessage=(TYPE_ARTEMISSENDPERIPHERALMESSAGE)pFuncs[61];
		if (NULL != pArtemisSendPeripheralMessage)
			return pArtemisSendPeripheralMessage(peripheral, send, recv, unit);
	}
	return (int)NULL;
}


/////////////////////////////////////////////////
// Get camera description, for 3rd-party software
// recv is a 40-byte buffer for the data
// info tells which data to return:
//  0  camera description from firmware
//  1  FTDI device name
//  2  FTDI device serial number
// unit is the camera number
// returns:
//  0  OK
//  1  camera busy
//  2  no camera active
typedef int (__stdcall * TYPE_ARTEMISGETDESCRIPTION)(char * recv, int info, int unit);
int ArtemisGetDescription(char * recv, int info, int unit)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[62])
			pFuncs[62]=GetProcAddress(hArtemisDLL, "ArtemisGetDescription");
		TYPE_ARTEMISGETDESCRIPTION pArtemisGetDescription=(TYPE_ARTEMISGETDESCRIPTION)pFuncs[62];
		if (NULL != pArtemisGetDescription)
			return pArtemisGetDescription(recv, info, unit);
	}
	return (int)NULL;
}



/////////////////////////////////////////////////
// Check camera licensing info.
// returns:
// true if camera is licensed, or if no licence required.
// false if camera licence is invalid.
typedef bool (__stdcall * TYPE_ARTEMISISLICENSED)(ArtemisHandle hCam);
bool ArtemisIsLicensed(ArtemisHandle hCam)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[63])
			pFuncs[63]=GetProcAddress(hArtemisDLL, "ArtemisIsLicensed");
		TYPE_ARTEMISISLICENSED pArtemisIsLicensed=(TYPE_ARTEMISISLICENSED)pFuncs[63];
		if (NULL != pArtemisIsLicensed)
			return pArtemisIsLicensed(hCam);
	}
	return (bool)NULL;
}


/////////////////////////////////////////////////
// Get camera's input voltage.
// returns:
// vInput=input voltage
// Error code on error
typedef int (__stdcall * TYPE_ARTEMISDIAGNOSTICINPUTVOLTAGE)(ArtemisHandle hCam, float* vInput);
int ArtemisDiagnosticInputVoltage(ArtemisHandle hCam, float* vInput)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[64])
			pFuncs[64]=GetProcAddress(hArtemisDLL, "ArtemisDiagnosticInputVoltage");
		TYPE_ARTEMISDIAGNOSTICINPUTVOLTAGE pArtemisDiagnosticInputVoltage=(TYPE_ARTEMISDIAGNOSTICINPUTVOLTAGE)pFuncs[64];
		if (NULL != pArtemisDiagnosticInputVoltage)
			return pArtemisDiagnosticInputVoltage(hCam, vInput);
	}
	return (int)NULL;
}


/////////////////////////////////////////////////
// Get camera's ClkSub and Amp voltages.
// returns:
// vClkSub=Clk Sub voltage
// vAmp=Amp voltage
// Error code on error
typedef int (__stdcall * TYPE_ARTEMISDIAGNOSTICCLKSUBAMPVOLTAGE)(ArtemisHandle hCam, float* vClkSub, float* vAmp);
int ArtemisDiagnosticClkSubAmpVoltage(ArtemisHandle hCam, float* vClkSub, float* vAmp)
{
	if (hArtemisDLL)
	{
		if (NULL == pFuncs[65])
			pFuncs[65]=GetProcAddress(hArtemisDLL, "ArtemisDiagnosticClkSubAmpVoltage");
		TYPE_ARTEMISDIAGNOSTICCLKSUBAMPVOLTAGE pArtemisDiagnosticClkSubAmpVoltage=(TYPE_ARTEMISDIAGNOSTICCLKSUBAMPVOLTAGE)pFuncs[65];
		if (NULL != pArtemisDiagnosticClkSubAmpVoltage)
			return pArtemisDiagnosticClkSubAmpVoltage(hCam, vClkSub, vAmp);
	}
	return (int)NULL;
}



// Try to load the Artemis DLL.
// Returns true if loaded ok.
bool ArtemisLoadDLL(char *FileName)
{
	hArtemisDLL=LoadLibrary(FileName);
	if (hArtemisDLL==NULL)
		return false;
	for (int i=0; i<NFUNCS; i++)
		pFuncs[i]=NULL;
	return true;
}

// Unload the Artemis DLL.
void ArtemisUnLoadDLL()
{
	if (hArtemisDLL!=NULL)
		FreeLibrary(hArtemisDLL);
	hArtemisDLL=NULL;
}

#endif // defined(_WXMSW_)
