/*
 * Implementation of IAudioData Interface
 *
 * Copyright 2012 Christian Costa
 *
 * 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 "wine/debug.h"

#define COBJMACROS

#include "winbase.h"
#include "amstream_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(amstream);

typedef struct {
    IAudioData IAudioData_iface;
    LONG ref;
    DWORD size;
    BYTE *data;
    BOOL data_owned;
    DWORD actual_data;
    WAVEFORMATEX wave_format;
} AMAudioDataImpl;

static inline AMAudioDataImpl *impl_from_IAudioData(IAudioData *iface)
{
    return CONTAINING_RECORD(iface, AMAudioDataImpl, IAudioData_iface);
}

/*** IUnknown methods ***/
static HRESULT WINAPI IAudioDataImpl_QueryInterface(IAudioData *iface, REFIID riid, void **ret_iface)
{
    TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ret_iface);

    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IAudioData))
    {
        IAudioData_AddRef(iface);
        *ret_iface = iface;
        return S_OK;
    }

    ERR("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ret_iface);
    return E_NOINTERFACE;
}

static ULONG WINAPI IAudioDataImpl_AddRef(IAudioData* iface)
{
    AMAudioDataImpl *This = impl_from_IAudioData(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(): new ref = %u\n", iface, This->ref);

    return ref;
}

static ULONG WINAPI IAudioDataImpl_Release(IAudioData* iface)
{
    AMAudioDataImpl *This = impl_from_IAudioData(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(): new ref = %u\n", iface, This->ref);

    if (!ref)
    {
        if (This->data_owned)
        {
            CoTaskMemFree(This->data);
        }

        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

/*** IMemoryData methods ***/
static HRESULT WINAPI IAudioDataImpl_SetBuffer(IAudioData* iface, DWORD size, BYTE *data, DWORD flags)
{
    AMAudioDataImpl *This = impl_from_IAudioData(iface);

    TRACE("(%p)->(%u,%p,%x)\n", iface, size, data, flags);

    if (!size)
    {
        return E_INVALIDARG;
    }

    if (This->data_owned)
    {
        CoTaskMemFree(This->data);
        This->data_owned = FALSE;
    }

    This->size = size;
    This->data = data;

    if (!This->data)
    {
        This->data = CoTaskMemAlloc(This->size);
        This->data_owned = TRUE;
        if (!This->data)
        {
            return E_OUTOFMEMORY;
        }
    }

    return S_OK;
}

static HRESULT WINAPI IAudioDataImpl_GetInfo(IAudioData* iface, DWORD *length, BYTE **data, DWORD *actual_data)
{
    AMAudioDataImpl *This = impl_from_IAudioData(iface);

    TRACE("(%p)->(%p,%p,%p)\n", iface, length, data, actual_data);

    if (!This->data)
    {
        return MS_E_NOTINIT;
    }

    if (length)
    {
        *length = This->size;
    }
    if (data)
    {
        *data = This->data;
    }
    if (actual_data)
    {
        *actual_data = This->actual_data;
    }

    return S_OK;
}

static HRESULT WINAPI IAudioDataImpl_SetActual(IAudioData* iface, DWORD data_valid)
{
    AMAudioDataImpl *This = impl_from_IAudioData(iface);

    TRACE("(%p)->(%u)\n", iface, data_valid);

    if (data_valid > This->size)
    {
        return E_INVALIDARG;
    }

    This->actual_data = data_valid;

    return S_OK;
}

/*** IAudioData methods ***/
static HRESULT WINAPI IAudioDataImpl_GetFormat(IAudioData* iface, WAVEFORMATEX *wave_format_current)
{
    AMAudioDataImpl *This = impl_from_IAudioData(iface);

    TRACE("(%p)->(%p)\n", iface, wave_format_current);

    if (!wave_format_current)
    {
        return E_POINTER;
    }

    *wave_format_current = This->wave_format;

    return S_OK;
}

static HRESULT WINAPI IAudioDataImpl_SetFormat(IAudioData* iface, const WAVEFORMATEX *wave_format)
{
    AMAudioDataImpl *This = impl_from_IAudioData(iface);

    TRACE("(%p)->(%p)\n", iface, wave_format);

    if (!wave_format)
    {
        return E_POINTER;
    }

    if (WAVE_FORMAT_PCM != wave_format->wFormatTag)
    {
        return E_INVALIDARG;
    }

    This->wave_format = *wave_format;

    return S_OK;
}

static const struct IAudioDataVtbl AudioData_Vtbl =
{
    /*** IUnknown methods ***/
    IAudioDataImpl_QueryInterface,
    IAudioDataImpl_AddRef,
    IAudioDataImpl_Release,
    /*** IMemoryData methods ***/
    IAudioDataImpl_SetBuffer,
    IAudioDataImpl_GetInfo,
    IAudioDataImpl_SetActual,
    /*** IAudioData methods ***/
    IAudioDataImpl_GetFormat,
    IAudioDataImpl_SetFormat
};

HRESULT AMAudioData_create(IUnknown *pUnkOuter, LPVOID *ppObj)
{
    AMAudioDataImpl *object;

    TRACE("(%p,%p)\n", pUnkOuter, ppObj);

    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AMAudioDataImpl));
    if (!object)
        return E_OUTOFMEMORY;

    object->IAudioData_iface.lpVtbl = &AudioData_Vtbl;
    object->ref = 1;

    object->wave_format.wFormatTag = WAVE_FORMAT_PCM;
    object->wave_format.nChannels = 1;
    object->wave_format.nSamplesPerSec = 11025;
    object->wave_format.wBitsPerSample = 16;
    object->wave_format.nBlockAlign = object->wave_format.wBitsPerSample * object->wave_format.nChannels / 8;
    object->wave_format.nAvgBytesPerSec = object->wave_format.nBlockAlign * object->wave_format.nSamplesPerSec;

    *ppObj = &object->IAudioData_iface;

    return S_OK;
}
