/*
 * 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 "wine/debug.h"
#include "shdocvw.h"
#include "urlhist.h"

WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);

static HRESULT WINAPI UrlHistoryStg_QueryInterface(IUrlHistoryStg2 *iface, REFIID riid, void **ppv)
{
    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(IID_IUnknown %p)\n", ppv);
        *ppv = iface;
    }else if(IsEqualGUID(&IID_IUrlHistoryStg, riid)) {
        TRACE("(IID_IUrlHistoryStg %p)\n", ppv);
        *ppv = iface;
    }else if(IsEqualGUID(&IID_IUrlHistoryStg2, riid)) {
        TRACE("(IID_IUrlHistoryStg2 %p)\n", ppv);
        *ppv = iface;
    }

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

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

static ULONG WINAPI UrlHistoryStg_AddRef(IUrlHistoryStg2 *iface)
{
    SHDOCVW_LockModule();
    return 2;
}

static ULONG WINAPI UrlHistoryStg_Release(IUrlHistoryStg2 *iface)
{
    SHDOCVW_UnlockModule();
    return 1;
}

static HRESULT WINAPI UrlHistoryStg_AddUrl(IUrlHistoryStg2 *iface, LPCOLESTR lpcsUrl,
        LPCOLESTR pocsTitle, DWORD dwFlags)
{
    FIXME("(%s %s %08x)\n", debugstr_w(lpcsUrl), debugstr_w(pocsTitle), dwFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI UrlHistoryStg_DeleteUrl(IUrlHistoryStg2 *iface, LPCOLESTR lpcsUrl,
        DWORD dwFlags)
{
    FIXME("(%s %08x)\n", debugstr_w(lpcsUrl), dwFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI UrlHistoryStg_QueryUrl(IUrlHistoryStg2 *iface, LPCOLESTR lpcsUrl,
        DWORD dwFlags, LPSTATURL lpSTATURL)
{
    FIXME("(%s %08x %p)\n", debugstr_w(lpcsUrl), dwFlags, lpSTATURL);
    return E_NOTIMPL;
}

static HRESULT WINAPI UrlHistoryStg_BindToObject(IUrlHistoryStg2 *iface, LPCOLESTR lpcsUrl,
        REFIID riid, void **ppv)
{
    FIXME("(%s %s %p)\n", debugstr_w(lpcsUrl), debugstr_guid(riid), ppv);
    return E_NOTIMPL;
}

static HRESULT WINAPI UrlHistoryStg_EnumUrls(IUrlHistoryStg2 *iface, IEnumSTATURL **ppEnum)
{
    FIXME("(%p)\n", ppEnum);
    return E_NOTIMPL;
}

static HRESULT WINAPI UrlHistoryStg_AddUrlAndNotify(IUrlHistoryStg2 *iface, LPCOLESTR pocsUrl,
        LPCOLESTR pocsTitle, DWORD dwFlags, BOOL fWriteHistory, IOleCommandTarget *poctNotify,
        IUnknown *punkISFolder)
{
    FIXME("(%s %s %08x %x %p %p)\n", debugstr_w(pocsUrl), debugstr_w(pocsTitle),
          dwFlags, fWriteHistory, poctNotify, punkISFolder);
    return E_NOTIMPL;
}

static HRESULT WINAPI UrlHistoryStg_ClearHistory(IUrlHistoryStg2 *iface)
{
    FIXME("()\n");
    return E_NOTIMPL;
}

static const IUrlHistoryStg2Vtbl UrlHistoryStg2Vtbl = {
    UrlHistoryStg_QueryInterface,
    UrlHistoryStg_AddRef,
    UrlHistoryStg_Release,
    UrlHistoryStg_AddUrl,
    UrlHistoryStg_DeleteUrl,
    UrlHistoryStg_QueryUrl,
    UrlHistoryStg_BindToObject,
    UrlHistoryStg_EnumUrls,
    UrlHistoryStg_AddUrlAndNotify,
    UrlHistoryStg_ClearHistory
};

static IUrlHistoryStg2 UrlHistoryStg2 = { &UrlHistoryStg2Vtbl };

HRESULT CUrlHistory_Create(IUnknown *pOuter, REFIID riid, void **ppv)
{
    if(pOuter)
        return CLASS_E_NOAGGREGATION;

    return IUrlHistoryStg_QueryInterface(&UrlHistoryStg2, riid, ppv);
}
