/* IDirectMusicTool8 Implementation
 *
 * Copyright (C) 2003-2004 Rok Mandeljc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 Library General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "dmime_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(dmime);

/* IDirectMusicTool8Impl IUnknown part: */
HRESULT WINAPI IDirectMusicTool8Impl_QueryInterface (LPDIRECTMUSICTOOL8 iface, REFIID riid, LPVOID *ppobj) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
	TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
	if (IsEqualIID (riid, &IID_IUnknown) || 
	    IsEqualIID (riid, &IID_IDirectMusicTool) ||
	    IsEqualIID (riid, &IID_IDirectMusicTool8)) {
		IDirectMusicTool8Impl_AddRef(iface);
		*ppobj = This;
		return S_OK;
	}
	WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj);
	return E_NOINTERFACE;
}

ULONG WINAPI IDirectMusicTool8Impl_AddRef (LPDIRECTMUSICTOOL8 iface) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
        ULONG ref = InterlockedIncrement(&This->ref);

	TRACE("(%p) : AddRef from %ld\n", This, ref - 1);

	DMIME_LockModule();

	return ref;
}

ULONG WINAPI IDirectMusicTool8Impl_Release (LPDIRECTMUSICTOOL8 iface) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
	ULONG ref = InterlockedDecrement(&This->ref);
	TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
	
	if (ref == 0) {
		HeapFree(GetProcessHeap(), 0, This);
	}

	DMIME_UnlockModule();
	
	return ref;
}

/* IDirectMusicTool8Impl IDirectMusicTool part: */
HRESULT WINAPI IDirectMusicTool8Impl_Init (LPDIRECTMUSICTOOL8 iface, IDirectMusicGraph* pGraph) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
	FIXME("(%p, %p): stub\n", This, pGraph);
	return S_OK;
}

HRESULT WINAPI IDirectMusicTool8Impl_GetMsgDeliveryType (LPDIRECTMUSICTOOL8 iface, DWORD* pdwDeliveryType) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
	FIXME("(%p, %p): stub\n", This, pdwDeliveryType);
	return S_OK;
}

HRESULT WINAPI IDirectMusicTool8Impl_GetMediaTypeArraySize (LPDIRECTMUSICTOOL8 iface, DWORD* pdwNumElements) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
	FIXME("(%p, %p): stub\n", This, pdwNumElements);
	return S_OK;
}

HRESULT WINAPI IDirectMusicTool8Impl_GetMediaTypes (LPDIRECTMUSICTOOL8 iface, DWORD** padwMediaTypes, DWORD dwNumElements) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
	FIXME("(%p, %p, %ld): stub\n", This, padwMediaTypes, dwNumElements);
	return S_OK;
}

HRESULT WINAPI IDirectMusicTool8Impl_ProcessPMsg (LPDIRECTMUSICTOOL8 iface, IDirectMusicPerformance* pPerf, DMUS_PMSG* pPMSG) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
	FIXME("(%p, %p, %p): stub\n", This, pPerf, pPMSG);
	return S_OK;
}

HRESULT WINAPI IDirectMusicTool8Impl_Flush (LPDIRECTMUSICTOOL8 iface, IDirectMusicPerformance* pPerf, DMUS_PMSG* pPMSG, REFERENCE_TIME rtTime) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
	FIXME("(%p, %p, %p, %lli): stub\n", This, pPerf, pPMSG, rtTime);
	return S_OK;
}

/* IDirectMusicTool8Impl IDirectMusicTool8 part: */
HRESULT WINAPI IDirectMusicTool8Impl_Clone (LPDIRECTMUSICTOOL8 iface, IDirectMusicTool** ppTool) {
	IDirectMusicTool8Impl *This = (IDirectMusicTool8Impl *)iface;
	FIXME("(%p, %p): stub\n", This, ppTool);
	return S_OK;
}

IDirectMusicTool8Vtbl DirectMusicTool8_Vtbl = {
	IDirectMusicTool8Impl_QueryInterface,
	IDirectMusicTool8Impl_AddRef,
	IDirectMusicTool8Impl_Release,
	IDirectMusicTool8Impl_Init,
	IDirectMusicTool8Impl_GetMsgDeliveryType,
	IDirectMusicTool8Impl_GetMediaTypeArraySize,
	IDirectMusicTool8Impl_GetMediaTypes,
	IDirectMusicTool8Impl_ProcessPMsg,
	IDirectMusicTool8Impl_Flush,
	IDirectMusicTool8Impl_Clone
};

/* for ClassFactory */
HRESULT WINAPI DMUSIC_CreateDirectMusicobjImpl (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter) {
	IDirectMusicTool8Impl* obj;
	
	obj = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicTool8Impl));
	if (NULL == obj) {
		*ppobj = NULL;
		return E_OUTOFMEMORY;
	}
	obj->lpVtbl = &DirectMusicTool8_Vtbl;
	obj->ref = 0; /* will be inited by QueryInterface */
	
	return IDirectMusicTool8Impl_QueryInterface ((LPDIRECTMUSICTOOL8)obj, lpcGUID, ppobj);	
}
