/*
 * Copyright 2009 Vincent Povirk 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 "config.h"

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "objbase.h"
#include "wincodec.h"

#include "wincodecs_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);

typedef struct {
    const IWICImagingFactoryVtbl    *lpIWICImagingFactoryVtbl;
    LONG ref;
} ImagingFactory;

static HRESULT WINAPI ImagingFactory_QueryInterface(IWICImagingFactory *iface, REFIID iid,
    void **ppv)
{
    ImagingFactory *This = (ImagingFactory*)iface;
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICImagingFactory, iid))
    {
        *ppv = This;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory *iface)
{
    ImagingFactory *This = (ImagingFactory*)iface;
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory *iface)
{
    ImagingFactory *This = (ImagingFactory*)iface;
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

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

    return ref;
}

static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename(
    IWICImagingFactory *iface, LPCWSTR wzFilename, const GUID *pguidVendor,
    DWORD dwDesiredAccess, WICDecodeOptions metadataOptions,
    IWICBitmapDecoder **ppIDecoder)
{
    FIXME("(%p,%s,%s,%u,%u,%p): stub\n", iface, debugstr_w(wzFilename),
        debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
    IWICImagingFactory *iface, IStream *pIStream, const GUID *pguidVendor,
    WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
    static int fixme=0;
    IEnumUnknown *enumdecoders;
    IUnknown *unkdecoderinfo;
    IWICBitmapDecoderInfo *decoderinfo;
    IWICBitmapDecoder *decoder=NULL;
    HRESULT res=S_OK;
    ULONG num_fetched;
    BOOL matches;

    TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor),
        metadataOptions, ppIDecoder);

    if (pguidVendor && !fixme++)
        FIXME("ignoring vendor GUID\n");

    res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
    if (FAILED(res)) return res;

    while (!decoder)
    {
        res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);

        if (res == S_OK)
        {
            res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo);

            if (SUCCEEDED(res))
            {
                res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches);

                if (SUCCEEDED(res) && matches)
                {
                    res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder);

                    /* FIXME: should use QueryCapability to choose a decoder */

                    if (SUCCEEDED(res))
                    {
                        res = IWICBitmapDecoder_Initialize(decoder, pIStream, metadataOptions);

                        if (FAILED(res))
                        {
                            IWICBitmapDecoder_Release(decoder);
                            decoder = NULL;
                        }
                    }
                }

                IWICBitmapDecoderInfo_Release(decoderinfo);
            }

            IUnknown_Release(unkdecoderinfo);
        }
        else
            break;
    }

    IEnumUnknown_Release(enumdecoders);

    if (decoder)
    {
        *ppIDecoder = decoder;
        return S_OK;
    }
    else
    {
        if (WARN_ON(wincodecs))
        {
            LARGE_INTEGER seek;
            BYTE data[4];
            ULONG bytesread;

            WARN("failed to load from a stream\n");

            seek.QuadPart = 0;
            res = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
            if (SUCCEEDED(res))
                res = IStream_Read(pIStream, data, 4, &bytesread);
            if (SUCCEEDED(res))
                WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
        }
        *ppIDecoder = NULL;
        return WINCODEC_ERR_COMPONENTNOTFOUND;
    }
}

static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle(
    IWICImagingFactory *iface, ULONG_PTR hFile, const GUID *pguidVendor,
    WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
{
    FIXME("(%p,%lx,%s,%u,%p): stub\n", iface, hFile, debugstr_guid(pguidVendor),
        metadataOptions, ppIDecoder);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateComponentInfo(IWICImagingFactory *iface,
    REFCLSID clsidComponent, IWICComponentInfo **ppIInfo)
{
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(clsidComponent), ppIInfo);
    return CreateComponentInfo(clsidComponent, ppIInfo);
}

static HRESULT WINAPI ImagingFactory_CreateDecoder(IWICImagingFactory *iface,
    REFGUID guidContainerFormat, const GUID *pguidVendor,
    IWICBitmapDecoder **ppIDecoder)
{
    FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidContainerFormat),
        debugstr_guid(pguidVendor), ppIDecoder);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateEncoder(IWICImagingFactory *iface,
    REFGUID guidContainerFormat, const GUID *pguidVendor,
    IWICBitmapEncoder **ppIEncoder)
{
    FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidContainerFormat),
        debugstr_guid(pguidVendor), ppIEncoder);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreatePalette(IWICImagingFactory *iface,
    IWICPalette **ppIPalette)
{
    TRACE("(%p,%p)\n", iface, ppIPalette);
    return PaletteImpl_Create(ppIPalette);
}

static HRESULT WINAPI ImagingFactory_CreateFormatConverter(IWICImagingFactory *iface,
    IWICFormatConverter **ppIFormatConverter)
{
    FIXME("(%p,%p): stub\n", iface, ppIFormatConverter);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateBitmapScaler(IWICImagingFactory *iface,
    IWICBitmapScaler **ppIBitmapScaler)
{
    FIXME("(%p,%p): stub\n", iface, ppIBitmapScaler);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateBitmapClipper(IWICImagingFactory *iface,
    IWICBitmapClipper **ppIBitmapClipper)
{
    FIXME("(%p,%p): stub\n", iface, ppIBitmapClipper);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateBitmapFlipRotator(IWICImagingFactory *iface,
    IWICBitmapFlipRotator **ppIBitmapFlipRotator)
{
    FIXME("(%p,%p): stub\n", iface, ppIBitmapFlipRotator);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateStream(IWICImagingFactory *iface,
    IWICStream **ppIWICStream)
{
    TRACE("(%p,%p)\n", iface, ppIWICStream);
    return StreamImpl_Create(ppIWICStream);
}

static HRESULT WINAPI ImagingFactory_CreateColorContext(IWICImagingFactory *iface,
    IWICColorContext **ppIColorContext)
{
    FIXME("(%p,%p): stub\n", iface, ppIColorContext);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateColorTransformer(IWICImagingFactory *iface,
    IWICColorTransform **ppIColorTransform)
{
    FIXME("(%p,%p): stub\n", iface, ppIColorTransform);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateBitmap(IWICImagingFactory *iface,
    UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat,
    WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
{
    FIXME("(%p,%u,%u,%s,%u,%p): stub\n", iface, uiWidth, uiHeight,
        debugstr_guid(pixelFormat), option, ppIBitmap);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateBitmapFromSource(IWICImagingFactory *iface,
    IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option,
    IWICBitmap **ppIBitmap)
{
    FIXME("(%p,%p,%u,%p): stub\n", iface, piBitmapSource, option, ppIBitmap);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFactory *iface,
    IWICBitmapSource *piBitmapSource, UINT x, UINT y, UINT width, UINT height,
    IWICBitmap **ppIBitmap)
{
    FIXME("(%p,%p,%u,%u,%u,%u,%p): stub\n", iface, piBitmapSource, x, y, width,
        height, ppIBitmap);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory *iface,
    UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, UINT cbStride,
    UINT cbBufferSize, BYTE *pbBuffer, IWICBitmap **ppIBitmap)
{
    FIXME("(%p,%u,%u,%s,%u,%u,%p,%p): stub\n", iface, uiWidth, uiHeight,
        debugstr_guid(pixelFormat), cbStride, cbBufferSize, pbBuffer, ppIBitmap);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory *iface,
    HBITMAP hBitmap, HPALETTE hPalette, WICBitmapAlphaChannelOption options,
    IWICBitmap **ppIBitmap)
{
    FIXME("(%p,%p,%p,%u,%p): stub\n", iface, hBitmap, hPalette, options, ppIBitmap);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory *iface,
    HICON hIcon, IWICBitmap **ppIBitmap)
{
    FIXME("(%p,%p,%p): stub\n", iface, hIcon, ppIBitmap);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateComponentEnumerator(IWICImagingFactory *iface,
    DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
{
    TRACE("(%p,%u,%u,%p)\n", iface, componentTypes, options, ppIEnumUnknown);
    return CreateComponentEnumerator(componentTypes, options, ppIEnumUnknown);
}

static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromDecoder(
    IWICImagingFactory *iface, IWICBitmapDecoder *pIDecoder,
    IWICFastMetadataEncoder **ppIFastEncoder)
{
    FIXME("(%p,%p,%p): stub\n", iface, pIDecoder, ppIFastEncoder);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromFrameDecode(
    IWICImagingFactory *iface, IWICBitmapFrameDecode *pIFrameDecoder,
    IWICFastMetadataEncoder **ppIFastEncoder)
{
    FIXME("(%p,%p,%p): stub\n", iface, pIFrameDecoder, ppIFastEncoder);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateQueryWriter(IWICImagingFactory *iface,
    REFGUID guidMetadataFormat, const GUID *pguidVendor,
    IWICMetadataQueryWriter **ppIQueryWriter)
{
    FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidMetadataFormat),
        debugstr_guid(pguidVendor), ppIQueryWriter);
    return E_NOTIMPL;
}

static HRESULT WINAPI ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory *iface,
    IWICMetadataQueryReader *pIQueryReader, const GUID *pguidVendor,
    IWICMetadataQueryWriter **ppIQueryWriter)
{
    FIXME("(%p,%p,%s,%p): stub\n", iface, pIQueryReader, debugstr_guid(pguidVendor),
        ppIQueryWriter);
    return E_NOTIMPL;
}

static const IWICImagingFactoryVtbl ImagingFactory_Vtbl = {
    ImagingFactory_QueryInterface,
    ImagingFactory_AddRef,
    ImagingFactory_Release,
    ImagingFactory_CreateDecoderFromFilename,
    ImagingFactory_CreateDecoderFromStream,
    ImagingFactory_CreateDecoderFromFileHandle,
    ImagingFactory_CreateComponentInfo,
    ImagingFactory_CreateDecoder,
    ImagingFactory_CreateEncoder,
    ImagingFactory_CreatePalette,
    ImagingFactory_CreateFormatConverter,
    ImagingFactory_CreateBitmapScaler,
    ImagingFactory_CreateBitmapClipper,
    ImagingFactory_CreateBitmapFlipRotator,
    ImagingFactory_CreateStream,
    ImagingFactory_CreateColorContext,
    ImagingFactory_CreateColorTransformer,
    ImagingFactory_CreateBitmap,
    ImagingFactory_CreateBitmapFromSource,
    ImagingFactory_CreateBitmapFromSourceRect,
    ImagingFactory_CreateBitmapFromMemory,
    ImagingFactory_CreateBitmapFromHBITMAP,
    ImagingFactory_CreateBitmapFromHICON,
    ImagingFactory_CreateComponentEnumerator,
    ImagingFactory_CreateFastMetadataEncoderFromDecoder,
    ImagingFactory_CreateFastMetadataEncoderFromFrameDecode,
    ImagingFactory_CreateQueryWriter,
    ImagingFactory_CreateQueryWriterFromReader
};

HRESULT ImagingFactory_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
    ImagingFactory *This;
    HRESULT ret;

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

    *ppv = NULL;

    if (pUnkOuter) return CLASS_E_NOAGGREGATION;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(ImagingFactory));
    if (!This) return E_OUTOFMEMORY;

    This->lpIWICImagingFactoryVtbl = &ImagingFactory_Vtbl;
    This->ref = 1;

    ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
    IUnknown_Release((IUnknown*)This);

    return ret;
}
