/*
 * Generic Implementation of IDispatch for strmbase classes
 *
 * Copyright 2012 Aric Stewart, 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
 */

#define COBJMACROS

#include "dshow.h"
#include "wine/unicode.h"
#include "wine/strmbase.h"
#include "uuids.h"
#include "vfwmsgs.h"
#include <assert.h>

HRESULT WINAPI BaseDispatch_Init(BaseDispatch *This, REFIID riid)
{
    HRESULT hr = E_FAIL;
    ITypeLib *pTypeLib;

    This->pTypeInfo = NULL;
    hr = LoadRegTypeLib(&LIBID_QuartzTypeLib, 1, 0, LOCALE_SYSTEM_DEFAULT, &pTypeLib);
    if (SUCCEEDED(hr))
    {
        hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, riid, &This->pTypeInfo);

    if (pTypeLib)
        ITypeLib_Release(pTypeLib);
    }
    return hr;
}

HRESULT WINAPI BaseDispatch_Destroy(BaseDispatch *This)
{
    if (This->pTypeInfo)
        ITypeInfo_Release(This->pTypeInfo);
    return S_OK;
}

HRESULT WINAPI BaseDispatchImpl_GetIDsOfNames(BaseDispatch *This, REFIID riid, OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid)
{
    if (This->pTypeInfo)
        return ITypeInfo_GetIDsOfNames(This->pTypeInfo, rgszNames, cNames, rgdispid);
    return E_NOTIMPL;
}

HRESULT WINAPI BaseDispatchImpl_GetTypeInfo(BaseDispatch *This, REFIID riid, UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
{
    if (This->pTypeInfo)
    {
        ITypeInfo_AddRef(This->pTypeInfo);
        *pptinfo = This->pTypeInfo;
        return S_OK;
    }
    return E_NOTIMPL;
}

HRESULT WINAPI BaseDispatchImpl_GetTypeInfoCount(BaseDispatch *This, UINT *pctinfo)
{
    if (This->pTypeInfo)
        *pctinfo = 1;
    else
        *pctinfo = 0;
    return S_OK;
}
