// Causeway DLL server implementation

#include "stdafx.h"
#include <initguid.h>

#include "jsvr.h"
#include "jexeodl.h"
#include "jdllodl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

typedef IJEXEServer FAR* PJS;	// J Server object
PJS pjs = 0;

// OLE interface requires BSTR arguments
static BSTR GetBSTR( LPCSTR string )
{
	WCHAR* wstring;
	BSTR bstring;

	bstring = SysAllocStringLen( 0, strlen( string ) );
	wstring  = (WCHAR*) bstring;
	while ( *string ) *wstring++ = *string++;
	return bstring;
}

// create J Server object
// dll = 1 creates a J DLL Server
// dll = 0 creates a J EXE Server
int jscreate(BOOL dll)
{
	HRESULT hr;
	LPUNKNOWN punk;
	long rc;
	
	if(pjs) return -1;	// already done
	CoInitialize(0);	// initialize OLE interface
	hr = CoCreateInstance(dll? CLSID_JDLLServer : CLSID_JEXEServer,
		0, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&punk );
	ASSERT(!FAILED(hr));
	if (FAILED(hr)) return hr;
	hr = punk->QueryInterface(dll ? IID_IJDLLServer : IID_IJEXEServer, (void**)&pjs );
	punk->Release();	// release is very important
	ASSERT(!FAILED(hr));
	if(FAILED(hr)) return hr;
	pjs->Transpose(0, &rc);	// C wants arrays in row major order
	ASSERT(!rc);
	if (!dll)
	{
		pjs->Show(1, &rc);
		ASSERT(!rc);
		pjs->Log(1,&rc);
		ASSERT(!rc);
	}
	return 0;
}

// close J Server
int jsdelete()
{
	long rc;

	if(!pjs) return -1;
	pjs->Quit( &rc );
	pjs->Release();
	pjs = 0;
	return rc;
}

int jsdo(LPCSTR expr)
{
	long	rc;
	BSTR jexpr;

	if (!pjs) return -1;
	jexpr = GetBSTR(expr);
	pjs->Do(jexpr, &rc);
	SysFreeString(jexpr);
	return rc;
}

int jsset(LPCSTR name, VARIANT* pv )
{
	long rc;
	BSTR jname;

	if(!pjs) return -1;
	jname = GetBSTR(name);
	pjs->Set(jname, pv, &rc);
	SysFreeString(jname);
	return rc;
}

int jsget(LPCSTR name, VARIANT* pv)
{
	long rc;
	BSTR jname;

	if(!pjs) return -1;
	jname = GetBSTR(name);
	pjs->Get(jname, pv, &rc);
	SysFreeString(jname);
	return rc;
}

int jserror(int ec, VARIANT* pv)
{
	long rc;

	if(!pjs) return -1;
	pjs->ErrorText(ec, pv, &rc);
	return rc;
}