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

#include "StdAfx.h"

#include "VWFC/PluginSupport/VWPluginLibraryApp.h"
#include "VWFC/PluginSupport/VWPluginLibraryRoutine.h"

using namespace VWFC::PluginSupport;


//////////////////////////////////////////////////////////////////////////////////
// VWPluginLibraryApp implementation
VWPluginLibraryApp::VWPluginLibraryApp()
{
	fnLastRoutineIndex		= 0;
}

VWPluginLibraryApp::~VWPluginLibraryApp()
{
}

void VWPluginLibraryApp::AddLibraryRoutine(VWPluginLibraryRoutine* pRoutine)
{
	VWFC_ASSERT( pRoutine );
	if ( pRoutine && fnLastRoutineIndex < MAX_ROUTINES_COUNT )
	{
		farrLibraryRoutines[ fnLastRoutineIndex ] = pRoutine;
		fnLastRoutineIndex++;
	}
}

long VWPluginLibraryApp::DispatchRoutine(long routineSelector, VWPluginLibraryArgTable& argTable, long &userData)
{
	farrRoutinesUserData	= (long*) userData;

	// set VectorWorks global memory when we are not initing or destroying
	// NOTE! This Global memory cannot be used in this situation
	// since it uses Plug-in library to access it, cannot call libary when they are inited
	if ( routineSelector == kPluginLIBInitGlobals  ){
		VWFC_ASSERT( farrRoutinesUserData == NULL );
		farrRoutinesUserData	= (long*) ::GS_NewPtr( gCBP, sizeof(long) * fnLastRoutineIndex );
		for(size_t i=0; i<fnLastRoutineIndex; i++)
			farrRoutinesUserData[i] = 0;
	}
	else if ( routineSelector == kPluginLIBDisposeGlobals ) {
		// do nothing
	}

	// pass the message to the routines for processing
	long	reply	= 0L;
	for(size_t i=0; i<fnLastRoutineIndex; i++) {
		VWPluginLibraryRoutine*	pRoutine	= farrLibraryRoutines[ i ];
		if ( pRoutine ) {
			if ( routineSelector == kPluginLIBInitGlobals ) {
				reply	|= pRoutine->InitPluginLibrary();
			}
			else if ( routineSelector == kPluginLIBDisposeGlobals ) {
				reply	|= pRoutine->DestroyPluginLibrary();
			}
			else if ( routineSelector >= 0 ) {
				pRoutine->SetUserData( farrRoutinesUserData[i] );
				pRoutine->DispatchRoutine( routineSelector, argTable );
				farrRoutinesUserData[i]	= pRoutine->GetUserData();
			}
		}
	}

	// free up
	if ( routineSelector == kPluginLIBDisposeGlobals ) {
		::GS_DisposePtr( gCBP, farrRoutinesUserData );
		farrRoutinesUserData	= NULL;
	}

	userData		= (long) farrRoutinesUserData;
	return reply | kUseSingleUserDataFlag;
}

VCOMError VWPluginLibraryApp::RegisterInterfaces(void* pModule)
{
#ifdef _VWFC_FOR_VW125x
	return 0;
#else
	VCOMError	result	= kVCOMError_NoError;
	for(size_t i=0; i<fnLastRoutineIndex; i++)
	{
		VWPluginLibraryRoutine*	pRoutine	= farrLibraryRoutines[ i ];
		if ( pRoutine ) {
			result	= pRoutine->RegisterInterfaces( pModule );
			if ( VCOM_FAILED( result ) ) {
				break;
			}
		}
	}

	return result;
#endif
}

void VWPluginLibraryApp::CreateInterfaceInstance(const VWIID& iid, IVWUnknown** ppOutInterface)
{
	for(size_t i=0; i<fnLastRoutineIndex; i++)
	{
		VWPluginLibraryRoutine*	pRoutine	= farrLibraryRoutines[ i ];
		if ( pRoutine ) {
			pRoutine->CreateInterfaceInstance( iid, ppOutInterface );
		}
	}
}

void VWPluginLibraryApp::DeleteInterfaceInstance(const VWIID& iid, IVWUnknown* pInterface)
{
	for(size_t i=0; i<fnLastRoutineIndex; i++)
	{
		VWPluginLibraryRoutine*	pRoutine	= farrLibraryRoutines[ i ];
		if ( pRoutine ) {
			pRoutine->DeleteInterfaceInstance( iid, pInterface );
		}
	}
}