/*
 * 				Windows Properties Functions
 *
static char Copyright[] = "Copyright Martin Ayotte, 1994";
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "windows.h"
#include "win.h"
#include "callback.h"
#include "stddebug.h"
/* #define DEBUG_PROP */
/* #undef  DEBUG_PROP */
#include "debug.h"

typedef struct tagPROPENTRY {
	LPSTR		PropName;
	WORD		Atom;
	HANDLE		hData;
	struct tagPROPENTRY	*lpPrevProp;
	struct tagPROPENTRY	*lpNextProp;
} PROPENTRY;
typedef PROPENTRY *LPPROPENTRY;


/*************************************************************************
 *				RemoveProp			[USER.24]
 */
HANDLE RemoveProp(HWND hWnd, LPSTR lpStr)
{
    WND 		*wndPtr;
	LPPROPENTRY lpProp;
	HANDLE		hOldData;
	if (((DWORD)lpStr & 0xFFFF0000) == 0L)
		dprintf_prop(stddeb, "RemoveProp(%04X, Atom %04X)\n", hWnd, LOWORD((DWORD)lpStr));
	else
		dprintf_prop(stddeb, "RemoveProp(%04X, '%s')\n", hWnd, lpStr);
	wndPtr = WIN_FindWndPtr(hWnd);
    if (wndPtr == NULL) {
    	printf("RemoveProp // Bad Window handle !\n");
    	return FALSE;
    	}
	lpProp = (LPPROPENTRY) GlobalLock(wndPtr->hProp);
	if (lpProp == NULL) {
		dprintf_prop(stddeb, "Property List Empty !\n");
		return 0;
		}
	while (TRUE) {
		if ((((DWORD)lpStr & 0xFFFF0000) == 0L && 
			lpProp->Atom == LOWORD((DWORD)lpStr)) ||
			(((DWORD)lpStr & 0xFFFF0000) != 0L && 
			lpProp->PropName != NULL &&
			strcmp(lpProp->PropName, lpStr) == 0)) {
		   	dprintf_prop(stddeb, "RemoveProp // Property found ! hData=%04X\n", lpProp->hData);
			hOldData = lpProp->hData;
			if (lpProp->lpPrevProp != NULL) 
				lpProp->lpPrevProp->lpNextProp = lpProp->lpNextProp;
			if (lpProp->lpNextProp != NULL) 
				lpProp->lpNextProp->lpPrevProp = lpProp->lpPrevProp;
			if (lpProp->PropName != NULL) free(lpProp->PropName);
			GlobalFree(lpProp);
			GlobalUnlock(wndPtr->hProp);
			return hOldData;
			}
		if (lpProp->lpNextProp == NULL) break;
		lpProp = lpProp->lpNextProp;
		}
	GlobalUnlock(wndPtr->hProp);
   	dprintf_prop(stddeb, "RemoveProp // Property not found !\n");
	return 0;
}


/*************************************************************************
 *				GetProp			[USER.25]
 */
HANDLE GetProp(HWND hWnd, LPSTR lpStr)
{
    WND 		*wndPtr;
	LPPROPENTRY lpProp;
	if (((DWORD)lpStr & 0xFFFF0000) == 0L)
		dprintf_prop(stddeb, "GetProp(%04X, Atom %04X)\n", hWnd, LOWORD((DWORD)lpStr));
	else
		dprintf_prop(stddeb, "GetProp(%04X, '%s')\n", hWnd, lpStr);
	wndPtr = WIN_FindWndPtr(hWnd);
    if (wndPtr == NULL) {
    	printf("GetProp // Bad Window handle !\n");
    	return 0;
    	}
	lpProp = (LPPROPENTRY) GlobalLock(wndPtr->hProp);
	if (lpProp == NULL) {
		dprintf_prop(stddeb, "Property List Empty !\n");
		return 0;
		}
	while (TRUE) {
		if ((((DWORD)lpStr & 0xFFFF0000) == 0L && 
			lpProp->Atom == LOWORD((DWORD)lpStr)) ||
			(((DWORD)lpStr & 0xFFFF0000) != 0L && 
			lpProp->PropName != NULL &&
			strcmp(lpProp->PropName, lpStr) == 0)) {
		   	dprintf_prop(stddeb, "GetProp // Property found ! hData=%04X\n", lpProp->hData);
			GlobalUnlock(wndPtr->hProp);
			return lpProp->hData;
			}
		if (lpProp->lpNextProp == NULL) break;
		lpProp = lpProp->lpNextProp;
		}
   	dprintf_prop(stddeb, "GetProp // Property not found !\n");
	GlobalUnlock(wndPtr->hProp);
	return 0;
}


/*************************************************************************
 *				SetProp			[USER.26]
 */
BOOL SetProp(HWND hWnd, LPSTR lpStr, HANDLE hData)
{
    WND 		*wndPtr;
    HANDLE 		hNewProp;
	LPPROPENTRY lpNewProp;
	LPPROPENTRY lpProp;
	if (((DWORD)lpStr & 0xFFFF0000) == 0L)
		dprintf_prop(stddeb, "SetProp(%04X, Atom %04X, %04X)\n", 
				hWnd, LOWORD((DWORD)lpStr), hData);
	else
		dprintf_prop(stddeb, "SetProp(%04X, '%s', %04X)\n", hWnd, lpStr, hData);
	wndPtr = WIN_FindWndPtr(hWnd);
    if (wndPtr == NULL) {
    	printf("SetProp // Bad Window handle !\n");
    	return FALSE;
    	}
	lpProp = (LPPROPENTRY) GlobalLock(wndPtr->hProp);
	if (lpProp != NULL) {
		while (TRUE) {
			if ((((DWORD)lpStr & 0xFFFF0000) == 0L && 
				lpProp->Atom == LOWORD((DWORD)lpStr)) ||
				(((DWORD)lpStr & 0xFFFF0000) != 0L && 
				lpProp->PropName != NULL &&
				strcmp(lpProp->PropName, lpStr) == 0)) {
			    dprintf_prop(stddeb, "SetProp // change already exinsting property !\n");
				lpProp->hData = hData;
				GlobalUnlock(wndPtr->hProp);
				return TRUE;
				}
			if (lpProp->lpNextProp == NULL) break;
			lpProp = lpProp->lpNextProp;
			}
		}
	hNewProp = GlobalAlloc(GMEM_MOVEABLE, sizeof(PROPENTRY));
	lpNewProp = (LPPROPENTRY) GlobalLock(hNewProp);
	if (lpNewProp == NULL) {
    	printf("SetProp // Can't allocate Property entry !\n");
		GlobalUnlock(wndPtr->hProp);
    	return FALSE;
		}
	dprintf_prop(stddeb, "SetProp // entry allocated %08X\n", 
    		(unsigned int) lpNewProp);
	if (lpProp == NULL) {
		wndPtr->hProp = hNewProp;
		lpNewProp->lpPrevProp = NULL;
	    dprintf_prop(stddeb, "SetProp // first entry \n");
		}
	else {
		lpProp->lpNextProp = lpNewProp;
		lpNewProp->lpPrevProp = lpProp;
		}
	lpNewProp->lpNextProp = NULL;
	lpNewProp->hData = hData;
	if (((DWORD)lpStr & 0xFFFF0000) == 0L) {
		lpNewProp->PropName = NULL;
		lpNewProp->Atom = LOWORD((DWORD)lpStr);
		}
	else {
		lpNewProp->Atom = 0;
		lpNewProp->PropName = malloc(strlen(lpStr) + 1);
		if (lpNewProp->PropName == NULL) {
	    	printf("SetProp // Can't allocate memory for Property Name !\n");
			GlobalUnlock(wndPtr->hProp);
    		return FALSE;
			}
		strcpy(lpNewProp->PropName, lpStr);
		}
	GlobalUnlock(hNewProp);
	GlobalUnlock(wndPtr->hProp);
	return TRUE;
}


/*************************************************************************
 *				EnumProps			[USER.27]
 */
int EnumProps(HWND hWnd, FARPROC lpEnumFunc)
{
    WND 		*wndPtr;
	LPPROPENTRY lpProp;
	LPSTR		str;
	int			nRet;
	printf("EnumProps(%04X, %08X)\n", hWnd, (unsigned int) lpEnumFunc);
	wndPtr = WIN_FindWndPtr(hWnd);
    if (wndPtr == NULL) {
    	printf("EnumProps // Bad Window handle !\n");
    	return 0;
    	}
	lpProp = (LPPROPENTRY) GlobalLock(wndPtr->hProp);
	if (lpProp == NULL) {
		printf("Property List Empty !\n");
		return 0;
		}
	if (lpEnumFunc == NULL)	return 0;
	while (TRUE) {
    	printf("EnumProps // lpProp->Atom=%04X !\n", lpProp->Atom);
		str = (LPSTR)MAKELONG(lpProp->Atom, 0); 
		if (lpProp->PropName != NULL) {
	    	printf("EnumProps // lpProp->PropName='%s' !\n", lpProp->PropName);
			str = lpProp->PropName; 
			}
                nRet = CallEnumPropProc( lpEnumFunc, hWnd,
                                         (LONG)str, lpProp->hData);
		if (nRet == 0) break;
		if (lpProp->lpNextProp == NULL) break;
		lpProp = lpProp->lpNextProp;
		}
	GlobalUnlock(wndPtr->hProp);
	return 0;
}


