/*				   
 * Copyright 1999 Marcus Meissner
 */
#include <string.h>
#include <stdio.h>
#include <assert.h>

#include "vfw.h"
#include "winbase.h"
#include "wine/winestring.h"
#include "driver.h"
#include "mmsystem.h"
#include "winerror.h"
#include "debugstr.h"
#include "debug.h"

typedef struct IAVIStreamImpl {
	/* IUnknown stuff */
	ICOM_VTABLE(IAVIStream)*	lpvtbl;
	DWORD		ref;
	/* IAVIStream stuff */
	LPVOID		lpInputFormat;
	DWORD		inputformatsize;
	BOOL		iscompressing;
	DWORD		curframe;

	    /* Compressor stuff */
	    HIC	hic;
	    LPVOID	lpCompressFormat;
	    ICINFO	icinfo;
	    DWORD	compbufsize;
	    LPVOID	compbuffer;

	    DWORD	decompbufsize;
	    LPVOID	decompbuffer;
	    LPVOID	decompformat;
	    AVICOMPRESSOPTIONS	aco;

	    LPVOID	lpPrev;	/* pointer to decompressed frame later */
	    LPVOID	lpPrevFormat; /* pointer to decompressed info later */
} IAVIStreamImpl;

void WINAPI
AVIFileInit(void) {
	FIXME(avifile,"(),stub!\n");
}

typedef struct IAVIFileImpl {
	/* IUnknown stuff */
	ICOM_VTABLE(IAVIFile)*	lpvtbl;
	DWORD				ref;
	/* IAVIFile stuff... */
} IAVIFileImpl;

struct ICOM_VTABLE(IAVIStream) iavist;

static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj) {
	ICOM_THIS(IAVIFileImpl,iface);
	char    xrefiid[50];

	WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
	TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",This,xrefiid,obj);
	if (	!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
		!memcmp(&IID_IAVIFile,refiid,sizeof(IID_IAVIFile))
	) {
		*obj = iface;
		return S_OK;
	}
	return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface) {
	ICOM_THIS(IAVIFileImpl,iface);
	
	FIXME(relay,"(%p)->AddRef()\n",iface);
	return ++(This->ref);
}

static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface) {
	ICOM_THIS(IAVIFileImpl,iface);
	
	FIXME(relay,"(%p)->Release()\n",iface);
	if (!--(This->ref)) {
		HeapFree(GetProcessHeap(),0,iface);
		return 0;
	}
	return This->ref;
}

static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size) {
	FIXME(avifile,"(%p)->Info(%p,%ld)\n",iface,afi,size);

	/* FIXME: fill out struct? */
	return E_FAIL;
}

static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) {
	FIXME(avifile,"(%p)->GetStream(%p,0x%08lx,%ld)\n",iface,avis,fccType,lParam);
	/* FIXME: create interface etc. */
	return E_FAIL;
}

static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) {
	ICOM_THIS(IAVIStreamImpl,iface);
	char		fcc[5];
	IAVIStreamImpl	*istream;

	FIXME(avifile,"(%p,%p,%p)\n",This,avis,asi);
	istream = (IAVIStreamImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIStreamImpl));
	istream->ref = 1;
	istream->lpvtbl = &iavist;
	fcc[4]='\0';
	memcpy(fcc,(char*)&(asi->fccType),4);
	FIXME(avifile,"\tfccType '%s'\n",fcc);
	memcpy(fcc,(char*)&(asi->fccHandler),4);
	FIXME(avifile,"\tfccHandler '%s'\n",fcc);
	FIXME(avifile,"\tdwFlags 0x%08lx\n",asi->dwFlags);
	FIXME(avifile,"\tdwCaps 0x%08lx\n",asi->dwCaps);
	FIXME(avifile,"\tname '%s'\n",debugstr_w(asi->szName));

	istream->curframe = 0;
	*avis = (PAVISTREAM)istream;
	return S_OK;
}

static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size) {
	FIXME(avifile,"(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,ckid,lpData,size);
	/* FIXME: write data to file */
	return E_FAIL;
}

static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size) {
	FIXME(avifile,"(%p)->ReadData(0x%08lx,%p,%p)\n",iface,ckid,lpData,size);
	/* FIXME: read at most size bytes from file */
	return E_FAIL;
}

static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface) {
	FIXME(avifile,"(%p)->EndRecord()\n",iface);
	/* FIXME: end record? */
	return E_FAIL;
}

static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam) {
	FIXME(avifile,"(%p)->DeleteStream(0x%08lx,%ld)\n",iface,fccType,lParam);
	/* FIXME: delete stream? */
	return E_FAIL;
}

struct ICOM_VTABLE(IAVIFile) iavift = {
    IAVIFile_fnQueryInterface,
    IAVIFile_fnAddRef,
    IAVIFile_fnRelease,
    IAVIFile_fnInfo,
    IAVIFile_fnGetStream,
    IAVIFile_fnCreateStream,
    IAVIFile_fnWriteData,
    IAVIFile_fnReadData,
    IAVIFile_fnEndRecord,
    IAVIFile_fnDeleteStream
};

HRESULT WINAPI AVIFileOpenA(
	PAVIFILE * ppfile,LPCSTR szFile,UINT uMode,LPCLSID lpHandler
) {
	char	buf[80];
	IAVIFileImpl	*iavi;


	if (HIWORD(lpHandler))
		WINE_StringFromCLSID(lpHandler,buf);
	else
		sprintf(buf,"<clsid-0x%04lx>",(DWORD)lpHandler);

	FIXME(avifile,"(%p,%s,0x%08lx,%s),stub!\n",ppfile,szFile,(DWORD)uMode,buf);
	iavi = (IAVIFileImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIFileImpl));
	iavi->ref = 1;
	iavi->lpvtbl = &iavift;
	*ppfile = (LPVOID)iavi;
	return S_OK;
}

static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) {
	ICOM_THIS(IAVIStreamImpl,iface);
	char    xrefiid[50];

	WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
	TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",This,xrefiid,obj);
	if (	!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
		!memcmp(&IID_IAVIStream,refiid,sizeof(IID_IAVIStream))
	) {
		*obj = This;
		return S_OK;
	}
	/* can return IGetFrame interface too */
	return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) {
	ICOM_THIS(IAVIStreamImpl,iface);
	
	FIXME(relay,"(%p)->AddRef()\n",iface);
	return ++(This->ref);
}

static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) {
	ICOM_THIS(IAVIStreamImpl,iface);
	
	FIXME(relay,"(%p)->Release()\n",iface);
	if (!--(This->ref)) {
		HeapFree(GetProcessHeap(),0,This);
		return 0;
	}
	return This->ref;
}

HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2) {
	FIXME(avifile,"(%p)->Create(0x%08lx,0x%08lx)\n",iface,lParam1,lParam2);
	return E_FAIL;
}

HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size) {
	FIXME(avifile,"(%p)->Info(%p,%ld)\n",iface,psi,size);
	return E_FAIL;
}

LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags) {
	FIXME(avifile,"(%p)->FindSample(%ld,0x%08lx)\n",iface,pos,flags);
	return E_FAIL;
}

HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) {
	FIXME(avifile,"(%p)->ReadFormat(%ld,%p,%p)\n",iface,pos,format,formatsize);
	return E_FAIL;
}

/*****************************************************************************
 *						[IAVIStream::SetFormat]
 */
HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) {
	IAVIStreamImpl	*as = (IAVIStreamImpl*)iface;

	FIXME(avifile,"(%p)->SetFormat(%ld,%p,%ld)\n",iface,pos,format,formatsize);
	if (as->lpInputFormat) HeapFree(GetProcessHeap(),0,as->lpInputFormat);
	as->inputformatsize = formatsize;
	as->lpInputFormat = HeapAlloc(GetProcessHeap(),0,formatsize);
	memcpy(as->lpInputFormat,format,formatsize);
	if (as->iscompressing) {
		int	xsize; 
		/* Set up the Compressor part */
		xsize = ICCompressGetFormatSize(as->hic,as->lpInputFormat);
		as->lpCompressFormat = HeapAlloc(GetProcessHeap(),0,xsize);
		ICCompressGetFormat(as->hic,as->lpInputFormat,as->lpCompressFormat);
		ICCompressBegin(as->hic,as->lpInputFormat,as->lpCompressFormat);
		as->compbufsize = ICCompressGetSize(as->hic,as->lpInputFormat,as->lpCompressFormat);
		as->compbuffer = HeapAlloc(GetProcessHeap(),0,as->compbufsize);

		/* Set up the Decompressor part (for prev frames?) */
		xsize=ICDecompressGetFormatSize(as->hic,as->lpCompressFormat);
		as->decompformat = HeapAlloc(GetProcessHeap(),0,xsize);
		ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat);
		as->decompbufsize=((LPBITMAPINFOHEADER)as->decompbuffer)->biSizeImage;
		as->decompbuffer = HeapReAlloc(GetProcessHeap(),0,as->decompbuffer,as->decompbufsize);
		memset(as->decompbuffer,0xff,as->decompbufsize);
		assert(HeapValidate(GetProcessHeap(),0,NULL));

		ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat);
		ICDecompressBegin(as->hic,as->lpCompressFormat,as->decompformat);
		as->lpPrev = as->lpPrevFormat = NULL;
	}
	return S_OK;
}

HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
	FIXME(avifile,"(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",iface,start,samples,buffer,buffersize,bytesread,samplesread);
	return E_FAIL;
}

HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
	IAVIStreamImpl	*as = (IAVIStreamImpl*)iface;
	DWORD		ckid,xflags;

	FIXME(avifile,"(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);

	ICCompress(
		as->hic,flags,
		as->lpCompressFormat,
		as->compbuffer,
		as->lpInputFormat,buffer,
		&ckid,&xflags,
		as->curframe,0xffffff/*framesize*/,as->aco.dwQuality,
		as->lpPrevFormat,as->lpPrev
	);
	ICDecompress(
		as->hic,
		flags,	/* FIXME: check */
		as->lpCompressFormat,
		as->compbuffer,
		as->decompformat,
		as->decompbuffer
	);
	/* We now have a prev format for the next compress ... */
	as->lpPrevFormat = as->decompformat;
	as->lpPrev = as->decompbuffer;
	return S_OK;
}

HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) {
	FIXME(avifile,"(%p)->Delete(%ld,%ld)\n",iface,start,samples);
	return E_FAIL;
}

HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) {
	FIXME(avifile,"(%p)->ReadData(0x%08lx,%p,%p)\n",iface,fcc,lp,lpread);
	return E_FAIL;
}

HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) {
	FIXME(avifile,"(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,fcc,lp,size);
	return E_FAIL;
}

HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) {
	FIXME(avifile,"(%p)->SetInfo(%p,%ld)\n",iface,info,infolen);
	return E_FAIL;
}

struct ICOM_VTABLE(IAVIStream) iavist = {
    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
};

HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE iface,PAVISTREAM *ppavi,AVISTREAMINFOA * psi) {
	AVISTREAMINFOW	psiw;
	
	/* Only the szName at the end is different */
	memcpy(&psiw,psi,sizeof(*psi)-sizeof(psi->szName));
	lstrcpynAtoW(psiw.szName,psi->szName,sizeof(psi->szName));
	return iface->lpvtbl->fnCreateStream(iface,ppavi,&psiw);
}

HRESULT WINAPI AVIFileCreateStreamW(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) {
	return iface->lpvtbl->fnCreateStream(iface,avis,asi);
}


HRESULT WINAPI AVIFileGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) {
	return iface->lpvtbl->fnGetStream(iface,avis,fccType,lParam);
}

HRESULT WINAPI AVIFileInfoA(PAVIFILE iface,LPAVIFILEINFOA afi,LONG size) {
	AVIFILEINFOW	afiw;
	HRESULT		hres;

	if (size < sizeof(AVIFILEINFOA))
		return AVIERR_BADSIZE;
	hres = iface->lpvtbl->fnInfo(iface,&afiw,sizeof(afiw));
	memcpy(afi,&afiw,sizeof(*afi)-sizeof(afi->szFileType));
	lstrcpynWtoA(afi->szFileType,afiw.szFileType,sizeof(afi->szFileType));
	return hres;
}

HRESULT WINAPI AVIStreamInfoW(PAVISTREAM iface,AVISTREAMINFOW *asi,LONG
 size) {
 	return iface->lpvtbl->fnInfo(iface,asi,size);
}

HRESULT WINAPI AVIStreamInfoA(PAVISTREAM iface,AVISTREAMINFOA *asi,LONG
 size) {
 	AVISTREAMINFOW	asiw;
	HRESULT			hres;

	if (size<sizeof(AVISTREAMINFOA))
		return AVIERR_BADSIZE;
 	hres = iface->lpvtbl->fnInfo(iface,&asiw,sizeof(asiw));
	memcpy(asi,&asiw,sizeof(asiw)-sizeof(asiw.szName));
	lstrcpynWtoA(asi->szName,asiw.szName,sizeof(asi->szName));
	return hres;
}

HRESULT WINAPI AVIFileInfoW(PAVIFILE iface,LPAVIFILEINFOW afi,LONG size) {
	return iface->lpvtbl->fnInfo(iface,afi,size);
}

HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,PAVISTREAM ppsSource,AVICOMPRESSOPTIONS *aco,CLSID *pclsidHandler) {
	char			fcc[5];
	IAVIStreamImpl	*as;
	FIXME(avifile,"(%p,%p,%p,%p)\n",ppsCompressed,ppsSource,aco,pclsidHandler);
	fcc[4]='\0';
	memcpy(fcc,&(aco->fccType),4);
	FIXME(avifile,"\tfccType: '%s'\n",fcc);
	memcpy(fcc,&(aco->fccHandler),4);
	FIXME(avifile,"\tfccHandler: '%s'\n",fcc);
	FIXME(avifile,"\tdwFlags: 0x%08lx\n",aco->dwFlags);

	/* we just create a duplicate for now */
	((IUnknown*)ppsSource)->lpvtbl->fnAddRef((IUnknown*)ppsSource);
	*ppsCompressed = ppsSource;
	as = (IAVIStreamImpl*)ppsSource;

	/* this is where the fun begins. Open a compressor and prepare it. */
	as->hic = ICOpen(aco->fccType,aco->fccHandler,ICMODE_COMPRESS);

	/* May happen. for instance if the codec is not able to compress */
	if (!as->hic) 
		return AVIERR_UNSUPPORTED;

	ICGetInfo(as->hic,&(as->icinfo),sizeof(ICINFO));
	FIXME(avifile,"Opened compressor: '%s' '%s'\n",debugstr_w(as->icinfo.szName),debugstr_w(as->icinfo.szDescription));
	as->iscompressing = TRUE;
	memcpy(&(as->aco),aco,sizeof(*aco));
	if (as->icinfo.dwFlags & VIDCF_COMPRESSFRAMES) {
		ICCOMPRESSFRAMES	icf;

		/* now what to fill in there ... Hmm */
		memset(&icf,0,sizeof(icf));
		icf.lDataRate 	= aco->dwBytesPerSecond;
		icf.lQuality 	= aco->dwQuality;
		icf.lKeyRate 	= aco->dwKeyFrameEvery;

		icf.GetData = (void*)0xdead4242;
		icf.PutData = (void*)0xdead4243;
		ICSendMessage(as->hic,ICM_COMPRESS_FRAMES_INFO,(LPARAM)&icf,sizeof(icf));
	}
	return S_OK;
}

HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG formatsize) {
	return iface->lpvtbl->fnSetFormat(iface,pos,format,formatsize);
}

HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG *formatsize) {
	return iface->lpvtbl->fnReadFormat(iface,pos,format,formatsize);
}

HRESULT WINAPI AVIStreamWrite(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
	return iface->lpvtbl->fnWrite(iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
}

HRESULT WINAPI AVIStreamRead(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
	return iface->lpvtbl->fnRead(iface,start,samples,buffer,buffersize,bytesread,samplesread);
}

HRESULT WINAPI AVIStreamWriteData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG size) {
	return iface->lpvtbl->fnWriteData(iface,fcc,lp,size);
}

HRESULT WINAPI AVIStreamReadData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG *lpread) {
	return iface->lpvtbl->fnReadData(iface,fcc,lp,lpread);
}

LONG WINAPI AVIStreamStart(PAVISTREAM iface) {
	AVISTREAMINFOW	si;

	iface->lpvtbl->fnInfo(iface,&si,sizeof(si));
	return si.dwStart;
}

LONG WINAPI AVIStreamLength(PAVISTREAM iface) {
	AVISTREAMINFOW	si;
	HRESULT			ret;

	ret = iface->lpvtbl->fnInfo(iface,&si,sizeof(si));
	if (ret) /* error */
		return 1;
	return si.dwLength;
}

ULONG WINAPI AVIStreamRelease(PAVISTREAM iface) {
	return ((LPUNKNOWN)iface)->lpvtbl->fnRelease((LPUNKNOWN)iface);
}

PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM iface,LPBITMAPINFOHEADER bmi) {
	FIXME(msvideo,"(%p)->(%p),stub!\n",iface,bmi);
	return NULL;
}

LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg,LONG pos) {
	return pg->lpvtbl->fnGetFrame(pg,pos);
}

HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg) {
	if (pg) ((LPUNKNOWN)pg)->lpvtbl->fnRelease((LPUNKNOWN)pg);
	return 0;
}

ULONG WINAPI AVIFileRelease(PAVIFILE iface) {
	return ((LPUNKNOWN)iface)->lpvtbl->fnRelease((LPUNKNOWN)iface);
}

void WINAPI AVIFileExit(void) {
	FIXME(avifile,"(), stub.\n");
}
