/*
 * Qcap implementation, dllentry points
 *
 * Copyright (C) 2003 Dominik Strasser
 * Copyright (C) 2005 Rolf Kalbermatter
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include "config.h"

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

#define COBJMACROS
#define NONAMELESSSTRUCT
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "objbase.h"
#include "uuids.h"
#include "strmif.h"

#include "dllsetup.h"
#include "qcap_main.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(qcap);

static DWORD objects_ref = 0;
static DWORD server_locks = 0;
static HINSTANCE ghInst = NULL;

static const WCHAR wAudioCaptFilter[] =
{'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0};
static const WCHAR wAVICompressor[] =
{'A','V','I',' ','C','o','m','p','r','e','s','s','o','r',0};
static const WCHAR wVFWCaptFilter[] =
{'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0};
static const WCHAR wVFWCaptFilterProp[] =
{'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',' ',
 'P','r','o','p','e','r','t','y',' ','P','a','g','e',0};
static const WCHAR wAVIMux[] =
{'A','V','I',' ','m','u','x',0};
static const WCHAR wAVIMuxPropPage[] =
{'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e',0};
static const WCHAR wAVIMuxPropPage1[] =
{'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e','1',0};
static const WCHAR wFileWriter[] =
{'F','i','l','e',' ','W','r','i','t','e','r',0};
static const WCHAR wCaptGraphBuilder[] =
{'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r',0};
static const WCHAR wCaptGraphBuilder2[] =
{'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r','2',0};
static const WCHAR wInfPinTeeFilter[] =
{'I','n','f','i','n','i','t','e',' ','P','i','n',' ','T','e','e',' ','F','i',
 'l','t','e','r',0};
static const WCHAR wSmartTeeFilter[] =
{'S','m','a','r','t',' ','T','e','e',' ','F','i','l','t','e','r',0};
static const WCHAR wAudioInMixerProp[] =
{'A','u','d','i','o','I','n','p','u','t','M','i','x','e','r',' ','P','r','o',
 'p','e','r','t','y',' ','P','a','g','e',0};
 
static CFactoryTemplate const g_cTemplates[] = {
/*
    {
        wAudioCaptureFilter, 
        &CLSID_AudioCaptureFilter,
        QCAP_createAudioCaptureFilter,
        NULL
    },{
        wAVICompressor, 
        &CLSID_AVICompressor, 
        QCAP_createAVICompressor,
        NULL
    },*/{
        wVFWCaptFilter,
        &CLSID_VfwCapture,
        QCAP_createVFWCaptureFilter,
        NULL
    },/*{
        wVFWCaptFilterProp,
        &CLSID_VFWCaptureFilterPropertyPage,
        QCAP_createVFWCaptureFilterPropertyPage,
        NULL
    },{
        wAVIMux,
        &CLSID_AVImux,
        QCAP_createAVImux,
        NULL
    },{
        wAVIMuxPropPage,
        &CLSID_AVImuxPropertyPage,
        QCAP_createAVImuxPropertyPage,
        NULL
    },{
        wAVIMuxPropPage1,
        &CLSID_AVImuxPropertyPage1,
        QCAP_createAVImuxPropertyPage1,
        NULL
    },{
        wFileWriter,
        &CLSID_FileWriter,
        QCAP_createFileWriter,
        NULL
    },*/{
        wCaptGraphBuilder,
        &CLSID_CaptureGraphBuilder,
        QCAP_createCaptureGraphBuilder2,
        NULL
    },{
        wCaptGraphBuilder2,
        &CLSID_CaptureGraphBuilder2,
        QCAP_createCaptureGraphBuilder2,
        NULL
    }/*,{
        wInfPinTeeFilter, 
        &CLSID_InfinitePinTeeFilter, 
        QCAP_createInfinitePinTeeFilter,
        NULL
    },{
        wSmartTeeFilter,
        &CLSID_SmartTeeFilter,
        QCAP_createSmartTeeFilter,
        NULL
    },{
        wAudioInMixerProp,
        &CLSID_AudioInputMixerPropertyPage,
        QCAP_createAudioInputMixerPropertyPage,
        NULL
    }*/
};

static int g_numTemplates = sizeof(g_cTemplates) / sizeof(g_cTemplates[0]);

/***********************************************************************
 *    Dll EntryPoint (QCAP.@)
 */
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls(hInstDLL);
            ghInst = hInstDLL;
            SetupInitializeServers(g_cTemplates, g_numTemplates, TRUE);
            break;
        case DLL_PROCESS_DETACH:
            SetupInitializeServers(g_cTemplates, g_numTemplates, FALSE);
            break;
    }
    return TRUE;
}

/***********************************************************************
 *    DllRegisterServer (QCAP.@)
 */
HRESULT WINAPI QCAP_DllRegisterServer()
{
    TRACE("()\n");

    return SetupRegisterServers(g_cTemplates, g_numTemplates, ghInst, TRUE);	
}

/***********************************************************************
 *    DllUnregisterServer (QCAP.@)
 */
HRESULT WINAPI QCAP_DllUnregisterServer(void)
{
    TRACE("\n");

    return SetupRegisterServers(g_cTemplates, g_numTemplates, ghInst, FALSE);	
}

/***********************************************************************
 *    DllCanUnloadNow (QCAP.@)
 */
HRESULT WINAPI QCAP_DllCanUnloadNow(void)
{
    TRACE("\n");

    if (objects_ref == 0 && server_locks == 0)
        return S_OK;
    return S_FALSE;	
}

/******************************************************************************
 * DLL ClassFactory
 */
typedef struct {
    IClassFactory ITF_IClassFactory;

    DWORD ref;
    LPFNNewCOMObject pfnCreateInstance;
} IClassFactoryImpl;

static HRESULT WINAPI
DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;

    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IClassFactory))
    {
        IClassFactory_AddRef(iface);
        *ppobj = This;
        return S_OK;
    }

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

static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;

    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
        HeapFree(GetProcessHeap(), 0, This);

    return ref;
}

static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
                                          REFIID riid, LPVOID *ppobj)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
    HRESULT hres = ERROR_SUCCESS;
    LPUNKNOWN punk;

    TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj);

    if (!ppobj)
        return E_POINTER;

    /* Enforce the normal OLE rules regarding interfaces and delegation */
    if (pOuter && !IsEqualGUID(riid, &IID_IUnknown))
        return E_NOINTERFACE;

    *ppobj = NULL;
    punk = This->pfnCreateInstance(pOuter, &hres);
    if (!punk)
    {
        /* No object created, update error if it isn't done already and return */
        if (!FAILED(hres))
            hres = E_OUTOFMEMORY;
    return hres;
    }

    if (SUCCEEDED(hres))
    {
        hres = IUnknown_QueryInterface(punk, riid, ppobj);
    }
    /* Releasing the object. If everything was successful, QueryInterface
       should have incremented the refcount once more, otherwise this will
       purge the object. */
    IUnknown_Release(punk);
    return hres;
}

static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
    TRACE("(%p)->(%d)\n",This, dolock);

    if (dolock)
        InterlockedIncrement(&server_locks);
    else
        InterlockedDecrement(&server_locks);
    return S_OK;
}

static const IClassFactoryVtbl DSCF_Vtbl =
{
    DSCF_QueryInterface,
    DSCF_AddRef,
    DSCF_Release,
    DSCF_CreateInstance,
    DSCF_LockServer
};

/***********************************************************************
 *    DllGetClassObject (QCAP.@)
 */
HRESULT WINAPI QCAP_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    const CFactoryTemplate *pList = g_cTemplates;
    IClassFactoryImpl *factory;
    int i;

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

    if (!ppv)
        return E_POINTER;

    *ppv = NULL;

    if (!IsEqualGUID(&IID_IClassFactory, riid) &&
        !IsEqualGUID(&IID_IUnknown, riid))
        return E_NOINTERFACE;

    for (i = 0; i < g_numTemplates; i++, pList++)
    {
        if (IsEqualGUID(pList->m_ClsID, rclsid))
            break;
    }

    if (i == g_numTemplates)
    {
        FIXME("%s: no class found.\n", debugstr_guid(rclsid));
        return CLASS_E_CLASSNOTAVAILABLE;
    }

    factory = HeapAlloc(GetProcessHeap(), 0, sizeof(IClassFactoryImpl));
    if (!factory)
        return E_OUTOFMEMORY;

    factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl;
    factory->ref = 1;

    factory->pfnCreateInstance = pList->m_lpfnNew;

    *ppv = &(factory->ITF_IClassFactory);
    return S_OK;
}

DWORD ObjectRefCount(BOOL increment)
{
    if (increment)
        return InterlockedIncrement(&objects_ref);
    return InterlockedDecrement(&objects_ref);
}
