/*
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 across 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;
    LRESULT             ret;

    hDest = FindWindowA("MS_WINHELP", NULL);
    if (!hDest) 
    {
        if (wCommand == HELP_QUIT) return TRUE;
        if (WinExec("winhlp32.exe -x", SW_SHOWNORMAL) < 32) 
        {
            ERR("can't start winhlp32.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;
    TRACE("Sending[%u]: cmd=%u data=%08x fn=%s\n",
          lpwh->size, lpwh->command, lpwh->data,
          lpwh->ofsFilename ? (LPSTR)lpwh + lpwh->ofsFilename : "");

    ret = SendMessageA(hDest, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
    HeapFree(GetProcessHeap(), 0, lpwh);
    return ret;
}


/**********************************************************************
 *		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;
}
