/* CIN source file */

#include "extcode.h"
#include <windows.h>
#include "..\..\..\Include\wrRtusbapi.h"

/* Typedefs */

typedef struct {
	int32 dimSize;
	int16 BufferEl[1];
	} TD4;
typedef TD4 **TD4Hdl;

typedef struct {
	TD4Hdl Buffer;
	uInt32 ReadOv;
	uInt32 ReadEvent;
	} TD3;

typedef struct {
	int32 dimSize;
	TD3 ReadBufferPars[1];
	} TD2;
typedef TD2 **TD2Hdl;

typedef struct {
	TD4Hdl Buffer;
	uInt32 WriteOv;
	uInt32 WriteEvent;
	} TD6;

typedef struct {
	int32 dimSize;
	TD6 WriteBufferPars[1];
	} TD5;
typedef TD5 **TD5Hdl;

typedef struct {
	uInt32 DllVersion;
	uInt32 InterfaceType;
	uInt32 InterfaceInstance;
	uInt32 ModuleHandle;
	TD2Hdl ReadBufferParsArray;
	TD5Hdl WriteBuffersParsArray;
	} TD1;

typedef struct {
	LVBoolean Status;
	uInt32 ViErrorNumber;
	LStrHandle ViName;
	LStrHandle ViErrorString;
	LStrHandle CinName;
	LStrHandle CinErrorString;
	} TD7;

#define	VI_NAME_STRING_LENGTH		(32)
#define	VI_ERROR_STRING_LENGTH		(128)
#define	CIN_NAME_STRING_LENGTH		(32)
#define	CIN_ERROR_STRING_LENGTH		(128)

enum {UNKNOWN_MODULE, USB2185_MODULE, USB3000_MODULE};

// объявления функций
CIN MgErr CINRun(TD1 *InterfaceInfo, TD7 *ViStatus);
CIN MgErr CINProperties(int32 prop, void *data);

// ---------------------------------------------------------------
// 
// ---------------------------------------------------------------
MgErr CINRun(TD1 *InterfaceInfo, TD7 *ViStatus)
{
	MgErr Error;

	// устанавливаем флажок, что всё в порядке
	ViStatus->Status= LVTRUE;

	// мы уже выделяли место под строчку с названием VI?
	if(LStrLen(*ViStatus->ViName) != VI_NAME_STRING_LENGTH)
	{
		// выделим место под строчку с названием VI
		Error = NumericArrayResize(uB, 1L, (UHandle*)&ViStatus->ViName, VI_NAME_STRING_LENGTH);
		if(Error != noErr) { ViStatus->Status= LVFALSE; return Error; }
		LStrLen(*ViStatus->ViName) = VI_NAME_STRING_LENGTH;
	}

	// мы уже выделяли место под строчку с ошибкой в VI?
	if(LStrLen(*ViStatus->ViErrorString) != VI_ERROR_STRING_LENGTH)
	{
		// выделим место под под строчку с ошибкой в VI
		Error = NumericArrayResize(uB, 1L, (UHandle*)&ViStatus->ViErrorString, VI_ERROR_STRING_LENGTH);
		if(Error != noErr) { ViStatus->Status= LVFALSE; return Error; }
		LStrLen(*ViStatus->ViErrorString) = VI_ERROR_STRING_LENGTH;
	}
	// копируем строчку об полном отсутствии ошибок
	strcpy(LStrBuf(*ViStatus->ViErrorString), "No VIs with Errors \n");
	

	// мы уже выделяли место под строчку с названием CIN?
	if(LStrLen(*ViStatus->CinName) != CIN_NAME_STRING_LENGTH)
	{
		// выделим место под под строчку с названием CIN
		Error = NumericArrayResize(uB, 1L, (UHandle*)&ViStatus->CinName, CIN_NAME_STRING_LENGTH);
		if(Error != noErr) { ViStatus->Status= LVFALSE; return Error; }
		LStrLen(*ViStatus->CinName) = CIN_NAME_STRING_LENGTH;
	}

	// мы уже выделяли место под строчку с ошибкой в CIN?
	if(LStrLen(*ViStatus->CinErrorString) != CIN_ERROR_STRING_LENGTH)
	{
		// выделим место под под строчку с ошибкой в VI
		Error = NumericArrayResize(uB, 1L, (UHandle*)&ViStatus->CinErrorString, CIN_ERROR_STRING_LENGTH);
		if(Error != noErr) { ViStatus->Status= LVFALSE; return Error; }
		LStrLen(*ViStatus->CinErrorString) = CIN_ERROR_STRING_LENGTH;
	}
	// копируем строчку об полном отсутствии ошибок
	strcpy(LStrBuf(*ViStatus->CinErrorString), "No CINs with Errors ");

	// получим версию используемой DLL
	InterfaceInfo->DllVersion = GetDllVersion_Rtusbapi();
	if(InterfaceInfo->DllVersion == CURRENT_VERSION_RTUSBAPI)
	{

		// с каким модулем работаем?
		if(InterfaceInfo->InterfaceType == USB3000_MODULE)
		{
			// проверим существует ли уже интерфейс с модулем USB3000
			if((LPVOID)InterfaceInfo->InterfaceInstance == NULL)
			{
				InterfaceInfo->InterfaceInstance = (DWORD)CreateInstance_Rtusbapi("usb3000");
				if((LPVOID)InterfaceInfo->InterfaceInstance == NULL)
				{
					ViStatus->Status= LVFALSE;
				}
			}       
			else
			{
				ViStatus->Status= LVFALSE;
			}
		}
		else 
		{ 
			ViStatus->Status= LVFALSE; 
		}

	}
	else 
	{ 
		// формируем строчку с названием CIN, где произошла ошибка
		strcpy(LStrBuf(*ViStatus->CinErrorString), "CreateInstance ");
		// формируем строчку c ошибкой в номере версии библиотеки Rtusbapi.dll
		// !!! Странно, но в конце строки нужен пробел, 
		// !!! чтобы она нормально отображалась в строковом индикаторе 
//		strcpy(LStrBuf(*ViStatus->CinErrorString), "Rtusbapi DLL rewg Version Error ");
			
		ViStatus->Status= LVFALSE; 
	}

	// выходим
	return noErr;
}

// ---------------------------------------------------------------
// заявляем, что данный CIN - потокобезопасный
// ---------------------------------------------------------------
CIN MgErr CINProperties(int32 prop, void *data)
{
	switch (prop) 
	{
		case kCINIsReentrant:
			*(Bool32 *)data = TRUE;
			return noErr;
	}
	return mgNotSupported;
}
