#include "StdAfx.h"
#include "lkfstatic.h"
#include "Protocol.h"

extern "C" {
#include "../../c/lkf5defs.h"
}

static LKFStatic *pStaticObject = 0;

static const char DEFAULT_STRING_DELIMITER[] = {13,10,0};

static void * __stdcall create_semaphore ()
{
	HANDLE sem;

	sem = CreateSemaphore (0,1,1,0);
	return (void *) sem;
}

static void __stdcall enter_semaphore (void *sem)
{
	HANDLE handle = (HANDLE) sem;
	WaitForSingleObject (handle, INFINITE);
}

static void __stdcall leave_semaphore (void *sem)
{
	HANDLE handle = (HANDLE) sem;
	ReleaseSemaphore (handle, 1, 0);
}

static void __stdcall close_semaphore (void *sem)
{
	HANDLE handle = (HANDLE) sem;
	CloseHandle (handle);
}

LKFStatic::LKFStatic(void)
{
	ULONG PathLen;
	CRegKey hklm = CRegKey (HKEY_LOCAL_MACHINE);
	CRegKey hksoft, hklkf;
	hksoft.Open (hklm.m_hKey, "SOFTWARE");
	hklkf.Create (hksoft.m_hKey, "LKF");
	Reg.Create (hklkf.m_hKey, "LKFServer"); 
	PathLen = MAX_PATH;
	GetRootPath (CurrentRootPath, &PathLen);
	GetLineSeparators (LineSepImport, LineSepExport);
}

int LKFStatic::Init ()
{
	lkf_semaphore_callbacks (create_semaphore, enter_semaphore, leave_semaphore, close_semaphore);
	lkf_set_global_inputpath (CurrentRootPath);
	return 0;
}

LKFStatic::~LKFStatic(void)
{
}

LKFStatic *GetStaticObject ()
{
	LKFStatic::EnterCS();
	if (pStaticObject == 0) {
		pStaticObject = new LKFStatic();
		LKFStatic::LeaveCS();
		pStaticObject->Init ();
	}
	else LKFStatic::LeaveCS();
	return pStaticObject;
}

const char *LKFStatic::GetRootPath (char *Path, ULONG *PathLen)
{
	if (Reg.QueryStringValue ("RootPath", Path, PathLen)) return 0;
	else return Path;
}

void LKFStatic::SetRootPath (const char *path)
{
	EnterCS ();
	Reg.SetStringValue ("RootPath", path); 
	LeaveCS ();
}

void LKFStatic::SetLineSeparators (const char *import, const char *cexport)
{
	EnterCS ();
	if (import) Reg.SetStringValue ("ImportSeparator", import);
	if (cexport) Reg.SetStringValue ("ExportSeparator", cexport);
	LeaveCS ();
}

void LKFStatic::GetCurrentLineSeparators (const char **import, const char **cexport)
{
	if (import) *import = LineSepImport;
	if (cexport) *cexport = LineSepExport;
}

void LKFStatic::GetLineSeparators (char *import, char *cexport)
{
	ULONG Len = MAX_LINESEP;
	if (import) {
		Reg.QueryStringValue ("ImportSeperator", import, &Len);
		if (!Len || !import[0]) strcpy (import, DEFAULT_STRING_DELIMITER);
		else if (Len < MAX_LINESEP) import[Len] = 0;
		else import[MAX_LINESEP-1] = 0;
	}
	Len = MAX_LINESEP;
	if (cexport) {
		Reg.QueryStringValue ("ExportSeparator", cexport, &Len);
		if (!Len || !cexport[0]) strcpy (cexport, DEFAULT_STRING_DELIMITER);
		else if (Len < MAX_LINESEP) cexport[Len] = 0;
		else cexport[MAX_LINESEP-1] = 0;
	}
}

const char *LKFStatic::GetCurrentRootPath (void)
{
	return CurrentRootPath;
}

void LKFStatic::EnterCS ()
{
}

void LKFStatic::LeaveCS ()
{
}

/* BSTR helper function ********************************************************************************/

BSTR createBSTRLen (const char *s, unsigned int len)
{
	if	(!len) return NULL;
	BSTR b_string = ::SysAllocStringLen(NULL ,len);
	if (b_string != NULL)
		MultiByteToWideChar	(CP_ACP ,0 ,s ,len ,b_string ,len);
	return b_string;
//	return SysAllocStringByteLen (s, (unsigned int) strlen (s));
}

BSTR createBSTR (const char *s)
{
	return createBSTRLen (s, (unsigned int) strlen (s));
}

char * createChar (const BSTR b_string)
{
	int		a_len;
	if	(b_string) a_len = ::SysStringLen(b_string)+1;
	else a_len = 1;
	char * c_string = new char [a_len+2];

	if	(c_string) {
		if (a_len == 1)
			c_string[0] = 0; /* V13.0 */
		else WideCharToMultiByte(CP_ACP ,0 ,b_string ,a_len ,c_string ,a_len ,NULL ,NULL);
	}
	return c_string;
}

char * createChar (const VARIANT variant)
{
	if (variant.vt == VT_BSTR) return createChar (variant.bstrVal);
	else return 0;
}



