#define INCL_WIN
#define INCL_DOS
#define INCL_GPI
#include <os2.h>
#include <string.h>

#include <hugelb.h>
#include <ecomedia.h>
#include "hlbtest.h"

MRESULT EXPENTRY wpMyClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);

PSZ ppszNames[]={"Beer", "Bigmac", "Cabbage", "Croissant", "Fruits", "Lemon", "Orange"};
PSZ ppszCalories[]={"115", "250", "10", "55", "77", "35", "45"};
PSZ ppszWeight[]={"250", "150", "500", "60", "200", "60", "65"};
PSZ ppszFields[]={"Name: ", "Calories: ", "Weight: "};
HBITMAP2 hbm2Images[NUM_ICONS]={NULLHANDLE, NULLHANDLE, NULLHANDLE, NULLHANDLE, NULLHANDLE, NULLHANDLE, NULLHANDLE};

ULONG main()
{
	HAB hab;
	HMQ hmq;
	HWND hwndFrame, hwndClient;
	ULONG flFrameCreationFlags=FCF_TITLEBAR|FCF_SIZEBORDER|FCF_MINMAX|FCF_SYSMENU|FCF_SHELLPOSITION|FCF_TASKLIST;
	QMSG  qMsg;

   hab=WinInitialize(0);
   if (!hab)
      return -1;

   hmq=WinCreateMsgQueue(hab, 0L);

   if (!hmq)
   {
      WinTerminate(hab);
      return -2;
   }

   if (!WinRegisterClass(hab, MY_CLIENT_CLASS, wpMyClientWndProc, CS_CLIPCHILDREN|CS_SIZEREDRAW, 0L))
   {
      WinDestroyMsgQueue(hmq);
      WinTerminate(hab);
      return -3;
   }

   if (!(hwndFrame=WinCreateStdWindow(HWND_DESKTOP, 0L, &flFrameCreationFlags, MY_CLIENT_CLASS, "Huge list box test", 0L, (HMODULE)0, ID_FRAME, &hwndClient)))
   {
      WinDestroyMsgQueue(hmq);
      WinTerminate(hab);
      return -4;
   }

   while (WinGetMsg(hab, &qMsg, 0, 0, 0))
      WinDispatchMsg(hab, &qMsg);

   WinDestroyWindow(hwndFrame);
   WinDestroyMsgQueue(hmq);
   WinTerminate(hab);
   return 0;
}

MRESULT EXPENTRY wpMyClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
	HPS			hps;
	HWND		hwndFrame, hwndListBox;
	RECTL		rcl, rcl1;
	HBITMAP2	hbm2, hbm2tmp;
	PVOID		pPngData;
	ULONG		ulItem, i, ulColor;
	CTLCOLOR	actlColor[2];
	BITMAP2HEADER bitmap2header;

	FONTMETRICS fm;
	FATTRS fat;

	switch (msg)
	{
		case WM_CREATE:
			if ((hwndListBox=HlbCreate(hwnd, WS_VISIBLE|LS_NOADJUSTPOS|LS_EXTENDEDSEL, 10, 10, 100, 100, hwnd, HWND_TOP, ID_LISTBOX, NULL))!=NULLHANDLE)
				if (HlbInsertItems(hwndListBox, 0, NUM_ICONS, ppszNames))
					for (i=0; i<NUM_ICONS; i++)
						if (!DosGetResource(NULLHANDLE, RT_PNG, IDI_ICONS+i+1, &pPngData))
						{
							hbm2=Gpi2ReadPng(pPngData, 0x00000000, 0L);
							hbm2tmp=Gpi2ScaleBitmap2(hbm2, CX_ICON, CY_ICON, TRUE);
							hbm2Images[i]=Gpi2ScaleBitmap2(hbm2, CX_IMAGE, CY_IMAGE, TRUE);
							Gpi2DeleteBitmap(hbm2);
							HlbSetItemHandle(hwndListBox, i, hbm2tmp);
							DosFreeResource(pPngData);
						}
			break;

		case WM_PAINT:
			if ((hps=WinBeginPaint(hwnd, NULLHANDLE, &rcl))!=NULLHANDLE)
			{
				// Fill background
				if (!WinQueryPresParam(hwnd, PP_BACKGROUNDCOLOR, PP_BACKGROUNDCOLORINDEX, NULL, sizeof(ULONG), &ulColor, QPF_ID2COLORINDEX))
					ulColor=WinQuerySysColor(HWND_DESKTOP, SYSCLR_WINDOW, 0L);

                GpiCreateLogColorTable(hps, 0L, LCOLF_RGB, 0L, 0L, NULL);
				WinFillRect(hps, &rcl, ulColor);

                if ((hwndListBox=WinWindowFromID(hwnd, ID_LISTBOX))!=NULLHANDLE)
					if ((ulItem=HlbQuerySelection(hwndListBox, LIT_CURSOR))!=LIT_NONE)
						if (WinQueryWindowRect(hwnd, &rcl1))
                    		if(Gpi2QueryBitmapInfo(hbm2Images[ulItem], &bitmap2header))
                    		{
                            	rcl1.xRight-=10;
                            	rcl1.xLeft=rcl1.xRight-CX_IMAGE;
                            	rcl1.yTop-=10;
                            	rcl1.yBottom=rcl1.yTop-CY_IMAGE;

                                rcl1.xLeft+=(CX_IMAGE-bitmap2header.usCx)/2;
                                rcl1.xRight=rcl1.xLeft+bitmap2header.usCx;
                                rcl1.yBottom+=(CY_IMAGE-bitmap2header.usCy)/2;
                                rcl1.yTop=rcl1.yBottom+bitmap2header.usCy;

                            	if (rcl1.xLeft<rcl.xRight && rcl1.xRight>rcl.xLeft && rcl1.yBottom<rcl.yTop && rcl1.yTop>rcl.yBottom)
                                	Gpi2DrawBitmap(hps, hbm2Images[ulItem], 2, (PPOINTL)&rcl1);
                    		}
				WinEndPaint(hps);
			}
			break;

		case WM_ADJUSTWINDOWPOS:
			hwndFrame=WinQueryWindow(hwnd, QW_PARENT);
			if ((((PSWP)mp1)->fl&SWP_HIDE))
                WinStoreWindowPos("Huge Listbox Test", "MainWindowSizeAndPosition", hwndFrame);
			else
			{
				if (!WinRestoreWindowPos("Huge Listbox Test", "MainWindowSizeAndPosition", hwndFrame))
					if ((hwndListBox=WinWindowFromID(hwnd, ID_LISTBOX))!=NULLHANDLE)
						WinSetPresParam(hwndListBox, PP_FONTNAMESIZE, strlen("9.WarpSans")+1, "9.WarpSans");
				WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER|SWP_SHOW|SWP_ACTIVATE);
			}
			break;

		case WM_SIZE:
			WinSetWindowPos(WinWindowFromID(hwnd, ID_LISTBOX), HWND_TOP, 10, 10, SHORT1FROMMP(mp2)-20-CX_IMAGE-10, SHORT2FROMMP(mp2)-20, SWP_MOVE|SWP_SIZE);
			break;

		case WM_DRAWITEM:
			if (SHORT1FROMMP(mp1)==ID_LISTBOX)
			{
				if (((POWNERITEM)mp2)->fsState==((POWNERITEM)mp2)->fsStateOld)
				{
                    actlColor[0].clrIndex=CCI_FOREGROUND;
                    actlColor[1].clrIndex=CCI_BACKGROUND;
                    WinQueryControlColors(((POWNERITEM)mp2)->hwnd, CCT_LISTBOX, CCF_APPLICATION, 2, actlColor);

                    GpiCreateLogColorTable(((POWNERITEM)mp2)->hps, 0L, LCOLF_RGB, 0L, 0L, NULL);
					rcl=((POWNERITEM)mp2)->rclItem;
					WinFillRect(((POWNERITEM)mp2)->hps, &rcl, actlColor[1].clrValue);
                    if(Gpi2QueryBitmapInfo(((POWNERITEM)mp2)->hItem, &bitmap2header))
                    {
                        rcl.xLeft+=(CX_ICON-bitmap2header.usCx)/2;
                        rcl.xRight=rcl.xLeft+bitmap2header.usCx;
                        rcl.yBottom+=(CY_ICON-bitmap2header.usCy)/2;
                        rcl.yTop=rcl.yBottom+bitmap2header.usCy;
                    }
					Gpi2DrawBitmap(((POWNERITEM)mp2)->hps, ((POWNERITEM)mp2)->hItem, 1, (PPOINTL)&rcl);

					GpiQueryFontMetrics(((POWNERITEM)mp2)->hps, sizeof(FONTMETRICS), &fm);
					memset(&fat, 0, sizeof(fat));
					fat.usRecordLength  = sizeof(FATTRS);
					fat.lMatch          = fm.lMatch;

					strcpy(fat.szFacename, fm.szFacename);
					fat.fsSelection     = FATTR_SEL_BOLD;
					GpiCreateLogFont(((POWNERITEM)mp2)->hps, 0, 1L, &fat);

                    rcl=((POWNERITEM)mp2)->rclItem;
					rcl.xLeft+=CX_ICON+10;

					GpiSetCharSet(((POWNERITEM)mp2)->hps, 1L);
					WinDrawText(((POWNERITEM)mp2)->hps, -1L, ppszFields[0], &rcl, actlColor[0].clrValue, actlColor[1].clrValue, DT_LEFT|DT_TOP|DT_QUERYEXTENT);
					WinDrawText(((POWNERITEM)mp2)->hps, -1L, ppszFields[0], &rcl, actlColor[0].clrValue, actlColor[1].clrValue, DT_LEFT|DT_TOP);
					rcl.xLeft=rcl.xRight;
					rcl.xRight=((POWNERITEM)mp2)->rclItem.xRight;

					GpiSetCharSet(((POWNERITEM)mp2)->hps, 0L);
					WinDrawText(((POWNERITEM)mp2)->hps, -1L, ppszNames[((POWNERITEM)mp2)->idItem], &rcl, actlColor[0].clrValue, actlColor[1].clrValue, DT_LEFT|DT_VCENTER);
					rcl.yTop=rcl.yBottom;
					rcl.yBottom=((POWNERITEM)mp2)->rclItem.yBottom;
					rcl.xLeft=((POWNERITEM)mp2)->rclItem.xLeft+CX_ICON+10;

					GpiSetCharSet(((POWNERITEM)mp2)->hps, 1L);
					WinDrawText(((POWNERITEM)mp2)->hps, -1L, ppszFields[1], &rcl, actlColor[0].clrValue, actlColor[1].clrValue, DT_LEFT|DT_TOP|DT_QUERYEXTENT);
					WinDrawText(((POWNERITEM)mp2)->hps, -1L, ppszFields[1], &rcl, actlColor[0].clrValue, actlColor[1].clrValue, DT_LEFT|DT_TOP);
					rcl.xLeft=rcl.xRight;
					rcl.xRight=((POWNERITEM)mp2)->rclItem.xRight;

					GpiSetCharSet(((POWNERITEM)mp2)->hps, 0L);
					WinDrawText(((POWNERITEM)mp2)->hps, -1L, ppszCalories[((POWNERITEM)mp2)->idItem], &rcl, actlColor[0].clrValue, actlColor[1].clrValue, DT_LEFT|DT_VCENTER);
					rcl.yTop=rcl.yBottom;
					rcl.yBottom=((POWNERITEM)mp2)->rclItem.yBottom;
					rcl.xLeft=((POWNERITEM)mp2)->rclItem.xLeft+CX_ICON+10;

					GpiSetCharSet(((POWNERITEM)mp2)->hps, 1L);
					WinDrawText(((POWNERITEM)mp2)->hps, -1L, ppszFields[2], &rcl, actlColor[0].clrValue, actlColor[1].clrValue, DT_LEFT|DT_TOP|DT_QUERYEXTENT);
					WinDrawText(((POWNERITEM)mp2)->hps, -1L, ppszFields[2], &rcl, actlColor[0].clrValue, actlColor[1].clrValue, DT_LEFT|DT_TOP);
					rcl.xLeft=rcl.xRight;
					rcl.xRight=((POWNERITEM)mp2)->rclItem.xRight;

					GpiSetCharSet(((POWNERITEM)mp2)->hps, 0L);
					WinDrawText(((POWNERITEM)mp2)->hps, -1L, ppszWeight[((POWNERITEM)mp2)->idItem], &rcl, actlColor[0].clrValue, actlColor[1].clrValue, DT_LEFT|DT_VCENTER);
				}
				return (MRESULT)TRUE;
			}
			break;

		case WM_CONTROL:
			if (SHORT1FROMMP(mp1)==ID_LISTBOX)
			{
				if (SHORT2FROMMP(mp1)==LN_SELECT)
					if (WinQueryWindowRect(hwnd, &rcl))
					{
						rcl.xRight-=10;
						rcl.xLeft=rcl.xRight-CX_IMAGE-10;
						rcl.yTop-=10;
						rcl.yBottom=rcl.yTop-CY_IMAGE-10;
						WinInvalidateRect(hwnd, &rcl, FALSE);
					}
			}
			break;

		case WM_MEASUREITEM:
			if (SHORT1FROMMP(mp1)==ID_LISTBOX)
				return MPFROM2SHORT(CY_ICON, 0);

		case WM_PRESPARAMCHANGED:
			WinInvalidateRect(hwnd, NULL, TRUE);
			break;

		case WM_DESTROY:
			hwndListBox=WinWindowFromID(hwnd, ID_LISTBOX);
			for (i=0; i<NUM_ICONS; i++)
			{
				hbm2=HlbQueryItemHandle(hwndListBox, i);
				Gpi2DeleteBitmap(hbm2);
                Gpi2DeleteBitmap(hbm2Images[i]);
			}
			WinDestroyWindow(hwndListBox);
			break;
	}
	return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
