/*
 * imaadp32.drv - IMA4 codec driver
 *
 * Copyright 2001 Hidenori Takeshima
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 * FIXME - no encoding.
 */

#include "config.h"

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winnls.h"
#include "winuser.h"
#include "mmsystem.h"
#include "msacm.h"
#include "../msacmdrv.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(imaadp32);

/***********************************************************************/

enum CodecType
{
	CodecType_Invalid,
	CodecType_EncIMAADPCM,
	CodecType_DecIMAADPCM,
};

typedef struct CodecImpl
{
	int	dummy;
} CodecImpl;

/***********************************************************************/


static const int ima_step[88+1] =
{
	/* from Y.Ajima's WAVFMT.TXT */
	    7,     8,     9,    10,    11,    12,    13,    14,
	   16,    17,    19,    21,    23,    25,    28,    31,
	   34,    37,    41,    45,    50,    55,    60,    66,
	   73,    80,    88,    97,   107,   118,   130,   143,
	  157,   173,   190,   209,   230,   253,   279,   307,
	  337,   371,   408,   449,   494,   544,   598,   658,
	  724,   796,   876,   963,  1060,  1166,  1282,  1411,
	 1552,  1707,  1878,  2066,  2272,  2499,  2749,  3024,
	 3327,  3660,  4026,  4428,  4871,  5358,  5894,  6484,
	 7132,  7845,  8630,  9493, 10442, 11487, 12635, 13899,
	15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};

static const int ima_indexupdate[8*2] =
{
	/* from Y.Ajima's WAVFMT.TXT */
	-1,-1,-1,-1, 2, 4, 6, 8,
	-1,-1,-1,-1, 2, 4, 6, 8,
};

static int stepindex_to_diff( int stepindex, int input )
{
	/* from Y.Ajima's WAVFMT.TXT */
	int absdiff;

	absdiff = (ima_step[stepindex]*((input&0x7)*2+1)) >> 3;
	return (input&0x8) ? (-absdiff) : absdiff;
}

static int update_stepindex( int oldindex, int input )
{
	int	index;

	index = oldindex + ima_indexupdate[input];
	return (index < 0) ? 0 : (index > 88) ? 88 : index;
}

static void decode_ima_block( int channels, int samplesperblock, SHORT* pDst, BYTE* pSrc )
{
	int	samp[2];
	int	stepindex[2];
	int	inputs[8];
	int	n,k,diff;

	for ( n = 0; n < channels; n++ )
	{
		samp[n] = *(SHORT*)pSrc; pSrc += sizeof(SHORT);
		stepindex[n] = *pSrc; pSrc += sizeof(SHORT);
		*pDst++ = samp[n];
	}
	samplesperblock --;

	while ( samplesperblock >= 8 )
	{
		for ( n = 0; n < channels; n++ )
		{
			for ( k = 0; k < 4; k++ )
			{
				inputs[k*2+0] = (*pSrc) & 0xf;
				inputs[k*2+1] = (*pSrc) >> 4;
				pSrc ++;
			}
			for ( k = 0; k < 8; k++ )
			{
				diff = stepindex_to_diff( stepindex[n], inputs[k] );
				stepindex[n] = update_stepindex( stepindex[n], inputs[k] );
				diff += samp[n];
				if ( diff < -32768 ) diff = -32768;
				if ( diff >  32767 ) diff =  32767;
				samp[n] = diff;
				pDst[k*channels+n] = samp[n];
			}
		}

		pDst += channels*8;
		samplesperblock -= 8;
	}
}

static LONG IMAADPCM32_Decode( int channels, int blockalign, int samplesperblock, BYTE* pbDst, DWORD cbDstLength, DWORD* pcbDstLengthUsed, BYTE* pbSrc, DWORD cbSrcLength, DWORD* pcbSrcLengthUsed )
{
	DWORD	cbDstLengthUsed = 0;
	DWORD	cbSrcLengthUsed = 0;
	int	dstblocksize;

	dstblocksize = samplesperblock*channels*sizeof(SHORT);
	while ( cbDstLength >= dstblocksize && cbSrcLength >= blockalign )
	{
		decode_ima_block( channels, samplesperblock, (SHORT*)pbDst, pbSrc );
		pbDst += dstblocksize;
		cbDstLength -= dstblocksize;
		cbDstLengthUsed += dstblocksize;
		pbSrc += blockalign;
		cbSrcLength -= blockalign;
		cbSrcLengthUsed += blockalign;
	}

	*pcbSrcLengthUsed = cbSrcLengthUsed;
	*pcbDstLengthUsed = cbDstLengthUsed;

	return MMSYSERR_NOERROR;
}


/***********************************************************************/

static LONG Codec_DrvQueryConfigure( CodecImpl* This )
{
	return MMSYSERR_NOTSUPPORTED;
}

static LONG Codec_DrvConfigure( CodecImpl* This, HWND hwnd, DRVCONFIGINFO* pinfo )
{
	return MMSYSERR_NOTSUPPORTED;
}

static LONG Codec_DriverDetails( ACMDRIVERDETAILSW* pDrvDetails )
{
	if ( pDrvDetails->cbStruct < sizeof(ACMDRIVERDETAILSW) )
		return MMSYSERR_INVALPARAM;

	ZeroMemory( pDrvDetails, sizeof(ACMDRIVERDETAILSW) );
	pDrvDetails->cbStruct = sizeof(ACMDRIVERDETAILSW);

	pDrvDetails->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
	pDrvDetails->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
	pDrvDetails->wMid = 0xff;	/* FIXME? */
	pDrvDetails->wPid = 0x00;	/* FIXME? */
	pDrvDetails->vdwACM = 0x01000000;	/* FIXME? */
	pDrvDetails->vdwDriver = 0x01000000;	/* FIXME? */
	pDrvDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
	pDrvDetails->cFormatTags = 2;
	pDrvDetails->cFilterTags = 0;
	pDrvDetails->hicon = (HICON)NULL;
	MultiByteToWideChar( CP_ACP, 0, "WineIMA", -1,
		pDrvDetails->szShortName,
		sizeof(pDrvDetails->szShortName)/sizeof(WCHAR) );
	MultiByteToWideChar( CP_ACP, 0, "Wine IMA codec", -1,
		pDrvDetails->szLongName,
		sizeof(pDrvDetails->szLongName)/sizeof(WCHAR) );
    MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
		pDrvDetails->szCopyright,
		sizeof(pDrvDetails->szCopyright)/sizeof(WCHAR) );
	MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
		pDrvDetails->szLicensing,
		sizeof(pDrvDetails->szLicensing)/sizeof(WCHAR) );
	pDrvDetails->szFeatures[0] = 0;

	return MMSYSERR_NOERROR;
}

static LONG Codec_QueryAbout( void )
{
	return MMSYSERR_NOTSUPPORTED;
}

static LONG Codec_About( HWND hwnd )
{
	return MMSYSERR_NOTSUPPORTED;
}

/***********************************************************************/

static LONG Codec_FormatTagDetails( CodecImpl* This, ACMFORMATTAGDETAILSW* pFmtTagDetails, DWORD dwFlags )
{
	FIXME( "enumerate tags\n" );

	switch ( dwFlags )
	{
	case ACM_FORMATTAGDETAILSF_INDEX:
		switch ( pFmtTagDetails->dwFormatTagIndex )
		{
		case 0:
			pFmtTagDetails->dwFormatTag = 0x11;	/* IMA ADPCM */
			break;
		case 1:
			pFmtTagDetails->dwFormatTag = 1;	/* PCM */
			break;
		default:
			return ACMERR_NOTPOSSIBLE;
		}
		break;
	case ACM_FORMATTAGDETAILSF_FORMATTAG:
		switch ( pFmtTagDetails->dwFormatTag )
		{
		case 0x11:	/* IMA ADPCM */
			pFmtTagDetails->dwFormatTagIndex = 0;
			break;
		case 1:	/* PCM */
			pFmtTagDetails->dwFormatTagIndex = 1;
			break;
		default:
			return ACMERR_NOTPOSSIBLE;
		}
		break;
	case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
		if ( pFmtTagDetails->dwFormatTag != 0 &&
			 pFmtTagDetails->dwFormatTag != 1 &&
			 pFmtTagDetails->dwFormatTag != 0x11 )
			return ACMERR_NOTPOSSIBLE;
		pFmtTagDetails->dwFormatTagIndex = 0;
		break;
	default:
		return MMSYSERR_NOTSUPPORTED;
	}

	pFmtTagDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
	pFmtTagDetails->cbFormatSize = sizeof(WAVEFORMATEX);
	pFmtTagDetails->cStandardFormats = 2;	/* FIXME */
	pFmtTagDetails->szFormatTag[0] = 0;	/* FIXME */

	return MMSYSERR_NOERROR;
}

static LONG Codec_FormatDetails( CodecImpl* This, ACMFORMATDETAILSW* pFmtDetails, DWORD dwFlags )
{
	FIXME( "enumerate standard formats\n" );

	if ( pFmtDetails->cbStruct < sizeof(ACMFORMATDETAILSW) )
		return MMSYSERR_INVALPARAM;
	pFmtDetails->cbStruct = sizeof(ACMFORMATDETAILSW);

	switch ( dwFlags )
	{
	case ACM_FORMATDETAILSF_INDEX:
		switch ( pFmtDetails->dwFormatIndex )
		{
		case 0:
			pFmtDetails->dwFormatTag = 0x11;	/* IMA ADPCM */
			break;
		case 1:
			pFmtDetails->dwFormatTag = 1;	/* PCM */
			break;
		default:
			return MMSYSERR_INVALPARAM;
		}
		break;
	case ACM_FORMATDETAILSF_FORMAT:
		switch ( pFmtDetails->dwFormatTag )
		{
		case 0x11:	/* IMA ADPCM */
			pFmtDetails->dwFormatIndex = 0;
			break;
		case 1:	/* PCM */
			pFmtDetails->dwFormatIndex = 1;
			break;
		default:
			return ACMERR_NOTPOSSIBLE;
		}
		break;
	default:
		return MMSYSERR_NOTSUPPORTED;
	}

	pFmtDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
	pFmtDetails->pwfx->wFormatTag = pFmtDetails->dwFormatTag;
	pFmtDetails->pwfx->nChannels = 1;
	pFmtDetails->pwfx->nSamplesPerSec = 11025;
	pFmtDetails->pwfx->wBitsPerSample = 4;
	if ( pFmtDetails->dwFormatTag == 1 )
	{
		pFmtDetails->cbwfx = sizeof(PCMWAVEFORMAT);
	}
	else
	{
		pFmtDetails->pwfx->cbSize = sizeof(WORD);
		pFmtDetails->cbwfx = sizeof(WAVEFORMATEX) + sizeof(WORD);
	}
	pFmtDetails->szFormat[0] = 0;	/* FIXME */

    return MMSYSERR_NOERROR;
}


static LONG Codec_FormatSuggest( CodecImpl* This, ACMDRVFORMATSUGGEST* pFmtSuggest )
{
	DWORD	fdwSuggest;

	FIXME( "get suggested format\n" );

	if ( pFmtSuggest->cbStruct != sizeof(ACMDRVFORMATSUGGEST) )
		return MMSYSERR_INVALPARAM;

	if ( pFmtSuggest->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
		 pFmtSuggest->cbwfxDst < sizeof(PCMWAVEFORMAT) )
		return MMSYSERR_INVALPARAM;

	fdwSuggest = pFmtSuggest->fdwSuggest;

	if ( fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS )
	{
		if ( pFmtSuggest->pwfxSrc->nChannels != pFmtSuggest->pwfxDst->nChannels )
			return ACMERR_NOTPOSSIBLE;
		fdwSuggest &= ~ACM_FORMATSUGGESTF_NCHANNELS;
	}

	if ( fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC )
	{
		if ( pFmtSuggest->pwfxSrc->nSamplesPerSec != pFmtSuggest->pwfxDst->nSamplesPerSec )
			return ACMERR_NOTPOSSIBLE;
		fdwSuggest &= ~ACM_FORMATSUGGESTF_NSAMPLESPERSEC;
	}

	if ( pFmtSuggest->pwfxSrc->wFormatTag == 1 )
	{
		/* Compressor */
		if ( pFmtSuggest->cbwfxDst < (sizeof(WAVEFORMATEX)+sizeof(WORD)) )
			return MMSYSERR_INVALPARAM;
		if ( pFmtSuggest->pwfxSrc->wBitsPerSample != 16 )
			return ACMERR_NOTPOSSIBLE;

		if ( fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG )
		{
			if ( pFmtSuggest->pwfxDst->wFormatTag != 0x11 )
				return ACMERR_NOTPOSSIBLE;
			fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
		}

		if ( fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE )
		{
			if ( pFmtSuggest->pwfxDst->wBitsPerSample != 4 )
				return ACMERR_NOTPOSSIBLE;
			fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
		}

		if ( fdwSuggest != 0 )
			return MMSYSERR_INVALFLAG;

		if ( !(fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG) )
			pFmtSuggest->pwfxDst->wFormatTag = 0x11;
		pFmtSuggest->pwfxDst->nChannels = pFmtSuggest->pwfxSrc->nChannels;
		pFmtSuggest->pwfxDst->nSamplesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec;
		pFmtSuggest->pwfxDst->nAvgBytesPerSec = 0; /* FIXME */
		pFmtSuggest->pwfxDst->nBlockAlign = 0; /* FIXME */
		pFmtSuggest->pwfxDst->wBitsPerSample = 4;
		pFmtSuggest->pwfxDst->cbSize = 2;

		FIXME( "no compressor" );
		return ACMERR_NOTPOSSIBLE;
	}
	else
	{
		/* Decompressor */
		if ( pFmtSuggest->cbwfxSrc < (sizeof(WAVEFORMATEX)+sizeof(WORD)) )
			return MMSYSERR_INVALPARAM;
		if ( pFmtSuggest->pwfxSrc->wFormatTag != 0x11 )
			return ACMERR_NOTPOSSIBLE;
		if ( pFmtSuggest->pwfxSrc->wBitsPerSample != 4 )
			return ACMERR_NOTPOSSIBLE;

		if ( fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG )
		{
			if ( pFmtSuggest->pwfxDst->wFormatTag != 1 )
				return ACMERR_NOTPOSSIBLE;
			fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
		}

		if ( fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE )
		{
			if ( pFmtSuggest->pwfxDst->wBitsPerSample != 16 )
				return ACMERR_NOTPOSSIBLE;
			fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
		}

		if ( fdwSuggest != 0 )
			return MMSYSERR_INVALFLAG;

		pFmtSuggest->pwfxDst->wFormatTag = 1;
		pFmtSuggest->pwfxDst->nChannels = pFmtSuggest->pwfxSrc->nChannels;
		pFmtSuggest->pwfxDst->nSamplesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec;
		pFmtSuggest->pwfxDst->nAvgBytesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec * pFmtSuggest->pwfxSrc->nChannels * 2;
		pFmtSuggest->pwfxDst->nBlockAlign = pFmtSuggest->pwfxSrc->nChannels * 2;
		pFmtSuggest->pwfxDst->wBitsPerSample = 16;
	}

	return MMSYSERR_NOERROR;
}

static LONG Codec_FilterTagDetails( CodecImpl* This, ACMFILTERTAGDETAILSW* pFilterTagDetails, DWORD dwFlags )
{
	/* This is a codec driver. */
	return MMSYSERR_NOTSUPPORTED;
}

static LONG Codec_FilterDetails( CodecImpl* This, ACMFILTERDETAILSW* pFilterDetails, DWORD dwFlags )
{
	/* This is a codec driver. */
	return MMSYSERR_NOTSUPPORTED;
}

static LONG Codec_StreamOpen( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst )
{
	enum CodecType	codectype = CodecType_Invalid;

	if ( pStreamInst->cbStruct != sizeof(ACMDRVSTREAMINSTANCE) )
	{
		TRACE("invalid size of struct\n");
		return MMSYSERR_INVALPARAM;
	}

	if ( pStreamInst->fdwOpen & (~(ACM_STREAMOPENF_ASYNC|ACM_STREAMOPENF_NONREALTIME|ACM_STREAMOPENF_QUERY|CALLBACK_EVENT|CALLBACK_FUNCTION|CALLBACK_WINDOW)) )
	{
		TRACE("unknown flags\n");
		return MMSYSERR_INVALFLAG;
	}

	/* No support for async operations. */
	if ( pStreamInst->fdwOpen & ACM_STREAMOPENF_ASYNC )
		return MMSYSERR_INVALFLAG;

	/* This is a codec driver. */
	if ( pStreamInst->pwfxSrc->nChannels != pStreamInst->pwfxDst->nChannels || pStreamInst->pwfxSrc->nSamplesPerSec != pStreamInst->pwfxDst->nSamplesPerSec )
		return ACMERR_NOTPOSSIBLE;
	if ( pStreamInst->pwfltr != NULL )
		return ACMERR_NOTPOSSIBLE;

	if ( pStreamInst->pwfxSrc->wFormatTag == 1 )
	{
		if ( pStreamInst->pwfxSrc->wBitsPerSample != 16 )
			return ACMERR_NOTPOSSIBLE;
		if ( pStreamInst->pwfxDst->wBitsPerSample != 4 )
			return ACMERR_NOTPOSSIBLE;

		/* Queried as a compressor */
		FIXME( "Compressor is not implemented now\n" );
		return ACMERR_NOTPOSSIBLE;
	}
	else
	if ( pStreamInst->pwfxDst->wFormatTag == 1 )
	{
		if ( pStreamInst->pwfxDst->wBitsPerSample != 16 )
			return ACMERR_NOTPOSSIBLE;
		if ( pStreamInst->pwfxSrc->wBitsPerSample != 4 )
			return ACMERR_NOTPOSSIBLE;

		switch ( pStreamInst->pwfxSrc->wFormatTag )
		{
		case 0x11: /* IMA ADPCM */
			TRACE( "IMG ADPCM deompressor\n" );
			codectype = CodecType_DecIMAADPCM;
			break;
		default:
			return ACMERR_NOTPOSSIBLE;
		}
	}
	else
	{
		return ACMERR_NOTPOSSIBLE;
	}

	if ( pStreamInst->fdwOpen & ACM_STREAMOPENF_QUERY )
		return MMSYSERR_NOERROR;

	pStreamInst->dwDriver = (DWORD)codectype;

	return MMSYSERR_NOERROR;
}

static LONG Codec_StreamClose( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst )
{
	return MMSYSERR_NOERROR;
}

static LONG Codec_StreamSize( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMSIZE* pStreamSize )
{
	enum CodecType	codectype;
	LONG	res;

	if ( pStreamSize->cbStruct != sizeof(ACMDRVSTREAMSIZE) )
		return MMSYSERR_INVALPARAM;

	codectype = (enum CodecType)pStreamInst->dwDriver;

	res = MMSYSERR_NOERROR;
	FIXME("()\n");
	switch ( codectype )
	{
	case CodecType_EncIMAADPCM:
		if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_SOURCE )
			pStreamSize->cbDstLength = 64 + (pStreamSize->cbSrcLength >> 2);
		else
		if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_DESTINATION )
			pStreamSize->cbSrcLength = pStreamSize->cbDstLength << 2;
		else
			res = MMSYSERR_INVALFLAG;
		break;
	case CodecType_DecIMAADPCM:
		if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_SOURCE )
			pStreamSize->cbDstLength = pStreamSize->cbSrcLength << 2;
		else
		if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_DESTINATION )
			pStreamSize->cbSrcLength = 64 + (pStreamSize->cbDstLength >> 2);
		else
			res = MMSYSERR_INVALFLAG;
		break;
	default:
		ERR( "CodecType_Invalid\n" );
		res = MMSYSERR_NOTSUPPORTED;
		break;
	}

	return res;
}

static LONG Codec_StreamConvert( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
{
	enum CodecType	codectype;
	LONG	res;

	codectype = (enum CodecType)pStreamInst->dwDriver;

	res = MMSYSERR_NOTSUPPORTED;
	switch ( codectype )
	{
	case CodecType_EncIMAADPCM:
		FIXME( "CodecType_EncIMAADPCM\n" );
		break;
	case CodecType_DecIMAADPCM:
		TRACE( "CodecType_DecIMAADPCM\n" );
		res = IMAADPCM32_Decode( pStreamInst->pwfxSrc->nChannels, pStreamInst->pwfxSrc->nBlockAlign, *(WORD*)(((BYTE*)pStreamInst->pwfxSrc) + sizeof(WAVEFORMATEX)), pStreamHdr->pbDst, pStreamHdr->cbDstLength, &pStreamHdr->cbDstLengthUsed, pStreamHdr->pbSrc, pStreamHdr->cbSrcLength, &pStreamHdr->cbSrcLengthUsed );
		break;
	default:
		ERR( "CodecType_Invalid\n" );
		break;
	}

	return res;
}

static LONG Codec_StreamReset( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, DWORD dwFlags )
{
	return MMSYSERR_NOTSUPPORTED;
}

static LONG Codec_StreamPrepare( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
{
	return MMSYSERR_NOTSUPPORTED;
}

static LONG Codec_StreamUnprepare( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
{
	return MMSYSERR_NOTSUPPORTED;
}



/***********************************************************************/

static CodecImpl* Codec_AllocDriver( void )
{
	CodecImpl*	This;

	This = HeapAlloc( GetProcessHeap(), 0, sizeof(CodecImpl) );
	if ( This == NULL )
		return NULL;
	ZeroMemory( This, sizeof(CodecImpl) );

	/* initialize members. */

	return This;
}

static void Codec_Close( CodecImpl* This )
{

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



/***********************************************************************/

LONG WINAPI IMAADP32_DriverProc(
	DWORD dwDriverId, HDRVR hdrvr, UINT msg, LONG lParam1, LONG lParam2 )
{
	TRACE( "DriverProc(%08lx,%08x,%08x,%08lx,%08lx)\n",
			 dwDriverId, hdrvr, msg, lParam1, lParam2 );

	switch ( msg )
	{
	case DRV_LOAD:
		TRACE("DRV_LOAD\n");
		return TRUE;
	case DRV_FREE:
		TRACE("DRV_FREE\n");
		return TRUE;
	case DRV_OPEN:
		TRACE("DRV_OPEN\n");
		return (LONG)Codec_AllocDriver();
	case DRV_CLOSE:
		TRACE("DRV_CLOSE\n");
		Codec_Close( (CodecImpl*)dwDriverId );
		return TRUE;
	case DRV_ENABLE:
		TRACE("DRV_ENABLE\n");
		return TRUE;
	case DRV_DISABLE:
		TRACE("DRV_DISABLE\n");
		return TRUE;
	case DRV_QUERYCONFIGURE:
		TRACE("DRV_QUERYCONFIGURE\n");
		return Codec_DrvQueryConfigure( (CodecImpl*)dwDriverId );
	case DRV_CONFIGURE:
		TRACE("DRV_CONFIGURE\n");
		return Codec_DrvConfigure( (CodecImpl*)dwDriverId,
					(HWND)lParam1, (DRVCONFIGINFO*)lParam2 );
	case DRV_INSTALL:
		TRACE("DRV_INSTALL\n");
		return DRVCNF_OK;
	case DRV_REMOVE:
		TRACE("DRV_REMOVE\n");
		return 0;
	case DRV_POWER:
		TRACE("DRV_POWER\n");
		return TRUE;

	case ACMDM_DRIVER_NOTIFY:
		return MMSYSERR_NOERROR;
	case ACMDM_DRIVER_DETAILS:
		return Codec_DriverDetails((ACMDRIVERDETAILSW*)lParam1);
	case ACMDM_DRIVER_ABOUT:
		TRACE("ACMDM_DRIVER_ABOUT\n");
		return (lParam1 == -1) ? Codec_QueryAbout() : Codec_About( (HWND)lParam1 );

	case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
		return MMSYSERR_NOTSUPPORTED;
	case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
		return MMSYSERR_NOTSUPPORTED;

	case ACMDM_FORMATTAG_DETAILS:
		return Codec_FormatTagDetails( (CodecImpl*)dwDriverId, (ACMFORMATTAGDETAILSW*)lParam1, (DWORD)lParam2 );
	case ACMDM_FORMAT_DETAILS:
		return Codec_FormatDetails( (CodecImpl*)dwDriverId, (ACMFORMATDETAILSW*)lParam1, (DWORD)lParam2 );
	case ACMDM_FORMAT_SUGGEST:
		return Codec_FormatSuggest( (CodecImpl*)dwDriverId, (ACMDRVFORMATSUGGEST*)lParam1 );

	case ACMDM_FILTERTAG_DETAILS:
		return Codec_FilterTagDetails( (CodecImpl*)dwDriverId, (ACMFILTERTAGDETAILSW*)lParam1, (DWORD)lParam2 );
	case ACMDM_FILTER_DETAILS:
		return Codec_FilterDetails( (CodecImpl*)dwDriverId, (ACMFILTERDETAILSW*)lParam1, (DWORD)lParam2 );

	case ACMDM_STREAM_OPEN:
		return Codec_StreamOpen( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1 );
	case ACMDM_STREAM_CLOSE:
		return Codec_StreamClose( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1 );
	case ACMDM_STREAM_SIZE:
		return Codec_StreamSize( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMSIZE*)lParam2 );
	case ACMDM_STREAM_CONVERT:
		return Codec_StreamConvert( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
	case ACMDM_STREAM_RESET:
		return Codec_StreamReset( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (DWORD)lParam2 );
	case ACMDM_STREAM_PREPARE:
		return Codec_StreamPrepare( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
	case ACMDM_STREAM_UNPREPARE:
		return Codec_StreamUnprepare( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );

	}

	return DefDriverProc( dwDriverId, hdrvr, msg, lParam1, lParam2 );
}

/***********************************************************************/

BOOL WINAPI IMAADP32_DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved )
{
	TRACE( "(%08x,%08lx,%p)\n",hInst,dwReason,lpvReserved );

	return TRUE;
}
