#include "XCCom.h"
#include "XCCom_i.c"
#include "msscript_i.c"

#include <stdio.h>

#include "XCircuit.h"
#include "XCArc.h"
#include "XCObject.h"
#include "XCPolygon.h"
#include "XCText.h"
#include "XCPoint.h"

static ITypeLib *tl = NULL;
/*static*/ IXCircuit *xc = NULL;

BEGIN_COM_INTERFACES
	DEFINE_COM_INTERFACE(XCircuit)
	DEFINE_COM_INTERFACE(XCMenuItem)
END_COM_INTERFACES

int COM_initialize()
{
	HRESULT hres;
	wchar_t filename[1024];
	XCircuit *xcobj;

	if (CoInitialize(NULL) != S_OK)
		return 0;

	if (GetModuleFileNameW(NULL, filename, 1024) == 1024)
		return 0;

	if (LoadTypeLib(filename, &tl) != S_OK)
		return 0;
	hres = RegisterTypeLib(tl, filename, NULL);

	//init_XCircuit(tl);
	COM_init_interfaces(tl);
	init_XCArc(tl);
	init_XCPolygon(tl);
	init_XCPoint(tl);
	init_XCText(tl);

	xcobj = (XCircuit*)make_XCircuit();
	IUnknown_QueryInterface(&xcobj->com.unk_iface, &IID_IXCircuit, (void**)&xc);
	IXCircuit_InitScript(xc);

	return 1;
}

int COM_terminate()
{
	HRESULT hres;
	TLIBATTR *tl_attr;

	IXCircuit_TermScript(xc);
	IXCircuit_Release(xc);

	close_XCText();
	close_XCPoint();
	close_XCPolygon();
	close_XCArc();
	//close_XCircuit();
	COM_term_interfaces();

	hres = ITypeLib_GetLibAttr(tl, &tl_attr);
	hres = UnRegisterTypeLib(&tl_attr->guid, tl_attr->wMajorVerNum, tl_attr->wMinorVerNum, tl_attr->lcid, tl_attr->syskind);
	ITypeLib_ReleaseTLibAttr(tl, tl_attr);

	ITypeLib_Release(tl);

	return 1;
}

void COM_execute(char *cmd)
{
	wchar_t ws[1024];

	mbstowcs(ws, cmd, 1024);
	IXCircuit_ExecuteStatement(xc, ws);
}

void COM_runscript(char *filename)
{
	FILE *fd = fopen(filename, "r");
	wchar_t *wdata;
	char *data;
	int len;

	if (fd == NULL) {
		Wprintf("Failed to open script");
		return;
	}
	fseek(fd, 0, SEEK_END);
	len = ftell(fd);
	fseek(fd, 0, SEEK_SET);

	data = (char*)malloc(sizeof(char)*(len+1));
	wdata = (wchar_t*)malloc(sizeof(wchar_t)*(len+1));
	fread(data, len, 1, fd);
	data[len] = 0;
	mbstowcs(wdata, data, len+1);
	fclose(fd);

	IXCircuit_ExecuteStatement(xc, wdata);
	free(data);
	free(wdata);
}

void COM_load_dotnet(char *filename)
{
	wchar_t *wfilename;
	BSTR str;
	int len;

	len = strlen(filename);
	wfilename = malloc(sizeof(wchar_t)*len+1);
	mbstowcs(wfilename, filename, len+1);
	str = SysAllocString(wfilename);

	IXCircuit_load_dotnet_plugin(xc, str);
	SysFreeString(str);
	free(wfilename);
}

void win32_fire_event(int evt_type)
{
	switch (evt_type) {
		case ModifiedChanged:
			xccom_object_fire_event(TOCOMOBJ(xc), &DIID_DXCEvents, 0x00001000);
			break;
		case ZoomChanged:
			xccom_object_fire_event(TOCOMOBJ(xc), &DIID_DXCEvents, 0x00001001);
			break;
	}
}
