/*
 * 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"

WINE_DEFAULT_DEBUG_CHANNEL(avifile);

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

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

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 INTERFACE IEditStreamInternal
DECLARE_INTERFACE_(IEditStreamInternal,IUnknown)
{
    /*** IUnknown methods ***/
    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;
    /*** IEditStreamInternal methods ***/
    STDMETHOD(GetEditStreamImpl)(THIS_ LPVOID*) PURE;
};
#undef INTERFACE

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

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

static HRESULT WINAPI IAVIEditStream_fnQueryInterface(IAVIEditStream*iface,REFIID refiid,LPVOID *obj);
static ULONG   WINAPI IAVIEditStream_fnAddRef(IAVIEditStream*iface);
static ULONG   WINAPI IAVIEditStream_fnRelease(IAVIEditStream*iface);
static HRESULT WINAPI IAVIEditStream_fnCut(IAVIEditStream*iface,LONG*plStart,
                                           LONG*plLength,PAVISTREAM*ppResult);
static HRESULT WINAPI IAVIEditStream_fnCopy(IAVIEditStream*iface,LONG*plStart,
                                            LONG*plLength,PAVISTREAM*ppResult);
static HRESULT WINAPI IAVIEditStream_fnPaste(IAVIEditStream*iface,LONG*plStart,
                                             LONG*plLength,PAVISTREAM pSource,
                                             LONG lStart,LONG lEnd);
static HRESULT WINAPI IAVIEditStream_fnClone(IAVIEditStream*iface,
                                             PAVISTREAM*ppResult);
static HRESULT WINAPI IAVIEditStream_fnSetInfo(IAVIEditStream*iface,
                                               LPAVISTREAMINFOW asi,LONG size);

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);
static ULONG   WINAPI IEditAVIStream_fnAddRef(IAVIStream*iface);
static ULONG   WINAPI IEditAVIStream_fnRelease(IAVIStream*iface);
static HRESULT WINAPI IEditAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2);
static HRESULT WINAPI IEditAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size);
static LONG    WINAPI IEditAVIStream_fnFindSample(IAVIStream*iface,LONG pos,
                                                  LONG flags);
static HRESULT WINAPI IEditAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG*formatsize);
static HRESULT WINAPI IEditAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize);
static HRESULT WINAPI IEditAVIStream_fnRead(IAVIStream*iface,LONG start,
                                            LONG samples,LPVOID buffer,
                                            LONG buffersize,LONG*bytesread,
                                            LONG*samplesread);
static HRESULT WINAPI IEditAVIStream_fnWrite(IAVIStream*iface,LONG start,
                                             LONG samples,LPVOID buffer,
                                             LONG buffersize,DWORD flags,
                                             LONG*sampwritten,LONG*byteswritten);
static HRESULT WINAPI IEditAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples);
static HRESULT WINAPI IEditAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,
                                                LPVOID lp,LONG *lpread);
static HRESULT WINAPI IEditAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,
                                                 LPVOID lp,LONG size);
static HRESULT WINAPI IEditAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen);

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
};

static HRESULT WINAPI IEditStreamInternal_fnQueryInterface(IEditStreamInternal*iface,REFIID refiid,LPVOID*obj);
static ULONG   WINAPI IEditStreamInternal_fnAddRef(IEditStreamInternal*iface);
static ULONG   WINAPI IEditStreamInternal_fnRelease(IEditStreamInternal*iface);
static HRESULT WINAPI IEditStreamInternal_fnGetEditStreamImpl(IEditStreamInternal*iface,LPVOID*ppimpl);

static const struct IEditStreamInternalVtbl ieditstreaminternal = {
  IEditStreamInternal_fnQueryInterface,
  IEditStreamInternal_fnAddRef,
  IEditStreamInternal_fnRelease,
  IEditStreamInternal_fnGetEditStreamImpl
};

typedef struct _IAVIEditStreamImpl IAVIEditStreamImpl;

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

  /* IAVIStream stuff */
  IAVIEditStreamImpl *pae;
} IEditAVIStreamImpl;

typedef struct _IEditStreamInternalImpl {
  /* IUnknown stuff */
  const IEditStreamInternalVtbl *lpVtbl;

  /* IEditStreamInternal stuff */
  IAVIEditStreamImpl *pae;
} IEditStreamInternalImpl;

struct _IAVIEditStreamImpl {
  /* IUnknown stuff */
  const IAVIEditStreamVtbl *lpVtbl;
  LONG  ref;

  /* IAVIEditStream stuff */
  IEditAVIStreamImpl      iAVIStream;
  IEditStreamInternalImpl iEditStreamInternal;

  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 */
};

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

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

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

  pedit->lpVtbl            = &ieditstream;
  pedit->iAVIStream.lpVtbl = &ieditstast;
  pedit->iAVIStream.pae    = pedit;
  pedit->iEditStreamInternal.lpVtbl = &ieditstreaminternal;
  pedit->iEditStreamInternal.pae    = pedit;
  pedit->ref = 1;

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

  return (PAVIEDITSTREAM)pedit;
}

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 = (IAVIEditStreamImpl *)iface;

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

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

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

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

    return S_OK;
  }

  return OLE_E_ENUM_NOMORE;
}

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

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

  return ref;
}

static ULONG   WINAPI IAVIEditStream_fnRelease(IAVIEditStream*iface)
{
  IAVIEditStreamImpl *This = (IAVIEditStreamImpl *)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 = (IAVIEditStreamImpl *)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 = (IAVIEditStreamImpl *)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,
                            (PAVISTREAM)&This->iAVIStream,*plStart,
                            *plStart + *plLength);
  *plStart = start;
  if (FAILED(hr))
    IAVIEditStream_Release((PAVIEDITSTREAM)pEdit);
  else
    *ppResult = (PAVISTREAM)&pEdit->iAVIStream;

  return hr;
}

static HRESULT WINAPI IAVIEditStream_fnPaste(IAVIEditStream*iface,LONG*plStart,
                                             LONG*plLength,PAVISTREAM pSource,
                                             LONG lStart,LONG lLength)
{
  IAVIEditStreamImpl *This = (IAVIEditStreamImpl *)iface;
  AVISTREAMINFOW      srcInfo;
  IEditStreamInternal*pInternal = NULL;
  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((PAVISTREAM)&This->iAVIStream, 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*)&pInternal))) {
    pInternal->lpVtbl->GetEditStreamImpl(pInternal, (LPVOID*)&pEdit);
    pInternal->lpVtbl->Release(pInternal);
  }

  /* 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((PAVISTREAM)&This->iAVIStream, *plStart) != *plStart ||
	  (This->nStreams > 0 && !AVIFILE_FormatsEqual((PAVISTREAM)&This->iAVIStream, 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 = (IAVIEditStreamImpl *)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 = (PAVISTREAM)&pEdit->iAVIStream;

  return AVIERR_OK;
}

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

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

  /* check parameters */
  if (asi == NULL)
    return AVIERR_BADPARAM;
  if (size != sizeof(AVISTREAMINFOW))
    return AVIERR_BADSIZE;
  if (asi->dwScale == 0 || asi->dwRate == 0 || (LONG)asi->dwQuality < -1 ||
      asi->dwQuality > ICQUALITY_HIGH)
    return AVIERR_ERROR;

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

  return AVIERR_OK;
}

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

  assert(This->pae != NULL);

  return IAVIEditStream_QueryInterface((IAVIEditStream*)This->pae,refiid,obj);
}

static ULONG   WINAPI IEditAVIStream_fnAddRef(IAVIStream*iface)
{
  IEditAVIStreamImpl *This = (IEditAVIStreamImpl *)iface;

  assert(This->pae != NULL);

  return IAVIEditStream_AddRef((IAVIEditStream*)This->pae);
}

static ULONG   WINAPI IEditAVIStream_fnRelease(IAVIStream*iface)
{
  IEditAVIStreamImpl *This = (IEditAVIStreamImpl *)iface;

  assert(This->pae != NULL);

  return IAVIEditStream_Release((IAVIEditStream*)This->pae);
}

static HRESULT WINAPI IEditAVIStream_fnCreate(IAVIStream*iface,
                                              LPARAM lParam1,LPARAM lParam2)
{
  IAVIEditStreamImpl *This = ((IEditAVIStreamImpl*)iface)->pae;

  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)
{
  IEditAVIStreamImpl *This = (IEditAVIStreamImpl *)iface;

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

  assert(This->pae != NULL);

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

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

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

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

static LONG    WINAPI IEditAVIStream_fnFindSample(IAVIStream*iface,LONG pos,
                                                  LONG flags)
{
  IAVIEditStreamImpl* const This = ((IEditAVIStreamImpl* const)iface)->pae;
  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* const This = ((IEditAVIStreamImpl* const)iface)->pae;
  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* const This = ((IEditAVIStreamImpl* const)iface)->pae;
  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)
{
  IEditAVIStreamImpl *This = (IEditAVIStreamImpl *)iface;

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

  return IAVIEditStream_Cut((IAVIEditStream*)This->pae,&start,&samples,NULL);
}

static HRESULT WINAPI IEditAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,
                                                LPVOID lp,LONG *lpread)
{
  IAVIEditStreamImpl* const This = ((IEditAVIStreamImpl* const)iface)->pae;
  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)
{
  IEditAVIStreamImpl *This = (IEditAVIStreamImpl *)iface;

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

  return IAVIEditStream_SetInfo((IAVIEditStream*)This->pae,info,len);
}

static HRESULT WINAPI IEditStreamInternal_fnQueryInterface(IEditStreamInternal*iface,REFIID refiid,LPVOID*obj)
{
  IEditStreamInternalImpl *This = (IEditStreamInternalImpl *)iface;

  assert(This->pae != NULL);

  return IAVIEditStream_QueryInterface((IAVIEditStream*)This->pae, refiid, obj);
}

static ULONG   WINAPI IEditStreamInternal_fnAddRef(IEditStreamInternal*iface)
{
  IEditStreamInternalImpl *This = (IEditStreamInternalImpl *)iface;

  assert(This->pae != NULL);

  return IAVIEditStream_AddRef((IAVIEditStream*)This->pae);
}

static ULONG   WINAPI IEditStreamInternal_fnRelease(IEditStreamInternal*iface)
{
  IEditStreamInternalImpl *This = (IEditStreamInternalImpl *)iface;

  assert(This->pae != NULL);

  return IAVIEditStream_Release((IAVIEditStream*)This->pae);
}

static HRESULT  WINAPI IEditStreamInternal_fnGetEditStreamImpl(IEditStreamInternal*iface,LPVOID*ppimpl)
{
  IEditStreamInternalImpl *This = (IEditStreamInternalImpl *)iface;

  TRACE("(%p,%p) -> %p\n", iface, ppimpl, This->pae);

  assert(This->pae != NULL);
  assert(ppimpl != NULL);

  *ppimpl = This->pae;
  return AVIERR_OK;
}
