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



#include "VWPluginParametricApp.h"



long										ParametricMain(long action, MCObjectHandle objHand, long message, long &userData);
VWFC::PluginSupport::VWPluginParametricApp*	CreateParametricInstance(MCObjectHandle hParametric);


#ifndef VWFC_NO_PLUGINMAIN


// predefine these hidden memory managment functions
namespace VWFC
{
	void	AllocateMemoryManagers(VWFC::MemoryManager::MManager** ppOutOldManager, VWFC::MemoryManager::MManager** ppOutOldVWManager);
	void	FreeMemoryManagers(VWFC::MemoryManager::MManager* pOldManager, VWFC::MemoryManager::MManager* pOldVWManager);
}

// MainEntry_Parametric
extern "C" long GS_EXTERNAL_ENTRY plugin_main(long action, MCObjectHandle parmHand, long message, long &userData, CallBackPtr cbpParam)
{
	GSExternalSetup( cbpParam );

#ifndef _VWFC_FOR_VW125x
    // initialize VCOM mechanizm
    ::GS_InitializeVCOM( gCBP );
#endif

	long	reply	= 0;

	{ // SCOPE
		// Init gSDK
		VCOMPtr<VectorWorks::ISDK> localSDKPtr(VectorWorks::IID_SDK);
		gSDK = localSDKPtr;

		// create the memory namagers
		// and verify their presents
		VWFC::MemoryManager::MManager* pOldManager		= NULL;
		VWFC::MemoryManager::MManager* pOldVWManager	= NULL;
		VWFC::AllocateMemoryManagers( & pOldManager, & pOldVWManager );

		VWFC_VERIFY( VWFC::GetMManager() != NULL && VWFC::GetVWMManager() != NULL );
		if ( VWFC::GetMManager() != NULL && VWFC::GetVWMManager() != NULL ) {
			////////////////////////////////////////////////////////////////////////
			// Call the object
			// call the user's main function
#ifndef _DEBUG
			try {
#endif
				reply = ParametricMain( action, parmHand, message, userData );
#ifndef _DEBUG
			}
			catch( ... ) {
				// ups, an error in the plug in
				VWFC_ASSERT( false );
			}
#endif

			// dump local memory leaks
			if ( VWFC::GetMManager() ) {
				VWFC::GetMManager()->DumpMemory( PLUGIN_NAME );
			}
		}
		
		// release the memory managers
		VWFC::FreeMemoryManagers( pOldManager, pOldVWManager );
	}

	GSExternalSetdown(0L);
	return reply;
}

#endif	// VWFC_NO_PLUGINMAIN

long ParametricMain(long action, MCObjectHandle objHand, long message, long &userData)
{
	long	reply	= kParametricNoErr;

	using namespace VWFC::PluginSupport;

	// allocate the application
	VWPluginParametricApp* pApp = ::CreateParametricInstance( objHand );

	VWFC_ASSERT( pApp );
	if ( pApp ) {
		pApp->SetUserData( userData );

		switch (action) {
			case kParametricInitGlobals:
				reply	= (long) pApp->InitializeApp();
				break;
			case kParametricDisposeGlobals:
				reply	= (long) pApp->DeinitializeApp();
				break;
			case kParametricRecalculate:
				reply	= (long) pApp->Recalculate();
				break;
			case kParametricPreference:
				reply	= (long) pApp->Preference();
				break;
			case kObjOnInitXProperties:
				reply	= (long) pApp->OnInitXProperties( (CodeRefID) message );
				break;
			case kObjOnSpecialEditID:
				reply	= (long) pApp->OnSpecialEditID();
				break;
			case kObjOnObjectUIButtonHit:
				reply	= (long) pApp->OnObjectUIButtonHit( message );
				break;
			case kObjOnWidgetPrep: {
					OnObjectWidgetPrepCall* pThisCall		= (OnObjectWidgetPrepCall*) message;
					IWidgetsProvider*       pWidgetProvider = pThisCall ? (IWidgetsProvider*) pThisCall->fpWidgetProvider : NULL;
					if ( pWidgetProvider && pApp->OnWidgetUpdate( pWidgetProvider ) ) {
						reply	= kObjectEventHandled;
					}
				} break;
			case kObjOnAddState: {
					ObjectState*	pObjState	= (ObjectState*) message;
					if ( pObjState ) {
						reply	= (long) pApp->OnAddState( *pObjState );
					}
				} break;
            case kObjOnCursor_Draw:
		    case kObjOnCursor_MouseDown:
		    case kObjOnCursor_Complete:
		    case kObjOnCursor_Cancel: 
            case kObjOnCursor_MouseMove:
                reply = pApp->OnCursorEvent(action, message);
                break;
			case kObjOnGetToolName: {
					TXString*	pToolName	= (TXString*) message;
					if ( pToolName ) {
						*pToolName	= pApp->OnGetToolName();
						if ( ! pToolName->IsEmpty() ) {
							reply		= kObjectEventHandled;
						}
					}
				} break;
			case kObjOnContextMenuInit: {
					const ObjectContextMenuEvent* pEventData           = (const ObjectContextMenuEvent*) message;
					IContextMenuProvider*         pContextMenuProvider = (pEventData && pEventData->fData)
																   ? (IContextMenuProvider*) pEventData->fData : NULL;
					if ( pContextMenuProvider ) {
						pApp->OnContextMenuInit( pContextMenuProvider );
					}
				} break;
			case kObjOnEyedropperPrepareCopy: {
					pApp->OnEyedropperPrepareCopy( (MCObjectHandle) message );
				} break;
			default:
				reply = pApp->OnDefaultEvent( action, message );
				break;
		}

		userData	= pApp->GetUserData();

		// free the application definition
		pApp->~VWPluginParametricApp();
		free( pApp );
		pApp		= NULL;
	}

	return reply;
}
