
#include <windows.h>
#include "DemopajaVersion.h"
#include "PajaTypes.h"
#include "DllInterfaceC.h"
#include "ClassDescC.h"

using namespace PluginClass;


DllInterfaceC::DllInterfaceC() :
	m_hDLL ( 0 ),
	m_pGetClassdescCount( 0 ),
	m_pGetClassdesc( 0 ),
	m_pGetApiVersion( 0 ),
	m_pGetDllName( 0 )
{
	// empty
}


DllInterfaceC::~DllInterfaceC()
{
	if( m_hDLL ) {
		::FreeLibrary( m_hDLL );
		m_hDLL = 0;
	}
}

bool
DllInterfaceC::init( const char* szDllName )
{
	m_hDLL = ::LoadLibrary( szDllName );

	if( m_hDLL != NULL ) {

		m_pGetClassdescCount = (GetClassdescCountF)::GetProcAddress( m_hDLL, "?get_classdesc_count@@YAHXZ" );
		if( !m_pGetClassdescCount ) {
			m_pGetClassdescCount = (GetClassdescCountF)::GetProcAddress( m_hDLL, "get_classdesc_count" );
			if( !m_pGetClassdescCount ) {
				//Release Dll if we werent able to get the function
				::FreeLibrary( m_hDLL );
				::OutputDebugString( "DLL_IFACE: class_desc_count failed\n" );
				return false;
			}
		}

		m_pGetApiVersion = (GetApiVersionF)::GetProcAddress( m_hDLL, "?get_api_version@@YAHXZ" );
		if( !m_pGetApiVersion ) {
			m_pGetApiVersion = (GetApiVersionF)::GetProcAddress( m_hDLL, "get_api_version" );
			if( !m_pGetApiVersion ) {
				//Release Dll if we werent able to get the function
				::FreeLibrary( m_hDLL );
				::OutputDebugString( "DLL_IFACE: class_api_version failed\n" );
				return false;
			}
		}

		m_pGetDllName = (GetDllNameF)::GetProcAddress( m_hDLL, "?get_dll_name@@YAPADXZ" );
		if( !m_pGetDllName ) {
			m_pGetDllName = (GetDllNameF)::GetProcAddress( m_hDLL, "get_dll_name" );
			if( !m_pGetDllName ) {
				//Release Dll if we werent able to get the function
				::FreeLibrary( m_hDLL );
				::OutputDebugString( "DLL_IFACE: class_dll_name failed\n" );
				return false;
			}
		}

		m_pGetClassdesc = (GetClassdescF)::GetProcAddress( m_hDLL, "?get_classdesc@@YAPAVClassDescC@PluginClass@@H@Z" );
		if( !m_pGetClassdesc ) {
			m_pGetClassdesc = (GetClassdescF)::GetProcAddress( m_hDLL, "get_classdesc" );
			if( !m_pGetClassdesc ) {
				//Release Dll if we werent able to get the function
				::FreeLibrary( m_hDLL );
				::OutputDebugString( "DLL_IFACE: class_classdesc failed\n" );
				return false;
			}
		}

		return true;
	}
	else {
		::OutputDebugString( "DLL_IFACE: LoadLibrary( \"" );
		::OutputDebugString( szDllName );
		::OutputDebugString( "\") failed with: " );

		LPVOID lpMsgBuf;
		FormatMessage( 
			FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			FORMAT_MESSAGE_FROM_SYSTEM | 
			FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			GetLastError(),
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
			(LPTSTR) &lpMsgBuf,
			0,
			NULL 
		);
		// Process any inserts in lpMsgBuf.
		// ...
		// Display the string.
		::OutputDebugString( (LPCTSTR)lpMsgBuf );
		// Free the buffer.
		LocalFree( lpMsgBuf );

	}
	return false;
}

PajaTypes::int32
DllInterfaceC::get_classdesc_count() const
{
	return m_pGetClassdescCount();
}

ClassDescC*
DllInterfaceC::get_classdesc( PajaTypes::int32 i )
{
	return m_pGetClassdesc( i );
}

PajaTypes::int32
DllInterfaceC::get_api_version() const
{
	return m_pGetApiVersion();
}

const char*
DllInterfaceC::get_dll_name() const
{
	return m_pGetDllName();
}
