/*
 * IDirectMusicSynthSink Implementation
 *
 * Copyright (C) 2003-2004 Rok Mandeljc
 * Copyright (C) 2012 Christian Costa
 *
 * This program 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 program 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 program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "dmsynth_private.h"
#include "initguid.h"
#include "uuids.h"

WINE_DEFAULT_DEBUG_CHANNEL(dmsynth);

static inline IDirectMusicSynthSinkImpl *impl_from_IDirectMusicSynthSink(IDirectMusicSynthSink *iface)
{
    return CONTAINING_RECORD(iface, IDirectMusicSynthSinkImpl, IDirectMusicSynthSink_iface);
}

/* IDirectMusicSynthSinkImpl IUnknown part: */
static HRESULT WINAPI IDirectMusicSynthSinkImpl_QueryInterface(LPDIRECTMUSICSYNTHSINK iface, REFIID riid, LPVOID *ret_iface)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_dmguid(riid), ret_iface);

    if (IsEqualIID (riid, &IID_IUnknown) ||
        IsEqualIID (riid, &IID_IDirectMusicSynthSink))
    {
        IUnknown_AddRef(iface);
        *ret_iface = iface;
        return S_OK;
    }
    else if (IsEqualIID(riid, &IID_IKsControl))
    {
        IUnknown_AddRef(iface);
        *ret_iface = &This->IKsControl_iface;
        return S_OK;
    }

    *ret_iface = NULL;

    WARN("(%p)->(%s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface);

    return E_NOINTERFACE;
}

static ULONG WINAPI IDirectMusicSynthSinkImpl_AddRef(LPDIRECTMUSICSYNTHSINK iface)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    DMSYNTH_LockModule();

    return ref;
}

static ULONG WINAPI IDirectMusicSynthSinkImpl_Release(LPDIRECTMUSICSYNTHSINK iface)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (!ref) {
        if (This->latency_clock)
            IReferenceClock_Release(This->latency_clock);
        HeapFree(GetProcessHeap(), 0, This);
    }

    DMSYNTH_UnlockModule();

    return ref;
}

/* IDirectMusicSynthSinkImpl IDirectMusicSynthSink part: */
static HRESULT WINAPI IDirectMusicSynthSinkImpl_Init(LPDIRECTMUSICSYNTHSINK iface, IDirectMusicSynth* synth)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);

    FIXME("(%p)->(%p): stub\n", This, synth);

    return S_OK;
}

static HRESULT WINAPI IDirectMusicSynthSinkImpl_SetMasterClock(LPDIRECTMUSICSYNTHSINK iface, IReferenceClock* clock)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);

    FIXME("(%p)->(%p): stub\n", This, clock);

    return S_OK;
}

static HRESULT WINAPI IDirectMusicSynthSinkImpl_GetLatencyClock(LPDIRECTMUSICSYNTHSINK iface, IReferenceClock** clock)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);

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

    if (!clock)
        return E_POINTER;

    *clock = This->latency_clock;
    IReferenceClock_AddRef(This->latency_clock);

    return S_OK;
}

static HRESULT WINAPI IDirectMusicSynthSinkImpl_Activate(LPDIRECTMUSICSYNTHSINK iface, BOOL enable)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);

    FIXME("(%p)->(%d): stub\n", This, enable);

    return S_OK;
}

static HRESULT WINAPI IDirectMusicSynthSinkImpl_SampleToRefTime(LPDIRECTMUSICSYNTHSINK iface, LONGLONG sample_time, REFERENCE_TIME* ref_time)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);

    FIXME("(%p)->(0x%s, %p): stub\n", This, wine_dbgstr_longlong(sample_time), ref_time);

    return S_OK;
}

static HRESULT WINAPI IDirectMusicSynthSinkImpl_RefTimeToSample(LPDIRECTMUSICSYNTHSINK iface, REFERENCE_TIME ref_time, LONGLONG* sample_time)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);

    FIXME("(%p)->(0x%s, %p): stub\n", This, wine_dbgstr_longlong(ref_time), sample_time);

    return S_OK;
}

static HRESULT WINAPI IDirectMusicSynthSinkImpl_SetDirectSound(LPDIRECTMUSICSYNTHSINK iface, LPDIRECTSOUND dsound, LPDIRECTSOUNDBUFFER dsound_buffer)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);

    FIXME("(%p)->(%p, %p): stub\n", This, dsound, dsound_buffer);

    return S_OK;
}

static HRESULT WINAPI IDirectMusicSynthSinkImpl_GetDesiredBufferSize(LPDIRECTMUSICSYNTHSINK iface, LPDWORD buffer_size_in_samples)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IDirectMusicSynthSink(iface);

    FIXME("(%p)->(%p): stub\n", This, buffer_size_in_samples);

    return S_OK;
}

static const IDirectMusicSynthSinkVtbl DirectMusicSynthSink_Vtbl = {
	IDirectMusicSynthSinkImpl_QueryInterface,
	IDirectMusicSynthSinkImpl_AddRef,
	IDirectMusicSynthSinkImpl_Release,
	IDirectMusicSynthSinkImpl_Init,
	IDirectMusicSynthSinkImpl_SetMasterClock,
	IDirectMusicSynthSinkImpl_GetLatencyClock,
	IDirectMusicSynthSinkImpl_Activate,
	IDirectMusicSynthSinkImpl_SampleToRefTime,
	IDirectMusicSynthSinkImpl_RefTimeToSample,
	IDirectMusicSynthSinkImpl_SetDirectSound,
	IDirectMusicSynthSinkImpl_GetDesiredBufferSize
};

static inline IDirectMusicSynthSinkImpl *impl_from_IKsControl(IKsControl *iface)
{
    return CONTAINING_RECORD(iface, IDirectMusicSynthSinkImpl, IKsControl_iface);
}

static HRESULT WINAPI DMSynthSinkImpl_IKsControl_QueryInterface(IKsControl* iface, REFIID riid, LPVOID *ppobj)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IKsControl(iface);

    return IDirectMusicSynthSinkImpl_QueryInterface(&This->IDirectMusicSynthSink_iface, riid, ppobj);
}

static ULONG WINAPI DMSynthSinkImpl_IKsControl_AddRef(IKsControl* iface)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IKsControl(iface);

    return IDirectMusicSynthSinkImpl_AddRef(&This->IDirectMusicSynthSink_iface);
}

static ULONG WINAPI DMSynthSinkImpl_IKsControl_Release(IKsControl* iface)
{
    IDirectMusicSynthSinkImpl *This = impl_from_IKsControl(iface);

    return IDirectMusicSynthSinkImpl_Release(&This->IDirectMusicSynthSink_iface);
}

static HRESULT WINAPI DMSynthSinkImpl_IKsControl_KsProperty(IKsControl* iface, PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData,
                                                            ULONG DataLength, ULONG* BytesReturned)
{
    TRACE("(%p)->(%p, %u, %p, %u, %p)\n", iface, Property, PropertyLength, PropertyData, DataLength, BytesReturned);

    TRACE("Property = %s - %u - %u\n", debugstr_guid(&Property->u.s.Set), Property->u.s.Id, Property->u.s.Flags);

    if (Property->u.s.Flags != KSPROPERTY_TYPE_GET)
    {
        FIXME("Property flags %u not yet supported\n", Property->u.s.Flags);
        return S_FALSE;
    }

    if (DataLength <  sizeof(DWORD))
        return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);

    if (IsEqualGUID(&Property->u.s.Set, &GUID_DMUS_PROP_SinkUsesDSound))
    {
        *(DWORD*)PropertyData = TRUE;
        *BytesReturned = sizeof(DWORD);
    }
    else
    {
        FIXME("Unknown property %s\n", debugstr_guid(&Property->u.s.Set));
        *(DWORD*)PropertyData = FALSE;
        *BytesReturned = sizeof(DWORD);
    }

    return S_OK;
}

static HRESULT WINAPI DMSynthSinkImpl_IKsControl_KsMethod(IKsControl* iface, PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData,
                                                          ULONG DataLength, ULONG* BytesReturned)
{
    FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface, Method, MethodLength, MethodData, DataLength, BytesReturned);

    return E_NOTIMPL;
}

static HRESULT WINAPI DMSynthSinkImpl_IKsControl_KsEvent(IKsControl* iface, PKSEVENT Event, ULONG EventLength, LPVOID EventData,
                                                         ULONG DataLength, ULONG* BytesReturned)
{
    FIXME("(%p)->(%p, %u, %p, %u, %p): stub\n", iface, Event, EventLength, EventData, DataLength, BytesReturned);

    return E_NOTIMPL;
}


static const IKsControlVtbl DMSynthSinkImpl_IKsControl_Vtbl = {
    DMSynthSinkImpl_IKsControl_QueryInterface,
    DMSynthSinkImpl_IKsControl_AddRef,
    DMSynthSinkImpl_IKsControl_Release,
    DMSynthSinkImpl_IKsControl_KsProperty,
    DMSynthSinkImpl_IKsControl_KsMethod,
    DMSynthSinkImpl_IKsControl_KsEvent
};

/* for ClassFactory */
HRESULT WINAPI DMUSIC_CreateDirectMusicSynthSinkImpl(LPCGUID riid, LPVOID* ret_iface, LPUNKNOWN unkouter)
{
    IDirectMusicSynthSinkImpl *obj;
    HRESULT hr;

    TRACE("(%p,%p,%p)\n", riid, ret_iface, unkouter);

    *ret_iface = NULL;

    obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicSynthSinkImpl));
    if (!obj)
        return E_OUTOFMEMORY;

    obj->IDirectMusicSynthSink_iface.lpVtbl = &DirectMusicSynthSink_Vtbl;
    obj->IKsControl_iface.lpVtbl = &DMSynthSinkImpl_IKsControl_Vtbl;
    obj->ref = 0;

    hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (LPVOID*)&obj->latency_clock);
    if (FAILED(hr))
    {
        HeapFree(GetProcessHeap(), 0, obj);
        return hr;
    }

    hr = IDirectMusicSynthSinkImpl_QueryInterface((LPDIRECTMUSICSYNTHSINK)obj, riid, ret_iface);
    if (FAILED(hr))
    {
        IReferenceClock_Release(obj->latency_clock);
        HeapFree(GetProcessHeap(), 0, obj);
        return hr;
    }

    return S_OK;
}
