/*
 * 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 "wingdi.h"
#include "objbase.h"
#include "wincodec.h"

#include "wincodecs_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);

struct bmp_pixelformat {
    const WICPixelFormatGUID *guid;
    UINT bpp;
    DWORD compression;
    DWORD redmask;
    DWORD greenmask;
    DWORD bluemask;
    DWORD alphamask;
};

static const struct bmp_pixelformat formats[] = {
    {&GUID_WICPixelFormat24bppBGR, 24, BI_RGB},
    {&GUID_WICPixelFormat16bppBGR555, 16, BI_RGB},
    {&GUID_WICPixelFormat16bppBGR565, 16, BI_BITFIELDS, 0xf800, 0x7e0, 0x1f, 0},
    {&GUID_WICPixelFormat32bppBGR, 32, BI_RGB},
#if 0
    /* Windows doesn't seem to support this one. */
    {&GUID_WICPixelFormat32bppBGRA, 32, BI_BITFIELDS, 0xff0000, 0xff00, 0xff, 0xff000000},
#endif
    {NULL}
};

typedef struct BmpFrameEncode {
    IWICBitmapFrameEncode IWICBitmapFrameEncode_iface;
    LONG ref;
    IStream *stream;
    BOOL initialized;
    UINT width, height;
    BYTE *bits;
    const struct bmp_pixelformat *format;
    double xres, yres;
    UINT lineswritten;
    UINT stride;
    BOOL committed;
} BmpFrameEncode;

static inline BmpFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface)
{
    return CONTAINING_RECORD(iface, BmpFrameEncode, IWICBitmapFrameEncode_iface);
}

static HRESULT WINAPI BmpFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid,
    void **ppv)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

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

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

static ULONG WINAPI BmpFrameEncode_AddRef(IWICBitmapFrameEncode *iface)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI BmpFrameEncode_Release(IWICBitmapFrameEncode *iface)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (ref == 0)
    {
        if (This->stream) IStream_Release(This->stream);
        HeapFree(GetProcessHeap(), 0, This->bits);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI BmpFrameEncode_Initialize(IWICBitmapFrameEncode *iface,
    IPropertyBag2 *pIEncoderOptions)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    TRACE("(%p,%p)\n", iface, pIEncoderOptions);

    if (This->initialized) return WINCODEC_ERR_WRONGSTATE;

    This->initialized = TRUE;

    return S_OK;
}

static HRESULT WINAPI BmpFrameEncode_SetSize(IWICBitmapFrameEncode *iface,
    UINT uiWidth, UINT uiHeight)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight);

    if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE;

    This->width = uiWidth;
    This->height = uiHeight;

    return S_OK;
}

static HRESULT WINAPI BmpFrameEncode_SetResolution(IWICBitmapFrameEncode *iface,
    double dpiX, double dpiY)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY);

    if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE;

    This->xres = dpiX;
    This->yres = dpiY;

    return S_OK;
}

static HRESULT WINAPI BmpFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface,
    WICPixelFormatGUID *pPixelFormat)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    int i;
    TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat));

    if (!This->initialized || This->bits) return WINCODEC_ERR_WRONGSTATE;

    for (i=0; formats[i].guid; i++)
    {
        if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0)
            break;
    }

    if (!formats[i].guid) i = 0;

    This->format = &formats[i];
    memcpy(pPixelFormat, This->format->guid, sizeof(GUID));

    return S_OK;
}

static HRESULT WINAPI BmpFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface,
    UINT cCount, IWICColorContext **ppIColorContext)
{
    FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
    return E_NOTIMPL;
}

static HRESULT WINAPI BmpFrameEncode_SetPalette(IWICBitmapFrameEncode *iface,
    IWICPalette *pIPalette)
{
    FIXME("(%p,%p): stub\n", iface, pIPalette);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI BmpFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface,
    IWICBitmapSource *pIThumbnail)
{
    FIXME("(%p,%p): stub\n", iface, pIThumbnail);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT BmpFrameEncode_AllocateBits(BmpFrameEncode *This)
{
    if (!This->bits)
    {
        if (!This->initialized || !This->width || !This->height || !This->format)
            return WINCODEC_ERR_WRONGSTATE;

        This->stride = (((This->width * This->format->bpp)+31)/32)*4;
        This->bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->stride * This->height);
        if (!This->bits) return E_OUTOFMEMORY;
    }

    return S_OK;
}

static HRESULT WINAPI BmpFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
    UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    HRESULT hr;
    WICRect rc;
    TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels);

    if (!This->initialized || !This->width || !This->height || !This->format)
        return WINCODEC_ERR_WRONGSTATE;

    hr = BmpFrameEncode_AllocateBits(This);
    if (FAILED(hr)) return hr;

    rc.X = 0;
    rc.Y = 0;
    rc.Width = This->width;
    rc.Height = lineCount;

    hr = copy_pixels(This->format->bpp, pbPixels, This->width, lineCount, cbStride,
        &rc, This->stride, This->stride*(This->height-This->lineswritten),
        This->bits + This->stride*This->lineswritten);

    if (SUCCEEDED(hr))
        This->lineswritten += lineCount;

    return hr;
}

static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface,
    IWICBitmapSource *pIBitmapSource, WICRect *prc)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    HRESULT hr;
    WICRect rc;
    WICPixelFormatGUID guid;
    TRACE("(%p,%p,%p)\n", iface, pIBitmapSource, prc);

    if (!This->initialized || !This->width || !This->height)
        return WINCODEC_ERR_WRONGSTATE;

    if (!This->format)
    {
        hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
        if (FAILED(hr)) return hr;
        hr = BmpFrameEncode_SetPixelFormat(iface, &guid);
        if (FAILED(hr)) return hr;
    }

    hr = IWICBitmapSource_GetPixelFormat(pIBitmapSource, &guid);
    if (FAILED(hr)) return hr;
    if (memcmp(&guid, This->format->guid, sizeof(GUID)) != 0)
    {
        /* should use WICConvertBitmapSource to convert, but that's unimplemented */
        ERR("format %s unsupported\n", debugstr_guid(&guid));
        return E_FAIL;
    }

    if (This->xres == 0.0 || This->yres == 0.0)
    {
        double xres, yres;
        hr = IWICBitmapSource_GetResolution(pIBitmapSource, &xres, &yres);
        if (FAILED(hr)) return hr;
        hr = BmpFrameEncode_SetResolution(iface, xres, yres);
        if (FAILED(hr)) return hr;
    }

    if (!prc)
    {
        UINT width, height;
        hr = IWICBitmapSource_GetSize(pIBitmapSource, &width, &height);
        if (FAILED(hr)) return hr;
        rc.X = 0;
        rc.Y = 0;
        rc.Width = width;
        rc.Height = height;
        prc = &rc;
    }

    if (prc->Width != This->width) return E_INVALIDARG;

    hr = BmpFrameEncode_AllocateBits(This);
    if (FAILED(hr)) return hr;

    hr = IWICBitmapSource_CopyPixels(pIBitmapSource, prc, This->stride,
        This->stride*(This->height-This->lineswritten),
        This->bits + This->stride*This->lineswritten);

    This->lineswritten += rc.Height;

    return S_OK;
}

static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface)
{
    BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface);
    BITMAPFILEHEADER bfh;
    BITMAPV5HEADER bih;
    UINT info_size;
    LARGE_INTEGER pos;
    ULONG byteswritten;
    HRESULT hr;

    TRACE("(%p)\n", iface);

    if (!This->bits || This->committed || This->height != This->lineswritten)
        return WINCODEC_ERR_WRONGSTATE;

    bfh.bfType = 0x4d42; /* "BM" */
    bfh.bfReserved1 = 0;
    bfh.bfReserved2 = 0;

    bih.bV5Size = info_size = sizeof(BITMAPINFOHEADER);
    bih.bV5Width = This->width;
    bih.bV5Height = -This->height; /* top-down bitmap */
    bih.bV5Planes = 1;
    bih.bV5BitCount = This->format->bpp;
    bih.bV5Compression = This->format->compression;
    bih.bV5SizeImage = This->stride*This->height;
    bih.bV5XPelsPerMeter = (This->xres+0.0127) / 0.0254;
    bih.bV5YPelsPerMeter = (This->yres+0.0127) / 0.0254;
    bih.bV5ClrUsed = 0;
    bih.bV5ClrImportant = 0;

    if (This->format->compression == BI_BITFIELDS)
    {
        if (This->format->alphamask)
            bih.bV5Size = info_size = sizeof(BITMAPV4HEADER);
        else
            info_size = sizeof(BITMAPINFOHEADER)+12;
        bih.bV5RedMask = This->format->redmask;
        bih.bV5GreenMask = This->format->greenmask;
        bih.bV5BlueMask = This->format->bluemask;
        bih.bV5AlphaMask = This->format->alphamask;
        bih.bV5AlphaMask = LCS_DEVICE_RGB;
    }

    bfh.bfSize = sizeof(BITMAPFILEHEADER) + info_size + bih.bV5SizeImage;
    bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + info_size;

    pos.QuadPart = 0;
    hr = IStream_Seek(This->stream, pos, STREAM_SEEK_SET, NULL);
    if (FAILED(hr)) return hr;

    hr = IStream_Write(This->stream, &bfh, sizeof(BITMAPFILEHEADER), &byteswritten);
    if (FAILED(hr)) return hr;
    if (byteswritten != sizeof(BITMAPFILEHEADER)) return E_FAIL;

    hr = IStream_Write(This->stream, &bih, info_size, &byteswritten);
    if (FAILED(hr)) return hr;
    if (byteswritten != info_size) return E_FAIL;

    hr = IStream_Write(This->stream, This->bits, bih.bV5SizeImage, &byteswritten);
    if (FAILED(hr)) return hr;
    if (byteswritten != bih.bV5SizeImage) return E_FAIL;

    This->committed = TRUE;

    return S_OK;
}

static HRESULT WINAPI BmpFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface,
    IWICMetadataQueryWriter **ppIMetadataQueryWriter)
{
    FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter);
    return E_NOTIMPL;
}

static const IWICBitmapFrameEncodeVtbl BmpFrameEncode_Vtbl = {
    BmpFrameEncode_QueryInterface,
    BmpFrameEncode_AddRef,
    BmpFrameEncode_Release,
    BmpFrameEncode_Initialize,
    BmpFrameEncode_SetSize,
    BmpFrameEncode_SetResolution,
    BmpFrameEncode_SetPixelFormat,
    BmpFrameEncode_SetColorContexts,
    BmpFrameEncode_SetPalette,
    BmpFrameEncode_SetThumbnail,
    BmpFrameEncode_WritePixels,
    BmpFrameEncode_WriteSource,
    BmpFrameEncode_Commit,
    BmpFrameEncode_GetMetadataQueryWriter
};

typedef struct BmpEncoder {
    IWICBitmapEncoder IWICBitmapEncoder_iface;
    LONG ref;
    IStream *stream;
    BmpFrameEncode *frame;
} BmpEncoder;

static inline BmpEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface)
{
    return CONTAINING_RECORD(iface, BmpEncoder, IWICBitmapEncoder_iface);
}

static HRESULT WINAPI BmpEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid,
    void **ppv)
{
    BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

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

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

static ULONG WINAPI BmpEncoder_AddRef(IWICBitmapEncoder *iface)
{
    BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI BmpEncoder_Release(IWICBitmapEncoder *iface)
{
    BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (ref == 0)
    {
        if (This->stream) IStream_Release(This->stream);
        if (This->frame) IWICBitmapFrameEncode_Release(&This->frame->IWICBitmapFrameEncode_iface);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI BmpEncoder_Initialize(IWICBitmapEncoder *iface,
    IStream *pIStream, WICBitmapEncoderCacheOption cacheOption)
{
    BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);

    TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption);

    IStream_AddRef(pIStream);
    This->stream = pIStream;

    return S_OK;
}

static HRESULT WINAPI BmpEncoder_GetContainerFormat(IWICBitmapEncoder *iface,
    GUID *pguidContainerFormat)
{
    FIXME("(%p,%s): stub\n", iface, debugstr_guid(pguidContainerFormat));
    return E_NOTIMPL;
}

static HRESULT WINAPI BmpEncoder_GetEncoderInfo(IWICBitmapEncoder *iface,
    IWICBitmapEncoderInfo **ppIEncoderInfo)
{
    FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI BmpEncoder_SetColorContexts(IWICBitmapEncoder *iface,
    UINT cCount, IWICColorContext **ppIColorContext)
{
    FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext);
    return E_NOTIMPL;
}

static HRESULT WINAPI BmpEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette)
{
    TRACE("(%p,%p)\n", iface, pIPalette);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI BmpEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail)
{
    TRACE("(%p,%p)\n", iface, pIThumbnail);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI BmpEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview)
{
    TRACE("(%p,%p)\n", iface, pIPreview);
    return WINCODEC_ERR_UNSUPPORTEDOPERATION;
}

static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface,
    IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions)
{
    BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
    BmpFrameEncode *encode;
    HRESULT hr;

    TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions);

    if (This->frame) return WINCODEC_ERR_UNSUPPORTEDOPERATION;

    if (!This->stream) return WINCODEC_ERR_NOTINITIALIZED;

    hr = CreatePropertyBag2(ppIEncoderOptions);
    if (FAILED(hr)) return hr;

    encode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameEncode));
    if (!encode)
    {
        IPropertyBag2_Release(*ppIEncoderOptions);
        *ppIEncoderOptions = NULL;
        return E_OUTOFMEMORY;
    }
    encode->IWICBitmapFrameEncode_iface.lpVtbl = &BmpFrameEncode_Vtbl;
    encode->ref = 2;
    IStream_AddRef(This->stream);
    encode->stream = This->stream;
    encode->initialized = FALSE;
    encode->width = 0;
    encode->height = 0;
    encode->bits = NULL;
    encode->format = NULL;
    encode->xres = 0.0;
    encode->yres = 0.0;
    encode->lineswritten = 0;
    encode->committed = FALSE;

    *ppIFrameEncode = &encode->IWICBitmapFrameEncode_iface;
    This->frame = encode;

    return S_OK;
}

static HRESULT WINAPI BmpEncoder_Commit(IWICBitmapEncoder *iface)
{
    BmpEncoder *This = impl_from_IWICBitmapEncoder(iface);
    TRACE("(%p)\n", iface);

    if (!This->frame || !This->frame->committed) return WINCODEC_ERR_WRONGSTATE;

    return S_OK;
}

static HRESULT WINAPI BmpEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface,
    IWICMetadataQueryWriter **ppIMetadataQueryWriter)
{
    FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter);
    return E_NOTIMPL;
}

static const IWICBitmapEncoderVtbl BmpEncoder_Vtbl = {
    BmpEncoder_QueryInterface,
    BmpEncoder_AddRef,
    BmpEncoder_Release,
    BmpEncoder_Initialize,
    BmpEncoder_GetContainerFormat,
    BmpEncoder_GetEncoderInfo,
    BmpEncoder_SetColorContexts,
    BmpEncoder_SetPalette,
    BmpEncoder_SetThumbnail,
    BmpEncoder_SetPreview,
    BmpEncoder_CreateNewFrame,
    BmpEncoder_Commit,
    BmpEncoder_GetMetadataQueryWriter
};

HRESULT BmpEncoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
    BmpEncoder *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(BmpEncoder));
    if (!This) return E_OUTOFMEMORY;

    This->IWICBitmapEncoder_iface.lpVtbl = &BmpEncoder_Vtbl;
    This->ref = 1;
    This->stream = NULL;
    This->frame = NULL;

    ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv);
    IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface);

    return ret;
}
