/*
 * Copyright 2002 Michael Günnewig
 *
 * 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 <assert.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "winerror.h"
#include "mmsystem.h"
#include "vfw.h"
#include "msacm.h"

#include "avifile_private.h"
#include "extrachunk.h"

#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(avifile);

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

#define formtypeWAVE    mmioFOURCC('W','A','V','E')
#define ckidWAVEFORMAT  mmioFOURCC('f','m','t',' ')
#define ckidWAVEFACT    mmioFOURCC('f','a','c','t')
#define ckidWAVEDATA    mmioFOURCC('d','a','t','a')

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

#define ENDIAN_SWAPWORD(x)  ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8))
#define ENDIAN_SWAPDWORD(x) (ENDIAN_SWAPWORD((x >> 16) & 0xFFFF) | \
                             ENDIAN_SWAPWORD(x & 0xFFFF) << 16)

#ifdef WORDS_BIGENDIAN
#define BE2H_WORD(x)  (x)
#define BE2H_DWORD(x) (x)
#define LE2H_WORD(x)  ENDIAN_SWAPWORD(x)
#define LE2H_DWORD(x) ENDIAN_SWAPDWORD(x)
#else
#define BE2H_WORD(x)  ENDIAN_SWAPWORD(x)
#define BE2H_DWORD(x) ENDIAN_SWAPDWORD(x)
#define LE2H_WORD(x)  (x)
#define LE2H_DWORD(x) (x)
#endif

typedef struct {
  FOURCC  fccType;
  DWORD   offset;
  DWORD   size;
  INT     encoding;
  DWORD   sampleRate;
  DWORD   channels;
} SUNAUDIOHEADER;

#define AU_ENCODING_ULAW_8                 1
#define AU_ENCODING_PCM_8                  2
#define AU_ENCODING_PCM_16                 3
#define AU_ENCODING_PCM_24                 4
#define AU_ENCODING_PCM_32                 5
#define AU_ENCODING_FLOAT                  6
#define AU_ENCODING_DOUBLE                 7
#define AU_ENCODING_ADPCM_G721_32         23
#define AU_ENCODING_ADPCM_G722            24
#define AU_ENCODING_ADPCM_G723_24         25
#define AU_ENCODING_ADPCM_G723_5          26
#define AU_ENCODING_ALAW_8                27

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

static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj);
static ULONG   WINAPI IAVIFile_fnAddRef(IAVIFile* iface);
static ULONG   WINAPI IAVIFile_fnRelease(IAVIFile* iface);
static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size);
static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam);
static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi);
static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size);
static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size);
static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface);
static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam);

static const struct IAVIFileVtbl iwavft = {
  IAVIFile_fnQueryInterface,
  IAVIFile_fnAddRef,
  IAVIFile_fnRelease,
  IAVIFile_fnInfo,
  IAVIFile_fnGetStream,
  IAVIFile_fnCreateStream,
  IAVIFile_fnWriteData,
  IAVIFile_fnReadData,
  IAVIFile_fnEndRecord,
  IAVIFile_fnDeleteStream
};

static HRESULT WINAPI IPersistFile_fnQueryInterface(IPersistFile*iface,REFIID refiid,LPVOID*obj);
static ULONG   WINAPI IPersistFile_fnAddRef(IPersistFile*iface);
static ULONG   WINAPI IPersistFile_fnRelease(IPersistFile*iface);
static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile*iface,CLSID*pClassID);
static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile*iface);
static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile*iface,LPCOLESTR pszFileName,DWORD dwMode);
static HRESULT WINAPI IPersistFile_fnSave(IPersistFile*iface,LPCOLESTR pszFileName,BOOL fRemember);
static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile*iface,LPCOLESTR pszFileName);
static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile*iface,LPOLESTR*ppszFileName);

static const struct IPersistFileVtbl iwavpft = {
  IPersistFile_fnQueryInterface,
  IPersistFile_fnAddRef,
  IPersistFile_fnRelease,
  IPersistFile_fnGetClassID,
  IPersistFile_fnIsDirty,
  IPersistFile_fnLoad,
  IPersistFile_fnSave,
  IPersistFile_fnSaveCompleted,
  IPersistFile_fnGetCurFile
};

static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj);
static ULONG   WINAPI IAVIStream_fnAddRef(IAVIStream*iface);
static ULONG   WINAPI IAVIStream_fnRelease(IAVIStream* iface);
static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2);
static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size);
static LONG    WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags);
static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize);
static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize);
static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread);
static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten);
static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples);
static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread);
static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size);
static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen);

static const struct IAVIStreamVtbl iwavst = {
  IAVIStream_fnQueryInterface,
  IAVIStream_fnAddRef,
  IAVIStream_fnRelease,
  IAVIStream_fnCreate,
  IAVIStream_fnInfo,
  IAVIStream_fnFindSample,
  IAVIStream_fnReadFormat,
  IAVIStream_fnSetFormat,
  IAVIStream_fnRead,
  IAVIStream_fnWrite,
  IAVIStream_fnDelete,
  IAVIStream_fnReadData,
  IAVIStream_fnWriteData,
  IAVIStream_fnSetInfo
};

typedef struct _IAVIFileImpl IAVIFileImpl;

typedef struct _IPersistFileImpl {
  /* IUnknown stuff */
  const IPersistFileVtbl *lpVtbl;

  /* IPersistFile stuff */
  IAVIFileImpl     *paf;
} IPersistFileImpl;

typedef struct _IAVIStreamImpl {
  /* IUnknown stuff */
  const IAVIStreamVtbl *lpVtbl;

  /* IAVIStream stuff */
  IAVIFileImpl     *paf;
} IAVIStreamImpl;

struct _IAVIFileImpl {
  /* IUnknown stuff */
  const IAVIFileVtbl *lpVtbl;
  LONG		    ref;

  /* IAVIFile, IAVIStream stuff... */
  IPersistFileImpl  iPersistFile;
  IAVIStreamImpl    iAVIStream;

  AVIFILEINFOW      fInfo;
  AVISTREAMINFOW    sInfo;

  LPWAVEFORMATEX    lpFormat;
  LONG              cbFormat;

  MMCKINFO          ckData;

  EXTRACHUNKS       extra;

  /* IPersistFile stuff ... */
  HMMIO             hmmio;
  LPWSTR            szFileName;
  UINT              uMode;
  BOOL              fDirty;
};

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

static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This);
static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This);
static HRESULT AVIFILE_SaveFile(const IAVIFileImpl *This);

HRESULT AVIFILE_CreateWAVFile(REFIID riid, LPVOID *ppv)
{
  IAVIFileImpl *pfile;
  HRESULT       hr;

  assert(riid != NULL && ppv != NULL);

  *ppv = NULL;

  pfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIFileImpl));
  if (pfile == NULL)
    return AVIERR_MEMORY;

  pfile->lpVtbl                = &iwavft;
  pfile->iPersistFile.lpVtbl   = &iwavpft;
  pfile->iAVIStream.lpVtbl     = &iwavst;
  pfile->ref = 0;
  pfile->iPersistFile.paf = pfile;
  pfile->iAVIStream.paf   = pfile;

  hr = IAVIFile_QueryInterface((IAVIFile*)pfile, riid, ppv);
  if (FAILED(hr))
    HeapFree(GetProcessHeap(), 0, pfile);

  return hr;
}

static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile *iface, REFIID refiid,
						LPVOID *obj)
{
  IAVIFileImpl *This = (IAVIFileImpl *)iface;

  TRACE("(%p,%s,%p)\n", This, debugstr_guid(refiid), obj);

  if (IsEqualGUID(&IID_IUnknown, refiid) ||
      IsEqualGUID(&IID_IAVIFile, refiid)) {
    *obj = iface;
    IAVIFile_AddRef(iface);
    return S_OK;
  } else if (This->fInfo.dwStreams == 1 &&
	     IsEqualGUID(&IID_IAVIStream, refiid)) {
    *obj = &This->iAVIStream;
    IAVIFile_AddRef(iface);
    return S_OK;
  } else if (IsEqualGUID(&IID_IPersistFile, refiid)) {
    *obj = &This->iPersistFile;
    IAVIFile_AddRef(iface);
    return S_OK;
  }

  return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile *iface)
{
  IAVIFileImpl *This = (IAVIFileImpl *)iface;

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

  return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI IAVIFile_fnRelease(IAVIFile *iface)
{
  IAVIFileImpl *This = (IAVIFileImpl *)iface;
  ULONG ref = InterlockedDecrement(&This->ref);

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

  if (!ref) {
    if (This->fDirty) {
      /* need to write headers to file */
      AVIFILE_SaveFile(This);
    }

    if (This->lpFormat != NULL) {
      HeapFree(GetProcessHeap(), 0, This->lpFormat);
      This->lpFormat = NULL;
      This->cbFormat = 0;
    }
    if (This->extra.lp != NULL) {
      HeapFree(GetProcessHeap(), 0, This->extra.lp);
      This->extra.lp = NULL;
      This->extra.cb = 0;
    }
    HeapFree(GetProcessHeap(), 0, This->szFileName);
    This->szFileName = NULL;
    if (This->hmmio != NULL) {
      mmioClose(This->hmmio, 0);
      This->hmmio = NULL;
    }

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

static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile *iface, LPAVIFILEINFOW afi,
				      LONG size)
{
  IAVIFileImpl *This = (IAVIFileImpl *)iface;

  TRACE("(%p,%p,%d)\n",iface,afi,size);

  if (afi == NULL)
    return AVIERR_BADPARAM;
  if (size < 0)
    return AVIERR_BADSIZE;

  /* update file info */
  This->fInfo.dwFlags = 0;
  This->fInfo.dwCaps  = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
  if (This->lpFormat != NULL) {
    assert(This->sInfo.dwScale != 0);

    This->fInfo.dwStreams             = 1;
    This->fInfo.dwScale               = This->sInfo.dwScale;
    This->fInfo.dwRate                = This->sInfo.dwRate;
    This->fInfo.dwLength              = This->sInfo.dwLength;
    This->fInfo.dwSuggestedBufferSize = This->ckData.cksize;
    This->fInfo.dwMaxBytesPerSec =
      MulDiv(This->sInfo.dwSampleSize,This->sInfo.dwRate,This->sInfo.dwScale);
  }

  memcpy(afi, &This->fInfo, min((DWORD)size, sizeof(This->fInfo)));

  if ((DWORD)size < sizeof(This->fInfo))
    return AVIERR_BUFFERTOOSMALL;
  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile *iface, PAVISTREAM *avis,
					   DWORD fccType, LONG lParam)
{
  IAVIFileImpl *This = (IAVIFileImpl *)iface;

  TRACE("(%p,%p,0x%08X,%d)\n", iface, avis, fccType, lParam);

  /* check parameter */
  if (avis == NULL)
    return AVIERR_BADPARAM;

  *avis = NULL;

  /* Does our stream exists? */
  if (lParam != 0 || This->fInfo.dwStreams == 0)
    return AVIERR_NODATA;
  if (fccType != 0 && fccType != streamtypeAUDIO)
    return AVIERR_NODATA;

  *avis = (PAVISTREAM)&This->iAVIStream;
  IAVIFile_AddRef(iface);

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile *iface,PAVISTREAM *avis,
					      LPAVISTREAMINFOW asi)
{
  IAVIFileImpl *This = (IAVIFileImpl *)iface;

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

  /* check parameters */
  if (avis == NULL || asi == NULL)
    return AVIERR_BADPARAM;

  *avis = NULL;

  /* We only support one audio stream */
  if (This->fInfo.dwStreams != 0 || This->lpFormat != NULL)
    return AVIERR_UNSUPPORTED;
  if (asi->fccType != streamtypeAUDIO)
    return AVIERR_UNSUPPORTED;

  /* Does the user have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  This->cbFormat = 0;
  This->lpFormat = NULL;

  memcpy(&This->sInfo, asi, sizeof(This->sInfo));

  /* make sure streaminfo if okay for us */
  This->sInfo.fccHandler          = 0;
  This->sInfo.dwFlags             = 0;
  This->sInfo.dwCaps              = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
  This->sInfo.dwStart             = 0;
  This->sInfo.dwInitialFrames     = 0;
  This->sInfo.dwFormatChangeCount = 0;
  memset(&This->sInfo.rcFrame, 0, sizeof(This->sInfo.rcFrame));

  This->fInfo.dwStreams = 1;
  This->fInfo.dwScale   = This->sInfo.dwScale;
  This->fInfo.dwRate    = This->sInfo.dwRate;
  This->fInfo.dwLength  = This->sInfo.dwLength;

  This->ckData.dwDataOffset = 0;
  This->ckData.cksize       = 0;

  *avis = (PAVISTREAM)&This->iAVIStream;
  IAVIFile_AddRef(iface);

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile *iface, DWORD ckid,
					   LPVOID lpData, LONG size)
{
  IAVIFileImpl *This = (IAVIFileImpl *)iface;

  TRACE("(%p,0x%08X,%p,%d)\n", iface, ckid, lpData, size);

  /* check parameters */
  if (lpData == NULL)
    return AVIERR_BADPARAM;
  if (size < 0)
    return AVIERR_BADSIZE;

  /* Do we have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  This->fDirty = TRUE;

  return WriteExtraChunk(&This->extra, ckid, lpData, size);
}

static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile *iface, DWORD ckid,
					  LPVOID lpData, LONG *size)
{
  IAVIFileImpl *This = (IAVIFileImpl *)iface;

  TRACE("(%p,0x%08X,%p,%p)\n", iface, ckid, lpData, size);

  return ReadExtraChunk(&This->extra, ckid, lpData, size);
}

static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile *iface)
{
  TRACE("(%p)\n",iface);

  /* This is only needed for interleaved files.
   * We have only one stream, which can't be interleaved.
   */
  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile *iface, DWORD fccType,
					      LONG lParam)
{
  IAVIFileImpl *This = (IAVIFileImpl *)iface;

  TRACE("(%p,0x%08X,%d)\n", iface, fccType, lParam);

  /* check parameter */
  if (lParam < 0)
    return AVIERR_BADPARAM;

  /* Do we have our audio stream? */
  if (lParam != 0 || This->fInfo.dwStreams == 0 ||
      (fccType != 0 && fccType != streamtypeAUDIO))
    return AVIERR_NODATA;

  /* Have user write permissions? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  HeapFree(GetProcessHeap(), 0, This->lpFormat);
  This->lpFormat = NULL;
  This->cbFormat = 0;

  /* update infos */
  This->ckData.dwDataOffset = 0;
  This->ckData.cksize       = 0;

  This->sInfo.dwScale   = 0;
  This->sInfo.dwRate    = 0;
  This->sInfo.dwLength  = 0;
  This->sInfo.dwSuggestedBufferSize = 0;

  This->fInfo.dwStreams = 0;
  This->fInfo.dwEditCount++;

  This->fDirty = TRUE;

  return AVIERR_OK;
}

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

static HRESULT WINAPI IPersistFile_fnQueryInterface(IPersistFile *iface,
						    REFIID refiid, LPVOID *obj)
{
  IPersistFileImpl *This = (IPersistFileImpl *)iface;

  assert(This->paf != NULL);

  return IAVIFile_QueryInterface((PAVIFILE)This->paf, refiid, obj);
}

static ULONG   WINAPI IPersistFile_fnAddRef(IPersistFile *iface)
{
  IPersistFileImpl *This = (IPersistFileImpl *)iface;

  assert(This->paf != NULL);

  return IAVIFile_AddRef((PAVIFILE)This->paf);
}

static ULONG   WINAPI IPersistFile_fnRelease(IPersistFile *iface)
{
  IPersistFileImpl *This = (IPersistFileImpl *)iface;

  assert(This->paf != NULL);

  return IAVIFile_Release((PAVIFILE)This->paf);
}

static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile *iface,
						LPCLSID pClassID)
{
  TRACE("(%p,%p)\n", iface, pClassID);

  if (pClassID == NULL)
    return AVIERR_BADPARAM;

  *pClassID = CLSID_WAVFile;

  return AVIERR_OK;
}

static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile *iface)
{
  IPersistFileImpl *This = (IPersistFileImpl *)iface;

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

  assert(This->paf != NULL);

  return (This->paf->fDirty ? S_OK : S_FALSE);
}

static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface,
					  LPCOLESTR pszFileName, DWORD dwMode)
{
  IAVIFileImpl *This = ((IPersistFileImpl*)iface)->paf;

  WCHAR wszStreamFmt[50];
  INT   len;

  TRACE("(%p,%s,0x%08X)\n", iface, debugstr_w(pszFileName), dwMode);

  /* check parameter */
  if (pszFileName == NULL)
    return AVIERR_BADPARAM;

  assert(This != NULL);
  if (This->hmmio != NULL)
    return AVIERR_ERROR; /* No reuse of this object for another file! */

  /* remember mode and name */
  This->uMode = dwMode;

  len = lstrlenW(pszFileName) + 1;
  This->szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
  if (This->szFileName == NULL)
    return AVIERR_MEMORY;
  lstrcpyW(This->szFileName, pszFileName);

  /* try to open the file */
  This->hmmio = mmioOpenW(This->szFileName, NULL, MMIO_ALLOCBUF | dwMode);
  if (This->hmmio == NULL) {
    /* mmioOpenW not in native DLLs of Win9x -- try mmioOpenA */
    LPSTR szFileName;
    len = WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1,
                              NULL, 0, NULL, NULL);
    szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR));
    if (szFileName == NULL)
      return AVIERR_MEMORY;

    WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, szFileName,
			len, NULL, NULL);

    This->hmmio = mmioOpenA(szFileName, NULL, MMIO_ALLOCBUF | dwMode);
    HeapFree(GetProcessHeap(), 0, szFileName);
    if (This->hmmio == NULL)
      return AVIERR_FILEOPEN;
  }

  memset(& This->fInfo, 0, sizeof(This->fInfo));
  memset(& This->sInfo, 0, sizeof(This->sInfo));

  LoadStringW(AVIFILE_hModule, IDS_WAVEFILETYPE, This->fInfo.szFileType,
	      sizeof(This->fInfo.szFileType)/sizeof(This->fInfo.szFileType[0]));
  if (LoadStringW(AVIFILE_hModule, IDS_WAVESTREAMFORMAT,
		  wszStreamFmt, sizeof(wszStreamFmt)/sizeof(wszStreamFmt[0])) > 0) {
    wsprintfW(This->sInfo.szName, wszStreamFmt,
	      AVIFILE_BasenameW(This->szFileName));
  }

  /* should we create a new file? */
  if (dwMode & OF_CREATE) {
    /* nothing more to do */
    return AVIERR_OK;
  } else
    return AVIFILE_LoadFile(This);
}

static HRESULT WINAPI IPersistFile_fnSave(IPersistFile *iface,
					  LPCOLESTR pszFileName,BOOL fRemember)
{
  TRACE("(%p,%s,%d)\n", iface, debugstr_w(pszFileName), fRemember);

  /* We write directly to disk, so nothing to do. */

  return AVIERR_OK;
}

static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile *iface,
						   LPCOLESTR pszFileName)
{
  TRACE("(%p,%s)\n", iface, debugstr_w(pszFileName));

  /* We write directly to disk, so nothing to do. */

  return AVIERR_OK;
}

static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile *iface,
						LPOLESTR *ppszFileName)
{
  IPersistFileImpl *This = (IPersistFileImpl *)iface;

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

  if (ppszFileName == NULL)
    return AVIERR_BADPARAM;

  *ppszFileName = NULL;

  assert(This->paf != NULL);

  if (This->paf->szFileName != NULL) {
    int len = lstrlenW(This->paf->szFileName) + 1;

    *ppszFileName = CoTaskMemAlloc(len * sizeof(WCHAR));
    if (*ppszFileName == NULL)
      return AVIERR_MEMORY;

    strcpyW(*ppszFileName, This->paf->szFileName);
  }

  return AVIERR_OK;
}

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

static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream *iface,
						  REFIID refiid, LPVOID *obj)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  assert(This->paf != NULL);

  return IAVIFile_QueryInterface((PAVIFILE)This->paf, refiid, obj);
}

static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream *iface)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  assert(This->paf != NULL);

  return IAVIFile_AddRef((PAVIFILE)This->paf);
}

static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  assert(This->paf != NULL);

  return IAVIFile_Release((PAVIFILE)This->paf);
}

static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream *iface, LPARAM lParam1,
					  LPARAM lParam2)
{
  TRACE("(%p,0x%08lX,0x%08lX)\n", iface, lParam1, lParam2);

  /* This IAVIStream interface needs an WAVFile */
  return AVIERR_UNSUPPORTED;
}

static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream *iface,LPAVISTREAMINFOW psi,
					LONG size)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,%p,%d)\n", iface, psi, size);

  if (psi == NULL)
    return AVIERR_BADPARAM;
  if (size < 0)
    return AVIERR_BADSIZE;

  memcpy(psi, &This->paf->sInfo, min((DWORD)size, sizeof(This->paf->sInfo)));

  if ((DWORD)size < sizeof(This->paf->sInfo))
    return AVIERR_BUFFERTOOSMALL;
  return AVIERR_OK;
}

static LONG WINAPI IAVIStream_fnFindSample(IAVIStream *iface, LONG pos,
					   LONG flags)
{
  IAVIFileImpl *This = ((IAVIStreamImpl*)iface)->paf;

  TRACE("(%p,%d,0x%08X)\n",iface,pos,flags);

  /* Do we have data? */
  if (This->lpFormat == NULL)
    return -1;

  /* We don't have an index */
  if (flags & FIND_INDEX)
    return -1;

  if (flags & FIND_FROM_START) {
    pos = This->sInfo.dwStart;
    flags &= ~(FIND_FROM_START|FIND_PREV);
    flags |= FIND_NEXT;
  }

  if (flags & FIND_FORMAT) {
    if ((flags & FIND_NEXT) && pos > 0)
      pos = -1;
    else
      pos = 0;
  }

  if ((flags & FIND_RET) == FIND_LENGTH ||
      (flags & FIND_RET) == FIND_SIZE)
    return This->sInfo.dwSampleSize;
  if ((flags & FIND_RET) == FIND_OFFSET)
    return This->ckData.dwDataOffset + pos * This->sInfo.dwSampleSize;

  return pos;
}

static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream *iface, LONG pos,
					      LPVOID format, LONG *formatsize)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,%d,%p,%p)\n", iface, pos, format, formatsize);

  if (formatsize == NULL)
    return AVIERR_BADPARAM;

  /* only interested in needed buffersize? */
  if (format == NULL || *formatsize <= 0) {
    *formatsize = This->paf->cbFormat;

    return AVIERR_OK;
  }

  /* copy initial format (only as much as will fit) */
  memcpy(format, This->paf->lpFormat, min(*formatsize, This->paf->cbFormat));
  if (*formatsize < This->paf->cbFormat) {
    *formatsize = This->paf->cbFormat;
    return AVIERR_BUFFERTOOSMALL;
  }

  *formatsize = This->paf->cbFormat;
  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos,
					     LPVOID format, LONG formatsize)
{
  IAVIFileImpl *This = ((IAVIStreamImpl*)iface)->paf;

  TRACE("(%p,%d,%p,%d)\n", iface, pos, format, formatsize);

  /* check parameters */
  if (format == NULL || formatsize <= sizeof(PCMWAVEFORMAT))
    return AVIERR_BADPARAM;

  /* We can only do this to an empty wave file, but ignore call
   * if still same format */
  if (This->lpFormat != NULL) {
    if (formatsize != This->cbFormat ||
	memcmp(format, This->lpFormat, formatsize) != 0)
      return AVIERR_UNSUPPORTED;

    return AVIERR_OK;
  }

  /* only support start at position 0 */
  if (pos != 0)
    return AVIERR_UNSUPPORTED;

  /* Do we have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  /* get memory for format and copy it */
  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, formatsize);
  if (This->lpFormat == NULL)
    return AVIERR_MEMORY;

  This->cbFormat = formatsize;
  memcpy(This->lpFormat, format, formatsize);

  /* update info's about 'data' chunk */
  This->ckData.dwDataOffset = formatsize + 7 * sizeof(DWORD);
  This->ckData.cksize       = 0;

  /* for non-pcm format we need also a 'fact' chunk */
  if (This->lpFormat->wFormatTag != WAVE_FORMAT_PCM)
    This->ckData.dwDataOffset += 3 * sizeof(DWORD);

  /* update stream and file info */
  This->sInfo.dwSampleSize = This->lpFormat->nBlockAlign;
  This->sInfo.dwScale      = This->lpFormat->nBlockAlign;
  This->sInfo.dwRate       = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwLength     = 0;
  This->sInfo.dwSuggestedBufferSize = 0;

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnRead(IAVIStream *iface, LONG start,
					LONG samples, LPVOID buffer,
					LONG buffersize, LPLONG bytesread,
					LPLONG samplesread)
{
  IAVIFileImpl *This = ((IAVIStreamImpl*)iface)->paf;

  TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", iface, start, samples, buffer,
	buffersize, bytesread, samplesread);

  /* clear return parameters if given */
  if (bytesread != NULL)
    *bytesread = 0;
  if (samplesread != NULL)
    *samplesread = 0;

  /* positions without data */
  if (start < 0 || (DWORD)start > This->sInfo.dwLength)
    return AVIERR_OK;

  /* check samples */
  if (samples < 0)
    samples = 0;
  if (buffersize > 0) {
    if (samples > 0)
      samples = min((DWORD)samples, buffersize / This->sInfo.dwSampleSize);
    else
      samples = buffersize / This->sInfo.dwSampleSize;
  }

  /* limit to end of stream */
  if ((DWORD)(start + samples) > This->sInfo.dwLength)
    samples = This->sInfo.dwLength - start;

  /* request only the sizes? */
  if (buffer == NULL || buffersize <= 0) {
    /* then I need at least one parameter for it */
    if (bytesread == NULL && samplesread == NULL)
      return AVIERR_BADPARAM;

    if (bytesread != NULL)
      *bytesread = samples * This->sInfo.dwSampleSize;
    if (samplesread != NULL)
      *samplesread = samples;

    return AVIERR_OK;
  }

  /* nothing to read? */
  if (samples == 0)
    return AVIERR_OK;

  /* Can I read at least one sample? */
  if ((DWORD)buffersize < This->sInfo.dwSampleSize)
    return AVIERR_BUFFERTOOSMALL;

  buffersize = samples * This->sInfo.dwSampleSize;

  if (mmioSeek(This->hmmio, This->ckData.dwDataOffset
	       + start * This->sInfo.dwSampleSize, SEEK_SET) == -1)
    return AVIERR_FILEREAD;
  if (mmioRead(This->hmmio, buffer, buffersize) != buffersize)
    return AVIERR_FILEREAD;

  /* fill out return parameters if given */
  if (bytesread != NULL)
    *bytesread = buffersize;
  if (samplesread != NULL)
    *samplesread = samples;  

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream *iface, LONG start,
					 LONG samples, LPVOID buffer,
					 LONG buffersize, DWORD flags,
					 LPLONG sampwritten,
					 LPLONG byteswritten)
{
  IAVIFileImpl *This = ((IAVIStreamImpl*)iface)->paf;

  TRACE("(%p,%d,%d,%p,%d,0x%08X,%p,%p)\n", iface, start, samples,
	buffer, buffersize, flags, sampwritten, byteswritten);

  /* clear return parameters if given */
  if (sampwritten != NULL)
    *sampwritten = 0;
  if (byteswritten != NULL)
    *byteswritten = 0;

  /* check parameters */
  if (buffer == NULL && (buffersize > 0 || samples > 0))
    return AVIERR_BADPARAM;

  /* Do we have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  /* < 0 means "append" */
  if (start < 0)
    start = This->sInfo.dwStart + This->sInfo.dwLength;

  /* check buffersize -- must multiple of samplesize */
  if (buffersize & ~(This->sInfo.dwSampleSize - 1))
    return AVIERR_BADSIZE;

  /* do we have anything to write? */
  if (buffer != NULL && buffersize > 0) {
    This->fDirty = 1;

    if (mmioSeek(This->hmmio, This->ckData.dwDataOffset +
		 start * This->sInfo.dwSampleSize, SEEK_SET) == -1)
      return AVIERR_FILEWRITE;
    if (mmioWrite(This->hmmio, buffer, buffersize) != buffersize)
      return AVIERR_FILEWRITE;

    This->sInfo.dwLength = max(This->sInfo.dwLength, (DWORD)start + samples);
    This->ckData.cksize  = max(This->ckData.cksize,
			       start * This->sInfo.dwSampleSize + buffersize);

    /* fill out return parameters if given */
    if (sampwritten != NULL)
      *sampwritten = samples;
    if (byteswritten != NULL)
      *byteswritten = buffersize;
  }

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream *iface, LONG start,
					  LONG samples)
{
  IAVIFileImpl *This = ((IAVIStreamImpl*)iface)->paf;

  TRACE("(%p,%d,%d)\n", iface, start, samples);

  /* check parameters */
  if (start < 0 || samples < 0)
    return AVIERR_BADPARAM;

  /* Delete before start of stream? */
  if ((DWORD)(start + samples) < This->sInfo.dwStart)
    return AVIERR_OK;

  /* Delete after end of stream? */
  if ((DWORD)start > This->sInfo.dwLength)
    return AVIERR_OK;

  /* For the rest we need write permissions */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  if ((DWORD)(start + samples) >= This->sInfo.dwLength) {
    /* deletion at end */
    samples = This->sInfo.dwLength - start;
    This->sInfo.dwLength -= samples;
    This->ckData.cksize  -= samples * This->sInfo.dwSampleSize;
  } else if ((DWORD)start <= This->sInfo.dwStart) {
    /* deletion at start */
    samples = This->sInfo.dwStart - start;
    start   = This->sInfo.dwStart;
    This->ckData.dwDataOffset += samples * This->sInfo.dwSampleSize;
    This->ckData.cksize       -= samples * This->sInfo.dwSampleSize;
  } else {
    /* deletion inside stream -- needs playlist and cue's */
    FIXME(": deletion inside of stream not supported!\n");

    return AVIERR_UNSUPPORTED;
  }

  This->fDirty = 1;

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream *iface, DWORD fcc,
					    LPVOID lp, LPLONG lpread)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  assert(This->paf != NULL);

  return IAVIFile_ReadData((PAVIFILE)This->paf, fcc, lp, lpread);
}

static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream *iface, DWORD fcc,
					     LPVOID lp, LONG size)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  return IAVIFile_WriteData((PAVIFILE)This->paf, fcc, lp, size);
}

static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream *iface,
					   LPAVISTREAMINFOW info, LONG infolen)
{
  FIXME("(%p,%p,%d): stub\n", iface, info, infolen);

  return E_FAIL;
}

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

static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This)
{
  MMCKINFO ckRIFF;
  MMCKINFO ck;

  This->sInfo.dwLength = 0; /* just to be sure */
  This->fDirty = FALSE;

  /* search for RIFF chunk */
  ckRIFF.fccType = 0; /* find any */
  if (mmioDescend(This->hmmio, &ckRIFF, NULL, MMIO_FINDRIFF) != S_OK) {
    return AVIFILE_LoadSunFile(This);
  }

  if (ckRIFF.fccType != formtypeWAVE)
    return AVIERR_BADFORMAT;

  /* search WAVE format chunk */
  ck.ckid = ckidWAVEFORMAT;
  if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck,
			     &ckRIFF, MMIO_FINDCHUNK) != S_OK)
    return AVIERR_FILEREAD;

  /* get memory for format and read it */
  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, ck.cksize);
  if (This->lpFormat == NULL)
    return AVIERR_FILEREAD;
  This->cbFormat = ck.cksize;

  if (mmioRead(This->hmmio, (HPSTR)This->lpFormat, ck.cksize) != ck.cksize)
    return AVIERR_FILEREAD;
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEREAD;

  /* Non-pcm formats have a fact chunk.
   * We don't need it, so simply add it to the extra chunks.
   */

  /* find the big data chunk */
  This->ckData.ckid = ckidWAVEDATA;
  if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &This->ckData,
			     &ckRIFF, MMIO_FINDCHUNK) != S_OK)
    return AVIERR_FILEREAD;

  memset(&This->sInfo, 0, sizeof(This->sInfo));
  This->sInfo.fccType      = streamtypeAUDIO;
  This->sInfo.dwRate       = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwSampleSize =
    This->sInfo.dwScale    = This->lpFormat->nBlockAlign;
  This->sInfo.dwLength     = This->ckData.cksize / This->lpFormat->nBlockAlign;
  This->sInfo.dwSuggestedBufferSize = This->ckData.cksize;

  This->fInfo.dwStreams = 1;

  if (mmioAscend(This->hmmio, &This->ckData, 0) != S_OK) {
    /* seems to be truncated */
    WARN(": file seems to be truncated!\n");
    This->ckData.cksize  = mmioSeek(This->hmmio, 0, SEEK_END) -
      This->ckData.dwDataOffset;
    This->sInfo.dwLength = This->ckData.cksize / This->lpFormat->nBlockAlign;
    This->sInfo.dwSuggestedBufferSize = This->ckData.cksize;
  }

  /* ignore errors */
  FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck, &ckRIFF, 0);

  return AVIERR_OK;
}

static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This)
{
  SUNAUDIOHEADER auhdr;

  mmioSeek(This->hmmio, 0, SEEK_SET);
  if (mmioRead(This->hmmio, (HPSTR)&auhdr, sizeof(auhdr)) != sizeof(auhdr))
    return AVIERR_FILEREAD;

  if (auhdr.fccType == 0x0064732E) {
    /* header in little endian */
    This->ckData.dwDataOffset = LE2H_DWORD(auhdr.offset);
    This->ckData.cksize       = LE2H_DWORD(auhdr.size);

    auhdr.encoding   = LE2H_DWORD(auhdr.encoding);
    auhdr.sampleRate = LE2H_DWORD(auhdr.sampleRate);
    auhdr.channels   = LE2H_DWORD(auhdr.channels);
  } else if (auhdr.fccType == mmioFOURCC('.','s','n','d')) {
    /* header in big endian */
    This->ckData.dwDataOffset = BE2H_DWORD(auhdr.offset);
    This->ckData.cksize       = BE2H_DWORD(auhdr.size);

    auhdr.encoding   = BE2H_DWORD(auhdr.encoding);
    auhdr.sampleRate = BE2H_DWORD(auhdr.sampleRate);
    auhdr.channels   = BE2H_DWORD(auhdr.channels);
  } else
    return AVIERR_FILEREAD;

  if (auhdr.channels < 1)
    return AVIERR_BADFORMAT;

  /* get size of header */
  switch(auhdr.encoding) {
  case AU_ENCODING_ADPCM_G721_32:
    This->cbFormat = sizeof(G721_ADPCMWAVEFORMAT); break;
  case AU_ENCODING_ADPCM_G723_24:
    This->cbFormat = sizeof(G723_ADPCMWAVEFORMAT); break;
  case AU_ENCODING_ADPCM_G722:
  case AU_ENCODING_ADPCM_G723_5:
    WARN("unsupported Sun audio format %d\n", auhdr.encoding);
    return AVIERR_UNSUPPORTED; /* FIXME */
  default:
    This->cbFormat = sizeof(WAVEFORMATEX); break;
  };

  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, This->cbFormat);
  if (This->lpFormat == NULL)
    return AVIERR_MEMORY;

  This->lpFormat->nChannels      = auhdr.channels;
  This->lpFormat->nSamplesPerSec = auhdr.sampleRate;
  switch(auhdr.encoding) {
  case AU_ENCODING_ULAW_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_MULAW;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_PCM_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_PCM_16:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 16;
    break;
  case AU_ENCODING_PCM_24:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 24;
    break;
  case AU_ENCODING_PCM_32:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 32;
    break;
  case AU_ENCODING_ALAW_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_ALAW;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_ADPCM_G721_32:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_G721_ADPCM;
    This->lpFormat->wBitsPerSample = (3*5*8);
    This->lpFormat->nBlockAlign    = 15*15*8;
    This->lpFormat->cbSize         = sizeof(WORD);
    ((LPG721_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
    break;
  case AU_ENCODING_ADPCM_G723_24:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_G723_ADPCM;
    This->lpFormat->wBitsPerSample = (3*5*8);
    This->lpFormat->nBlockAlign    = 15*15*8;
    This->lpFormat->cbSize         = 2*sizeof(WORD);
    ((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->cbExtraSize   = 0;
    ((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
    break;
  default:
    WARN("unsupported Sun audio format %d\n", auhdr.encoding);
    return AVIERR_UNSUPPORTED;
  };

  This->lpFormat->nBlockAlign =
    (This->lpFormat->nChannels * This->lpFormat->wBitsPerSample) / 8;
  if (This->lpFormat->nBlockAlign == 0 && This->lpFormat->wBitsPerSample < 8)
    This->lpFormat->nBlockAlign++;
  This->lpFormat->nAvgBytesPerSec =
    This->lpFormat->nBlockAlign * This->lpFormat->nSamplesPerSec;

  This->fDirty = 0;

  This->sInfo.fccType               = streamtypeAUDIO;
  This->sInfo.fccHandler            = 0;
  This->sInfo.dwFlags               = 0;
  This->sInfo.wPriority             = 0;
  This->sInfo.wLanguage             = 0;
  This->sInfo.dwInitialFrames       = 0;
  This->sInfo.dwScale               = This->lpFormat->nBlockAlign;
  This->sInfo.dwRate                = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwStart               = 0;
  This->sInfo.dwLength              =
    This->ckData.cksize / This->lpFormat->nBlockAlign;
  This->sInfo.dwSuggestedBufferSize = This->sInfo.dwLength;
  This->sInfo.dwSampleSize          = This->lpFormat->nBlockAlign;

  This->fInfo.dwStreams = 1;
  This->fInfo.dwScale   = 1;
  This->fInfo.dwRate    = This->lpFormat->nSamplesPerSec;
  This->fInfo.dwLength  =
    MulDiv(This->ckData.cksize, This->lpFormat->nSamplesPerSec,
	   This->lpFormat->nAvgBytesPerSec);

  return AVIERR_OK;
}

static HRESULT AVIFILE_SaveFile(const IAVIFileImpl *This)
{
  MMCKINFO ckRIFF;
  MMCKINFO ck;

  mmioSeek(This->hmmio, 0, SEEK_SET);

  /* create the RIFF chunk with formtype WAVE */
  ckRIFF.fccType = formtypeWAVE;
  ckRIFF.cksize  = 0;
  if (mmioCreateChunk(This->hmmio, &ckRIFF, MMIO_CREATERIFF) != S_OK)
    return AVIERR_FILEWRITE;

  /* the next chunk is the format */
  ck.ckid   = ckidWAVEFORMAT;
  ck.cksize = This->cbFormat;
  if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (This->lpFormat != NULL && This->cbFormat > 0) {
    if (mmioWrite(This->hmmio, (HPSTR)This->lpFormat, ck.cksize) != ck.cksize)
      return AVIERR_FILEWRITE;
  }
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;

  /* fact chunk is needed for non-pcm waveforms */
  if (This->lpFormat != NULL && This->cbFormat > sizeof(PCMWAVEFORMAT) &&
      This->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
    WAVEFORMATEX wfx;
    DWORD        dwFactLength;
    HACMSTREAM   has;

    /* try to open an appropriate audio codec to figure out
     * data for fact-chunk */
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    if (acmFormatSuggest(NULL, This->lpFormat, &wfx,
			 sizeof(wfx), ACM_FORMATSUGGESTF_WFORMATTAG)) {
      acmStreamOpen(&has, NULL, This->lpFormat, &wfx, NULL,
		    0, 0, ACM_STREAMOPENF_NONREALTIME);
      acmStreamSize(has, This->ckData.cksize, &dwFactLength,
		    ACM_STREAMSIZEF_SOURCE);
      dwFactLength /= wfx.nBlockAlign;
      acmStreamClose(has, 0);

      /* create the fact chunk */
      ck.ckid   = ckidWAVEFACT;
      ck.cksize = sizeof(dwFactLength);

      /* test for enough space before data chunk */
      if (mmioSeek(This->hmmio, 0, SEEK_CUR) > This->ckData.dwDataOffset
	  - ck.cksize - 4 * sizeof(DWORD))
	return AVIERR_FILEWRITE;
      if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
	return AVIERR_FILEWRITE;
      if (mmioWrite(This->hmmio, (HPSTR)&dwFactLength, ck.cksize) != ck.cksize)
	return AVIERR_FILEWRITE;
      if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
	return AVIERR_FILEWRITE;
    } else
      ERR(": fact chunk is needed for non-pcm files -- currently no codec found, so skipped!\n");
  }

  /* if there was extra stuff, we need to fill it with JUNK */
  if (mmioSeek(This->hmmio, 0, SEEK_CUR) + 2 * sizeof(DWORD) < This->ckData.dwDataOffset) {
    ck.ckid   = ckidAVIPADDING;
    ck.cksize = 0;
    if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
      return AVIERR_FILEWRITE;

    if (mmioSeek(This->hmmio, This->ckData.dwDataOffset
		 - 2 * sizeof(DWORD), SEEK_SET) == -1)
      return AVIERR_FILEWRITE;
    if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
      return AVIERR_FILEWRITE;
  }

  /* create the data chunk */
  ck.ckid   = ckidWAVEDATA;
  ck.cksize = This->ckData.cksize;
  if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (mmioSeek(This->hmmio, This->ckData.cksize, SEEK_CUR) == -1)
    return AVIERR_FILEWRITE;
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;

  /* some optional extra chunks? */
  if (This->extra.lp != NULL && This->extra.cb > 0) {
    /* chunk headers are already in structure */
    if (mmioWrite(This->hmmio, This->extra.lp, This->extra.cb) != This->extra.cb)
      return AVIERR_FILEWRITE;
  }

  /* close RIFF chunk */
  if (mmioAscend(This->hmmio, &ckRIFF, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (mmioFlush(This->hmmio, 0) != S_OK)
    return AVIERR_FILEWRITE;

  return AVIERR_OK;
}
