//////////////////////////////////////////////////////////////////////////////////////////
//	MiniCadCallBacks.cpp
//	
//	Copyright © Diehl Graphsoft, Inc  1993-1998.
//	All Rights Reserved.
//	
//	Defines SDK library functions & utility functionality.
//	Includes the file which defines the entire set of SDK functions.
//
// SourceSafe information for this version:
//    $Revision: 2 $
//    $Date: 9/22/00 2:40 PM $
//    $Author: Jeff $
//////////////////////////////////////////////////////////////////////////////////////////


#include "StdHeaders.h"

// [1/96, MJH] this should be defined in the source file, not the header
#define _MINICADCALLBACKS_CPP

#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>

#if GS_WIN
	#include <MacMemory.h>
#endif

#include "CallbackIDs.h"
#include "GSString.h"
#include "MiniCadCallBacks.h"


Boolean	TVariableBlock::GetStr255(GSStringPtr data) const
{ 
	if (eType == t_Str255) {
		StringCopy(fData.uStr, data, sizeof(GSStr255));
		return true ;
	} 
	else return false ;
}


TVariableBlock& TVariableBlock::operator=(ConstGSStr255Param data) 
{   
	StringCopy(data, fData.uStr, sizeof(fData.uStr));
	eType = t_Str255 ;
	return *this ;
}


////////////////////////
// GLOBAL pointer to the SDK VCOM funtion interface
//   In VectorWorks, this is initialized during start up
//   In externals, this should be queried in the main.
////////////////////////

VectorWorks::ISDK* gSDK		= NULL;


////////////////////////
// GLOBAL CallBackPtr
//   In MiniCAD, this should be passed to all GS_ calls and does nothing
//   In externals, this should be assigned cbp at main()
////////////////////////

CallBackPtr gCBP = nil;

void GS_API SetupGlobalCBP(CallBackPtr cbp)
{
	gCBP = cbp;
}


extern "C" {
// GS_SDKPPC_JAK2
#ifdef _MINICAD_
	// If _MINICAD_ we are building the main application...
	#define CALLBACKPTR CallBackPtr
//	#ifdef powerc
//	#define GET_CB_UPP(fn) UniversalProcPtr f = (UniversalProcPtr) FIDToPtr(kcb##fn); \
//							if (f) f = (UniversalProcPtr) f->routineRecords[0].procDescriptor
//	#else
	// The macro GET_CB_UPP is used by the AppleScript which generates "MiniCadCallBacks.Defs.cpp".
	#define GET_CB_UPP(fn) UniversalProcPtr f = (UniversalProcPtr) FIDToPtr(kcb##fn)
//	#endif
	#define CALL_PROC(fn)	((fn##Ptr) f)
#else
	// else we are building Plug-ins...
//	#define XCALL(fn)	GenericFunctionPtr f = (*cbp->rPtr)(kcb##fn); if (f) ((fn##Ptr) f)
//	#define XFN(fn)		GenericFunctionPtr f = (*cbp->rPtr)(kcb##fn); return f ? ((fn##Ptr) f)
	
	#define CALLBACKPTR CallBackPtr cbp

//	#ifdef powerc		
//		#define GET_CB_UPP(fn) UniversalProcPtr f = (UniversalProcPtr) CallRetrieverProc(cbp->rPtr, kcb##fn); \
//							if (f) f = (UniversalProcPtr) f->routineRecords[0].procDescriptor
//	#else
		#define GET_CB_UPP(fn) GenericFunctionPtr f = (*cbp->rPtr)(kcb##fn)		
//	#endif
	#define CALL_PROC(fn)	((fn##Ptr) f)
#endif

// include the automatically generated portion of this file
#if !GS_INLINE_SDK_CALLS
#include "MiniCadCallBacks.Defs.cpp"
#endif


//#undef XCALL
//#undef XFN

}


//////////////////////////////////////////////////////////////////////
// Implementations for library calls
//////////////////////////////////////////////////////////////////////



double_gs GS_LIBRARY GS_CoordLengthToPageLengthN(CallBackPtr cbp, WorldCoord len)
{
	double_gs result;
	GS_CoordLengthToPageLengthN(cbp, len, result);
	return result;
}

double_gs GS_LIBRARY GS_CoordLengthToUnitsLengthN(CallBackPtr cbp, WorldCoord len)
{
	double_gs result;
	GS_CoordLengthToUnitsLengthN(cbp, len, result);
	return result;
}


void GS_LIBRARY GS_HLock(CallBackPtr cbp, GSHandle handle)
{
	GS_SetHandleState(cbp, handle, true);
}

void GS_LIBRARY GS_HUnlock(CallBackPtr cbp, GSHandle handle)
{
	GS_SetHandleState(cbp, handle, false);
}


#if !_WIN_EXTERNAL_ && !_GSWINSDK_

	OSErr GS_LIBRARY GS_GetApplicationFolder(CallBackPtr cbp, short& vRefNum, long& dirID)
	{
		return GS_GetFolder(cbp, kApplicationFolder, vRefNum, dirID);
	}

	OSErr GS_LIBRARY GS_GetOverlaysFolder(CallBackPtr cbp, short& vRefNum, long& dirID)
	{
		return GS_GetFolder(cbp, kOverlaysFolder, vRefNum, dirID);
	}

	OSErr GS_LIBRARY GS_GetExternalsFolder(CallBackPtr cbp, short& vRefNum, long& dirID)
	{
		return GS_GetFolder(cbp, kExternalsFolder, vRefNum, dirID);
	}

#endif // !_WIN_EXTERNAL_ && !_GSWINSDK_

// ---------------------------------------------------------------------------------------------
// VCOM supprot
// ---------------------------------------------------------------------------------------------
void**		gVCOMCallback		= 0;

// ---------------------------------------------------------------------------------------------
VCOMError	GS_InitializeVCOM(void* cbpParam)
{
	// init VCOM callback
	::GS_Kludge( (CallBackPtr) cbpParam, 499, 0, & gVCOMCallback );
	return kVCOMError_NoError;
}

VCOMError	GS_VWRegisterInterface(const VWIID& iid, void* argTable)
{
	typedef long (*TRegisterInterface)(void* pInLibFile, void* pInIID);
	void*		pLibFile	= argTable;

	VCOMError	err			= kVCOMError_NotInitialized;
	if ( gVCOMCallback ) {
		TRegisterInterface	pRegisterInterfaceFunc	= (TRegisterInterface) gVCOMCallback[0];
		if ( pRegisterInterfaceFunc ) {
			err	= (*pRegisterInterfaceFunc)( pLibFile, (void*) & iid );
		}
	}

	return err;
}

VCOMError	GS_VWRegisterInterface(const VWIID& iid, const VWIID& iidContainer, void* argTable)
{
	typedef long (*TRegisterInterfaceInContainer)(void* pInLibFile, void* pInIID, void* pInIIDContainer);
	void*		pLibFile	= argTable;

	VCOMError	err			= kVCOMError_NotInitialized;
	if ( gVCOMCallback ) {
		TRegisterInterfaceInContainer	pRegisterInterfaceInContainerFunc	= (TRegisterInterfaceInContainer) gVCOMCallback[3];
		if ( pRegisterInterfaceInContainerFunc ) {
			err	= (*pRegisterInterfaceInContainerFunc)( pLibFile, (void*) & iid, (void*) & iidContainer );
		}
	}

	return err;
}

VCOMError	GS_VWQueryInterface(const VWIID& iid, IVWUnknown** ppInterface)
{
	typedef long (*TQueryInterface)(void* pInIID, void** ppInInterface);

	if ( gVCOMCallback == NULL )
		return kVCOMError_NotInitialized;
	
	TQueryInterface		pQueryInterfaceFunc		= (TQueryInterface) gVCOMCallback[1];
	
	if ( pQueryInterfaceFunc == NULL )
		return kVCOMError_InvalidArg;

	return (*pQueryInterfaceFunc)( (void*) & iid, (void**) ppInterface );
}

void		GS_VWNotifyDeleteInterface(IVWUnknown* pInterface)
{
	typedef long (*TNotifyDeleteInterface)(void* pInInterface);

	if ( gVCOMCallback ) {
		TNotifyDeleteInterface		pNotifyDeleteInterfaceFunc		= (TNotifyDeleteInterface) gVCOMCallback[2];
	
		if ( pNotifyDeleteInterfaceFunc ) {
			pNotifyDeleteInterfaceFunc( pInterface );
		}
	}
}

size_t		GS_VWGetContainerInterfacesCount(const VWIID& iidContainer)
{
	typedef size_t (*TGetContainerInterfacesCount)(void* pInIIDContainer);

	size_t	interfCnt	= 0;
	if ( gVCOMCallback ) {
		TGetContainerInterfacesCount	pGetInterfCntFun		= (TGetContainerInterfacesCount) gVCOMCallback[4];
		if ( pGetInterfCntFun ) {
			interfCnt	= pGetInterfCntFun( (void*) & iidContainer );
		}
	}

	return interfCnt;
}

VWIID		GS_VWGetContainerInterface(const VWIID& iidContainer, size_t index)
{
	typedef size_t (*TGetContainerInterface)(void* pInIIDContainer, size_t index, void* pOutIID);

	VWIID	resultIID;
    resultIID.data1		= 0;
    resultIID.data2		= 0;
    resultIID.data3		= 0;
    resultIID.data4[0]	= 0;
    resultIID.data4[1]	= 0;
    resultIID.data4[2]	= 0;
    resultIID.data4[3]	= 0;
    resultIID.data4[4]	= 0;
    resultIID.data4[5]	= 0;
    resultIID.data4[6]	= 0;
    resultIID.data4[7]	= 0;
	if ( gVCOMCallback ) {
		TGetContainerInterface	pGetInterfFun		= (TGetContainerInterface) gVCOMCallback[5];
		if ( pGetInterfFun ) {
			pGetInterfFun( (void*) & iidContainer, index, (void*) & resultIID );
		}
	}

	return resultIID;
}



