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

#include "VWPluginMenuApp.h"

long MenuMain(long action, long message, long &userData);
long DangerousMenuMain(long action, long message1, long & userData);

VWFC::PluginSupport::VWPluginMenuApp* CreateMenuInstance();



#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);
}

long LocalPluginMain(long action, long message1, long& userData);

extern "C" long GS_EXTERNAL_ENTRY plugin_main(long action, long message1, long &userData, CallBackPtr cbpParam)
{
	// saved gCBP for inner calls ... the menu could be called within another call
	// this usually is done for kMenuCheckHilite or kMenuNotify
	CallBackPtr	pCBPSaved	= gCBP;
	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 ) {

#ifndef _DEBUG
			try
#endif
			{
				// call the user's main function
				if (action != kMenuCheckHilite && action != kMenuNotify)
					reply = MenuMain( action, message1, userData );
				else
					reply = DangerousMenuMain( action, message1, 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 );
		
		// restore saved gCBP for inner calls ... the menu could be called within another call
		// this usually is done for kMenuCheckHilite or kMenuNotify
		gCBP		= pCBPSaved;
	}

	GSExternalSetdown(0);
	
	return reply;
}

#endif // VWFC_NO_PLUGINMAIN

//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
#ifdef VWFC_APPLICATION_TOOL
# define VWFC_NO_PLUGINMAIN
# include "MainEntry_Tool.h"
# undef VWFC_NO_PLUGINMAIN
#endif


long MenuMain(long action, long message, long &userData)
{
	long	reply = 0;

	using namespace VWFC::PluginSupport;

	// allocate the application
	VWPluginMenuApp* pApp = ::CreateMenuInstance();

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

		switch(action) {
			case kMenuInitGlobals:
				pApp->InitializeApp();
				break;
			case kMenuDisposeGlobals:
				pApp->DeinitializeApp();
				break;
			case kMenuDoInterface:
				pApp->SetMenuChunkInfo( (MenuChunkInfo*) message );
				pApp->DoInterface();
				reply	= pApp->GetResult();
				break;
			case kMenuAddItems:
				break;
			case kMenuItemEnabled: {
					MenuChunkInfo	menuInfo;
					menuInfo.menuID			= 0;
					menuInfo.itemID			= 0;
					menuInfo.modifiers		= 0;
					menuInfo.chunkIndex		= DemoteTo<Sint16>( kVStanev, message );
					pApp->SetMenuChunkInfo( & menuInfo );

					bool	bIsItemEnabled	= pApp->GetItemEnabled();
					reply					= pApp->GetResult();
					if ( reply == 0 ) {
						reply	= bIsItemEnabled ? kMenuItemIsEnabled : kMenuItemIsDisabled;
					}
				} break;
			case kMenuAccessCheck:
				break;
			case kMenuItemCheck:
				break;
			case kMenuHandleToolAction: {
#ifdef VWFC_APPLICATION_TOOL
					MenuToolActionHandlerParams*	pMenuToolParams	= (MenuToolActionHandlerParams*) message;
					if ( pMenuToolParams ) {
						reply	= ToolMain( pMenuToolParams->fToolAction, pMenuToolParams->fToolMessage1, pMenuToolParams->fToolMessage2, userData );
					}
#else
					DSTOP(( kVStanev, "This menu received tool event, but the VWFC plug-in is not defined as VWFC_APPLICATION_TOOL" ));
#endif
				} break;

#ifndef _VWFC_FOR_VW125x
			case kMenuItemDisplayContextualHelp: {
					pApp->SetMenuChunkInfo( (MenuChunkInfo*) message );
					TXString	contextualHelpID	= pApp->GetContextualHelpID();
					if ( ! contextualHelpID.IsEmpty() ) {
						if ( ::GS_DisplayContextualHelp( gCBP, contextualHelpID ) ) {
							reply = kMenuItemHasContextualHelp;
						}
						else if ( contextualHelpID.GetAt(0) == '-' || contextualHelpID.GetAt(0) == '_' || contextualHelpID.GetAt(0) == '.' ) {
							// the plug-in doesn't suply help ID
							// dont consider that problem
							reply = kMenuItemHasContextualHelp;
						}
					}
				} break;
#endif
			default:
				reply = pApp->OnDefaultEvent( action, message );
				break;
		}

		userData	= pApp->GetUserData();

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

	return reply;
}

long DangerousMenuMain(long action, long message1, long & userData)
{
	long	reply = 0;

	using namespace VWFC::PluginSupport;

	// allocate the application
	VWPluginMenuApp* pApp = ::CreateMenuInstance();

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

		switch(action) {
			case kMenuNotify:
				pApp->NotifyCallback( (EMenuCallbackEvent) message1 );
				break;
		}

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

	return reply;
}
