///////////////////////////////////////////////////////////////////////////
//	fwxDCam.h: Interface for the CfwxDCam class.
////
#if !defined(AFX_FWXDCAM_H__DA059584_FF29_11D1_8F3F_00104B9F75DE__INCLUDED_)
#define AFX_FWXDCAM_H__DA059584_FF29_11D1_8F3F_00104B9F75DE__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#define LINKDLL __declspec(dllexport)

#include "fwx1394API.h"

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000


#define FWXDCAM_MAX_STRING_LEN	64

#define FWXDCAM_SPEED100_MAXBYTES	1250
#define FWXDCAM_SPEED200_MAXBYTES	2500

// Base address for all digital camera registers
#define FWXDCAM_COMMAND_REG_BASE_HI		0xFFFF
#define FWXDCAM_COMMAND_REG_BASE_LO		0xF0000000

// Configuration ROM addresses and offsets
#define FWXDCAM_UNIT_DIR_OFFSET_REG				0x424
#define FWXDCAM_UNIT_DEPEND_DIR_OFFSET			0x000C
#define FWXDCAM_UNIT_DEPEND_COMMAND_REGS_OFFSET	0x0004
#define FWXDCAM_UNIT_DEPEND_VENDOR_NAME_OFFSET	0x0008
#define FWXDCAM_UNIT_DEPEND_MODEL_NAME_OFFSET	0x000C

// Base Address offsets for all camera registers
#define FWXDCAM_INITIALIZE_REG			0x000

#define FWXDCAM_INQREG_V_FORMAT			0x100
#define FWXDCAM_INQREG_V_MODE			0x180

#define FWXDCAM_INQREG_V_RATE_START		0x200
#define FWXDCAM_INQREG_V_RATE_0_0		FWXDCAM_INQREG_V_RATE_START
#define FWXDCAM_INQREG_V_RATE_0_1		FWXDCAM_INQREG_V_RATE_START+0x4
#define FWXDCAM_INQREG_V_RATE_0_2		FWXDCAM_INQREG_V_RATE_START+0x8
#define FWXDCAM_INQREG_V_RATE_0_3		FWXDCAM_INQREG_V_RATE_START+0xC
#define FWXDCAM_INQREG_V_RATE_0_4		FWXDCAM_INQREG_V_RATE_START+0x10
#define FWXDCAM_INQREG_V_RATE_0_5		FWXDCAM_INQREG_V_RATE_START+0x14

#define FWXDCAM_INQREG_BASIC_FUNC		0x400
#define FWXDCAM_INQREG_FEATURE_HI		0x404
#define FWXDCAM_INQREG_FEATURE_LO		0x408

#define FWXDCAM_INQREG_BRIGHTNESS		0x500
#define FWXDCAM_INQREG_EXPOSURE			0x504
#define FWXDCAM_INQREG_SHARPNESS		0x508
#define FWXDCAM_INQREG_WHITE_BALANCE	0x50C
#define FWXDCAM_INQREG_HUE				0x510
#define FWXDCAM_INQREG_SATURATION		0x514
#define FWXDCAM_INQREG_GAMMA			0x518
#define FWXDCAM_INQREG_SHUTTER			0x51C
#define FWXDCAM_INQREG_GAIN				0x520
#define FWXDCAM_INQREG_IRIS				0x524
#define FWXDCAM_INQREG_FOCUS			0x528
#define FWXDCAM_INQREG_ZOOM				0x580
#define FWXDCAM_INQREG_PAN				0x584
#define FWXDCAM_INQREG_TILT				0x588

#define FWXDCAM_CSR_CUR_V_FRM_RATE		0x600
#define FWXDCAM_CSR_CUR_V_MODE			0x604
#define FWXDCAM_CSR_CUR_V_FORMAT		0x608
#define FWXDCAM_CSR_ISO_CHANNEL_SPEED	0x60C
#define FWXDCAM_CSR_CAMERA_POWER		0x610
#define FWXDCAM_CSR_ISO_TRANSMIT		0x614
#define FWXDCAM_CSR_MEMORY_SAVE			0x618
#define FWXDCAM_CSR_ONE_SHOT			0x61C
#define FWXDCAM_CSR_MEM_SAVE_CHANNEL	0x620
#define FWXDCAM_CSR_CUR_MEM_CHANNEL		0x624

#define FWXDCAM_CSR_BRIGHTNESS			0x800
#define FWXDCAM_CSR_EXPOSURE			0x804
#define FWXDCAM_CSR_SHARPNESS			0x808
#define FWXDCAM_CSR_WHITE_BALANCE		0x80C
#define FWXDCAM_CSR_HUE					0x810
#define FWXDCAM_CSR_SATURATION			0x814
#define FWXDCAM_CSR_GAMMA				0x818
#define FWXDCAM_CSR_SHUTTER				0x81C
#define FWXDCAM_CSR_GAIN				0x820
#define FWXDCAM_CSR_IRIS				0x824
#define FWXDCAM_CSR_FOCUS				0x828
#define FWXDCAM_CSR_ZOOM				0x880
#define FWXDCAM_CSR_PAN					0x884
#define FWXDCAM_CSR_TILT				0x888


// Inquiry register masks
#define FWXDCAM_INQMASK_V_FORMAT_0		0x80000000
#define FWXDCAM_INQMASK_V_MODE_0		0x80000000
#define FWXDCAM_INQMASK_V_MODE_1		0x40000000
#define FWXDCAM_INQMASK_V_MODE_2		0x20000000
#define FWXDCAM_INQMASK_V_MODE_3		0x10000000
#define FWXDCAM_INQMASK_V_MODE_4		0x08000000
#define FWXDCAM_INQMASK_V_MODE_5		0x04000000
#define FWXDCAM_INQMASK_V_RATE_3		0x40000000
#define FWXDCAM_INQMASK_V_RATE_7		0x20000000
#define FWXDCAM_INQMASK_V_RATE_15		0x10000000
#define FWXDCAM_INQMASK_V_RATE_30		0x08000000
#define FWXDCAM_INQMASK_V_RATE_60		0x04000000

#define FWXDCAM_INQMASK_POWER_CONTROL	0x00008000
#define FWXDCAM_INQMASK_ONE_SHOT		0x00001000
#define FWXDCAM_INQMASK_MEM_CHANNELS	0x0000000F

#define FWXDCAM_INQMASK_BRIGHTNESS		0x80000000
#define FWXDCAM_INQMASK_EXPOSURE		0x40000000
#define FWXDCAM_INQMASK_SHARPNESS		0x20000000
#define FWXDCAM_INQMASK_WHITE_BALANCE	0x10000000
#define FWXDCAM_INQMASK_HUE				0x08000000
#define FWXDCAM_INQMASK_SATURATION		0x04000000
#define FWXDCAM_INQMASK_GAMMA			0x02000000
#define FWXDCAM_INQMASK_SHUTTER			0x01000000
#define FWXDCAM_INQMASK_GAIN			0x00800000
#define FWXDCAM_INQMASK_IRIS			0x00400000
#define FWXDCAM_INQMASK_FOCUS			0x00200000
#define FWXDCAM_INQMASK_ZOOM			0x80000000
#define FWXDCAM_INQMASK_PAN				0x40000000
#define FWXDCAM_INQMASK_TILT			0x20000000

#define FWXDCAM_INQMASK_PRESENCE		0x80000000
#define FWXDCAM_INQMASK_READOUT			0x08000000
#define FWXDCAM_INQMASK_ONOFF			0x04000000
#define FWXDCAM_INQMASK_AUTO			0x02000000
#define FWXDCAM_INQMASK_MANUAL			0x01000000
#define FWXDCAM_INQMASK_MINVALUE		0x00FFF000
#define FWXDCAM_INQMASK_MAXVALUE		0x00000FFF

#define FWXDCAM_CSRMASK_V_FRAME_RATE	0xE0000000
#define FWXDCAM_CSRSHFT_V_FRAME_RATE	29
#define FWXDCAM_CSRMASK_V_MODE			0xE0000000
#define FWXDCAM_CSRSHFT_V_MODE			29
#define FWXDCAM_CSRMASK_V_FORMAT		0xE0000000
#define FWXDCAM_CSRSHFT_V_FORMAT		29
#define FWXDCAM_CSRMASK_ISO_CHANNEL		0xF0000000
#define FWXDCAM_CSRSHFT_ISO_CHANNEL		28
#define FWXDCAM_CSRMASK_ISO_SPEED		0x03000000
#define FWXDCAM_CSRSHFT_ISO_SPEED		24
#define FWXDCAM_CSRMASK_CAMERA_POWER	0x80000000
#define FWXDCAM_CSRMASK_ISO_TRANSMIT	0x80000000
#define FWXDCAM_CSRMASK_MEM_SAVE_CHANNEL 0xF0000000
#define FWXDCAM_CSRSHFT_MEM_SAVE_CHANNEL 28
#define FWXDCAM_CSRMASK_CUR_MEM_CHANNEL	0xF0000000
#define FWXDCAM_CSRSHFT_CUR_MEM_CHANNEL	28

#define FWXDCAM_CSRMASK_PRESENCE		0x80000000
#define FWXDCAM_CSRSHFT_PRESENCE		31
#define FWXDCAM_CSRMASK_ONOFF			0x02000000
#define FWXDCAM_CSRSHFT_ONOFF			25
#define FWXDCAM_CSRMASK_AM_MODE			0x01000000
#define FWXDCAM_CSRSHFT_AM_MODE			24
#define FWXDCAM_CSRMASK_FEATURE_VAL		0x00000FFF


class LINKDLL CfwxDCam
{
public:

	enum FUNCTION
	{
		Power = 0,
		One_Shot,
		Memory_Channels
	};

	enum FEATURE
	{
		Brightness = 10,
		Exposure,
		Sharpness,
		White_Balance,
		Hue,
		Saturation,
		Gamma,
		Shutter,
		Gain,
		Iris,
		Focus,
		Zoom,
		Pan,
		Tilt
	};

	enum FEATURE_INQUIRY
	{
		Presence_Inq = 100,
		ReadOut_Inq,
		OnOff_Inq,
		Auto_Inq,
		Manual_Inq,
		MIN_Value,
		MAX_Value
	};

	enum FEATURE_CONTROL
	{
		Presence = 200,
		OnOff,
		AM_Mode,
		Value
	};


public:
	CfwxDCam();
	virtual ~CfwxDCam();

	ULONG GetLastError(void) { return m_nLastError; };
	fwxGUID_t GetGUID(void) { return m_GUID; };
	BOOL SetGUID(fwxGUID_t GUID);
	fwxHandle_t GetHandle(void) { return m_hCamera; };
	HANDLE GetResources(void) { return m_hResources; };

	BOOL InitializeFactorySettings(void);

	BOOL InqVideoFormat(Quadlet *pQuad);
	BOOL InqVideoMode(UINT nVFormat, Quadlet *pQuad);
	BOOL InqVideoFrameRate(UINT nVFormat, UINT nVMode, Quadlet *pQuad);

	BOOL InqBasicFunction(Quadlet *pQuad);
	int  InqBasicFunction(FUNCTION nFunction);

	BOOL InqFeaturesHi(Quadlet *pQuad);
	BOOL InqFeaturesLo(Quadlet *pQuad);
	int  InqFeature(FEATURE nFeature);

	BOOL InqFeatureElement(FEATURE nFeature, Quadlet *pQuad);
	int  InqFeatureElement(FEATURE nFeature, FEATURE_INQUIRY nFInq);

	int  GetVFrameRate(void);
	BOOL SetVFrameRate(UINT nRate);
	int  GetVMode(void);
	BOOL SetVMode(UINT nMode);
	int  GetVFormat(void);
	BOOL SetVFormat(UINT nFormat);
	int  GetIsoChannel(void);
	int  GetIsoSpeed(void);
	BOOL SetIsoChannelSpeed(UINT nChannel, UINT nSpeed);
	int  GetCameraPower(void);
	BOOL SetCameraPower(BOOL bOn);
	int  GetIsoTransmit(void);
	BOOL SetIsoTransmit(BOOL bOn, BOOL bDrvReceive = TRUE);
	BOOL TakeOneShot(void);
	BOOL SaveSettings(UINT nChannel);
	BOOL LoadSettings(UINT nChannel);
	int  GetCurrentMemChannel(void);

	BOOL GetFeature(FEATURE nFeature, Quadlet *pQuad);
	BOOL SetFeature(FEATURE nFeature, Quadlet *pQuad);
	int  GetFeatureControl(FEATURE nFeature, FEATURE_CONTROL nControl);
	BOOL SetFeatureControl(FEATURE nFeature, FEATURE_CONTROL nControl, UINT nVal);

	TCHAR *GetVendorName(void) { return m_szVendorName; };
	TCHAR *GetModelName(void)  { return m_szModelName;  };

	fwxHandle_t Open(void);
	fwxHandle_t Open(ULONG nVendDeviceID, ULONG nChipID);
	BOOL Close(void);
	BOOL AllocateIsoResources(UINT nFrames, LPVOID *pBuffer);
	BOOL FreeIsoResources(void);
	BOOL StartIsoReceive(void);
	BOOL StopIsoReceive(void);

	HANDLE GetDeviceRemovedEvent(void) { return m_DeviceProps.hDeviceRemovedEvent; };
	HANDLE GetFrameCompleteEvent(UINT nFrame);

	ULONG GetDriverFramesReceived(void);

private:
	fwxGUID_t	m_GUID;
	fwxDeviceProperties_t m_DeviceProps;
	ULONG		m_nLastError;
	Quadlet		m_CommandRegsAddr;
	fwxHandle_t	m_hCamera;
	HANDLE		m_hResources;
	HANDLE		*m_pFrameEvents;
	UINT		m_nFrames;
	ULONG		m_nVendDeviceID;
	Quadlet		m_FeaturePresenceHi;
	Quadlet		m_FeaturePresenceLo;
	TCHAR		m_szVendorName[FWXDCAM_MAX_STRING_LEN];
	TCHAR		m_szModelName[FWXDCAM_MAX_STRING_LEN];
	UINT		m_nVideoFormat;
	UINT		m_nVideoMode;
	UINT		m_nVideoFrameRate;
	UINT		m_nChannel;
	UINT		m_nSpeed;

	typedef struct {
		UINT Length;
		UINT CRC;
		TCHAR Name[FWXDCAM_MAX_STRING_LEN];
	} fwxNameLeaf_t;


	int  GetCSR(DWORD CSRAddr, DWORD CSRMask, DWORD CSRShift);
	BOOL SetCSR(UINT val, DWORD CSRAddr, DWORD CSRShift);

	BOOL ReadFeaturePresence(void);
	BOOL ReadQuadlet(Quadlet offset, Quadlet *pQuad);
	BOOL WriteQuadlet(Quadlet offset, Quadlet *pQuad);
	BOOL ReadROM(void);
	BOOL ReadBlock(Quadlet offset, ULONG nBytes, LPVOID pBuffer);
	BOOL ReadNameLeaf(Quadlet LeafOffset, fwxNameLeaf_t *NameLeaf);
	BOOL ReverseString(TCHAR *pString);
	BOOL DeleteFrameEventHandles(void);

};

#endif // _fwxDCam_H_

