/*
 * Copyright 2003 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 "winuser.h"
#include "wingdi.h"
#include "winerror.h"
#include "mmsystem.h"
#include "vfw.h"

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

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

WINE_DEFAULT_DEBUG_CHANNEL(avifile);

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

/* internal interface to get access to table of stream in an editable stream */

DEFINE_AVIGUID(IID_IEditStreamInternal, 0x0002000A,0,0);

typedef struct _EditStreamTable {
  PAVISTREAM pStream;  /* stream which contains the data */
  DWORD      dwStart;  /* where starts the part which is also our */
  DWORD      dwLength; /* how many is also in this stream */
} EditStreamTable;

#define EditStreamEnd(This,streamNr) ((This)->pStreams[streamNr].dwStart + \
                                      (This)->pStreams[streamNr].dwLength)

typedef struct _IAVIEditStreamImpl IAVIEditStreamImpl;

struct _IAVIEditStreamImpl {
  IAVIEditStream       IAVIEditStream_iface;
  IAVIStream           IAVIStream_iface;

  LONG                 ref;

  AVISTREAMINFOW       sInfo;

  EditStreamTable     *pStreams;
  DWORD                nStreams;   /* current fill level of pStreams table */
  DWORD                nTableSize; /* size of pStreams table */

  BOOL                 bDecompress;
  PAVISTREAM           pCurStream;
  PGETFRAME            pg;         /* IGetFrame for pCurStream */
  LPBITMAPINFOHEADER   lpFrame;    /* frame of pCurStream */
};

static inline IAVIEditStreamImpl *impl_from_IAVIEditStream(IAVIEditStream *iface)
{
    return CONTAINING_RECORD(iface, IAVIEditStreamImpl, IAVIEditStream_iface);
}

static inline IAVIEditStreamImpl *impl_from_IAVIStream(IAVIStream *iface)
{
    return CONTAINING_RECORD(iface, IAVIEditStreamImpl, IAVIStream_iface);
}

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

static HRESULT AVIFILE_FindStreamInTable(IAVIEditStreamImpl* const This,
					 DWORD pos,PAVISTREAM *ppStream,
					 DWORD* streamPos,
					 DWORD* streamNr,BOOL bFindSample)
{
  DWORD n;

  TRACE("(%p,%u,%p,%p,%p,%d)\n",This,pos,ppStream,streamPos,
        streamNr,bFindSample);

  if (pos < This->sInfo.dwStart)
    return AVIERR_BADPARAM;

  pos -= This->sInfo.dwStart;
  for (n = 0; n < This->nStreams; n++) {
    if (pos < This->pStreams[n].dwLength) {
      *ppStream  = This->pStreams[n].pStream;
      *streamPos = This->pStreams[n].dwStart + pos;
      if (streamNr != NULL)
        *streamNr = n;

      return AVIERR_OK;
    }
    pos -= This->pStreams[n].dwLength;
  }
  if (pos == 0 && bFindSample) {
    *ppStream  = This->pStreams[--n].pStream;
    *streamPos = EditStreamEnd(This, n);
    if (streamNr != NULL)
      *streamNr = n;

    TRACE(" -- pos=0 && b=1 -> (%p,%u,%u)\n",*ppStream, *streamPos, n);
    return AVIERR_OK;
  } else {
    *ppStream = NULL;
    *streamPos = 0;
    if (streamNr != NULL)
      *streamNr = 0;

    TRACE(" -> ERROR (NULL,0,0)\n");
    return AVIERR_BADPARAM;
  }
}

static LPVOID AVIFILE_ReadFrame(IAVIEditStreamImpl* const This,
                                PAVISTREAM pstream, LONG pos)
{
  PGETFRAME pg;

  TRACE("(%p,%p,%d)\n",This,pstream,pos);

  if (pstream == NULL)
    return NULL;

  /* if stream changes make sure that only palette changes */
  if (This->pCurStream != pstream) {
    pg = AVIStreamGetFrameOpen(pstream, NULL);
    if (pg == NULL)
      return NULL;
    if (This->pg != NULL) {
      if (IGetFrame_SetFormat(pg, This->lpFrame, NULL, 0, 0, -1, -1) != S_OK) {
        AVIStreamGetFrameClose(pg);
        ERR(": IGetFrame_SetFormat failed\n");
        return NULL;
      }
      AVIStreamGetFrameClose(This->pg);
    }
    This->pg         = pg;
    This->pCurStream = pstream;
  }

  /* now get the decompressed frame */
  This->lpFrame = AVIStreamGetFrame(This->pg, pos);
  if (This->lpFrame != NULL)
    This->sInfo.dwSuggestedBufferSize = This->lpFrame->biSizeImage;

  return This->lpFrame;
}

static HRESULT AVIFILE_RemoveStream(IAVIEditStreamImpl* const This, DWORD nr)
{
  assert(This != NULL);
  assert(nr < This->nStreams);

  /* remove part nr */
  IAVIStream_Release(This->pStreams[nr].pStream);
  This->nStreams--;
  if (This->nStreams - nr > 0) {
    memmove(This->pStreams + nr, This->pStreams + nr + 1,
            (This->nStreams - nr) * sizeof(EditStreamTable));
  }
  This->pStreams[This->nStreams].pStream  = NULL;
  This->pStreams[This->nStreams].dwStart  = 0;
  This->pStreams[This->nStreams].dwLength = 0;

  /* try to merge the part before the deleted one and the one after it */
  if (0 < nr && 0 < This->nStreams &&
      This->pStreams[nr - 1].pStream == This->pStreams[nr].pStream) {
    if (EditStreamEnd(This, nr - 1) == This->pStreams[nr].dwStart) {
      This->pStreams[nr - 1].dwLength += This->pStreams[nr].dwLength;
      return AVIFILE_RemoveStream(This, nr);
    }
  }

  return AVIERR_OK;
}

static BOOL AVIFILE_FormatsEqual(PAVISTREAM avi1, PAVISTREAM avi2)
{
  LPVOID fmt1 = NULL, fmt2 = NULL;
  LONG size1, size2, start1, start2;
  BOOL status = FALSE;

  assert(avi1 != NULL && avi2 != NULL);

  /* get stream starts and check format sizes */
  start1 = AVIStreamStart(avi1);
  start2 = AVIStreamStart(avi2);
  if (FAILED(AVIStreamFormatSize(avi1, start1, &size1)))
    return FALSE;
  if (FAILED(AVIStreamFormatSize(avi2, start2, &size2)))
    return FALSE;
  if (size1 != size2)
    return FALSE;

  /* sizes match, now get formats and compare them */
  fmt1 = HeapAlloc(GetProcessHeap(), 0, size1);
  if (fmt1 == NULL)
    return FALSE;
  if (SUCCEEDED(AVIStreamReadFormat(avi1, start1, fmt1, &size1))) {
    fmt2 = HeapAlloc(GetProcessHeap(), 0, size1);
    if (fmt2 != NULL) {
      if (SUCCEEDED(AVIStreamReadFormat(avi2, start2, fmt2, &size1)))
        status = (memcmp(fmt1, fmt2, size1) == 0);
    }
  }

  HeapFree(GetProcessHeap(), 0, fmt2);
  HeapFree(GetProcessHeap(), 0, fmt1);

  return status;
}

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

static HRESULT WINAPI IAVIEditStream_fnQueryInterface(IAVIEditStream*iface,REFIID refiid,LPVOID *obj)
{
  IAVIEditStreamImpl *This = impl_from_IAVIEditStream(iface);

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

  if (IsEqualGUID(&IID_IUnknown, refiid) ||
      IsEqualGUID(&IID_IAVIEditStream, refiid) ||
      IsEqualGUID(&IID_IEditStreamInternal, refiid)) {
    *obj = iface;
    IAVIEditStream_AddRef(iface);

    return S_OK;
  } else if (IsEqualGUID(&IID_IAVIStream, refiid)) {
    *obj = &This->IAVIStream_iface;
    IAVIEditStream_AddRef(iface);

    return S_OK;
  }

  return E_NOINTERFACE;
}

static ULONG   WINAPI IAVIEditStream_fnAddRef(IAVIEditStream*iface)
{
  IAVIEditStreamImpl *This = impl_from_IAVIEditStream(iface);
  ULONG ref = InterlockedIncrement(&This->ref);

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

  return ref;
}

static ULONG   WINAPI IAVIEditStream_fnRelease(IAVIEditStream*iface)
{
  IAVIEditStreamImpl *This = impl_from_IAVIEditStream(iface);
  DWORD i;
  ULONG ref = InterlockedDecrement(&This->ref);

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

  if (!ref) {
    /* release memory */
    if (This->pg != NULL)
      AVIStreamGetFrameClose(This->pg);
    if (This->pStreams != NULL) {
      for (i = 0; i < This->nStreams; i++) {
        if (This->pStreams[i].pStream != NULL)
          IAVIStream_Release(This->pStreams[i].pStream);
      }
      HeapFree(GetProcessHeap(), 0, This->pStreams);
    }

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

static HRESULT WINAPI IAVIEditStream_fnCut(IAVIEditStream*iface,LONG*plStart,
                                           LONG*plLength,PAVISTREAM*ppResult)
{
  IAVIEditStreamImpl *This = impl_from_IAVIEditStream(iface);
  PAVISTREAM stream;
  DWORD      start, len, streamPos, streamNr;
  HRESULT    hr;

  TRACE("(%p,%p,%p,%p)\n",iface,plStart,plLength,ppResult);

  if (ppResult != NULL)
    *ppResult = NULL;
  if (plStart == NULL || plLength == NULL || *plStart < 0)
    return AVIERR_BADPARAM;

  /* if asked for cut part copy it before deleting */
  if (ppResult != NULL) {
    hr = IAVIEditStream_Copy(iface, plStart, plLength, ppResult);
    if (FAILED(hr))
      return hr;
  }

  start = *plStart;
  len   = *plLength;

  /* now delete the requested part */
  while (len > 0) {
    hr = AVIFILE_FindStreamInTable(This, start, &stream,
                                   &streamPos, &streamNr, FALSE);
    if (FAILED(hr))
      return hr;
    if (This->pStreams[streamNr].dwStart == streamPos) {
      /* deleting from start of part */
      if (len < This->pStreams[streamNr].dwLength) {
        start += len;
        This->pStreams[streamNr].dwStart  += len;
        This->pStreams[streamNr].dwLength -= len;
        This->sInfo.dwLength -= len;
        len = 0;

        /* we must return decompressed data now */
        This->bDecompress = TRUE;
      } else {
        /* deleting hole part */
        len -= This->pStreams[streamNr].dwLength;
        AVIFILE_RemoveStream(This,streamNr);
      }
    } else if (EditStreamEnd(This, streamNr) <= streamPos + len) {
      /* deleting at end of a part */
      DWORD count = EditStreamEnd(This, streamNr) - streamPos;
      This->sInfo.dwLength -= count;
      len                  -= count;
      This->pStreams[streamNr].dwLength =
        streamPos - This->pStreams[streamNr].dwStart;
    } else {
      /* splitting */
      if (This->nStreams + 1 >= This->nTableSize) {
        This->pStreams = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pStreams,
                                     (This->nTableSize + 32) * sizeof(EditStreamTable));
        if (This->pStreams == NULL)
          return AVIERR_MEMORY;
        This->nTableSize += 32;
      }
      memmove(This->pStreams + streamNr + 1, This->pStreams + streamNr,
              (This->nStreams - streamNr) * sizeof(EditStreamTable));
      This->nStreams++;

      IAVIStream_AddRef(This->pStreams[streamNr + 1].pStream);
      This->pStreams[streamNr + 1].dwStart  = streamPos + len;
      This->pStreams[streamNr + 1].dwLength =
        EditStreamEnd(This, streamNr) - This->pStreams[streamNr + 1].dwStart;

      This->pStreams[streamNr].dwLength =
        streamPos - This->pStreams[streamNr].dwStart;
      This->sInfo.dwLength -= len;
      len = 0;
    }
  }

  This->sInfo.dwEditCount++;

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIEditStream_fnCopy(IAVIEditStream*iface,LONG*plStart,
                                            LONG*plLength,PAVISTREAM*ppResult)
{
  IAVIEditStreamImpl *This = impl_from_IAVIEditStream(iface);
  IAVIEditStreamImpl* pEdit;
  HRESULT hr;
  LONG start = 0;

  TRACE("(%p,%p,%p,%p)\n",iface,plStart,plLength,ppResult);

  if (ppResult == NULL)
    return AVIERR_BADPARAM;
  *ppResult = NULL;
  if (plStart == NULL || plLength == NULL || *plStart < 0 || *plLength < 0)
    return AVIERR_BADPARAM;

  /* check bounds */
  if (*(LPDWORD)plLength > This->sInfo.dwLength)
    *(LPDWORD)plLength = This->sInfo.dwLength;
  if (*(LPDWORD)plStart < This->sInfo.dwStart) {
    *(LPDWORD)plLength -= This->sInfo.dwStart - *(LPDWORD)plStart;
    *(LPDWORD)plStart   = This->sInfo.dwStart;
    if (*plLength < 0)
      return AVIERR_BADPARAM;
  }
  if (*(LPDWORD)plStart + *(LPDWORD)plLength > This->sInfo.dwStart + This->sInfo.dwLength)
    *(LPDWORD)plLength = This->sInfo.dwStart + This->sInfo.dwLength -
      *(LPDWORD)plStart;

  pEdit = (IAVIEditStreamImpl*)AVIFILE_CreateEditStream(NULL);
  if (pEdit == NULL)
    return AVIERR_MEMORY;

  hr = IAVIEditStream_Paste((PAVIEDITSTREAM)pEdit, &start, plLength, &This->IAVIStream_iface,
                            *plStart, *plStart + *plLength);
  *plStart = start;
  if (FAILED(hr))
    IAVIEditStream_Release((PAVIEDITSTREAM)pEdit);
  else
    *ppResult = &This->IAVIStream_iface;

  return hr;
}

static HRESULT WINAPI IAVIEditStream_fnPaste(IAVIEditStream*iface,LONG*plStart,
                                             LONG*plLength,PAVISTREAM pSource,
                                             LONG lStart,LONG lLength)
{
  IAVIEditStreamImpl *This = impl_from_IAVIEditStream(iface);
  AVISTREAMINFOW      srcInfo;
  IAVIEditStreamImpl *pEdit = NULL;
  PAVISTREAM          pStream;
  DWORD               startPos, endPos, streamNr, nStreams;
  ULONG               n;

  TRACE("(%p,%p,%p,%p,%d,%d)\n",iface,plStart,plLength,
	pSource,lStart,lLength);

  if (pSource == NULL)
    return AVIERR_BADHANDLE;
  if (plStart == NULL || *plStart < 0)
    return AVIERR_BADPARAM;
  if (This->sInfo.dwStart + This->sInfo.dwLength < *plStart)
    return AVIERR_BADPARAM; /* Can't paste with holes */
  if (FAILED(IAVIStream_Info(pSource, &srcInfo, sizeof(srcInfo))))
    return AVIERR_ERROR;
  if (lStart < srcInfo.dwStart || lStart >= srcInfo.dwStart + srcInfo.dwLength)
    return AVIERR_BADPARAM;
  if (This->sInfo.fccType == 0) {
    /* This stream is empty */
    IAVIStream_Info(pSource, &This->sInfo, sizeof(This->sInfo));
    This->sInfo.dwStart  = *plStart;
    This->sInfo.dwLength = 0;
  }
  if (This->sInfo.fccType != srcInfo.fccType)
    return AVIERR_UNSUPPORTED; /* different stream types */
  if (lLength == -1) /* Copy the hole stream */
    lLength = srcInfo.dwLength;
  if (lStart + lLength > srcInfo.dwStart + srcInfo.dwLength)
    lLength = srcInfo.dwStart + srcInfo.dwLength - lStart;
  if (lLength + *plStart >= 0x80000000)
    return AVIERR_MEMORY;

  /* streamtype specific tests */
  if (srcInfo.fccType == streamtypeVIDEO) {
    LONG size;

    size = srcInfo.rcFrame.right - srcInfo.rcFrame.left;
    if (size != This->sInfo.rcFrame.right - This->sInfo.rcFrame.left)
      return AVIERR_UNSUPPORTED; /* FIXME: Can't GetFrame convert it? */
    size = srcInfo.rcFrame.bottom - srcInfo.rcFrame.top;
    if (size != This->sInfo.rcFrame.bottom - This->sInfo.rcFrame.top)
      return AVIERR_UNSUPPORTED; /* FIXME: Can't GetFrame convert it? */
  } else if (srcInfo.fccType == streamtypeAUDIO) {
    if (!AVIFILE_FormatsEqual(&This->IAVIStream_iface, pSource))
      return AVIERR_UNSUPPORTED;
  } else {
    /* FIXME: streamtypeMIDI and streamtypeTEXT */
    return AVIERR_UNSUPPORTED;
  }

  /* try to get an IEditStreamInternal interface */
  if (SUCCEEDED(IAVIStream_QueryInterface(pSource, &IID_IEditStreamInternal, (LPVOID*)&pEdit)))
      IAVIEditStream_Release(&pEdit->IAVIEditStream_iface);  /* pSource holds a reference */

  /* for video must check for change of format */
  if (This->sInfo.fccType == streamtypeVIDEO) {
    if (! This->bDecompress) {
      /* Need to decompress if any of the following conditions matches:
       *  - pSource is an editable stream which decompresses
       *  - the nearest keyframe of pSource isn't lStart
       *  - the nearest keyframe of this stream isn't *plStart
       *  - the format of pSource doesn't match this one
       */
      if ((pEdit != NULL && pEdit->bDecompress) ||
	  AVIStreamNearestKeyFrame(pSource, lStart) != lStart ||
          AVIStreamNearestKeyFrame(&This->IAVIStream_iface, *plStart) != *plStart ||
          (This->nStreams > 0 && !AVIFILE_FormatsEqual(&This->IAVIStream_iface, pSource))) {
	/* Use first stream part to get format to convert everything to */
	AVIFILE_ReadFrame(This, This->pStreams[0].pStream,
			  This->pStreams[0].dwStart);

	/* Check if we could convert the source streams to the desired format... */
	if (pEdit != NULL) {
	  if (FAILED(AVIFILE_FindStreamInTable(pEdit, lStart, &pStream,
					       &startPos, &streamNr, TRUE)))
	    return AVIERR_INTERNAL;
	  for (n = lStart; n < lStart + lLength; streamNr++) {
	    if (AVIFILE_ReadFrame(This, pEdit->pStreams[streamNr].pStream, startPos) == NULL)
	      return AVIERR_BADFORMAT;
	    startPos = pEdit->pStreams[streamNr].dwStart;
	    n += pEdit->pStreams[streamNr].dwLength;
	  }
	} else if (AVIFILE_ReadFrame(This, pSource, lStart) == NULL)
	  return AVIERR_BADFORMAT;

	This->bDecompress      = TRUE;
	This->sInfo.fccHandler = 0;
      }
    } else if (AVIFILE_ReadFrame(This, pSource, lStart) == NULL)
      return AVIERR_BADFORMAT; /* Can't convert source to own format */
  } /* FIXME: something special for the other formats? */

  /* Make sure we have enough memory for parts */
  if (pEdit != NULL) {
    DWORD nLastStream;

    AVIFILE_FindStreamInTable(pEdit, lStart + lLength, &pStream,
			      &endPos, &nLastStream, TRUE);
    AVIFILE_FindStreamInTable(pEdit, lStart, &pStream,
			      &startPos, &streamNr, FALSE);
    if (nLastStream == streamNr)
      nLastStream++;

    nStreams = nLastStream - streamNr;
  } else 
    nStreams = 1;
  if (This->nStreams + nStreams + 1 > This->nTableSize) {
    n = This->nStreams + nStreams + 33;

    This->pStreams = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pStreams, n * sizeof(EditStreamTable));
    if (This->pStreams == NULL)
      return AVIERR_MEMORY;
    This->nTableSize = n;
  }

  if (plLength != NULL)
    *plLength = lLength;

  /* now do the real work */
  if (This->sInfo.dwStart + This->sInfo.dwLength > *plStart) {
    AVIFILE_FindStreamInTable(This, *plStart, &pStream,
			      &startPos, &streamNr, FALSE);
    if (startPos != This->pStreams[streamNr].dwStart) {
      /* split stream streamNr at startPos */
      memmove(This->pStreams + streamNr + nStreams + 1,
	      This->pStreams + streamNr,
	      (This->nStreams + nStreams - streamNr + 1) * sizeof(EditStreamTable));

      This->pStreams[streamNr + 2].dwLength =
	EditStreamEnd(This, streamNr + 2) - startPos;
      This->pStreams[streamNr + 2].dwStart = startPos;
      This->pStreams[streamNr].dwLength =
	startPos - This->pStreams[streamNr].dwStart;
      IAVIStream_AddRef(This->pStreams[streamNr].pStream);
      streamNr++;
    } else {
      /* insert before stream at streamNr */
      memmove(This->pStreams + streamNr + nStreams, This->pStreams + streamNr,
	      (This->nStreams + nStreams - streamNr) * sizeof(EditStreamTable));
    }
  } else /* append the streams */
    streamNr = This->nStreams;

  if (pEdit != NULL) {
    /* insert the parts of the editable stream instead of itself */
    AVIFILE_FindStreamInTable(pEdit, lStart + lLength, &pStream,
			      &endPos, NULL, FALSE);
    AVIFILE_FindStreamInTable(pEdit, lStart, &pStream, &startPos, &n, FALSE);

    memcpy(This->pStreams + streamNr, pEdit->pStreams + n,
	   nStreams * sizeof(EditStreamTable));
    if (This->pStreams[streamNr].dwStart < startPos) {
      This->pStreams[streamNr].dwLength =
	EditStreamEnd(This, streamNr) - startPos;
      This->pStreams[streamNr].dwStart  = startPos;
    }
    if (endPos < EditStreamEnd(This, streamNr + nStreams))
      This->pStreams[streamNr + nStreams].dwLength =
	endPos - This->pStreams[streamNr + nStreams].dwStart;
  } else {
    /* a simple stream */
    This->pStreams[streamNr].pStream  = pSource;
    This->pStreams[streamNr].dwStart  = lStart;
    This->pStreams[streamNr].dwLength = lLength;
  }

  for (n = 0; n < nStreams; n++) {
    IAVIStream_AddRef(This->pStreams[streamNr + n].pStream);
    if (0 < streamNr + n &&
	This->pStreams[streamNr + n - 1].pStream != This->pStreams[streamNr + n].pStream) {
      This->sInfo.dwFlags |= AVISTREAMINFO_FORMATCHANGES;
      This->sInfo.dwFormatChangeCount++;
    }
  }
  This->sInfo.dwEditCount++;
  This->sInfo.dwLength += lLength;
  This->nStreams += nStreams;

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIEditStream_fnClone(IAVIEditStream*iface,
                                             PAVISTREAM*ppResult)
{
  IAVIEditStreamImpl *This = impl_from_IAVIEditStream(iface);
  IAVIEditStreamImpl* pEdit;
  DWORD i;

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

  if (ppResult == NULL)
    return AVIERR_BADPARAM;
  *ppResult = NULL;

  pEdit = (IAVIEditStreamImpl*)AVIFILE_CreateEditStream(NULL);
  if (pEdit == NULL)
    return AVIERR_MEMORY;
  if (This->nStreams > pEdit->nTableSize) {
    pEdit->pStreams = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pEdit->pStreams,
                                  This->nStreams * sizeof(EditStreamTable));
    if (pEdit->pStreams == NULL)
      return AVIERR_MEMORY;
    pEdit->nTableSize = This->nStreams;
  }
  pEdit->nStreams = This->nStreams;
  memcpy(pEdit->pStreams, This->pStreams,
         This->nStreams * sizeof(EditStreamTable));
  memcpy(&pEdit->sInfo,&This->sInfo,sizeof(This->sInfo));
  for (i = 0; i < This->nStreams; i++) {
    if (pEdit->pStreams[i].pStream != NULL)
      IAVIStream_AddRef(pEdit->pStreams[i].pStream);
  }

  *ppResult = &This->IAVIStream_iface;

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIEditStream_fnSetInfo(IAVIEditStream*iface,
                                               LPAVISTREAMINFOW asi,LONG size)
{
  IAVIEditStreamImpl *This = impl_from_IAVIEditStream(iface);

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

  /* check parameters */
  if (size >= 0 && size < sizeof(AVISTREAMINFOW))
    return AVIERR_BADSIZE;

  This->sInfo.wLanguage = asi->wLanguage;
  This->sInfo.wPriority = asi->wPriority;
  This->sInfo.dwStart   = asi->dwStart;
  This->sInfo.dwRate    = asi->dwRate;
  This->sInfo.dwScale   = asi->dwScale;
  This->sInfo.dwQuality = asi->dwQuality;
  CopyRect(&This->sInfo.rcFrame, &asi->rcFrame);
  memcpy(This->sInfo.szName, asi->szName, sizeof(asi->szName));
  This->sInfo.dwEditCount++;

  return AVIERR_OK;
}

static const struct IAVIEditStreamVtbl ieditstream = {
  IAVIEditStream_fnQueryInterface,
  IAVIEditStream_fnAddRef,
  IAVIEditStream_fnRelease,
  IAVIEditStream_fnCut,
  IAVIEditStream_fnCopy,
  IAVIEditStream_fnPaste,
  IAVIEditStream_fnClone,
  IAVIEditStream_fnSetInfo
};

static HRESULT WINAPI IEditAVIStream_fnQueryInterface(IAVIStream*iface,
                                                      REFIID refiid,LPVOID*obj)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );
  return IAVIEditStream_QueryInterface(&This->IAVIEditStream_iface,refiid,obj);
}

static ULONG   WINAPI IEditAVIStream_fnAddRef(IAVIStream*iface)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );
  return IAVIEditStream_AddRef(&This->IAVIEditStream_iface);
}

static ULONG   WINAPI IEditAVIStream_fnRelease(IAVIStream*iface)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );
  return IAVIEditStream_Release(&This->IAVIEditStream_iface);
}

static HRESULT WINAPI IEditAVIStream_fnCreate(IAVIStream*iface,
                                              LPARAM lParam1,LPARAM lParam2)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );

  if (lParam2 != 0)
    return AVIERR_ERROR;

  if (This->pStreams == NULL) {
    This->pStreams = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256 * sizeof(EditStreamTable));
    if (This->pStreams == NULL)
      return AVIERR_MEMORY;
    This->nTableSize = 256;
  }

  if (lParam1 != 0) {
    IAVIStream_Info((PAVISTREAM)lParam1, &This->sInfo, sizeof(This->sInfo));
    IAVIStream_AddRef((PAVISTREAM)lParam1);
    This->pStreams[0].pStream  = (PAVISTREAM)lParam1;
    This->pStreams[0].dwStart  = This->sInfo.dwStart;
    This->pStreams[0].dwLength = This->sInfo.dwLength;
    This->nStreams = 1;
  }
  return AVIERR_OK;
}

static HRESULT WINAPI IEditAVIStream_fnInfo(IAVIStream*iface,
                                            AVISTREAMINFOW *psi,LONG size)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );

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

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

  if (This->bDecompress)
    This->sInfo.fccHandler = 0;

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

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

static LONG    WINAPI IEditAVIStream_fnFindSample(IAVIStream*iface,LONG pos,
                                                  LONG flags)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );
  PAVISTREAM stream;
  DWORD      streamPos, streamNr;

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

  if (flags & FIND_FROM_START)
    pos = (LONG)This->sInfo.dwStart;

  /* outside of stream? */
  if (pos < (LONG)This->sInfo.dwStart ||
      (LONG)This->sInfo.dwStart + (LONG)This->sInfo.dwLength <= pos)
    return -1;

  /* map our position to a stream and position in it */
  if (AVIFILE_FindStreamInTable(This, pos, &stream, &streamPos,
                                &streamNr, TRUE) != S_OK)
    return -1; /* doesn't exist */

  if (This->bDecompress) {
    /* only one stream -- format changes only at start */
    if (flags & FIND_FORMAT)
      return (flags & FIND_NEXT ? -1 : 0);

    /* FIXME: map positions back to us */
    return IAVIStream_FindSample(stream, streamPos, flags);
  } else {
    /* assume change of format every frame */
    return pos;
  }
}

static HRESULT WINAPI IEditAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,
                                                  LPVOID format,LONG*fmtsize)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );
  LPBITMAPINFOHEADER  lp;
  PAVISTREAM          stream;
  DWORD               n;
  HRESULT             hr;

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

  if (fmtsize == NULL || pos < This->sInfo.dwStart ||
      This->sInfo.dwStart + This->sInfo.dwLength <= pos)
    return AVIERR_BADPARAM;

  /* find stream corresponding to position */
  hr = AVIFILE_FindStreamInTable(This, pos, &stream, &n, NULL, FALSE);
  if (FAILED(hr))
    return hr;

  if (! This->bDecompress)
    return IAVIStream_ReadFormat(stream, n, format, fmtsize);

  lp = AVIFILE_ReadFrame(This, stream, n);
  if (lp == NULL)
    return AVIERR_ERROR;
  if (lp->biBitCount <= 8) {
    n  = (lp->biClrUsed > 0 ? lp->biClrUsed : 1 << lp->biBitCount);
    n *= sizeof(RGBQUAD);
  } else
    n = 0;
  n += lp->biSize;
  
  memcpy(format, lp, min((LONG)n, *fmtsize));
  hr = ((LONG)n > *fmtsize ? AVIERR_BUFFERTOOSMALL : AVIERR_OK);
  *fmtsize = n;

  return hr;
}

static HRESULT WINAPI IEditAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,
                                                 LPVOID format,LONG formatsize)
{
  TRACE("(%p,%d,%p,%d)\n",iface,pos,format,formatsize);

  return AVIERR_UNSUPPORTED;
}

static HRESULT WINAPI IEditAVIStream_fnRead(IAVIStream*iface,LONG start,
                                            LONG samples,LPVOID buffer,
                                            LONG buffersize,LONG*bytesread,
                                            LONG*samplesread)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );
  PAVISTREAM stream;
  DWORD   streamPos, streamNr;
  LONG    readBytes, readSamples, count;
  HRESULT hr;

  TRACE("(%p,%d,%d,%p,%d,%p,%p) -- 0x%08X\n",iface,start,samples,
        buffer,buffersize,bytesread,samplesread,This->sInfo.fccType);

  /* check parameters */
  if (bytesread != NULL)
    *bytesread = 0;
  if (samplesread != NULL)
    *samplesread = 0;
  if (buffersize < 0)
    return AVIERR_BADSIZE;
  if ((DWORD)start < This->sInfo.dwStart ||
      This->sInfo.dwStart + This->sInfo.dwLength < (DWORD)start)
    return AVIERR_BADPARAM;

  if (! This->bDecompress) {
    /* audio like data -- sample-based */
    do {
      if (samples == 0)
        return AVIERR_OK; /* nothing at all or already done */

      if (FAILED(AVIFILE_FindStreamInTable(This, start, &stream,
                                           &streamPos, &streamNr, FALSE)))
        return AVIERR_ERROR;

      /* limit to end of the stream */
      count = samples;
      if (streamPos + count > EditStreamEnd(This, streamNr))
        count = EditStreamEnd(This, streamNr) - streamPos;

      hr = IAVIStream_Read(stream, streamPos, count, buffer, buffersize,
                           &readBytes, &readSamples);
      if (FAILED(hr))
        return hr;
      if (readBytes == 0 && readSamples == 0 && count != 0)
        return AVIERR_FILEREAD; /* for bad stream implementations */

      if (samplesread != NULL)
        *samplesread += readSamples;
      if (bytesread != NULL)
        *bytesread += readBytes;
      if (buffer != NULL) {
        buffer = ((LPBYTE)buffer)+readBytes;
        buffersize     -= readBytes;
      }
      start   += count;
      samples -= count;
    } while (This->sInfo.dwStart + This->sInfo.dwLength > start);
  } else {
    /* video like data -- frame-based */
    LPBITMAPINFOHEADER lp;

    if (samples == 0)
      return AVIERR_OK;

    if (FAILED(AVIFILE_FindStreamInTable(This, start, &stream,
                                         &streamPos, &streamNr, FALSE)))
      return AVIERR_ERROR;

    lp = AVIFILE_ReadFrame(This, stream, streamPos);
    if (lp == NULL)
      return AVIERR_ERROR;

    if (buffer != NULL) {
      /* need size of format to skip */
      if (lp->biBitCount <= 8) {
        count  = lp->biClrUsed > 0 ? lp->biClrUsed : 1 << lp->biBitCount;
        count *= sizeof(RGBQUAD);
      } else
        count = 0;
      count += lp->biSize;

      if (buffersize < lp->biSizeImage)
        return AVIERR_BUFFERTOOSMALL;
      memcpy(buffer, (LPBYTE)lp + count, lp->biSizeImage);
    }

    if (bytesread != NULL)
      *bytesread = lp->biSizeImage;
    if (samplesread != NULL)
      *samplesread = 1;
  }

  return AVIERR_OK;
}

static HRESULT WINAPI IEditAVIStream_fnWrite(IAVIStream*iface,LONG start,
                                             LONG samples,LPVOID buffer,
                                             LONG buffersize,DWORD flags,
                                             LONG*sampwritten,LONG*byteswritten)
{
  TRACE("(%p,%d,%d,%p,%d,0x%08X,%p,%p)\n",iface,start,samples,buffer,
        buffersize,flags,sampwritten,byteswritten);

  /* be sure return parameters have correct values */
  if (sampwritten != NULL)
    *sampwritten = 0;
  if (byteswritten != NULL)
    *byteswritten = 0;

  return AVIERR_UNSUPPORTED;
}

static HRESULT WINAPI IEditAVIStream_fnDelete(IAVIStream*iface,LONG start,
                                              LONG samples)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );

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

  return IAVIEditStream_Cut(&This->IAVIEditStream_iface,&start,&samples,NULL);
}

static HRESULT WINAPI IEditAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,
                                                LPVOID lp,LONG *lpread)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );
  DWORD n;

  TRACE("(%p,0x%08X,%p,%p)\n",iface,fcc,lp,lpread);

  /* check parameters */
  if (lp == NULL || lpread == NULL)
    return AVIERR_BADPARAM;

  /* simply ask every stream and return the first block found */
  for (n = 0; n < This->nStreams; n++) {
    HRESULT hr = IAVIStream_ReadData(This->pStreams[n].pStream,fcc,lp,lpread);

    if (SUCCEEDED(hr))
      return hr;
  }

  *lpread = 0;
  return AVIERR_NODATA;
}

static HRESULT WINAPI IEditAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,
                                                 LPVOID lp,LONG size)
{
  TRACE("(%p,0x%08X,%p,%d)\n",iface,fcc,lp,size);

  return AVIERR_UNSUPPORTED;
}

static HRESULT WINAPI IEditAVIStream_fnSetInfo(IAVIStream*iface,
                                               AVISTREAMINFOW*info,LONG len)
{
  IAVIEditStreamImpl *This = impl_from_IAVIStream( iface );

  TRACE("(%p,%p,%d)\n",iface,info,len);

  return IAVIEditStream_SetInfo(&This->IAVIEditStream_iface,info,len);
}

static const struct IAVIStreamVtbl ieditstast = {
  IEditAVIStream_fnQueryInterface,
  IEditAVIStream_fnAddRef,
  IEditAVIStream_fnRelease,
  IEditAVIStream_fnCreate,
  IEditAVIStream_fnInfo,
  IEditAVIStream_fnFindSample,
  IEditAVIStream_fnReadFormat,
  IEditAVIStream_fnSetFormat,
  IEditAVIStream_fnRead,
  IEditAVIStream_fnWrite,
  IEditAVIStream_fnDelete,
  IEditAVIStream_fnReadData,
  IEditAVIStream_fnWriteData,
  IEditAVIStream_fnSetInfo
};

PAVIEDITSTREAM AVIFILE_CreateEditStream(PAVISTREAM pstream)
{
  IAVIEditStreamImpl *pedit = NULL;

  pedit = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIEditStreamImpl));
  if (pedit == NULL)
    return NULL;

  pedit->IAVIEditStream_iface.lpVtbl = &ieditstream;
  pedit->IAVIStream_iface.lpVtbl = &ieditstast;
  pedit->ref = 1;

  IAVIStream_Create(&pedit->IAVIStream_iface, (LPARAM)pstream, 0);

  return (PAVIEDITSTREAM)pedit;
}
