#include <owl/window.h>
#include "../../../include/com_server.h"

DEFINE_GUID(CLSID_LED, 0x681299e1, 0x8bb4, 0x11d3, 0xad, 0xaa, 0x00,0x60,0x67,0x49,0x62,0x45);

class LEDWin: public TWindow {
public:
	LEDWin(TWindow* parent, ImpComponent* pcomp, BoolConnection& pin);
private:
	virtual void SetupWindow();
	virtual void Paint(TDC& dc, bool, TRect&);
	void EvSize(uint sizeType, TSize& size);

	void pinChanged();
	void CmToggle();
	void CmConnect();

	CallOnChange<BoolConnection::BaseType, LEDWin> coc;
	ImpComponent* pComp;

DECLARE_RESPONSE_TABLE(LEDWin);
};

DEFINE_RESPONSE_TABLE1(LEDWin, TWindow)
	EV_WM_SIZE,
	EV_COMMAND(10, CmConnect),
	EV_COMMAND(20, CmToggle),
END_RESPONSE_TABLE;

LEDWin::LEDWin(TWindow* parent, ImpComponent* pcomp, BoolConnection& pin):
		TWindow(parent, 0 , new TModule("led.dll")),
		coc(pin, this, &LEDWin::pinChanged),
		pComp(pcomp) {
	Attr.W=104;
	Attr.H=104;
}

void LEDWin::SetupWindow() {
	TWindow::SetupWindow();
	ContextPopupMenu = new TPopupMenu;
	// This TPopupMenu will be deleted by the TWindow destructor. So don't call delete yourself!
	ContextPopupMenu->AppendMenu(MF_STRING, 10, "&Connect...");
	ContextPopupMenu->AppendMenu(MF_STRING, 20, "&Toggle Led");
	pinChanged();
}

void LEDWin::Paint(TDC& dc, bool, TRect&) {
	TMemoryDC memDC(dc);
	TBitmap led(*GetModule(), coc->get() ? "ledOn" : "ledOff");
	memDC.SelectObject(led);
   dc.StretchBlt(0, 0, GetClientRect().Width(), GetClientRect().Height(), memDC, 0 , 0, led.Width(), led.Height(), SRCCOPY);
}

void LEDWin::EvSize(uint sizeType, TSize& size) {
	TWindow::EvSize(sizeType, size);
	Invalidate(false);
}

void LEDWin::pinChanged() {
	pComp->SetCompWinIcon(GetModule()->LoadIcon(coc->get() ? "iconLedOn" : "iconLedOff"));
	pComp->SetCompWinTitle(coc->get() ? "Led is ON" : "Led is OFF");
	Invalidate(false);
}

void LEDWin::CmToggle() {
	coc->set(!coc->get());
}

void LEDWin::CmConnect() {
	pComp->ConnectDialog();
}

class LED: public ImpComponent {
public:
	LED();
private:
	virtual HWND CreateComponentWindow(HWND parent);
	TWindow* LEDWindow;
	BoolConnection	pin;
};

LED::LED(): LEDWindow(0) {
	SetComponentName("Led");
	SetGroupName("CDK Borland C++ 5.02 Examples");
	Expose(pin, "Led input");
}

HWND LED::CreateComponentWindow(HWND parent) {
	if (LEDWindow==0) {
		LEDWindow = new LEDWin(::GetWindowPtr(parent), this, pin);
		// This LEDWin will be deleted by its parent. So don't call delete yourself!
		LEDWindow->Create();
	}
	return LEDWindow->GetHandle();
}

void RegisterClassFactories() {
	ClassFactory* new_classfactory(new ComponentFactory<LED>(CLSID_LED));
	class_factories.push_back(new_classfactory);
}
