//
//	Copyright © 2005 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#include "StdAfx.h"

#include "VWFC/PluginSupport/VWPluginLibraryArgTable.h"

using namespace VWFC::Tools;
using namespace VWFC::PluginSupport;


//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
VWPluginLibraryArgTable::VWPluginLibraryArgTable()
{
	// init the new art table
	for(size_t i=0; i<kMaxPluginLibraryArgs; i++ )
		fNewArgTable.args[i].argType	= kNullArgType;
	fNewArgTable.functionResult.argType	= kNullArgType;

	// set arg table pointers
	fpArgTable		= & fNewArgTable;
	for(size_t i=0; i<kMaxPluginLibraryArgs; i++ )
		farrArguments[ i ].fpArgument	= & fpArgTable->args[ i ];
	fResultArgument.fpArgument		= & fpArgTable->functionResult;
}

VWPluginLibraryArgTable::VWPluginLibraryArgTable(PluginLibraryArgTable* pArgTable)
{
	fpArgTable		= pArgTable;
	for(size_t i=0; i<kMaxPluginLibraryArgs; i++ )
		farrArguments[ i ].fpArgument	= & fpArgTable->args[ i ];
	fResultArgument.fpArgument		= & fpArgTable->functionResult;
}

VWPluginLibraryArgTable::~VWPluginLibraryArgTable()
{
}

VWPluginLibraryArgument& VWPluginLibraryArgTable::GetArgument(size_t index)
{
	VWFC_ASSERT( fpArgTable );
	VWFC_ASSERT( index < kMaxPluginLibraryArgs );

	VWPluginLibraryArgument&	argument	= farrArguments[ index ];

	return argument;
}

VWPluginLibraryArgument& VWPluginLibraryArgTable::GetResult()
{
	return fResultArgument;
}

VWPluginLibraryArgTable::operator PluginLibraryArgTable*()
{
	return fpArgTable;
}

//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
VWPluginLibraryArgument::VWPluginLibraryArgument()
{
	fpArgument		= NULL;
}

VWPluginLibraryArgument::~VWPluginLibraryArgument()
{
}

//kIntegerArgType			// use intValue field of PluginLibraryArg
//kIntegerVarArgType		// use intValue
short VWPluginLibraryArgument::GetArgInteger() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kIntegerArgType );
	return fpArgument->intValue;
}

short& VWPluginLibraryArgument::GetArgIntegerVar()
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == kIntegerVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = kIntegerVarArgType;
	return fpArgument->intValue;
}

void VWPluginLibraryArgument::SetArgInteger(short value)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType		= kIntegerArgType;
	fpArgument->intValue	= value;
}

//kLongArgType			// use longValue
//kLongVarArgType		// use longValue
long VWPluginLibraryArgument::GetArgLong() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kLongArgType );
	return fpArgument->longValue;
}

long& VWPluginLibraryArgument::GetArgLongVar()
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == kLongVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = kLongVarArgType;
	return fpArgument->longValue;
}

void VWPluginLibraryArgument::SetArgLong(long value)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType		= kLongArgType;
	fpArgument->longValue	= value;
}

//kRealArgType			// use realValue
//kRealVarArgType		// use realValue
double_gs VWPluginLibraryArgument::GetArgReal() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kRealArgType );
	return fpArgument->realValue;
}

double_gs& VWPluginLibraryArgument::GetArgRealVar()
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == kRealVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = kRealVarArgType;
	return fpArgument->realValue;
}

void VWPluginLibraryArgument::SetArgReal(double_gs value)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType		= kRealArgType;
	fpArgument->realValue	= value;
}

//kAngleArgType			// use realValue
double_gs VWPluginLibraryArgument::GetArgAngle() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kAngleArgType );
	return fpArgument->realValue;
}

void VWPluginLibraryArgument::SetArgAngle(double_gs value)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType		= kAngleArgType;
	fpArgument->realValue	= value;
}

//kDistanceArgType		// use realValue
double_gs VWPluginLibraryArgument::GetArgDistance() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kDistanceArgType );
	return fpArgument->realValue;
}

void VWPluginLibraryArgument::SetArgDistance(double_gs value)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType			= kDistanceArgType;
	fpArgument->realValue		= value;
}

//kPointArgType				// use ptValue in SDK.  Use 2 REAL variables in VS.
//kGlobalPointArgType		// use ptValue in SDK.  Use 2 REAL variables in VS.
//kGlobalPointVarArgType	// use ptValue in SDK.  Use 2 REAL variables in VS.
_WorldPt VWPluginLibraryArgument::GetArgPoint() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kPointArgType || fpArgument->argType == kGlobalPointArgType );
	return fpArgument->ptValue;
}

_WorldPt& VWPluginLibraryArgument::GetArgPointVar()
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == kGlobalPointVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = kGlobalPointVarArgType;
	return fpArgument->ptValue;
}

void VWPluginLibraryArgument::SetArgPoint(const _WorldPt& value)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType		= kPointArgType;
	fpArgument->ptValue		= value;
}

//k3DPointArgType			// use pt3Value in SDK.  Use 3 REAL variables in VS.
//k3DPointVarArgType		// use pt3Value in SDK.  Use 3 REAL variables in VS.
_WorldPt3 VWPluginLibraryArgument::GetArg3DPoint() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == k3DPointArgType );
	return fpArgument->pt3Value;
}

_WorldPt3& VWPluginLibraryArgument::GetArg3DPointVar()
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == k3DPointVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = k3DPointVarArgType;
	return fpArgument->pt3Value;
}

void VWPluginLibraryArgument::SetArg3DPoint(const _WorldPt3& value)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType			= k3DPointArgType;
	fpArgument->pt3Value		= value;
}

//kVectorArgType		// use vec.vecValue
//kVectorVarArgType		// use vec.vecValue
_WorldPt3 VWPluginLibraryArgument::GetArgVector() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kVectorArgType );
	return fpArgument->vecValue;
}

_WorldPt3& VWPluginLibraryArgument::GetArgVectorVar()
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == kVectorVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = kVectorVarArgType;
	return fpArgument->vecValue;
}

void VWPluginLibraryArgument::SetArgVector(const _WorldPt3& value)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType			= kVectorArgType;
	fpArgument->vecValue		= value;
}

//kBooleanArgType			// use boolValue
//kBooleanVarArgType		// use boolValue
Boolean VWPluginLibraryArgument::GetArgBoolean() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kBooleanArgType );
	return fpArgument->boolValue;
}

Boolean& VWPluginLibraryArgument::GetArgBooleanVar()
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == kBooleanVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = kBooleanVarArgType;
	return fpArgument->boolValue;
}

void VWPluginLibraryArgument::SetArgBoolean(Boolean value)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType		= kBooleanArgType;
	fpArgument->boolValue	= value;
}

//kStringArgType			// use strValue
//kStringVarArgType			// use strValue
TXString VWPluginLibraryArgument::GetArgString() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kStringArgType );
	return TXString( fpArgument->strValue );
}

GSStr255& VWPluginLibraryArgument::GetArgStringVar()
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == kStringVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = kStringVarArgType;
	return fpArgument->strValue;
}

void VWPluginLibraryArgument::SetArgString(const TXString& value) const
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType		= kStringArgType;
	size_t				len	= value.GetLength();
	if ( len ) {
		const Uchar*	pascalStr		= (const unsigned char*) value;
		VWFC_ASSERT( len+1 < sizeof(fpArgument->strValue) );
		memcpy( & fpArgument->strValue, pascalStr, len+1 );
	}
	else {
		fpArgument->strValue[0] = 0x00;
	}
}


//kCharArgType				// use charValue
//kCharVarArgType			// use charValue
unsigned char VWPluginLibraryArgument::GetArgChar() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kCharArgType );
	return fpArgument->charValue;
}

unsigned char& VWPluginLibraryArgument::GetArgCharVar()
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == kCharVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = kCharVarArgType;
	return fpArgument->charValue;
}

// kVoidPtr
void* VWPluginLibraryArgument::GetArgVoidPtr() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kVoidPtr );
	return fpArgument->voidData;
}

void VWPluginLibraryArgument::SetArgVoidPtr(void* ptr)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType			= kVoidPtr;
	fpArgument->voidData		= ptr;
}

//kHandleArgType		// use handleValue
//kHandleVarArgType		// use handleValue
MCObjectHandle VWPluginLibraryArgument::GetArgHandle() const
{
	VWFC_ASSERT( fpArgument && fpArgument->argType == kHandleArgType );
	return fpArgument->handleValue;
}

MCObjectHandle& VWPluginLibraryArgument::GetArgHandleVar() const
{
	VWFC_ASSERT( fpArgument && (fpArgument->argType == kNullArgType || fpArgument->argType == kHandleVarArgType) );
	if ( fpArgument->argType == kNullArgType ) fpArgument->argType = kHandleVarArgType;
	return fpArgument->handleValue;
}

void VWPluginLibraryArgument::SetArgHandle(MCObjectHandle handle)
{
	VWFC_ASSERT( fpArgument );
	fpArgument->argType		= kHandleArgType;
	fpArgument->handleValue	= handle;
}

//kCharDynarrayArgType	// use dadValue
//kCharDynarrayVarArgType	// use dadValue
//kCharArrayVarArgType	// use dadValue
//kColorArgType			// use intValue
//kColorVarArgType		// use intValue
//kStyleArgType			// use styleValue

//kPointRecArgType		// use ptValue in SDK.  Use new "POINT" data structure in VS.  New for VW 10.
//kPointRecVarArgType		// use ptValue in SDK.  Use new "POINT" data structure in VS. New for VW 10.
//kPoint3DRecArgType		// use pt3Value in SDK. Use new "POINT3D" data structure in VS. New for VW 10.
//kPoint3DRecVarArgType	// use pt3Value in SDK. Use new "POINT3D" data structure in VS. New for VW 10. 
//kRGBColorRecArgType		// use colorVar in SDK. Use new "RGBCOLOR" data structure in VS. New for VW 10.
//kRGBColorRecVarArgType	// use colorVar in SDK. Use new "RGBCOLOR" data structure in VS. New for VW 10.
