/* Control Panel management
 *
 * Copyright 2001 Eric Pouech
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/winbase16.h"
#include "wownt32.h"
#include "wine/debug.h"
#include "cpl.h"
#include "wine/unicode.h"

#define NO_SHLWAPI_REG
#include "shlwapi.h"

#include "cpanel.h"

WINE_DEFAULT_DEBUG_CHANNEL(shlctrl);

CPlApplet*	Control_UnloadApplet(CPlApplet* applet)
{
    unsigned	i;
    CPlApplet*	next;

    for (i = 0; i < applet->count; i++) {
        if (!applet->info[i].dwSize) continue;
        applet->proc(applet->hWnd, CPL_STOP, i, applet->info[i].lData);
    }
    if (applet->proc) applet->proc(applet->hWnd, CPL_EXIT, 0L, 0L);
    FreeLibrary(applet->hModule);
    next = applet->next;
    HeapFree(GetProcessHeap(), 0, applet);
    return next;
}

CPlApplet*	Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel)
{
    CPlApplet*	applet;
    unsigned 	i;
    CPLINFO	info;
    NEWCPLINFOW newinfo;

    if (!(applet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*applet))))
       return applet;

    applet->hWnd = hWnd;

    if (!(applet->hModule = LoadLibraryW(cmd))) {
        WARN("Cannot load control panel applet %s\n", debugstr_w(cmd));
	goto theError;
    }
    if (!(applet->proc = (APPLET_PROC)GetProcAddress(applet->hModule, "CPlApplet"))) {
        WARN("Not a valid control panel applet %s\n", debugstr_w(cmd));
	goto theError;
    }
    if (!applet->proc(hWnd, CPL_INIT, 0L, 0L)) {
        WARN("Init of applet has failed\n");
	goto theError;
    }
    if ((applet->count = applet->proc(hWnd, CPL_GETCOUNT, 0L, 0L)) == 0) {
        WARN("No subprogram in applet\n");
	goto theError;
    }

    applet = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, applet,
			 sizeof(*applet) + (applet->count - 1) * sizeof(NEWCPLINFOW));

    for (i = 0; i < applet->count; i++) {
       ZeroMemory(&newinfo, sizeof(newinfo));
       newinfo.dwSize = sizeof(NEWCPLINFOA);
       applet->info[i].dwSize = sizeof(NEWCPLINFOW);
       /* proc is supposed to return a null value upon success for
	* CPL_INQUIRE and CPL_NEWINQUIRE
	* However, real drivers don't seem to behave like this
	* So, use introspection rather than return value
	*/
       applet->proc(hWnd, CPL_NEWINQUIRE, i, (LPARAM)&newinfo);
       if (newinfo.hIcon == 0) {
	   applet->proc(hWnd, CPL_INQUIRE, i, (LPARAM)&info);
	   if (info.idIcon == 0 || info.idName == 0) {
	       WARN("Couldn't get info from sp %u\n", i);
	       applet->info[i].dwSize = 0;
	   } else {
	       /* convert the old data into the new structure */
	       applet->info[i].dwFlags = 0;
	       applet->info[i].dwHelpContext = 0;
	       applet->info[i].lData = info.lData;
	       applet->info[i].hIcon = LoadIconW(applet->hModule,
						 MAKEINTRESOURCEW(info.idIcon));
	       LoadStringW(applet->hModule, info.idName,
			   applet->info[i].szName, sizeof(applet->info[i].szName) / sizeof(WCHAR));
	       LoadStringW(applet->hModule, info.idInfo,
			   applet->info[i].szInfo, sizeof(applet->info[i].szInfo) / sizeof(WCHAR));
	       applet->info[i].szHelpFile[0] = '\0';
	   }
       }
       else
       {
           CopyMemory(&applet->info[i], &newinfo, newinfo.dwSize);
	   if (newinfo.dwSize != sizeof(NEWCPLINFOW))
           {
	       applet->info[i].dwSize = sizeof(NEWCPLINFOW);
               MultiByteToWideChar(CP_ACP, 0, ((LPNEWCPLINFOA)&newinfo)->szName,
	                           sizeof(((LPNEWCPLINFOA)&newinfo)->szName) / sizeof(CHAR),
			           applet->info[i].szName,
			           sizeof(applet->info[i].szName) / sizeof(WCHAR));
               MultiByteToWideChar(CP_ACP, 0, ((LPNEWCPLINFOA)&newinfo)->szInfo,
	                           sizeof(((LPNEWCPLINFOA)&newinfo)->szInfo) / sizeof(CHAR),
			           applet->info[i].szInfo,
			           sizeof(applet->info[i].szInfo) / sizeof(WCHAR));
               MultiByteToWideChar(CP_ACP, 0, ((LPNEWCPLINFOA)&newinfo)->szHelpFile,
	                           sizeof(((LPNEWCPLINFOA)&newinfo)->szHelpFile) / sizeof(CHAR),
			           applet->info[i].szHelpFile,
			           sizeof(applet->info[i].szHelpFile) / sizeof(WCHAR));
           }
       }
    }

    applet->next = panel->first;
    panel->first = applet;

    return applet;

 theError:
    Control_UnloadApplet(applet);
    return NULL;
}

static void 	 Control_WndProc_Create(HWND hWnd, const CREATESTRUCTA* cs)
{
   CPanel*	panel = (CPanel*)cs->lpCreateParams;

   SetWindowLongPtrA(hWnd, 0, (LONG_PTR)panel);
   panel->status = 0;
   panel->hWnd = hWnd;
}

#define	XICON	32
#define XSTEP	128
#define	YICON	32
#define YSTEP	64

static BOOL	Control_Localize(const CPanel* panel, unsigned cx, unsigned cy,
				 CPlApplet** papplet, unsigned* psp)
{
    unsigned	i, x = (XSTEP-XICON)/2, y = 0;
    CPlApplet*	applet;
    RECT	rc;

    GetClientRect(panel->hWnd, &rc);
    for (applet = panel->first; applet; applet = applet->next) {
        for (i = 0; i < applet->count; i++) {
	    if (!applet->info[i].dwSize) continue;
	    if (x + XSTEP >= rc.right - rc.left) {
	        x = (XSTEP-XICON)/2;
		y += YSTEP;
	    }
	    if (cx >= x && cx < x + XICON && cy >= y && cy < y + YSTEP) {
	        *papplet = applet;
	        *psp = i;
		return TRUE;
	    }
	    x += XSTEP;
	}
    }
    return FALSE;
}

static LRESULT Control_WndProc_Paint(const CPanel* panel, WPARAM wParam)
{
    HDC		hdc;
    PAINTSTRUCT	ps;
    RECT	rc, txtRect;
    unsigned	i, x = 0, y = 0;
    CPlApplet*	applet;
    HGDIOBJ	hOldFont;

    hdc = (wParam) ? (HDC)wParam : BeginPaint(panel->hWnd, &ps);
    hOldFont = SelectObject(hdc, GetStockObject(ANSI_VAR_FONT));
    GetClientRect(panel->hWnd, &rc);
    for (applet = panel->first; applet; applet = applet->next) {
        for (i = 0; i < applet->count; i++) {
	    if (x + XSTEP >= rc.right - rc.left) {
	        x = 0;
		y += YSTEP;
	    }
	    if (!applet->info[i].dwSize) continue;
	    DrawIcon(hdc, x + (XSTEP-XICON)/2, y, applet->info[i].hIcon);
	    txtRect.left = x;
	    txtRect.right = x + XSTEP;
	    txtRect.top = y + YICON;
	    txtRect.bottom = y + YSTEP;
	    DrawTextW(hdc, applet->info[i].szName, -1, &txtRect,
		      DT_CENTER | DT_VCENTER);
	    x += XSTEP;
	}
    }
    SelectObject(hdc, hOldFont);
    if (!wParam) EndPaint(panel->hWnd, &ps);
    return 0;
}

static LRESULT Control_WndProc_LButton(CPanel* panel, LPARAM lParam, BOOL up)
{
    unsigned	i;
    CPlApplet*	applet;

    if (Control_Localize(panel, LOWORD(lParam), HIWORD(lParam), &applet, &i)) {
       if (up) {
	   if (panel->clkApplet == applet && panel->clkSP == i) {
	       applet->proc(applet->hWnd, CPL_DBLCLK, i, applet->info[i].lData);
	   }
       } else {
	   panel->clkApplet = applet;
	   panel->clkSP = i;
       }
    }
    return 0;
}

static LRESULT WINAPI	Control_WndProc(HWND hWnd, UINT wMsg,
					WPARAM lParam1, LPARAM lParam2)
{
   CPanel*	panel = (CPanel*)GetWindowLongPtrA(hWnd, 0);

   if (panel || wMsg == WM_CREATE) {
      switch (wMsg) {
      case WM_CREATE:
	 Control_WndProc_Create(hWnd, (CREATESTRUCTA*)lParam2);
	 return 0;
      case WM_DESTROY:
         {
	    CPlApplet*	applet = panel->first;
	    while (applet)
	       applet = Control_UnloadApplet(applet);
         }
         PostQuitMessage(0);
	 break;
      case WM_PAINT:
	 return Control_WndProc_Paint(panel, lParam1);
      case WM_LBUTTONUP:
	 return Control_WndProc_LButton(panel, lParam2, TRUE);
      case WM_LBUTTONDOWN:
	 return Control_WndProc_LButton(panel, lParam2, FALSE);
/* EPP       case WM_COMMAND: */
/* EPP 	 return Control_WndProc_Command(mwi, lParam1, lParam2); */
      }
   }

   return DefWindowProcA(hWnd, wMsg, lParam1, lParam2);
}

static void    Control_DoInterface(CPanel* panel, HWND hWnd, HINSTANCE hInst)
{
    WNDCLASSA	wc;
    MSG		msg;
    const CHAR* appName = "Wine Control Panel";
    wc.style = CS_HREDRAW|CS_VREDRAW;
    wc.lpfnWndProc = Control_WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = sizeof(CPlApplet*);
    wc.hInstance = hInst;
    wc.hIcon = 0;
    wc.hCursor = 0;
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "Shell_Control_WndClass";

    if (!RegisterClassA(&wc)) return;

    CreateWindowExA(0, wc.lpszClassName, appName,
		    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		    CW_USEDEFAULT, CW_USEDEFAULT,
		    CW_USEDEFAULT, CW_USEDEFAULT,
		    hWnd, NULL, hInst, panel);
    if (!panel->hWnd) return;

    if (!panel->first) {
	/* FIXME appName & message should be localized  */
	MessageBoxA(panel->hWnd, "Cannot load any applets", appName, MB_OK);
	return;
    }

    while (GetMessageA(&msg, panel->hWnd, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessageA(&msg);
    }
}

static	void	Control_DoWindow(CPanel* panel, HWND hWnd, HINSTANCE hInst)
{
    HANDLE		h;
    WIN32_FIND_DATAW	fd;
    WCHAR		buffer[MAX_PATH];
    static const WCHAR wszAllCpl[] = {'*','.','c','p','l',0};
    WCHAR *p;

    GetSystemDirectoryW( buffer, MAX_PATH );
    p = buffer + strlenW(buffer);
    *p++ = '\\';
    lstrcpyW(p, wszAllCpl);

    if ((h = FindFirstFileW(buffer, &fd)) != INVALID_HANDLE_VALUE) {
        do {
	   lstrcpyW(p, fd.cFileName);
	   Control_LoadApplet(hWnd, buffer, panel);
	} while (FindNextFileW(h, &fd));
	FindClose(h);
    }

    Control_DoInterface(panel, hWnd, hInst);
}

static	void	Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
   /* forms to parse:
    *	foo.cpl,@sp,str
    *	foo.cpl,@sp
    *	foo.cpl,,str
    *	foo.cpl @sp
    *	foo.cpl str
    *   "a path\foo.cpl"
    */
{
    LPWSTR	buffer;
    LPWSTR	beg = NULL;
    LPWSTR	end;
    WCHAR	ch;
    LPWSTR       ptr;
    unsigned 	sp = 0;
    LPWSTR	extraPmts = NULL;
    int        quoted = 0;

    buffer = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(wszCmd) + 1) * sizeof(*wszCmd));
    if (!buffer) return;

    end = lstrcpyW(buffer, wszCmd);

    for (;;) {
	ch = *end;
        if (ch == '"') quoted = !quoted;
	if (!quoted && (ch == ' ' || ch == ',' || ch == '\0')) {
	    *end = '\0';
	    if (beg) {
	        if (*beg == '@') {
		    sp = atoiW(beg + 1);
		} else if (*beg == '\0') {
		    sp = 0;
		} else {
		    extraPmts = beg;
		}
	    }
	    if (ch == '\0') break;
	    beg = end + 1;
	    if (ch == ' ') while (end[1] == ' ') end++;
	}
	end++;
    }
    while ((ptr = StrChrW(buffer, '"')))
	memmove(ptr, ptr+1, lstrlenW(ptr)*sizeof(WCHAR));

    TRACE("cmd %s, extra %s, sp %d\n", debugstr_w(buffer), debugstr_w(extraPmts), sp);

    Control_LoadApplet(hWnd, buffer, panel);

    if (panel->first) {
       CPlApplet* applet = panel->first;

       assert(applet && applet->next == NULL);
       if (sp >= applet->count) {
	  WARN("Out of bounds (%u >= %u), setting to 0\n", sp, applet->count);
	  sp = 0;
       }
       if (applet->info[sp].dwSize) {
	  if (!applet->proc(applet->hWnd, CPL_STARTWPARMSA, sp, (LPARAM)extraPmts))
	     applet->proc(applet->hWnd, CPL_DBLCLK, sp, applet->info[sp].lData);
       }
       Control_UnloadApplet(applet);
    }
    HeapFree(GetProcessHeap(), 0, buffer);
}

/*************************************************************************
 * Control_RunDLLW			[SHELL32.@]
 *
 */
void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow)
{
    CPanel	panel;

    TRACE("(%p, %p, %s, 0x%08lx)\n",
	  hWnd, hInst, debugstr_w(cmd), nCmdShow);

    memset(&panel, 0, sizeof(panel));

    if (!cmd || !*cmd) {
        Control_DoWindow(&panel, hWnd, hInst);
    } else {
        Control_DoLaunch(&panel, hWnd, cmd);
    }
}

/*************************************************************************
 * Control_RunDLLA			[SHELL32.@]
 *
 */
void WINAPI Control_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
{
    DWORD len = MultiByteToWideChar(CP_ACP, 0, cmd, -1, NULL, 0 );
    LPWSTR wszCmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (wszCmd && MultiByteToWideChar(CP_ACP, 0, cmd, -1, wszCmd, len ))
    {
        Control_RunDLLW(hWnd, hInst, wszCmd, nCmdShow);
    }
    HeapFree(GetProcessHeap(), 0, wszCmd);
}

/*************************************************************************
 * Control_FillCache_RunDLLW			[SHELL32.@]
 *
 */
HRESULT WINAPI Control_FillCache_RunDLLW(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
{
    FIXME("%p %p 0x%08lx 0x%08lx stub\n", hWnd, hModule, w, x);
    return 0;
}

/*************************************************************************
 * Control_FillCache_RunDLLA			[SHELL32.@]
 *
 */
HRESULT WINAPI Control_FillCache_RunDLLA(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
{
    return Control_FillCache_RunDLLW(hWnd, hModule, w, x);
}


/*************************************************************************
 * RunDLL_CallEntry16				[SHELL32.122]
 * the name is probably wrong
 */
void WINAPI RunDLL_CallEntry16( DWORD proc, HWND hwnd, HINSTANCE inst,
                                LPCSTR cmdline, INT cmdshow )
{
    WORD args[5];
    SEGPTR cmdline_seg;

    TRACE( "proc %lx hwnd %p inst %p cmdline %s cmdshow %d\n",
           proc, hwnd, inst, debugstr_a(cmdline), cmdshow );

    cmdline_seg = MapLS( cmdline );
    args[4] = HWND_16(hwnd);
    args[3] = MapHModuleLS(inst);
    args[2] = SELECTOROF(cmdline_seg);
    args[1] = OFFSETOF(cmdline_seg);
    args[0] = cmdshow;
    WOWCallback16Ex( proc, WCB16_PASCAL, sizeof(args), args, NULL );
    UnMapLS( cmdline_seg );
}

/*************************************************************************
 * CallCPLEntry16				[SHELL32.166]
 *
 * called by desk.cpl on "Advanced" with:
 * hMod("DeskCp16.Dll"), pFunc("CplApplet"), 0, 1, 0xc, 0
 *
 */
DWORD WINAPI CallCPLEntry16(HMODULE hMod, FARPROC pFunc, DWORD dw3, DWORD dw4, DWORD dw5, DWORD dw6)
{
    FIXME("(%p, %p, %08lx, %08lx, %08lx, %08lx): stub.\n", hMod, pFunc, dw3, dw4, dw5, dw6);
    return 0x0deadbee;
}
