#include "WSEngineer.h"
#include <stdio.h>
#include <assert.h>

LPInitializeEngineer CWSEngineer::m_pInitializeEngineer = NULL;
LPSegmentAText	CWSEngineer::m_pSegmentAText = NULL;
LPSegmentWText	CWSEngineer::m_pSegmentWText = NULL;
HINSTANCE       CWSEngineer::m_hInstWSEngineer = NULL;
bool            CWSEngineer::m_bLoadWSDLL = false;

CWSEngineer::CWSEngineer()
{
	m_hInstWSEngineer = NULL;
	InitializeCriticalSection(&m_CriticalSection);
}

CWSEngineer::~CWSEngineer()
{
	UnloadDLL();
	DeleteCriticalSection(&m_CriticalSection);
}

void CWSEngineer::UnloadDLL()
{
	if(m_hInstWSEngineer != NULL)
	{
		FreeLibrary(m_hInstWSEngineer);
		m_hInstWSEngineer = NULL;
		m_pInitializeEngineer = NULL;
		m_pSegmentAText = NULL;
		m_pSegmentWText = NULL;
	}

	m_bLoadWSDLL = false;
}

bool CWSEngineer::LoadDLL()
{
	if(m_bLoadWSDLL) return true;

	CHAR szPath[MAX_PATH];
	memset(szPath,0,MAX_PATH*sizeof(CHAR));
	GetModuleFileName(NULL,szPath,MAX_PATH);
	PCHAR pch = strrchr(szPath,'\\');
	assert(pch != NULL);
	*(pch+1) = 0;
	TCHAR szDLLFileName[MAX_PATH];
	memset(szDLLFileName,0,MAX_PATH*sizeof(CHAR));
	strcpy(szDLLFileName,szPath);
	strcat(szDLLFileName,"WS.dll");
	m_hInstWSEngineer = LoadLibrary(szDLLFileName);
	if(m_hInstWSEngineer == NULL)
	{
		printf("Cannot Load WSDLL\n");
		return false;
	}

	m_pInitializeEngineer = (LPInitializeEngineer)GetProcAddress(m_hInstWSEngineer,"InitializeEngineer");
	if(m_pInitializeEngineer == NULL)
	{
		printf("Cannot Load the InitializeEngineer\n");
		UnloadDLL();
		return false;
	}

	m_pSegmentAText = (LPSegmentAText)GetProcAddress(m_hInstWSEngineer,"SegmentAText");
	if(m_pSegmentAText == NULL)
	{
		printf("Cannot Load the SegmentAText\n");
		UnloadDLL();
		return false;
	}

	m_pSegmentWText = (LPSegmentWText)GetProcAddress(m_hInstWSEngineer,"ProcessUnicodeText");
	if(m_pSegmentWText == NULL)
	{
		printf("Cannot Load the SegmentWText\n");
		UnloadDLL();
		return false;
	}
		
	m_bLoadWSDLL = true;

	return true;
}

bool CWSEngineer::InitializeEngineer(const char* pszKnowlegebasePath)
{
	if(!m_bLoadWSDLL) LoadDLL();
	if(!m_bLoadWSDLL) return false;

	bool bSuccess = false;
	EnterCriticalSection(&m_CriticalSection);
	if(m_pInitializeEngineer != NULL)
	{
		bSuccess = m_pInitializeEngineer(pszKnowlegebasePath);
	}
	LeaveCriticalSection(&m_CriticalSection);

	return bSuccess;
}

PCHAR CWSEngineer::SegmentAText(const PCHAR pszInput)
{
	if(!m_bLoadWSDLL) LoadDLL();
	if(!m_bLoadWSDLL) return false;

	PCHAR pszRet = 0;
	EnterCriticalSection(&m_CriticalSection);
	if(m_pSegmentAText != NULL)
	{
		pszRet = m_pSegmentAText(pszInput);
	}
	LeaveCriticalSection(&m_CriticalSection);

	return pszRet;
}

PWCHAR CWSEngineer::SegmentWText(const PWCHAR pszInput)
{
	if(!m_bLoadWSDLL) LoadDLL();
	if(!m_bLoadWSDLL) return false;

	PWCHAR pszRet = 0;
	EnterCriticalSection(&m_CriticalSection);
	if(m_pSegmentWText != NULL)
	{
		pszRet = m_pSegmentWText(pszInput);
	}
	LeaveCriticalSection(&m_CriticalSection);

	return pszRet;
}
