#include <CtrlLib/CtrlLib.h>

using namespace Upp;

String GetKeyDescEx(int key)
{
	String desc = GetKeyDesc(key & ~K_KEYUP);
	if(key & K_KEYUP)
		desc << " UP";
	return desc;
}

struct App : TopWindow {
	ArrayCtrl  log;

	void Log(const String& s)
	{
		log.Add(s);
		log.GoEnd();
	}

	void Activate() override
	{
		Log("Activate");
		SetFocus();
	}

	void Deactivate() override
	{
		Log("Deactivate");
	}

	Image FrameMouseEvent(int event, Point p, int zdelta, dword keyflags) override
	{
		if(event != CURSORIMAGE)
			Log(Format("FrameMouseEvent(%d, Point(%d, %d), %d, %x)",
			           event, p.x, p.y, zdelta, (int)keyflags));
		return TopWindow::FrameMouseEvent(event, p, zdelta, keyflags);
	}

	Image MouseEvent(int event, Point p, int zdelta, dword keyflags) override
	{
		if(event != CURSORIMAGE)
			Log(Format("MouseEvent(%d, Point(%d, %d), %d, %x)",
			           event, p.x, p.y, zdelta, (int)keyflags));
		return TopWindow::MouseEvent(event, p, zdelta, keyflags);
	}

	void MouseEnter(Point p, dword keyflags) override
	{
		Log(Format("MouseEnter(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void MouseMove(Point p, dword keyflags) override
	{
		Log(Format("MouseMove(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void LeftDown(Point p, dword keyflags) override
	{
		Log(Format("LeftDown(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
		SetFocus();
	}

	void LeftDouble(Point p, dword keyflags) override
	{
		Log(Format("LeftDouble(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void LeftTriple(Point p, dword keyflags) override
	{
		Log(Format("LeftTriple(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}
	
	void LeftDrag(Point p, dword keyflags) override {
		Log(Format("LeftDrag(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}
	
	void LeftHold(Point p, dword keyflags) override {
		Log(Format("LeftHold(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void LeftRepeat(Point p, dword keyflags) override
	{
		Log(Format("LeftRepeat(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void LeftUp(Point p, dword keyflags) override
	{
		Log(Format("LeftUp(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void RightDown(Point p, dword keyflags) override
	{
		Log(Format("RightDown(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void RightDouble(Point p, dword keyflags) override
	{
		Log(Format("RightDouble(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void RightTriple(Point p, dword keyflags) override
	{
		Log(Format("RightTriple(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}
	
	void RightDrag(Point p, dword keyflags) override {
		Log(Format("RightDrag(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}
	
	void RightHold(Point p, dword keyflags) override {
		Log(Format("RightHold(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void RightRepeat(Point p, dword keyflags) override
	{
		Log(Format("RightRepeat(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void RightUp(Point p, dword keyflags) override
	{
		Log(Format("RightUp(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void MiddleDown(Point p, dword keyflags) override
	{
		Log(Format("MiddleDown(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void MiddleDouble(Point p, dword keyflags) override
	{
		Log(Format("MiddleDouble(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void MiddleTriple(Point p, dword keyflags) override
	{
		Log(Format("MiddleTriple(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}
	
	void MiddleDrag(Point p, dword keyflags) override {
		Log(Format("MiddleDrag(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}
	
	void MiddleHold(Point p, dword keyflags) override {
		Log(Format("MiddleHold(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void MiddleRepeat(Point p, dword keyflags) override
	{
		Log(Format("MiddleRepeat(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void MiddleUp(Point p, dword keyflags) override
	{
		Log(Format("MiddleUp(Point(%d, %d), %x)", p.x, p.y, (int)keyflags));
	}

	void MouseWheel(Point p, int zdelta, dword keyflags) override
	{
		Log(Format("MouseWheel(Point(%d, %d), %d, %x)", p.x, p.y, zdelta, (int)keyflags));
	}

	void HorzMouseWheel(Point p, int zdelta, dword keyflags) override
	{
		Log(Format("HorzMouseWheel(Point(%d, %d), %d, %x)", p.x, p.y, zdelta, (int)keyflags));
	}

	void MouseLeave() override
	{
		Log("MouseLeave");
	}

	Image CursorImage(Point p, dword keyflags) override
	{
		return keyflags & K_CTRL ? CtrlImg::swap_color_cursor() : Image::Arrow();
	}

	bool Key(dword key, int count) override
	{
		Log(Format("Key(%x, %d) ", (int)key, count) + GetKeyDescEx(key));
		return false;
	}

	void GotFocus() override
	{
		Log("GotFocus");
	}

	void LostFocus() override
	{
		Log("LostFocus");
	}

	bool HotKey(dword key) override
	{
		Log(Format("HotKey(%x) ", (int)key) + GetKeyDescEx(key));
		return false;
	}

	void ChildGotFocus() override
	{
		Log("ChildGotFocus");
	}

	void ChildLostFocus() override
	{
		Log("ChildLostFocus");
	}

	void Layout() override
	{
		Log("Layout");
	}

	App()
	{
		Title("Events");
		SetFrame(InsetFrame());
		AddFrame(InsetFrame());
		AddFrame(InsetFrame());
		AddFrame(InsetFrame());
		log.AddColumn("");
		log.NoHeader();
		Add(log.HSizePos().BottomPosZ(0, 200));
	}

	~App()
	{
		Shutdown();
	}
};

GUI_APP_MAIN
{
	App().Run();
}
