/*
 * Win32 user functions
 *
 * Copyright 1995 Martin von Loewis
 */

/* This file contains only wrappers to existing Wine functions or trivial
   stubs. 'Real' implementations go into context specific files */

#include <unistd.h>
#include <stdio.h>
#include "windows.h"
#include "winerror.h"
#include "relay32.h"
#include "alias.h"
#include "stackframe.h"
#include "xmalloc.h"
#include "handle32.h"
#include "struct32.h"
#include "resource32.h"
#include "string32.h"
#include "dialog.h"
#include "win.h"
#include "debug.h"
#include "stddebug.h"

/* Structure copy functions */
static void MSG16to32(MSG *msg16,struct WIN32_MSG *msg32)
{
	msg32->hwnd=(DWORD)msg16->hwnd;
	msg32->message=msg16->message;
	msg32->wParam=msg16->wParam;
	msg32->lParam=msg16->lParam;
	msg32->time=msg16->time;
	msg32->pt.x=msg16->pt.x;
	msg32->pt.y=msg16->pt.y;
}

static void MSG32to16(struct WIN32_MSG *msg32,MSG *msg16)
{
	msg16->hwnd=(HWND)msg32->hwnd;
	msg16->message=msg32->message;
	msg16->wParam=msg32->wParam;
	msg16->lParam=msg32->lParam;
	msg16->time=msg32->time;
	msg16->pt.x=msg32->pt.x;
	msg16->pt.y=msg32->pt.y;
}

void USER32_RECT32to16(const RECT32* r32,RECT *r16)
{
	r16->left = r32->left;
	r16->right = r32->right;
	r16->top = r32->top;
	r16->bottom = r32->bottom;
}

void USER32_RECT16to32(const RECT* r16,RECT32 *r32)
{
	r32->left = r16->left;
	r32->right = r16->right;
	r32->top = r16->top;
	r32->bottom = r16->bottom;
}

/***********************************************************************
 *           RegisterClassA      (USER32.426)
 */
ATOM USER32_RegisterClassA(WNDCLASSA* wndclass)
{
	WNDCLASS copy;
	HANDLE classh = 0, menuh = 0;
	SEGPTR classsegp, menusegp;
	char *classbuf, *menubuf;

	ATOM retval;
	copy.style=wndclass->style;
	ALIAS_RegisterAlias(0,0,(DWORD)wndclass->lpfnWndProc);
	copy.lpfnWndProc=wndclass->lpfnWndProc;
	copy.cbClsExtra=wndclass->cbClsExtra;
	copy.cbWndExtra=wndclass->cbWndExtra;
	copy.hInstance=(HINSTANCE)wndclass->hInstance;
	copy.hIcon=(HICON)wndclass->hIcon;
	copy.hCursor=(HCURSOR)wndclass->hCursor;
	copy.hbrBackground=(HBRUSH)wndclass->hbrBackground;

	/* FIXME: There has to be a better way of doing this - but neither
	malloc nor alloca will work */

	if(wndclass->lpszMenuName)
	{
		menuh = GlobalAlloc(0, strlen(wndclass->lpszMenuName)+1);
		menusegp = WIN16_GlobalLock(menuh);
		menubuf = PTR_SEG_TO_LIN(menusegp);
		strcpy( menubuf, wndclass->lpszMenuName);
		copy.lpszMenuName=menusegp;
	}else
		copy.lpszMenuName=0;
	if(wndclass->lpszClassName)
	{
		classh = GlobalAlloc(0, strlen(wndclass->lpszClassName)+1);
		classsegp = WIN16_GlobalLock(classh);
		classbuf = PTR_SEG_TO_LIN(classsegp);
		strcpy( classbuf, wndclass->lpszClassName);
		copy.lpszClassName=classsegp;
	}
	retval = RegisterClass(&copy);
	GlobalFree(menuh);
	GlobalFree(classh);
	return retval;
}

/***********************************************************************
 *          GetMessageA          (USER32.269)
 */
BOOL USER32_GetMessageA(struct WIN32_MSG* lpmsg,DWORD hwnd,DWORD min,DWORD max)
{
	BOOL ret;
	MSG msg;
	ret=GetMessage(MAKE_SEGPTR(&msg),(HWND)hwnd,min,max);
	MSG16to32(&msg,lpmsg);
	return ret;
}

/***********************************************************************
 *          BeginPaint           (USER32.9)
 */
HDC USER32_BeginPaint(DWORD hwnd,struct WIN32_PAINTSTRUCT *lpps)
{
	PAINTSTRUCT ps;
	HDC ret;
	ret=BeginPaint((HWND)hwnd,&ps);
	lpps->hdc=(DWORD)ps.hdc;
	lpps->fErase=ps.fErase;
	lpps->rcPaint.top=ps.rcPaint.top;
	lpps->rcPaint.left=ps.rcPaint.left;
	lpps->rcPaint.right=ps.rcPaint.right;
	lpps->rcPaint.bottom=ps.rcPaint.bottom;
	lpps->fRestore=ps.fRestore;
	lpps->fIncUpdate=ps.fIncUpdate;
	return ret;
}

/***********************************************************************
 *          EndPaint             (USER32.175)
 */
BOOL USER32_EndPaint(DWORD hwnd,struct WIN32_PAINTSTRUCT *lpps)
{
	PAINTSTRUCT ps;
	ps.hdc=(HDC)lpps->hdc;
	ps.fErase=lpps->fErase;
	ps.rcPaint.top=lpps->rcPaint.top;
	ps.rcPaint.left=lpps->rcPaint.left;
	ps.rcPaint.right=lpps->rcPaint.right;
	ps.rcPaint.bottom=lpps->rcPaint.bottom;
	ps.fRestore=lpps->fRestore;
	ps.fIncUpdate=lpps->fIncUpdate;
	EndPaint((HWND)hwnd,&ps);
	return TRUE;
}

/***********************************************************************
 *         DispatchMessageA       (USER32.140)
 */
LONG USER32_DispatchMessageA(struct WIN32_MSG* lpmsg)
{
	MSG msg;
	LONG ret;
	MSG32to16(lpmsg,&msg);
	ret=DispatchMessage(&msg);
	MSG16to32(&msg,lpmsg);
	return ret;
}

/***********************************************************************
 *         TranslateMessage       (USER32.555)
 */
BOOL USER32_TranslateMessage(struct WIN32_MSG* lpmsg)
{
	MSG msg;
	MSG32to16(lpmsg,&msg);
	return TranslateMessage(&msg);
}

/***********************************************************************
 *         CreateWindowExA        (USER32.82)
 */
DWORD USER32_CreateWindowExA(long flags,char* class,char *title,
	long style,int x,int y,int width,int height,DWORD parent,DWORD menu,
	DWORD instance,DWORD param)
{
    DWORD retval;
    HANDLE classh=0, titleh=0;
    SEGPTR classsegp=0, titlesegp=0;
    char *classbuf, *titlebuf;
	int usec,uset;

    /*Have to translate CW_USEDEFAULT */
    if(x==CW_USEDEFAULT32)x=CW_USEDEFAULT;
    if(y==CW_USEDEFAULT32)y=CW_USEDEFAULT;
    if(width==CW_USEDEFAULT32)width=CW_USEDEFAULT;
    if(height==CW_USEDEFAULT32)height=CW_USEDEFAULT;

    /* FIXME: There has to be a better way of doing this - but neither
    malloc nor alloca will work */
	usec = HIWORD(class);
	uset = HIWORD(title);

	if(usec){
    	classh = GlobalAlloc(0, strlen(class)+1);
    	classsegp = WIN16_GlobalLock(classh);
    	classbuf = PTR_SEG_TO_LIN(classsegp);
    	strcpy( classbuf, class );
	}
	if(uset){
    	titleh = GlobalAlloc(0, strlen(title)+1);
    	titlesegp = WIN16_GlobalLock(titleh);
    	titlebuf = PTR_SEG_TO_LIN(titlesegp);
    	strcpy( titlebuf, title );
	}
    
    retval = (DWORD) CreateWindowEx(flags,(usec ? classsegp : (SEGPTR)class),
				  (uset ? titlesegp : (SEGPTR)title),style,x,y,width,height,
				  (HWND)parent,(HMENU)menu,(HINSTANCE)instance,
				  (DWORD)param);
    if(usec)GlobalFree(classh);
    if(uset)GlobalFree(titleh);
    return retval;
}

DWORD USER32_CreateWindowExW(long flags,LPCWSTR class,LPCWSTR title,
	long style,int x,int y,int width,int height,DWORD parent,DWORD menu,
	DWORD instance,DWORD param)
{
	HWND hwnd;
	LPSTR c,t;
	int usec,uset;
	usec=HIWORD(class);
	uset=HIWORD(title);
	c = usec ? STRING32_DupUniToAnsi(class) : (LPSTR)class;
	t = uset ? STRING32_DupUniToAnsi(title) : (LPSTR)title;
	hwnd=USER32_CreateWindowExA(flags,c,t,style,x,y,width,height,parent,menu,
		instance,param);
	if(usec)free(c);
	if(uset)free(t);
	return hwnd;
}

/***********************************************************************
 *         InvalidateRect           (USER32.327)
 */
BOOL USER32_InvalidateRect(HWND hWnd,const RECT32 *lpRect,BOOL bErase)
{
	RECT r;

	if (lpRect == NULL)
		InvalidateRect(hWnd, (RECT *)NULL, bErase);
	else {
		USER32_RECT32to16(lpRect,&r);
		InvalidateRect(hWnd,&r,bErase);
	}
	/* FIXME: Return meaningful value */
	return TRUE;
}

/***********************************************************************
 *          DrawTextA                (USER32.163)
 */
int USER32_DrawTextA(HDC hdc,LPCSTR lpStr,int count,RECT32* r32,UINT uFormat)
{
	RECT r;
	USER32_RECT32to16(r32,&r);
	return DrawText(hdc,lpStr,count,&r,uFormat);
}

/***********************************************************************
 *          GetClientRect            (USER32.219)
 */
BOOL USER32_GetClientRect(HWND hwnd,RECT32 *r32)
{
	RECT r;
	GetClientRect(hwnd,&r);
	USER32_RECT16to32(&r,r32);
	/* FIXME: return value */
	return 0;
}

UINT USER32_SetTimer(HWND hwnd, UINT id, UINT timeout, void *proc)

{
    dprintf_win32(stddeb, "USER32_SetTimer: %d %d %d %08lx\n", hwnd, id, timeout,
(LONG)proc );
    return SetTimer( hwnd, id, timeout, MAKE_SEGPTR(proc));
}   

/* WARNING: It has not been verified that the signature or semantics
   of the corresponding NT function is the same */

HWND USER32_CreateDialogIndirectParamAorW(HINSTANCE hInst,LPVOID templ,
	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam,int A)
{
	DLGTEMPLATE32 *dlgTempl=templ;
	DLGITEMTEMPLATE32 *dlgitem;
	WORD *ptr;
	DWORD MenuName=0;
	DWORD ClassName=0;
	DWORD szFontName=0;
	WORD wPointSize;
	HFONT hFont=0;
	HMENU hMenu=0;
	DWORD exStyle;
	DWORD szCaption;
	RECT rect;
	DIALOGINFO *dlgInfo;
	WND *wndPtr;
	WORD xUnit = xBaseUnit;
	WORD yUnit = yBaseUnit;
	int i;
	DWORD ClassId;
	DWORD Text;
	HWND hwnd,hwndCtrl;
	HWND hwndDefButton=0;
	WCHAR buffer[200];

	/* parse the dialog template header*/
	exStyle = dlgTempl->dwExtendedStyle;
	ptr = (WORD*)(dlgTempl+1);
	switch(*ptr){
		case 0: MenuName=0;ptr++;break;
		case 0xFFFF: MenuName=*(ptr+1);ptr+=2;break;
		default: MenuName = (DWORD)ptr;
			ptr += STRING32_lstrlenW(ptr)+1;
	}
	switch(*ptr){ 
		case 0: ClassName = DIALOG_CLASS_ATOM;ptr++;break;
		case 0xFFFF: ClassName = *(ptr+1);ptr+=2;break;
		default: ClassName = (DWORD)ptr;
				ptr += STRING32_lstrlenW(ptr)+1;
	}
	szCaption=(DWORD)ptr;
	ptr+=STRING32_lstrlenW(ptr)+1;
	if(dlgTempl->style & DS_SETFONT)
	{
		wPointSize = *ptr;
		ptr++;
		szFontName = (DWORD)ptr;
		ptr+=STRING32_lstrlenW(ptr)+1;
	}
	
	if(MenuName) hMenu=WIN32_LoadMenuW(hInst,(LPWSTR)MenuName);
	if(dlgTempl->style & DS_SETFONT)
	{
		fprintf(stderr,"Win32: dialog fonts not supported yet\n");
	}
	
	/* Create dialog main window */
	rect.left = rect.top = 0;
	rect.right = dlgTempl->cx * xUnit / 4;
	rect.bottom = dlgTempl->cy * yUnit / 8;

	/* FIXME: proper modalframe handling ??*/
	if (dlgTempl->style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;

	/* FIXME: AdjustWindowRectEx */

	rect.right -= rect.left;
	rect.bottom -= rect.top;

	if(dlgTempl->x == CW_USEDEFAULT)
		rect.left = rect.top = CW_USEDEFAULT;
	else{
		rect.left += dlgTempl->x * xUnit / 4;
		rect.top += dlgTempl->y * yUnit / 8;
		if (!(dlgTempl->style & DS_ABSALIGN))
			ClientToScreen(hWndParent, (POINT *)&rect );
	}

	/* FIXME: Here is the place to consider A */
	hwnd = USER32_CreateWindowExW(exStyle, (LPWSTR)ClassName, (LPWSTR)szCaption,
		dlgTempl->style & ~WS_VISIBLE, 
		rect.left, rect.top, rect.right, rect.bottom,
		hWndParent, hMenu, hInst, 0);

	if(!hwnd)
	{
		if(hFont)DeleteObject(hFont);
		if(hMenu)DeleteObject(hMenu);
		return 0;
	}

	wndPtr = WIN_FindWndPtr(hwnd);

	/* FIXME: should purge junk from system menu, but windows/dialog.c
	   says this does not belong here */

	/* Create control windows */
	dprintf_dialog(stddeb, " BEGIN\n" );
	dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
	dlgInfo->msgResult = 0;	/* This is used to store the default button id */
	dlgInfo->hDialogHeap = 0;

	for (i = 0; i < dlgTempl->noOfItems; i++)
	{
		if((int)ptr&3)
		{
			fprintf(stddeb,"DWORD aligning\n");
			ptr++;
		}
		dlgitem = (DLGITEMTEMPLATE32*)ptr;
		ptr = (WORD*)(dlgitem+1);
		if(*ptr == 0xFFFF) {
			/* FIXME: ignore HIBYTE? */
			ClassId = *(ptr+1);
			ptr+=2;
		}else{
			ClassId = (DWORD)ptr;
			ptr += STRING32_lstrlenW(ptr)+1;
		}
		if(*ptr == 0xFFFF) {
			Text = *(ptr+1);
			ptr+=2;
		}else{
			Text = (DWORD)ptr;
			ptr += STRING32_lstrlenW(ptr)+1;
		}
		if(!HIWORD(ClassId))
		{
			switch(LOWORD(ClassId))
			{
				case 0x80: STRING32_AnsiToUni(buffer,"BUTTON" ); break;
				case 0x81: STRING32_AnsiToUni( buffer, "EDIT" ); break;
				case 0x82: STRING32_AnsiToUni( buffer, "STATIC" ); break;
				case 0x83: STRING32_AnsiToUni( buffer, "LISTBOX" ); break;
				case 0x84: STRING32_AnsiToUni( buffer, "SCROLLBAR" ); break;
				case 0x85: STRING32_AnsiToUni( buffer, "COMBOBOX" ); break;
				default:   buffer[0] = '\0'; break;
			}
			ClassId = (DWORD)buffer;
		}
		/*FIXME: debugging output*/
		/*FIXME: local edit ?*/
		exStyle = dlgitem->dwExtendedStyle|WS_EX_NOPARENTNOTIFY;
		if(*ptr)
		{
			fprintf(stderr,"having data\n");
		}
		ptr++;
		hwndCtrl = USER32_CreateWindowExW(WS_EX_NOPARENTNOTIFY,
			(LPWSTR)ClassId, (LPWSTR)Text,
			dlgitem->style | WS_CHILD,
			dlgitem->x * xUnit / 4,
			dlgitem->y * yUnit / 8,
			dlgitem->cx * xUnit / 4,
			dlgitem->cy * yUnit / 8,
			hwnd, (HMENU)((DWORD)dlgitem->id),
			hInst, (SEGPTR)0 );
		SetWindowPos( hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0,
			SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
		/* Send initialisation messages to the control */
		if (hFont) SendMessage( hwndCtrl, WM_SETFONT, (WPARAM)hFont, 0 );
		if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
		{
			/* If there's already a default push-button, set it back */
			/* to normal and use this one instead. */
			if (hwndDefButton)
				SendMessage( hwndDefButton, BM_SETSTYLE, BS_PUSHBUTTON, FALSE);
			hwndDefButton = hwndCtrl;
			dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID );
		}
	}
	dprintf_dialog(stddeb, " END\n" );

	 /* Initialise dialog extra data */
	ALIAS_RegisterAlias(0,0,lpDialogFunc);
	dlgInfo->dlgProc   = lpDialogFunc;
	dlgInfo->hUserFont = hFont;
	dlgInfo->hMenu     = hMenu;
	dlgInfo->xBaseUnit = xUnit;
	dlgInfo->yBaseUnit = yUnit;
	dlgInfo->hwndFocus = DIALOG_GetFirstTabItem( hwnd );

	/* Send initialisation messages and set focus */
	if (dlgInfo->hUserFont)
		SendMessage( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
	if (SendMessage( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, dwInitParam ))
		SetFocus( dlgInfo->hwndFocus );
	if (dlgTempl->style & WS_VISIBLE) ShowWindow(hwnd, SW_SHOW);
		return hwnd;
}

HWND USER32_CreateDialogIndirectParamW(HINSTANCE hInst,LPVOID dlgTempl,
	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	return USER32_CreateDialogIndirectParamAorW(hInst,dlgTempl,hWndParent,
		lpDialogFunc,dwInitParam,0);
}

HWND USER32_CreateDialogIndirectParamA(HINSTANCE hInst,LPVOID dlgTempl,
	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	return USER32_CreateDialogIndirectParamAorW(hInst,dlgTempl,hWndParent,
		lpDialogFunc,dwInitParam,1);
}

HWND USER32_CreateDialogParamW(HINSTANCE hInst,LPCWSTR lpszName,
	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	HANDLE32 hrsrc;
	hrsrc=FindResource32(hInst,lpszName,(LPWSTR)RT_DIALOG);
	if(!hrsrc)return 0;
	return USER32_CreateDialogIndirectParamW(hInst,
		LoadResource32(hInst, hrsrc),hWndParent,lpDialogFunc,dwInitParam);
}

HWND USER32_CreateDialogParamA(HINSTANCE hInst,LPCSTR lpszName,
	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	HWND res;
	if(!HIWORD(lpszName))
		res = USER32_CreateDialogParamW(hInst,(LPCWSTR)lpszName,hWndParent,
				lpDialogFunc,dwInitParam);
	else{
		LPWSTR uni=STRING32_DupAnsiToUni(lpszName);
		res=USER32_CreateDialogParamW(hInst,uni,hWndParent,
			lpDialogFunc,dwInitParam);
	}
	return res;
}

int USER32_DialogBoxIndirectParamW(HINSTANCE hInstance,LPVOID dlgTempl,
	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	HWND hwnd;
	hwnd = USER32_CreateDialogIndirectParamW(hInstance,dlgTempl,
		hWndParent,lpDialogFunc,dwInitParam);
	if(hwnd)return DIALOG_DoDialogBox(hwnd,hWndParent);
	return -1;
}

int USER32_DialogBoxIndirectParamA(HINSTANCE hInstance,LPVOID dlgTempl,
	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	HWND hwnd;
	hwnd = USER32_CreateDialogIndirectParamA(hInstance,dlgTempl,
		hWndParent,lpDialogFunc,dwInitParam);
	if(hwnd)return DIALOG_DoDialogBox(hwnd,hWndParent);
	return -1;
}

int USER32_DialogBoxParamW(HINSTANCE hInstance,LPCWSTR lpszName,
	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	HWND hwnd;
	hwnd = USER32_CreateDialogParamW(hInstance,lpszName,
		hWndParent,lpDialogFunc,dwInitParam);
	if(hwnd)return DIALOG_DoDialogBox(hwnd,hWndParent);
	 return -1;
}

int USER32_DialogBoxParamA(HINSTANCE hInstance,LPCSTR lpszName,
	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	HWND hwnd;
	hwnd = USER32_CreateDialogParamA(hInstance,lpszName,
		hWndParent,lpDialogFunc,dwInitParam);
	if(hwnd)return DIALOG_DoDialogBox(hwnd,hWndParent);
	return -1;
}
