/*
	DLGTEMP.CPP - Zugriff auf DLGTEMPLATE einer DialogBox
	(C) 1991 by Joachim Kainz 'On a mission from Bhudda'
*/
	#include "dlgtemp.hpp"
	#include <string.h>
/*
	Tools zum Bearbeiten des Resource
	___________________________________________________________________
*/
	static LPSTR CopyResourcePtr	(			 LPSTR  lpPtr);
	static BOOL  FreeResourcePtr	(			 LPSTR &lpPtr);
	static BYTE  GetResourceByte	(			 LPSTR &lpDlg);
	static int 	 GetResourceInt		(			 LPSTR &lpDlg);
	static long  GetResourceLong	(			 LPSTR &lpDlg);
	static LPSTR GetResourcePtr		(			 LPSTR &lpDlg);
	static WORD  GetResourcePtrSize	(			 LPSTR &lpPtr);
	static void  SetResourceByte	(PSTR &pDlg, BYTE byValue);
	static void	 SetResourceInt		(PSTR &pDlg, int   nValue);
	static void  SetResourceLong	(PSTR &pDlg, long  lValue);
	static void	 SetResourcePtr		(PSTR &pDlg, LPSTR  lpPtr);

	inline int GetResourceInt (LPSTR & lpDlg)
	{
		int nResult = *(int far *) lpDlg;

		lpDlg += sizeof (int);

		return nResult;
	}

	inline BYTE GetResourceByte (LPSTR & lpDlg)
	{
		BYTE byResult = *(BYTE far *) lpDlg;

		lpDlg  += sizeof (BYTE);

		return byResult;
	}

	inline long GetResourceLong (LPSTR & lpDlg)
	{
		long lResult = *(long far *) lpDlg;

		lpDlg  += sizeof (long);

		return lResult;
	}

	LPSTR GetResourcePtr (LPSTR &lpDlg)
	{
		LPSTR lpResult;

		if (*lpDlg == -1) {

			lpResult = MAKEINTRESOURCE (*(WORD far *) (++lpDlg));
			lpDlg	+= sizeof (int);

			return lpResult;

		}

		WORD wLen = lstrlen (lpDlg);

		if (!wLen) {

			lpDlg++;
			return NULL;

		}

		lpResult = new char [wLen+1];

		if (!lpResult)
			return (LPSTR) -1l;

		_fmemmove (lpResult, lpDlg, wLen+1);

		lpDlg += wLen+1;

		return lpResult;
	}

	BOOL FreeResourcePtr (LPSTR & lpPtr)
	{
		if (!lpPtr)
			return TRUE;

		if (!HIWORD (lpPtr)) {

			lpPtr = NULL;
			return TRUE;

		}

		delete (PSTR) lpPtr;

		lpPtr = NULL;

		return TRUE;
	}

	WORD GetResourcePtrSize (LPSTR & lpPtr)
	{
		if (!lpPtr)
			return 1;

		if (!HIWORD (lpPtr))
			return 3;

		return lstrlen (lpPtr)+1;
	}


	LPSTR CopyResourcePtr (LPSTR lpPtr)
	{
		if (!lpPtr)
			return NULL;

		if (!HIWORD (lpPtr))
			return lpPtr;

		WORD  wLen  = lstrlen (lpPtr);
		LPSTR lpNew = new char [wLen+1];

		if (!lpNew)
			return (LPSTR) -1l;

		_fmemmove (lpNew, lpPtr, wLen+1);

		return lpNew;
	}

	void SetResourcePtr (PSTR &pDlg, LPSTR lpPtr)
	{
		if (!lpPtr) {

			*(pDlg++) = '\0';
			return;

		}

		if (!HIWORD (lpPtr)) {

			*(			pDlg ++) = -1;
			*(((WORD *) pDlg)++) = LOWORD (lpPtr);

			return;

		}

		WORD wMem = lstrlen (lpPtr)+1;

		_fmemmove (pDlg, lpPtr, wMem);

		pDlg += wMem;
	}

	inline void SetResourceByte (PSTR &pDlg, BYTE byValue)
	{
		*(pDlg++) = byValue;
	}

	inline void SetResourceInt	 (PSTR &pDlg, int nValue)
	{
		*(((int *)pDlg)++) = nValue;
	}

	inline void SetResourceLong (PSTR &pDlg, long lValue)
	{
		*(((long *)pDlg)++) = lValue;
	}
/*
	DLGTEMPLATE
	___________________________________________________________________
*/
	EXPORT DLGTEMPLATE::DLGTEMPLATE (LPSTR lpDlgTemp)
	{
		_fmemset (this, 0, sizeof *this);

		HANDLE hDlg = FindResource (
						GetInstance (),
						lpDlgTemp,
						RT_DIALOG
					  );

		if (!hDlg)
			return;

		hDlg = LoadResource (GetInstance (), hDlg);

		if (!hDlg)
			return;

		LPSTR lpDlg = LockResource (hDlg);

		if (!lpDlg) {

			hDlg = FreeResource (hDlg);
			return;

		}

		int nItemCount;

		lStyle		  = GetResourceLong (lpDlg);
		nItemCount	  = GetResourceByte (lpDlg);
		x			  = GetResourceInt	(lpDlg);
		y			  = GetResourceInt	(lpDlg);
		cx			  = GetResourceInt	(lpDlg);
		cy			  = GetResourceInt	(lpDlg);
		lpMenuName	  = GetResourcePtr	(lpDlg);
		lpClassName   = GetResourcePtr	(lpDlg);
		lpCaptionText = GetResourcePtr	(lpDlg);

		if (lStyle & DS_SETFONT) {

			font.nSize		= GetResourceInt (lpDlg);
			font.lpFaceName	= GetResourcePtr (lpDlg);

		}

		pdtit = new DLGITEMTEMPLATE [nItemCount];

		for (int m=0; m<nItemCount; m++)
			if (!pdtit [m].ConvertResource (lpDlg))
				break;

		UnlockResource (hDlg);

		hDlg = FreeResource (hDlg);

		byItemCount = m;

		bValid = m				==	nItemCount	&&
				 lpMenuName		!= (LPSTR) -1l	&&
				 lpClassName	!= (LPSTR) -1l	&&
				 lpCaptionText	!= (LPSTR) -1l;
	}

	EXPORT DLGTEMPLATE::~DLGTEMPLATE ()
	{
		if (byItemCount) {

			delete [byItemCount] pdtit;
			byItemCount = 0;

		}

		FreeResourcePtr (	  lpMenuName   );
		FreeResourcePtr (	  lpClassName  );
		FreeResourcePtr (	  lpCaptionText);
		FreeResourcePtr (font.lpFaceName   );

		bValid = FALSE;
	}

	BOOL EXPORT DLGTEMPLATE::SetClass (LPSTR lpNewClsName)
	{
		FreeResourcePtr (lpClassName);

		lpClassName = CopyResourcePtr (lpNewClsName);

		return TRUE;
	}

	WORD EXPORT DLGTEMPLATE::GetSize ()
	{
		WORD wSize = sizeof 			(long		  )+
					 sizeof 			(BYTE		  )+
					 sizeof 			(int 		  )*4+
					 GetResourcePtrSize (lpMenuName   )+
					 GetResourcePtrSize (lpClassName  )+
					 GetResourcePtrSize (lpCaptionText);

		if (lStyle & DS_SETFONT)
			wSize += sizeof 			(short int		)+
					 GetResourcePtrSize (font.lpFaceName);

		for (int m=0; m<byItemCount; m++)
			wSize += pdtit [m].GetSize ();

		return wSize;
	}

	PSTR EXPORT DLGTEMPLATE::operator PSTR ()
	{
		WORD wResSize	= GetSize ();
		PSTR pComponent	= new char [wResSize],
			 pResource	= pComponent;

		if (!pComponent)
			return NULL;

		SetResourceLong (pComponent, lStyle		  );
		SetResourceByte (pComponent, byItemCount  );
		SetResourceInt	(pComponent, x			  );
		SetResourceInt	(pComponent, y			  );
		SetResourceInt	(pComponent, cx			  );
		SetResourceInt	(pComponent, cy			  );
		SetResourcePtr	(pComponent, lpMenuName   );
		SetResourcePtr	(pComponent, lpClassName  );
		SetResourcePtr	(pComponent, lpCaptionText);

		if (lStyle & DS_SETFONT) {

			*(((int  *) pComponent)++) = font.nSize;
			SetResourcePtr (pComponent, font.lpFaceName);

		}

		for (int m=0; m<byItemCount; m++)
			if (!pdtit [m].MakeResource (pComponent)) {

				break;
				delete pResource;

				return NULL;

			}

		return pResource;
	}

	WORD EXPORT DLGITEMTEMPLATE::GetSize ()
	{
		WORD wSize = sizeof 			(int	)*5+
					 sizeof 			(long	)+
					 GetResourcePtrSize (lpClass)+
					 GetResourcePtrSize (lpText )+
					 sizeof 			(BYTE	)+
					 byInfo;

		return wSize;
	}

	BOOL EXPORT DLGITEMTEMPLATE::MakeResource (PSTR &pDlg)
	{
		SetResourceInt	(pDlg, x		);
		SetResourceInt	(pDlg, y		);
		SetResourceInt	(pDlg, cx		);
		SetResourceInt	(pDlg, cy		);
		SetResourceInt	(pDlg, nID		);
		SetResourceLong	(pDlg, lStyle	);
		SetResourcePtr	(pDlg, lpClass	);
		SetResourcePtr	(pDlg, lpText	);
		SetResourceByte	(pDlg, byInfo	);

		if (byInfo) {

			memmove (pDlg, pData, byInfo);

			pDlg += byInfo;

		}

		return TRUE;
	}

	BOOL EXPORT DLGITEMTEMPLATE::ConvertResource (LPSTR &lpDlg)
	{
		if (!Reset ())
			return FALSE;

		x		= GetResourceInt	(lpDlg);
		y		= GetResourceInt	(lpDlg);
		cx		= GetResourceInt	(lpDlg);
		cy		= GetResourceInt	(lpDlg);
		nID		= GetResourceInt	(lpDlg);
		lStyle	= GetResourceLong	(lpDlg);
		lpClass	= GetCtlClass		(lpDlg);
		lpText	= GetResourcePtr	(lpDlg);
		byInfo	= GetResourceByte	(lpDlg);

		if (byInfo) {

			pData = new char [byInfo];

			_fmemmove (pData, lpDlg, byInfo);

			lpDlg += byInfo;

		}

		return TRUE;
	}

	#define CTL_BUTTON		128
	#define CTL_EDIT		129
	#define CTL_STATIC		130
	#define CTL_LISTBOX		131
	#define CTL_COMBOBOX	133

	LPSTR DLGITEMTEMPLATE::GetCtlClass (LPSTR &lpDlg)
	{
		if (*lpDlg >= 0)
			return GetResourcePtr (lpDlg);

		PSTR pClass = new char [10];

		switch ((BYTE) *lpDlg) {

		  case CTL_BUTTON:
            lstrcpy (pClass, "button");
            break;

          case CTL_EDIT:
            lstrcpy (pClass, "edit");
            break;

          case CTL_STATIC:
            lstrcpy (pClass, "static");
            break;

          case CTL_LISTBOX:
            lstrcpy (pClass, "listbox");
            break;

		  case CTL_COMBOBOX:
            lstrcpy (pClass, "combobox");
            break;

		}

		++lpDlg;

        return pClass;
    }

	BOOL DLGITEMTEMPLATE::Reset ()
	{
		if (byInfo)
			delete pData;

		return	FreeResourcePtr (lpClass) &&
				FreeResourcePtr (lpText );
	}

	EXPORT DLGITEMTEMPLATE::~DLGITEMTEMPLATE ()
	{
		Reset ();
	}

	EXPORT DLGITEMTEMPLATE::DLGITEMTEMPLATE ()
	{
		_fmemset (this, 0, sizeof *this);
	}

	EXPORT DLGITEMTEMPLATE::DLGITEMTEMPLATE (const DLGITEMTEMPLATE &dit)
	{
		CopyDlgItem (dit);
	}

	DLGITEMTEMPLATE EXPORT DLGITEMTEMPLATE::operator = (const DLGITEMTEMPLATE &dit)
	{
		CopyDlgItem (dit);

		return *this;
	}

	BOOL DLGITEMTEMPLATE::CopyDlgItem (const DLGITEMTEMPLATE &dit)
	{
		x		= dit.x;
		y		= dit.y;
		cx		= dit.cx;
		cy		= dit.cy;
		nID		= dit.nID;
		lStyle	= dit.lStyle;
		lpClass	= CopyResourcePtr (dit.lpClass);
		lpText	= CopyResourcePtr (dit.lpText );
		byInfo	= dit.byInfo;

		if (byInfo) {

			pData = new char [byInfo];

			if (!pData)
				return FALSE;

			_fmemmove (pData, dit.pData, byInfo);

		}

		return	lpClass	!= (LPSTR) -1l &&
				lpText	!= (LPSTR) -1l;
	}

	DLGITEMTEMPLATE EXPORT DLGTEMPLATE::operator [] (WORD wItem)
	{
		return pdtit [wItem];
	}
