#ifndef TCI_CALLBACKS_H
#define TCI_CALLBACKS_H

#include "TciData.h"
#ifdef _WIN32
	#ifdef _MSC_VER
		#if _MSC_VER >= 1600
			#include <stdint.h>
		#else
			typedef int int32_t;
		#endif
	#else
		#include <stdint.h>
	#endif
#else
#include <stdint.h>
#endif

#if !defined (_M_IX86) && !defined(__i386__)
#define ATTR_STDCALL
#elif defined(_WIN32)
#define ATTR_STDCALL __stdcall
#else
#define ATTR_STDCALL __attribute__((stdcall))
#endif

typedef struct TciObjidValue32
{
	int32_t length;
	TciObjidElemValue* elements;
} TciObjidValue32;

typedef struct TciCharStringValue32
{
	int32_t length;
	char* string;
} TciCharStringValue32;

typedef struct TciUCStringValue32
{
	int32_t length;
	wchar_t * string;
} TciUCStringValue32;

// Type
typedef void (ATTR_STDCALL * FTciErrorReq)(const char *);
typedef Type (ATTR_STDCALL * FTciGetTypeForName)(const char *);
typedef TciModuleIdType (ATTR_STDCALL * FTciGetDefiningModule)(Type);
typedef String (ATTR_STDCALL * FTciGetName)(Type);
typedef TciTypeClass (ATTR_STDCALL * FTciGetTypeClass)(Type);
typedef Value (ATTR_STDCALL * FTciNewInstance)(Type);
typedef String (ATTR_STDCALL * FTciGetTypeEncoding)(Type);
typedef String* (ATTR_STDCALL * FGetTypeExtension)(Type);
typedef String (ATTR_STDCALL * FTciGetTypeEncodingVariant)(Type);
// Value
typedef String (ATTR_STDCALL * FTciGetValueEncoding)(Value);
typedef String (ATTR_STDCALL * FTciGetValueEncodingVariant)(Value);
typedef Type (ATTR_STDCALL * FTciGetType)(Value);
typedef Boolean (ATTR_STDCALL * FTciNotPresent)(Value);
typedef void (ATTR_STDCALL * FTciSetNull)(Value);
typedef Boolean (ATTR_STDCALL * FTciIsNull)(Value);
// Integer value
typedef String (ATTR_STDCALL * FTciGetIntAbs)(Value inst);
typedef unsigned long int (ATTR_STDCALL * FTciIntGetNumberOfDigits)(Value inst);
typedef Boolean (ATTR_STDCALL * FTciGetIntSign)(Value inst);
typedef char (ATTR_STDCALL * FTciGetIntDigit)(Value inst, int32_t position);
typedef void (ATTR_STDCALL * FTciSetIntAbs)(Value inst, String value);
typedef void (ATTR_STDCALL * FTciSetNumberOfDigits)(Value inst, int32_t dig_num);
typedef void (ATTR_STDCALL * FTciSetIntSign)(Value inst, Boolean sign);
typedef void (ATTR_STDCALL * FTciSetIntDigit)(Value inst, int32_t position, char digit);
// Float value
typedef double (ATTR_STDCALL * FTciGetFloatValue)(Value inst);
typedef void (ATTR_STDCALL * FTciSetFloatValue)(Value inst, double value);
// Boolean value
typedef Boolean (ATTR_STDCALL * FTciGetBooleanValue)(Value inst);
typedef void (ATTR_STDCALL * FTciSetBooleanValue)(Value inst, Boolean value);
// Objid value
typedef TciObjidValue32 (ATTR_STDCALL * FTciGetTciObjidValue)(Value inst);
typedef void (ATTR_STDCALL * FTciSetObjidValue)(Value inst, TciObjidValue32 value);
// Charstring value
typedef TciCharStringValue32 (ATTR_STDCALL * FTciGetCStringValue)(Value inst);
typedef int32_t (ATTR_STDCALL * FTciGetCStringLength)(Value inst);
typedef char (ATTR_STDCALL * FTciGetCStringCharValue)(Value inst, int32_t position);
typedef void (ATTR_STDCALL * FTciSetCStringCharValue)(Value inst, int32_t position, char value);
typedef void (ATTR_STDCALL * FTciSetCStringValue)(Value inst, TciCharStringValue32 value);
typedef void (ATTR_STDCALL * FTciSetCStringLength)(Value inst, int32_t len);
//Universal Charstring value
typedef TciUCStringValue32 (ATTR_STDCALL * FTciGetUCStringValue)(Value inst);
typedef int32_t (ATTR_STDCALL * FTciGetUCStringLength)(Value inst);
typedef void (ATTR_STDCALL * FTciGetUCStringCharValue)(Value inst, int32_t position, TciUCValueOld result);
typedef void (ATTR_STDCALL * FTciSetUCStringCharValue)(Value inst, int32_t position, TciUCValueOld value);
typedef void (ATTR_STDCALL * FTciSetUCStringValue)(Value inst, TciUCStringValue32 value);
typedef void (ATTR_STDCALL * FTciSetUCStringLength)(Value inst, int32_t len);
// Bitstring value
typedef String (ATTR_STDCALL * FTciGetBStringValue)(Value inst);
typedef int32_t (ATTR_STDCALL * FTciGetBStringLength)(Value inst);
typedef int32_t (ATTR_STDCALL * FTciGetBStringBitValue)(Value inst, int32_t position);
typedef void (ATTR_STDCALL * FTciSetBStringBitValue)(Value inst, int32_t position, int32_t value);
typedef void (ATTR_STDCALL * FTciSetBStringValue)(Value inst, String value);
typedef void (ATTR_STDCALL * FTciSetBStringLength)(Value inst, int32_t len);
// Hexstring value
typedef String (ATTR_STDCALL * FTciGetHStringValue)(Value inst);
typedef int32_t (ATTR_STDCALL * FTciGetHStringLength)(Value inst);
typedef int32_t (ATTR_STDCALL * FTciGetHStringHexValue)(Value inst, int32_t position);
typedef void (ATTR_STDCALL * FTciSetHStringHexValue)(Value inst, int32_t position, int32_t value);
typedef void (ATTR_STDCALL * FTciSetHStringValue)(Value inst, String value);	
typedef void (ATTR_STDCALL * FTciSetHStringLength)(Value inst, int32_t len);
// Octetstring value
typedef String (ATTR_STDCALL * FTciGetOStringValue)(Value inst);
typedef int32_t (ATTR_STDCALL * FTciGetOStringLength)(Value inst);
typedef int (ATTR_STDCALL * FTciGetOStringOctetValue)(Value inst, int32_t position);
typedef void (ATTR_STDCALL * FTciSetOStringOctetValue)(Value inst, int32_t position, int32_t value);
typedef void (ATTR_STDCALL * FTciSetOStringValue)(Value inst, String value);
typedef void (ATTR_STDCALL * FTciSetOStringLength)(Value inst, int32_t len);
// Record value
typedef Value (ATTR_STDCALL * FTciGetRecFieldValue)(Value inst, String fieldName);
typedef void (ATTR_STDCALL * FTciSetRecFieldValue)(Value inst, String fieldName, Value value);
typedef char** (ATTR_STDCALL * FTciGetRecFieldNames)(Value inst);
typedef void (ATTR_STDCALL * FSetFieldOmitted)(Value inst, String fieldName);
// RecordOf value
typedef Type (ATTR_STDCALL * FTciGetRecOfElementType)(Value inst);
typedef Value (ATTR_STDCALL * FTciGetRecOfFieldValue)(Value inst, int32_t position);
typedef int32_t (ATTR_STDCALL * FTciGetRecOfLength)(Value inst);
typedef void (ATTR_STDCALL * FTciAppendRecOfFieldValue)(Value inst, Value value);
typedef void (ATTR_STDCALL * FTciSetRecOfFieldValue)(Value inst, int32_t position, Value value);
typedef void (ATTR_STDCALL * FTciSetRecOfLength)(Value inst, int32_t len);
typedef int32_t (ATTR_STDCALL * FTciGetRecordOfOffset)(Value inst);
// Union value
typedef Value (ATTR_STDCALL * FTciGetUnionVariant)(Value inst, String variantName);
typedef void (ATTR_STDCALL * FTciSetUnionVariant)(Value inst, String variantName, Value value);
typedef String (ATTR_STDCALL * FTciGetUnionPresentVariantName)(Value inst);
typedef char** (ATTR_STDCALL * FTciGetUnionVariantNames)(Value inst);
// Enumerated value
typedef String (ATTR_STDCALL * FTciGetEnumValue)(Value inst);
typedef void (ATTR_STDCALL * FTciSetEnumValue)(Value inst, String enumValue);
// Verdict value
typedef int32_t (ATTR_STDCALL * FTciGetVerdictValue)(Value inst);
typedef void (ATTR_STDCALL * FTciSetVerdictValue)(Value inst, int32_t verdict);
// Address value
typedef Value (ATTR_STDCALL * FTciGetAddressValue)(Value inst);
typedef void (ATTR_STDCALL * FTciSetAddressValue)(Value inst, Value value);
// Char value
typedef void (ATTR_STDCALL * FTciSetCharValue)(Value inst, char value);
typedef char (ATTR_STDCALL * FTciGetCharValue)(Value inst);
// Universal char value
typedef void (ATTR_STDCALL * FTciGetUCharValue)(Value inst, TciUCValueOld value);
typedef void (ATTR_STDCALL * FTciSetUCharValue)(Value inst, TciUCValueOld value);
// C++ extension
typedef Value (ATTR_STDCALL * FTciCloneValue)(Value inst);
typedef Boolean (ATTR_STDCALL * FTciOperatorEquals)(Value inst, Value value);
typedef Boolean (ATTR_STDCALL * FTciOperatorLess)(Value inst, Value value);
// Value template
typedef Boolean (ATTR_STDCALL * FTciIsOmit)(TciValueTemplate inst);
typedef Boolean (ATTR_STDCALL * FTciIsAny)(TciValueTemplate inst);
typedef Boolean(ATTR_STDCALL * FTciIsAnyOrOmit)(TciValueTemplate inst);
typedef String(ATTR_STDCALL * FTciGetTemplateDef)(TciValueTemplate inst);
// Non-value template
typedef Boolean(ATTR_STDCALL * FTciIsAnyNonValue)(TciNonValueTemplate inst);
typedef Boolean(ATTR_STDCALL * FTciIsAllNonValue)(TciNonValueTemplate inst);
typedef String(ATTR_STDCALL * FTciGetTemplateDefNonValue)(TciNonValueTemplate inst);
// Value list
typedef int(ATTR_STDCALL * FTciGetValueListSize)(TciValueList inst);
typedef Boolean(ATTR_STDCALL * FTciIsValueListEmpty)(TciValueList inst);
typedef Value(ATTR_STDCALL * FTciGetValueListItem)(TciValueList inst, int32_t index);
//Universal Charstring value TCI 4.2.2
typedef TciUCStringValue (ATTR_STDCALL * FTciGetUCStringValueWchar)(Value inst);
typedef void (ATTR_STDCALL * FTciSetUCStringValueWchar)(Value inst, TciUCStringValue value);
//Logging to TestCast log window
typedef void (ATTR_STDCALL * FTciSIWriteToTCLog)(const wchar_t * message);
//invoking internal codec
typedef Value (ATTR_STDCALL * FTciSIInternalDecode)(const BinaryString * pBS, const Type decodingHypothesis);
typedef BinaryString *(ATTR_STDCALL * FTciSIInternalEncode)(const Value value);
typedef void (ATTR_STDCALL * FTciReleaseBinaryStringManaged)(BinaryString * bs);
//Enum value additions from 4.3.1
typedef int32_t (ATTR_STDCALL * FTciGetEnumInt)(Value inst);
typedef void (ATTR_STDCALL * FTciSetEnumInt)(Value inst, int32_t intVal);

typedef struct TCallbacks
{
	// Type
	FTciErrorReq fTciErrorReq;
	FTciGetTypeForName fTciGetTypeForName;
	FTciGetDefiningModule fGetDefiningModule;
	FTciGetName fGetName;
	FTciGetTypeClass fGetTypeClass;
	FTciNewInstance fNewInstance;
	FTciGetTypeEncoding fGetTypeEncoding;
	FGetTypeExtension fGetTypeExtension;
	FTciGetTypeEncodingVariant fGetTypeEncodingVariant;
	// Value
	FTciGetValueEncoding fGetValueEncoding;
	FTciGetValueEncodingVariant fGetValueEncodingVariant;
	FTciGetType fGetType;
	FTciNotPresent fNotPresent;
	// Integer value
	FTciGetIntAbs fGetIntAbs;
	FTciIntGetNumberOfDigits fIntGetNumberOfDigits;
	FTciGetIntSign fGetIntSign;
	FTciGetIntDigit fGetIntDigit;
	FTciSetIntAbs fSetIntAbs;
	FTciSetNumberOfDigits fSetNumberOfDigits;
	FTciSetIntSign fSetIntSign;
	FTciSetIntDigit fSetIntDigit;
	// Float value
	FTciGetFloatValue fGetFloatValue;
	FTciSetFloatValue fSetFloatValue;
	// Boolean value
	FTciGetBooleanValue fGetBooleanValue;
	FTciSetBooleanValue fSetBooleanValue;
	// Objid value
	FTciGetTciObjidValue fGetObjidValue;
	FTciSetObjidValue fSetObjidValue;
	// Charstring value
	FTciGetCStringValue fGetCStringValue;
	FTciGetCStringLength fGetCStringLength;
	FTciGetCStringCharValue fGetCStringCharValue;
	FTciSetCStringCharValue fSetCStringCharValue;
	FTciSetCStringValue fSetCStringValue;
	FTciSetCStringLength fSetCStringLength;
	// Universal charstring value
	FTciGetUCStringValue fGetUCStringValue;
	FTciGetUCStringLength fGetUCStringLength;
	FTciGetUCStringCharValue fGetUCStringCharValue;
	FTciSetUCStringCharValue fSetUCStringCharValue;
	FTciSetUCStringValue fSetUCStringValue;
	FTciSetUCStringLength fSetUCStringLength;
	// Bitstring value
	FTciGetBStringValue fGetBStringValue;
	FTciGetBStringLength fGetBStringLength;
	FTciGetBStringBitValue fGetBStringBitValue;
	FTciSetBStringBitValue fSetBStringBitValue;
	FTciSetBStringValue fSetBStringValue;
	FTciSetBStringLength fSetBStringLength;
	// Hexstring value
	FTciGetHStringValue fGetHStringValue;
	FTciGetHStringLength fGetHStringLength;
	FTciGetHStringHexValue fGetHStringHexValue;
	FTciSetHStringHexValue fSetHStringHexValue;
	FTciSetHStringValue fSetHStringValue;
	FTciSetHStringLength fSetHStringLength;
	// Octetstring value
	FTciGetOStringValue fGetOStringValue;
	FTciGetOStringLength fGetOStringLength;
	FTciGetOStringOctetValue fGetOStringOctetValue;
	FTciSetOStringOctetValue fSetOStringOctetValue;
	FTciSetOStringValue fSetOStringValue;
	FTciSetOStringLength fSetOStringLength;
	// Record value
	FTciGetRecFieldValue fGetRecFieldValue;
	FTciSetRecFieldValue fSetRecFieldValue;
	FTciGetRecFieldNames fGetRecFieldNames;
	FSetFieldOmitted fSetFieldOmitted;
	// RecordOf value
	FTciGetRecOfElementType fGetRecOfElementType;
	FTciGetRecOfFieldValue fGetRecOfFieldValue;
	FTciGetRecOfLength fGetRecOfLength;
	FTciAppendRecOfFieldValue fAppendRecOfFieldValue;
	FTciSetRecOfFieldValue fSetRecOfFieldValue;
	FTciSetRecOfLength fSetRecOfLength;
	// Union value
	FTciGetUnionVariant fGetUnionVariant;
	FTciSetUnionVariant fSetUnionVariant;
	FTciGetUnionPresentVariantName fGetUnionPresentVariantName;
	FTciGetUnionVariantNames fGetUnionVariantNames;
	// Enumerated value
	FTciGetEnumValue fGetEnumValue;
	FTciSetEnumValue fSetEnumValue;
	// Verdict value
	FTciGetVerdictValue fGetVerdictValue;
	FTciSetVerdictValue fSetVerdictValue;
	// Address value
	FTciGetAddressValue fGetAddressValue;
	FTciSetAddressValue fSetAddressValue;
	// Char value
	FTciGetCharValue fGetCharValue;
	FTciSetCharValue fSetCharValue;
	// Universal char value
	FTciGetUCharValue fGetUCharValue;
	FTciSetUCharValue fSetUCharValue;
} TCallbacks;

void initTci(void);
void disposeTci(void);

#endif
