//
// Copyright © Vectorworks, Inc. 2008.
// All Rights Reserved.
// 

#pragma once


namespace VectorWorks
{
	namespace PluginSupport
	{
		// ----------------------------------------------------------------------------------------------------
		typedef VWIID	TSinkIID;

		// ----------------------------------------------------------------------------------------------------
		// Base class for extension sink
		class DYNAMIC_ATTRIBUTE IExtensionSink : public IVWUnknown
		{
		public:
		};

		// ----------------------------------------------------------------------------------------------------
		// Base class for Vectorworks extensions implementation
		class DYNAMIC_ATTRIBUTE IExtensionApp : public IVWSingletonUnknown
		{
		public:
			virtual TXString VCOM_CALLTYPE			GetUniversalName() = 0;
			virtual IExtensionSink* VCOM_CALLTYPE	GetEventSink(const TSinkIID& iid) = 0;
		};

		// ----------------------------------------------------------------------------------------------------
		// {23D80C42-DC4D-4d1d-BFF2-CAE178A54059}
		static const TSinkIID IID_LegacyEventSink = { 0x23d80c42, 0xdc4d, 0x4d1d, { 0xbf, 0xf2, 0xca, 0xe1, 0x78, 0xa5, 0x40, 0x59 } };
		// ----------------------------------------------------------------------------------------------------
		class DYNAMIC_ATTRIBUTE ILegacyEventSink : public IExtensionSink
		{
		public:
			virtual long VCOM_CALLTYPE				Main(long action, long message1, long message2) = 0;
		};

		// ----------------------------------------------------------------------------------------------------
		// {EC158212-E80C-4680-B05B-569914FC29E5}
		static const TSinkIID IID_ProtectionProvider = { 0xec158212, 0xe80c, 0x4680, { 0xb0, 0x5b, 0x56, 0x99, 0x14, 0xfc, 0x29, 0xe5 } };
		// ----------------------------------------------------------------------------------------------------
		class DYNAMIC_ATTRIBUTE IProtectionProvider : public IExtensionSink
		{
		public:
			virtual void VCOM_CALLTYPE				GetProduct(Uint32& outFlags, Uint16& outMode) = 0;
		};
	}

	// Helper tools
	namespace PluginSupport
	{
		//------------------------------------------------------------------
		template<class T> void REGISTER_Interface(const VWIID& iid, long action, void* pInfo, long& ioData, CallBackPtr cbp, long& reply)
		{
			if ( action == kVCOMRegisterInterfaces ) {
				::GS_VWRegisterInterface(iid, pInfo);
			}
			else if ( action == kVCOMQueryInterface && pInfo ) {
				if ( *((VWIID*) pInfo) == iid ) {
					T*			instance	= new T( cbp );
					ioData					= (long) instance;
				}
				if ( ioData == 0 || reply != kVCOMError_NoError ) {
					reply	= kVCOMError_NoInstance;
				}
			}
			else if ( action == kVCOMReleaseInterface && pInfo ) {
				if ( *((VWIID*) pInfo) == iid ) {
					T* implementation = dynamic_cast<T*>( (IVWUnknown*) ioData );
					if ( VERIFYN( kVStanev, implementation ) ) {
						delete implementation;
					}
					if ( implementation == 0 || reply != kVCOMError_NoError ) {
						reply	= kVCOMError_NoInstance;
					}
				}
			}
		}

		// --------------------------------------------------------------------------------------------------------
		template<class T> void REGISTER_ExtensionApp(const VWGroupID& groupID, const VWIID& iid, long action, void* pInfo, long& ioData, CallBackPtr cbp, long& reply)
		{
			using namespace VectorWorks::PluginSupport;
			if ( action == kVCOMRegisterInterfaces ) {
				::GS_VWRegisterInterface(iid, groupID, pInfo);
			}
			else if ( action == kVCOMQueryInterface && pInfo ) {
				if ( *((VWIID*) pInfo) == iid ) {
					T*			instance	= new T( cbp );
					ioData					= (long) instance;
					if ( ioData == 0 || reply != kVCOMError_NoError ) {
						reply	= kVCOMError_NoInstance;
					}
				}
			}
			else if ( action == kVCOMReleaseInterface && pInfo ) {
				if ( *((VWIID*) pInfo) == iid ) {
					T* implementation = dynamic_cast<T*>( (IVWUnknown*) ioData );
					if ( VERIFYN( kVStanev, implementation ) ) {
						delete implementation;
					}
					if ( implementation == 0 || reply != kVCOMError_NoError ) {
						reply	= kVCOMError_NoInstance;
					}
				}
			}
		}
	}
}
