/*
 * Windows Help
 *
 * Copyright 1996 Martin von Loewis
 *           2002 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 "config.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "wine/debug.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"

WINE_DEFAULT_DEBUG_CHANNEL(win);

/* Wine doesn't use the way WinHelp API sends information in Windows, because:
 * 1/ it's not consistent acrosss Win9x, NT...
 * 2/ NT implementation is not yet fully understood (and includes some shared
 *     memory mechanism)
 * 3/ uses a dynamically allocated message number (WM_WINHELP), which 
 *    obfuscates the code
 *
 * So we use (for now) the simple protocol:
 * 1/ it's based on copy data
 * 2/ we tag the message with a magic number, to make it a bit more robust 
 *   (even if it's not 100% safe)
 * 3/ data structure (WINHELP) has the same layout that the one used on Win95. 
 *    This doesn't bring much, except not going to far away from real 
 *    implementation.
 *
 * This means anyway that native winhelp.exe and winhlp32.exe cannot be 
 * called/manipulated from WinHelp API.
 */
typedef struct
{
    WORD size;
    WORD command;
    LONG data;
    LONG reserved;
    WORD ofsFilename;
    WORD ofsData;
} WINHELP;

/* magic number for this message:
 *  aide means help is French ;-) 
 *  SOS means ???
 */
#define WINHELP_MAGIC   0xA1DE505

/**********************************************************************
 *		WinHelpA (USER32.@)
 */
BOOL WINAPI WinHelpA( HWND hWnd, LPCSTR lpHelpFile, UINT wCommand, ULONG_PTR dwData )
{
    COPYDATASTRUCT      cds;
    HWND                hDest;
    int                 size, dsize, nlen;
    WINHELP*            lpwh;

    hDest = FindWindowA("MS_WINHELP", NULL);
    if (!hDest) 
    {
        if (wCommand == HELP_QUIT) return TRUE;
        if (WinExec("winhelp.exe -x", SW_SHOWNORMAL) < 32) 
        {
            ERR("can't start winhelp.exe -x ?\n");
            return FALSE;
        }
        if (!(hDest = FindWindowA("MS_WINHELP", NULL))) 
        {
            FIXME("Did not find a MS_WINHELP Window\n");
            return FALSE;
        }
    }

    switch (wCommand)
    {
    case HELP_CONTEXT:
    case HELP_SETCONTENTS:
    case HELP_CONTENTS:
    case HELP_CONTEXTPOPUP:
    case HELP_FORCEFILE:
    case HELP_HELPONHELP:
    case HELP_FINDER:
    case HELP_QUIT:
        dsize = 0;
        break;
    case HELP_KEY:
    case HELP_PARTIALKEY:
    case HELP_COMMAND:
        dsize = dwData ? strlen((LPSTR)dwData) + 1 : 0;
        break;
    case HELP_MULTIKEY:
        dsize = ((LPMULTIKEYHELPA)dwData)->mkSize;
        break;
    case HELP_SETWINPOS:
        dsize = ((LPHELPWININFOA)dwData)->wStructSize;
        break;
    default:
        FIXME("Unknown help command %d\n", wCommand);
        return FALSE;
    }
    if (lpHelpFile)
        nlen = strlen(lpHelpFile) + 1;
    else
        nlen = 0;
    size = sizeof(WINHELP) + nlen + dsize;

    lpwh = HeapAlloc(GetProcessHeap(), 0, size);
    if (!lpwh) return FALSE;

    cds.dwData = WINHELP_MAGIC;
    cds.cbData = size;
    cds.lpData = (void*)lpwh;

    lpwh->size = size;
    lpwh->command = wCommand;
    lpwh->data = dwData;
    if (nlen) 
    {
        strcpy(((char*)lpwh) + sizeof(WINHELP), lpHelpFile);
        lpwh->ofsFilename = sizeof(WINHELP);
    } else
        lpwh->ofsFilename = 0;
    if (dsize) 
    {
        memcpy(((char*)lpwh) + sizeof(WINHELP) + nlen, (LPSTR)dwData, dsize);
        lpwh->ofsData = sizeof(WINHELP) + nlen;
    } else
        lpwh->ofsData = 0;
    WINE_TRACE("Sending[%u]: cmd=%u data=%08lx fn=%s\n", 
               lpwh->size, lpwh->command, lpwh->data,
               lpwh->ofsFilename ? (LPSTR)lpwh + lpwh->ofsFilename : "");

    return SendMessageA(hDest, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
}


/**********************************************************************
 *		WinHelpW (USER32.@)
 */
BOOL WINAPI WinHelpW( HWND hWnd, LPCWSTR helpFile, UINT command, ULONG_PTR dwData )
{
    INT len;
    LPSTR file;
    BOOL ret = FALSE;

    if (!helpFile) return WinHelpA( hWnd, NULL, command, dwData );

    len = WideCharToMultiByte( CP_ACP, 0, helpFile, -1, NULL, 0, NULL, NULL );
    if ((file = HeapAlloc( GetProcessHeap(), 0, len )))
    {
        WideCharToMultiByte( CP_ACP, 0, helpFile, -1, file, len, NULL, NULL );
        ret = WinHelpA( hWnd, file, command, dwData );
        HeapFree( GetProcessHeap(), 0, file );
    }
    return ret;
}
