/*
 *    MSXML Class Factory
 *
 * Copyright 2002 Lionel Ulmer
 * Copyright 2005 Mike McCormack
 *
 * 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 "config.h"

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "msxml.h"
#include "xmldom.h"
#include "msxml2.h"

/* undef the #define in msxml2 so that we can access the v.2 version
   independent CLSID as well as the v.3 one. */
#undef CLSID_DOMDocument

#include "wine/debug.h"

#include "msxml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

typedef HRESULT (*fnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);

/******************************************************************************
 * MSXML ClassFactory
 */
typedef struct _xmlcf
{
    const struct IClassFactoryVtbl *lpVtbl;
    fnCreateInstance pfnCreateInstance;
} xmlcf;

static inline xmlcf *impl_from_IClassFactory( IClassFactory *iface )
{
    return (xmlcf *)((char*)iface - FIELD_OFFSET(xmlcf, lpVtbl));
}

static HRESULT WINAPI xmlcf_QueryInterface(
    IClassFactory *iface,
    REFIID riid,
    LPVOID *ppobj )
{
    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IClassFactory))
    {
        IClassFactory_AddRef( iface );
        *ppobj = iface;
        return S_OK;
    }

    FIXME("interface %s not implemented\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI xmlcf_AddRef(
    IClassFactory *iface )
{
    return 2;
}

static ULONG WINAPI xmlcf_Release(
    IClassFactory *iface )
{
    return 1;
}

static HRESULT WINAPI xmlcf_CreateInstance(
    IClassFactory *iface,
    LPUNKNOWN pOuter,
    REFIID riid,
    LPVOID *ppobj )
{
    xmlcf *This = impl_from_IClassFactory( iface );
    HRESULT r;
    IUnknown *punk;
    
    TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );

    *ppobj = NULL;

    if (pOuter)
        return CLASS_E_NOAGGREGATION;

    r = This->pfnCreateInstance( pOuter, (LPVOID*) &punk );
    if (FAILED(r))
        return r;

    r = IUnknown_QueryInterface( punk, riid, ppobj );
    IUnknown_Release( punk );
    return r;
}

static HRESULT WINAPI xmlcf_LockServer(
    IClassFactory *iface,
    BOOL dolock)
{
    FIXME("(%p)->(%d),stub!\n",iface,dolock);
    return S_OK;
}

static const struct IClassFactoryVtbl xmlcf_vtbl =
{
    xmlcf_QueryInterface,
    xmlcf_AddRef,
    xmlcf_Release,
    xmlcf_CreateInstance,
    xmlcf_LockServer
};

static xmlcf domdoccf = { &xmlcf_vtbl, DOMDocument_create };
static xmlcf schemacf = { &xmlcf_vtbl, SchemaCache_create };
static xmlcf xmldoccf = { &xmlcf_vtbl, XMLDocument_create };
static xmlcf saxreadcf = { &xmlcf_vtbl, SAXXMLReader_create };
static xmlcf httpreqcf = { &xmlcf_vtbl, XMLHTTPRequest_create };

/******************************************************************
 *		DllGetClassObject (MSXML3.@)
 */
HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
{
    IClassFactory *cf = NULL;

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

    if( IsEqualCLSID( rclsid, &CLSID_DOMDocument ) ||   /* Version indep. v 2.x */
        IsEqualCLSID( rclsid, &CLSID_DOMDocument2 ) ||  /* Version indep. v 3.0 */
        IsEqualCLSID( rclsid, &CLSID_DOMDocument30 )||  /* Version dep.   v 3.0 */
        IsEqualCLSID( rclsid, &CLSID_DOMDocument40 ))   /* Version dep.   v 4.0 */
    {
        cf = (IClassFactory*) &domdoccf.lpVtbl;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache ) ||
             IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache30 ) )
    {
        cf = (IClassFactory*) &schemacf.lpVtbl;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_XMLDocument ) )
    {
        cf = (IClassFactory*) &xmldoccf.lpVtbl;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_DOMFreeThreadedDocument ) ||   /* Version indep. v 2.x */
             IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument ) ||
             IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument30 ))
    {
        cf = (IClassFactory*) &domdoccf.lpVtbl;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_SAXXMLReader) ||
             IsEqualCLSID( rclsid, &CLSID_SAXXMLReader30 ) ||
             IsEqualCLSID( rclsid, &CLSID_SAXXMLReader40 ))
    {
        cf = (IClassFactory*) &saxreadcf.lpVtbl;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_XMLHTTPRequest))
    {
        cf = (IClassFactory*) &httpreqcf.lpVtbl;
    }

    if ( !cf )
        return CLASS_E_CLASSNOTAVAILABLE;

    return IClassFactory_QueryInterface( cf, iid, ppv );
}
