/*
 * Implementation of the Spooler Setup API (Printing)
 *
 * Copyright 2007 Detlef Riekenberg
 *
 * 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 <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wingdi.h"
#include "winnls.h"
#include "winver.h"
#include "winspool.h"

#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ntprint);

typedef struct {
  LPMONITOR_INFO_2W mi2;    /* Buffer for installed Monitors */
  DWORD installed;          /* Number of installed Monitors */
} monitorinfo_t;

/*****************************************************
 *      DllMain
 */
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("(%p, %d, %p)\n",hinstDLL, fdwReason, lpvReserved);

    switch(fdwReason)
    {
        case DLL_WINE_PREATTACH:
            return FALSE;           /* prefer native version */

        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls( hinstDLL );
            break;
    }
    return TRUE;
}

/*****************************************************
 *  PSetupCreateMonitorInfo  [NTPRINT.@]
 *
 *
 */

HANDLE WINAPI PSetupCreateMonitorInfo(DWORD unknown1, WCHAR *server)
{
    monitorinfo_t * mi=NULL;
    DWORD needed;
    DWORD res;

    TRACE("(%d, %s)\n", unknown1, debugstr_w(server));

    mi = HeapAlloc(GetProcessHeap(), 0, sizeof(monitorinfo_t));
    if (!mi) {
        /* FIXME: SetLastError() needed? */
        return NULL;
    }

    /* Get the needed size for all Monitors */
    res = EnumMonitorsW(server, 2, NULL, 0, &needed, &mi->installed);
    if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
        mi->mi2 = HeapAlloc(GetProcessHeap(), 0, needed);
        res = EnumMonitorsW(server, 2, (LPBYTE) mi->mi2, needed, &needed, &mi->installed);
    }

    if (!res) {
        HeapFree(GetProcessHeap(), 0, mi);
        return NULL;
    }

    TRACE("=> %p (%u monitors installed)\n", mi, mi->installed);
    return mi;
}

/*****************************************************
 *  PSetupDestroyMonitorInfo  [NTPRINT.@]
 *
 */

VOID WINAPI PSetupDestroyMonitorInfo(HANDLE monitorinfo)
{
    monitorinfo_t * mi = monitorinfo;

    TRACE("(%p)\n", mi);
    if (mi) {
        if (mi->installed) HeapFree(GetProcessHeap(), 0, mi->mi2);
        HeapFree(GetProcessHeap(), 0, mi);
    }
}

/*****************************************************
 *  PSetupEnumMonitor  [NTPRINT.@]
 *
 * Copy the selected Monitorname to a buffer
 *
 * PARAMS
 *  monitorinfo [I]  HANDLE from PSetupCreateMonitorInfo
 *  index       [I]  Nr. of the Monitorname to copy
 *  buffer      [I]  Target, that receive the Monitorname
 *  psize       [IO] PTR to a DWORD that hold the size of the buffer and receive
 *                   the needed size, when the buffer is too small
 *
 * RETURNS
 *  Success:  TRUE
 *  Failure:  FALSE
 *
 * NOTES
 *   size is in Bytes on w2k and WCHAR on XP
 *
 */

BOOL WINAPI PSetupEnumMonitor(HANDLE monitorinfo, DWORD index, LPWSTR buffer, LPDWORD psize)
{
    monitorinfo_t * mi = monitorinfo;
    LPWSTR  nameW;
    DWORD   len;

    TRACE("(%p, %u, %p, %p) => %d\n", mi, index, buffer, psize, psize ? *psize : 0);

    if (index < mi->installed) {
        nameW = mi->mi2[index].pName;
        len = lstrlenW(nameW) + 1;
        if (len <= *psize) {
            memcpy(buffer, nameW, len * sizeof(WCHAR));
            TRACE("#%u: %s\n", index, debugstr_w(buffer));
            return TRUE;
        }
        *psize = len;
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }
    SetLastError(ERROR_NO_MORE_ITEMS);
    return FALSE;
}
