#include <stdio.h>

#include "lgi/common/Lgi.h"
#include "lgi/common/List.h"
#include "lgi/common/DisplayString.h"
#include "LgiIde.h"

class CharItem : public LListItem
{
	LSurface *pDC;

public:
	CharItem(LSurface *pdc)
	{
		pDC = pdc;
	}

	~CharItem()
	{
		DeleteObj(pDC);
	}

	void OnPaintColumn(LItem::ItemPaintCtx &Ctx, int i, LItemColumn *c)
	{
		LListItem::OnPaintColumn(Ctx, i, c);

		if (i == 1)
		{
			Ctx.pDC->Blt(Ctx.x1, Ctx.y1, pDC);
		}
	}

	void OnMeasure(LPoint *Info)
	{
		LListItem::OnMeasure(Info);
		if (pDC)
			Info->y = MAX(Info->y, pDC->Y());
	}
};

class SysCharSupportPriv : public LResourceLoad
{
public:
	LList *Match, *NonMatch;

	SysCharSupportPriv()
	{
		Match = NonMatch = 0;
	}

	void Search(const char *ch)
	{
		if (ch && Match && NonMatch)
		{
			Match->Empty();
			NonMatch->Empty();

			GUtf8Str Utf((char*)ch);
			uint32_t c = Utf;

			char msg[256];
			sprintf(msg, "%i 0x%x", c, c);
			Match->GetWindow()->SetCtrlName(IDC_VALUE, msg);

			LFontSystem *s = LFontSystem::Inst();
			if (s)
			{
				LString::Array Fonts;
				if (s->EnumerateFonts(Fonts))
				{
					for (auto &f : Fonts)
					{
						LFont *Fnt = new LFont;
						if (Fnt)
						{
							Fnt->SubGlyphs(false);

							if (Fnt->Create(f, "16pt"))
							{
								LList *m = _HasUnicodeGlyph(Fnt->GetGlyphMap(), c) ? Match : NonMatch;

								LMemDC *pDC = new LMemDC;
								if (pDC)
								{
									char16 Str[] = { (char16)c, 0 };
									LDisplayString d(Fnt, Str);
									if (pDC->Create(d.X(), d.Y(), System32BitColourSpace))
									{
										pDC->Colour(L_WORKSPACE);
										pDC->Colour(L_TEXT);
										d.Draw(pDC, 0, 0);
									}
								}

								LListItem *i;
								m->Insert(i = new CharItem(pDC));
								if (i)
								{
									i->SetText(f);
								}
							}

							DeleteObj(Fnt);
						}
					}
				}				
			}
		}
	}
};

SysCharSupport::SysCharSupport(AppWnd *app)
{
	d = new SysCharSupportPriv;
	Name("System Character Support");

	if (Attach(0))
	{
		d->LoadFromResource(IDD_CHAR, this, &GetPos());
		MoveToCenter();
		AttachChildren();
		GetViewById(IDC_MATCH, d->Match);
		GetViewById(IDC_NOT_MATCH, d->NonMatch);
		OnPosChange();

		Visible(true);
	}
}

SysCharSupport::~SysCharSupport()
{
	DeleteObj(d);
}

void SysCharSupport::OnPosChange()
{
	/*
	if (d->Match)
	{
		LRect c = GetClient();
		LRect r = d->Lst->GetPos();
		r.x2 = c.x2 - r.x1;
		r.y2 = c.y2 - r.x1;
		d->Lst->SetPos(r);
	}
	*/
}

int SysCharSupport::OnNotify(LViewI *v, LNotification n)
{
	switch (v->GetId())
	{
		case IDOK:
		{
			d->Search(GetCtrlName(IDC_CHAR));
			break;
		}
	}

	return 0;
}
