/*
 * Copyright 2006 Jacek 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 "config.h"

#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "optary.h"

#include "wine/debug.h"

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

typedef struct load_opt {
    DWORD option;
    PVOID buffer;
    DWORD size;

    struct load_opt *next;
} load_opt;

typedef struct {
    const IHtmlLoadOptionsVtbl *lpHtmlLoadOptionsVtbl;

    LONG ref;

    load_opt *opts;
} HTMLLoadOptions;

#define LOADOPTS(x)  ((IHtmlLoadOptions*) &(x)->lpHtmlLoadOptionsVtbl)

#define LOADOPTS_THIS(iface) DEFINE_THIS(HTMLLoadOptions, HtmlLoadOptions, iface)

static HRESULT WINAPI HtmlLoadOptions_QueryInterface(IHtmlLoadOptions *iface,
        REFIID riid, void **ppv)
{
    HTMLLoadOptions *This = LOADOPTS_THIS(iface);

    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = LOADOPTS(This);
    }else if(IsEqualGUID(&IID_IOptionArray, riid)) {
        TRACE("(%p)->(IID_IOptionArray %p)\n", This, ppv);
        *ppv = LOADOPTS(This);
    }else if(IsEqualGUID(&IID_IHtmlLoadOptions, riid)) {
        TRACE("(%p)->(IID_IHtmlLoadOptions %p)\n", This, ppv);
        *ppv = LOADOPTS(This);
    }

    if(*ppv) {
        IHtmlLoadOptions_AddRef(LOADOPTS(This));
        return S_OK;
    }

    WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
    return E_NOINTERFACE;
}

static ULONG WINAPI HtmlLoadOptions_AddRef(IHtmlLoadOptions *iface)
{
    HTMLLoadOptions *This = LOADOPTS_THIS(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI HtmlLoadOptions_Release(IHtmlLoadOptions *iface)
{
    HTMLLoadOptions *This = LOADOPTS_THIS(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        load_opt *iter = This->opts, *last;

        while(iter) {
            last = iter;
            iter = iter->next;

            mshtml_free(last->buffer);
            mshtml_free(last);
        }

        mshtml_free(This);
    }

    return ref;
}

static HRESULT WINAPI HtmlLoadOptions_QueryOption(IHtmlLoadOptions *iface, DWORD dwOption,
        LPVOID pBuffer, ULONG *pcbBuf)
{
    HTMLLoadOptions *This = LOADOPTS_THIS(iface);
    load_opt *iter;

    TRACE("(%p)->(%d %p %p)\n", This, dwOption, pBuffer, pcbBuf);

    for(iter = This->opts; iter; iter = iter->next) {
        if(iter->option == dwOption)
            break;
    }

    if(!iter) {
        *pcbBuf = 0;
        return S_OK;
    }

    if(*pcbBuf < iter->size) {
        *pcbBuf = iter->size;
        return E_FAIL;
    }

    memcpy(pBuffer, iter->buffer, iter->size);
    *pcbBuf = iter->size;

    return S_OK;
}

static HRESULT WINAPI HtmlLoadOptions_SetOption(IHtmlLoadOptions *iface, DWORD dwOption,
        LPVOID pBuffer, ULONG cbBuf)
{
    HTMLLoadOptions *This = LOADOPTS_THIS(iface);
    load_opt *iter = NULL;

    TRACE("(%p)->(%d %p %d)\n", This, dwOption, pBuffer, cbBuf);

    for(iter = This->opts; iter; iter = iter->next) {
        if(iter->option == dwOption)
            break;
    }

    if(!iter) {
        iter = mshtml_alloc(sizeof(load_opt));
        iter->next = This->opts;
        This->opts = iter;

        iter->option = dwOption;
    }else {
        mshtml_free(iter->buffer);
    }

    if(!cbBuf) {
        iter->buffer = NULL;
        iter->size = 0;

        return S_OK;
    }

    iter->size = cbBuf;
    iter->buffer = mshtml_alloc(cbBuf);
    memcpy(iter->buffer, pBuffer, iter->size);

    return S_OK;
}

#undef LOADOPTS_THIS

static const IHtmlLoadOptionsVtbl HtmlLoadOptionsVtbl = {
    HtmlLoadOptions_QueryInterface,
    HtmlLoadOptions_AddRef,
    HtmlLoadOptions_Release,
    HtmlLoadOptions_QueryOption,
    HtmlLoadOptions_SetOption
};

HRESULT HTMLLoadOptions_Create(IUnknown *pUnkOuter, REFIID riid, void** ppv)
{
    HTMLLoadOptions *ret;
    HRESULT hres;

    TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppv);

    ret = mshtml_alloc(sizeof(HTMLLoadOptions));

    ret->lpHtmlLoadOptionsVtbl = &HtmlLoadOptionsVtbl;
    ret->ref = 1;
    ret->opts = NULL;

    hres = IHtmlLoadOptions_QueryInterface(LOADOPTS(ret), riid, ppv);
    IHtmlLoadOptions_Release(LOADOPTS(ret));

    return hres;
}
