/*
 * Copyright 1999 Corel Corporation
 * Sean Langley
 * Copyright 2010  Geoffrey Hausheer
 * Copyright 2010 Piotr Caban for CodeWeavers
 *
 * 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
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "ole2.h"
#include "olectl.h"
#include "oledlg.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

typedef struct {
    IPropertyPageSite IPropertyPageSite_iface;
    LCID lcid;
    LONG ref;
} PropertyPageSite;

static inline PropertyPageSite *impl_from_IPropertyPageSite(IPropertyPageSite *iface)
{
    return CONTAINING_RECORD(iface, PropertyPageSite, IPropertyPageSite_iface);
}

static INT_PTR CALLBACK property_sheet_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    IPropertyPage *property_page = (IPropertyPage*)GetWindowLongPtrW(hwnd, DWLP_USER);

    switch(msg) {
    case WM_INITDIALOG: {
        RECT rect;

        property_page = (IPropertyPage*)((LPPROPSHEETPAGEW)lparam)->lParam;

        GetClientRect(hwnd, &rect);
        IPropertyPage_Activate(property_page, hwnd, &rect, TRUE);
        IPropertyPage_Show(property_page, SW_SHOW);

        SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)property_page);
        return FALSE;
    }
    case WM_DESTROY:
        IPropertyPage_Show(property_page, SW_HIDE);
        IPropertyPage_Deactivate(property_page);
        return FALSE;
    default:
        return FALSE;
    }
}

static HRESULT WINAPI PropertyPageSite_QueryInterface(IPropertyPageSite*  iface,
        REFIID  riid, void**  ppv)
{
    TRACE("(%p riid: %s)\n",iface, debugstr_guid(riid));

    if(IsEqualGUID(&IID_IUnknown, riid)
            || IsEqualGUID(&IID_IPropertyPageSite, riid))
        *ppv = iface;
    else {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI PropertyPageSite_AddRef(IPropertyPageSite* iface)
{
    PropertyPageSite *this = impl_from_IPropertyPageSite(iface);
    LONG ref = InterlockedIncrement(&this->ref);

    TRACE("(%p) ref=%d\n", this, ref);
    return ref;
}

static ULONG WINAPI PropertyPageSite_Release(IPropertyPageSite* iface)
{
    PropertyPageSite *this = impl_from_IPropertyPageSite(iface);
    LONG ref = InterlockedDecrement(&this->ref);

    TRACE("(%p) ref=%d\n", this, ref);
    if(!ref)
        HeapFree(GetProcessHeap(), 0, this);
    return ref;
}

static HRESULT WINAPI PropertyPageSite_OnStatusChange(
        IPropertyPageSite *iface, DWORD dwFlags)
{
    TRACE("(%p, %x)\n", iface, dwFlags);
    return S_OK;
}

static HRESULT WINAPI PropertyPageSite_GetLocaleID(
        IPropertyPageSite *iface, LCID *pLocaleID)
{
    PropertyPageSite *this = impl_from_IPropertyPageSite(iface);

    TRACE("(%p, %p)\n", iface, pLocaleID);
    *pLocaleID = this->lcid;
    return S_OK;
}

static HRESULT WINAPI PropertyPageSite_GetPageContainer(
        IPropertyPageSite* iface, IUnknown** ppUnk)
{
    FIXME("(%p, %p)\n", iface, ppUnk);
    return E_NOTIMPL;
}

static HRESULT WINAPI PropertyPageSite_TranslateAccelerator(
        IPropertyPageSite* iface, MSG *pMsg)
{
    FIXME("(%p, %p)\n", iface, pMsg);
    return E_NOTIMPL;
}

static IPropertyPageSiteVtbl PropertyPageSiteVtbl = {
    PropertyPageSite_QueryInterface,
    PropertyPageSite_AddRef,
    PropertyPageSite_Release,
    PropertyPageSite_OnStatusChange,
    PropertyPageSite_GetLocaleID,
    PropertyPageSite_GetPageContainer,
    PropertyPageSite_TranslateAccelerator
};

/***********************************************************************
 * OleCreatePropertyFrameIndirect (OLEAUT32.416)
 */
HRESULT WINAPI OleCreatePropertyFrameIndirect(LPOCPFIPARAMS lpParams)
{
    static const WCHAR comctlW[] = { 'c','o','m','c','t','l','3','2','.','d','l','l',0 };

    PROPSHEETHEADERW property_sheet;
    PROPSHEETPAGEW property_sheet_page;
    struct {
        DLGTEMPLATE template;
        WORD menu;
        WORD class;
        WORD title;
    } *dialogs;
    IPropertyPage **property_page;
    PropertyPageSite *property_page_site;
    HRESULT res;
    ULONG i;
    HMODULE hcomctl;
    HRSRC property_sheet_dialog_find = NULL;
    HGLOBAL property_sheet_dialog_load = NULL;
    WCHAR *property_sheet_dialog_data = NULL;
    HDC hdc;
    LOGFONTW font_desc;
    HFONT hfont;
    LONG font_width = 4, font_height = 8;

    if(!lpParams)
        return E_POINTER;

    TRACE("(%d %p %d %d %s %d %p %d %p %d %d)\n", lpParams->cbStructSize,
            lpParams->hWndOwner, lpParams->x, lpParams->y,
            debugstr_w(lpParams->lpszCaption), lpParams->cObjects,
            lpParams->lplpUnk, lpParams->cPages, lpParams->lpPages,
            lpParams->lcid, lpParams->dispidInitialProperty);

    if(!lpParams->lplpUnk || !lpParams->lpPages)
        return E_POINTER;

    if(lpParams->cbStructSize != sizeof(OCPFIPARAMS)) {
        WARN("incorrect structure size\n");
        return E_INVALIDARG;
    }

    if(lpParams->dispidInitialProperty)
        FIXME("dispidInitialProperty not yet implemented\n");

    hdc = GetDC(NULL);
    hcomctl = LoadLibraryW(comctlW);
    if(hcomctl)
        property_sheet_dialog_find = FindResourceW(hcomctl,
                MAKEINTRESOURCEW(1006 /*IDD_PROPSHEET*/), (LPWSTR)RT_DIALOG);
    if(property_sheet_dialog_find)
        property_sheet_dialog_load = LoadResource(hcomctl, property_sheet_dialog_find);
    if(property_sheet_dialog_load)
        property_sheet_dialog_data = LockResource(property_sheet_dialog_load);

    if(property_sheet_dialog_data) {
        if(property_sheet_dialog_data[1] == 0xffff) {
            ERR("Expected DLGTEMPLATE structure\n");
            FreeLibrary(hcomctl);
            return E_OUTOFMEMORY;
        }

        property_sheet_dialog_data += sizeof(DLGTEMPLATE)/sizeof(WCHAR);
        /* Skip menu, class and title */
        property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
        property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
        property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;

        memset(&font_desc, 0, sizeof(LOGFONTW));
        /* Calculate logical height */
        font_desc.lfHeight = -MulDiv(property_sheet_dialog_data[0],
                GetDeviceCaps(hdc, LOGPIXELSY), 72);
        font_desc.lfCharSet = DEFAULT_CHARSET;
        memcpy(font_desc.lfFaceName, property_sheet_dialog_data+1,
                sizeof(WCHAR)*(lstrlenW(property_sheet_dialog_data+1)+1));
        hfont = CreateFontIndirectW(&font_desc);

        if(hfont) {
            hfont = SelectObject(hdc, hfont);
            font_width = GdiGetCharDimensions(hdc, NULL, &font_height);
            SelectObject(hdc, hfont);
        }
    }
    if(hcomctl)
        FreeLibrary(hcomctl);
    ReleaseDC(NULL, hdc);

    memset(&property_sheet, 0, sizeof(property_sheet));
    property_sheet.dwSize = sizeof(property_sheet);
    if(lpParams->lpszCaption) {
        property_sheet.dwFlags = PSH_PROPTITLE;
        property_sheet.pszCaption = lpParams->lpszCaption;
    }

    property_sheet.u3.phpage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
            lpParams->cPages*sizeof(HPROPSHEETPAGE));
    property_page = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
            lpParams->cPages*sizeof(IPropertyPage*));
    dialogs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
            lpParams->cPages*sizeof(*dialogs));
    if(!property_sheet.u3.phpage || !property_page || !dialogs) {
        HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
        HeapFree(GetProcessHeap(), 0, property_page);
        HeapFree(GetProcessHeap(), 0, dialogs);
        return E_OUTOFMEMORY;
    }

    memset(&property_sheet_page, 0, sizeof(PROPSHEETPAGEW));
    property_sheet_page.dwSize = sizeof(PROPSHEETPAGEW);
    property_sheet_page.dwFlags = PSP_DLGINDIRECT|PSP_USETITLE;
    property_sheet_page.pfnDlgProc = property_sheet_proc;

    for(i=0; i<lpParams->cPages; i++) {
        PROPPAGEINFO page_info;

        res = CoCreateInstance(&lpParams->lpPages[i], NULL, CLSCTX_INPROC_SERVER,
                &IID_IPropertyPage, (void**)&property_page[i]);
        if(FAILED(res))
            continue;

        property_page_site = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyPageSite));
        if(!property_page_site)
            continue;
        property_page_site->IPropertyPageSite_iface.lpVtbl = &PropertyPageSiteVtbl;
        property_page_site->ref = 1;
        property_page_site->lcid = lpParams->lcid;

        res = IPropertyPage_SetPageSite(property_page[i],
                &property_page_site->IPropertyPageSite_iface);
        IPropertyPageSite_Release(&property_page_site->IPropertyPageSite_iface);
        if(FAILED(res))
            continue;

        res = IPropertyPage_SetObjects(property_page[i],
                lpParams->cObjects, lpParams->lplpUnk);
        if(FAILED(res))
            continue;

        res = IPropertyPage_GetPageInfo(property_page[i], &page_info);
        if(FAILED(res))
            continue;

        dialogs[i].template.cx = MulDiv(page_info.size.cx, 4, font_width);
        dialogs[i].template.cy = MulDiv(page_info.size.cy, 8, font_height);

        property_sheet_page.u.pResource = &dialogs[i].template;
        property_sheet_page.lParam = (LPARAM)property_page[i];
        property_sheet_page.pszTitle = page_info.pszTitle;

        property_sheet.u3.phpage[property_sheet.nPages++] =
            CreatePropertySheetPageW(&property_sheet_page);
    }

    PropertySheetW(&property_sheet);

    for(i=0; i<lpParams->cPages; i++) {
        if(property_page[i]) {
            IPropertyPage_SetPageSite(property_page[i], NULL);
            IPropertyPage_Release(property_page[i]);
        }
    }

    HeapFree(GetProcessHeap(), 0, dialogs);
    HeapFree(GetProcessHeap(), 0, property_page);
    HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
    return S_OK;
}

/***********************************************************************
 * OleCreatePropertyFrame (OLEAUT32.417)
 */
HRESULT WINAPI OleCreatePropertyFrame(
        HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption, ULONG cObjects,
        LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid,
        DWORD dwReserved, LPVOID pvReserved)
{
    OCPFIPARAMS ocpf;

    ocpf.cbStructSize =  sizeof(OCPFIPARAMS);
    ocpf.hWndOwner    = hwndOwner;
    ocpf.x            = x;
    ocpf.y            = y;
    ocpf.lpszCaption  = lpszCaption;
    ocpf.cObjects     = cObjects;
    ocpf.lplpUnk      = ppUnk;
    ocpf.cPages       = cPages;
    ocpf.lpPages      = pPageClsID;
    ocpf.lcid         = lcid;
    ocpf.dispidInitialProperty = 0;

    return OleCreatePropertyFrameIndirect(&ocpf);
}
