/*
 * Internet Messaging APIs
 *
 * Copyright 2006 Robert Shearman 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
 */

#define COBJMACROS

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winnt.h"
#include "winuser.h"
#include "ole2.h"
#include "ocidl.h"
#include "rpcproxy.h"
#include "initguid.h"
#include "mimeole.h"

#include "inetcomm_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);

static HINSTANCE instance;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    static IMimeInternational *international;

    TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason)
    {
    case DLL_WINE_PREATTACH:
        return FALSE;
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hinstDLL);
        instance = hinstDLL;
        if (!InternetTransport_RegisterClass(hinstDLL))
            return FALSE;
        MimeInternational_Construct(&international);
        break;
    case DLL_PROCESS_DETACH:
        if (lpvReserved) break;
        IMimeInternational_Release(international);
        InternetTransport_UnregisterClass(hinstDLL);
        break;
    }
    return TRUE;
}

/******************************************************************************
 * ClassFactory
 */
typedef struct
{
    IClassFactory IClassFactory_iface;
    HRESULT (*create_object)(IUnknown *, void **);
} cf;

static inline cf *impl_from_IClassFactory( IClassFactory *iface )
{
    return CONTAINING_RECORD(iface, cf, IClassFactory_iface);
}

static HRESULT WINAPI cf_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 cf_AddRef( IClassFactory *iface )
{
    return 2;
}

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

static HRESULT WINAPI cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter,
                                         REFIID riid, LPVOID *ppobj )
{
    cf *This = impl_from_IClassFactory( iface );
    HRESULT r;
    IUnknown *punk;

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

    *ppobj = NULL;

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

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

    return r;
}

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

static const struct IClassFactoryVtbl cf_vtbl =
{
    cf_QueryInterface,
    cf_AddRef,
    cf_Release,
    cf_CreateInstance,
    cf_LockServer
};

static cf mime_body_cf      = { { &cf_vtbl }, MimeBody_create };
static cf mime_allocator_cf = { { &cf_vtbl }, MimeAllocator_create };
static cf mime_message_cf   = { { &cf_vtbl }, MimeMessage_create };
static cf mime_security_cf  = { { &cf_vtbl }, MimeSecurity_create };
static cf virtual_stream_cf = { { &cf_vtbl }, VirtualStream_create };

/***********************************************************************
 *              DllGetClassObject (INETCOMM.@)
 */
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_ISMTPTransport))
        return SMTPTransportCF_Create(iid, ppv);

    if (IsEqualCLSID(rclsid, &CLSID_ISMTPTransport2))
        return SMTPTransportCF_Create(iid, ppv);

    if (IsEqualCLSID(rclsid, &CLSID_IIMAPTransport))
        return IMAPTransportCF_Create(iid, ppv);

    if (IsEqualCLSID(rclsid, &CLSID_IPOP3Transport))
        return POP3TransportCF_Create(iid, ppv);

    if ( IsEqualCLSID( rclsid, &CLSID_IMimeSecurity ))
    {
        cf = &mime_security_cf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_IMimeMessage ))
    {
        cf = &mime_message_cf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_IMimeBody ))
    {
        cf = &mime_body_cf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_IMimeAllocator ))
    {
        cf = &mime_allocator_cf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_IVirtualStream ))
    {
        cf = &virtual_stream_cf.IClassFactory_iface;
    }

    if ( !cf )
    {
        FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
        return CLASS_E_CLASSNOTAVAILABLE;
    }

    return IClassFactory_QueryInterface( cf, iid, ppv );
}

/***********************************************************************
 *              DllCanUnloadNow (INETCOMM.@)
 */
HRESULT WINAPI DllCanUnloadNow(void)
{
    return S_FALSE;
}

/***********************************************************************
 *		DllRegisterServer (INETCOMM.@)
 */
HRESULT WINAPI DllRegisterServer(void)
{
    return __wine_register_resources( instance );
}

/***********************************************************************
 *		DllUnregisterServer (INETCOMM.@)
 */
HRESULT WINAPI DllUnregisterServer(void)
{
    return __wine_unregister_resources( instance );
}
