/* 
 * Copyright 2000 Bradley Baetz
 *
 * Fixme: Some flags are ignored
 *
 * Handle palettes
 */

#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/winbase16.h"
#include "debugtools.h"
#include "vfw.h"
#include "vfw16.h"
#include "windef.h"

DEFAULT_DEBUG_CHANNEL(msvideo);

typedef struct {
	HDC hdc;
	INT dxDst;
	INT dyDst;
	LPBITMAPINFOHEADER lpbi;
	INT dxSrc;
	INT dySrc;
	HPALETTE hpal;				/* Palette to use for the DIB */
	BOOL begun;					/* DrawDibBegin has been called */
	LPBITMAPINFOHEADER lpbiOut;	/* Output format */
	HIC hic;					/* HIC for decompression */
	HDC hMemDC;					/* DC for buffering */
	HBITMAP hOldDib;			/* Original Dib */
	HBITMAP hDib;				/* DibSection */
	LPVOID lpvbits;				/* Buffer for holding decompressed dib */
} WINE_HDD;

/***********************************************************************
 *		DrawDibOpen		[MSVFW32.10]
 */
HDRAWDIB VFWAPI DrawDibOpen(void) {
	HDRAWDIB hdd;

	TRACE("(void)\n");
	hdd = GlobalAlloc16(GHND,sizeof(WINE_HDD));
	TRACE("=> %d\n",hdd);
	return hdd;
}

/***********************************************************************
 *		DrawDibOpen		[MSVIDEO.102]
 */
HDRAWDIB16 VFWAPI DrawDibOpen16(void) {
	return (HDRAWDIB16)DrawDibOpen();
}

/***********************************************************************
 *		DrawDibClose		[MSVFW32.5]
 */
BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
	WINE_HDD *whdd = GlobalLock16(hdd);

	TRACE("(0x%08lx)\n",(DWORD)hdd);

	if (!whdd)
		return FALSE;

	if (whdd->begun)
		DrawDibEnd(hdd);

	GlobalUnlock16(hdd);
	GlobalFree16(hdd);
	return TRUE;
}

/***********************************************************************
 *		DrawDibClose		[MSVIDEO.103]
 */
BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd) {
	return DrawDibClose(hdd);
}

/***********************************************************************
 *		DrawDibEnd		[MSVFW32.7]
 */
BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
	BOOL ret = TRUE;
	WINE_HDD *whdd = GlobalLock16(hdd);
	
	TRACE("(0x%08lx)\n",(DWORD)hdd);

	whdd->hpal = 0; /* Do not free this */
	whdd->hdc = 0;
	if (whdd->lpbi) {
		HeapFree(GetProcessHeap(),0,whdd->lpbi);
		whdd->lpbi = NULL;
	}
	if (whdd->lpbiOut) {
		HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
		whdd->lpbiOut = NULL;
	}

	whdd->begun = FALSE;

	/*if (whdd->lpvbits)
	  HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/

	if (whdd->hMemDC) {
		SelectObject(whdd->hMemDC,whdd->hOldDib);
		DeleteDC(whdd->hMemDC);
	}

	if (whdd->hDib)
		DeleteObject(whdd->hDib);
	
	if (whdd->hic) {
		ICDecompressEnd(whdd->hic);
		ICClose(whdd->hic);
	}

	whdd->lpvbits = NULL;

	GlobalUnlock16(hdd);
	return ret;
}

/***********************************************************************
 *		DrawDibEnd		[MSVIDEO.105]
 */
BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd) {
	return DrawDibEnd(hdd);
}

/***********************************************************************
 *              DrawDibBegin            [MSVFW32.3]
 */
BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
						 HDC      hdc,
						 INT      dxDst,
						 INT      dyDst,
						 LPBITMAPINFOHEADER lpbi,
						 INT      dxSrc,
						 INT      dySrc,
						 UINT     wFlags) {
	BOOL ret = TRUE;
	WINE_HDD *whdd;

	TRACE("(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx)\n",
		hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
	);
	TRACE("lpbi: %ld,%ld/%ld,%d,%d,%ld,%ld,%ld,%ld,%ld,%ld\n",
		  lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes, 
		  lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage, 
		  lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed, 
		  lpbi->biClrImportant);

	if (wFlags & ~(DDF_BUFFER))
		FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));

	whdd = (WINE_HDD*)GlobalLock16(hdd);
	if (!whdd) return FALSE;

	if (whdd->begun)
		DrawDibEnd(hdd);

	if (lpbi->biCompression) {
		DWORD size = 0;

		whdd->hic = ICOpen(ICTYPE_VIDEO,lpbi->biCompression,ICMODE_DECOMPRESS);
		if (!whdd->hic) {
			WARN("Could not open IC. biCompression == 0x%08lx\n",lpbi->biCompression);
			ret = FALSE;
		}

		if (ret) {
			size = ICDecompressGetFormat(whdd->hic,lpbi,NULL);
			if (size == ICERR_UNSUPPORTED) {
				WARN("Codec doesn't support GetFormat, giving up.\n");
				ret = FALSE;
			}
		}

		if (ret) {
			whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);

			if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
				ret = FALSE;
		}

		if (ret) {
			/* FIXME: Use Ex functions if available? */
			if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
				ret = FALSE;

			TRACE("biSizeImage == %ld\n",whdd->lpbiOut->biSizeImage);
			TRACE("biCompression == %ld\n",whdd->lpbiOut->biCompression);
			TRACE("biBitCount == %d\n",whdd->lpbiOut->biBitCount);
		}
	} else {
		DWORD dwSize;
		/* No compression */
		TRACE("Not compressed!\n");
		dwSize = lpbi->biSize + lpbi->biClrUsed*sizeof(RGBQUAD);
		whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,dwSize);
		memcpy(whdd->lpbiOut,lpbi,dwSize);
	}

	if (ret) {
		/*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
		
		whdd->hMemDC = CreateCompatibleDC(hdc);
		TRACE("Creating: %ld,%p\n",whdd->lpbiOut->biSize,whdd->lpvbits);
		whdd->hDib = CreateDIBSection(whdd->hMemDC,(BITMAPINFO *)whdd->lpbiOut,DIB_RGB_COLORS,&(whdd->lpvbits),0,0);
		if (!whdd->hDib) {
			TRACE("Error: %ld\n",GetLastError());
		}
		TRACE("Created: %d,%p\n",whdd->hDib,whdd->lpvbits);
		whdd->hOldDib = SelectObject(whdd->hMemDC,whdd->hDib);
	}

	if (ret) {
		whdd->hdc = hdc;
		whdd->dxDst = dxDst;
		whdd->dyDst = dyDst;
		whdd->lpbi = HeapAlloc(GetProcessHeap(),0,lpbi->biSize);
		memcpy(whdd->lpbi,lpbi,lpbi->biSize);
		whdd->dxSrc = dxSrc;
		whdd->dySrc = dySrc;
		whdd->begun = TRUE;
		whdd->hpal = 0;
	} else {
		if (whdd->hic)
			ICClose(whdd->hic);
		if (whdd->lpbiOut) {
			HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
			whdd->lpbiOut = NULL;
		}
	}

	GlobalUnlock16(hdd);

	return ret;
}

/************************************************************************
 *		DrawDibBegin		[MSVIDEO.104]
 */
BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd,
						   HDC16      hdc,
						   INT16      dxDst,
						   INT16      dyDst,
						   LPBITMAPINFOHEADER lpbi,
						   INT16      dxSrc,
						   INT16      dySrc,
						   UINT16     wFlags) {
	return DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,wFlags);
}

/**********************************************************************
 *		DrawDibDraw		[MSVFW32.6]
 */
BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
	INT xDst, INT yDst, INT dxDst, INT dyDst,
	LPBITMAPINFOHEADER lpbi,
	LPVOID lpBits,
	INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
	UINT wFlags
) {
	WINE_HDD *whdd;
	BOOL ret = TRUE;

	TRACE("(%d,0x%lx,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
		  hdd,(DWORD)hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,(DWORD)wFlags
	);

	if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME | 
				   DDF_UPDATE | DDF_DONTDRAW))
		FIXME("wFlags == 0x%08lx not handled\n",(DWORD)wFlags);

	if (!lpBits) {
		/* Undocumented? */
		lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(lpbi->biClrUsed*sizeof(RGBQUAD));
	}

	whdd = GlobalLock16(hdd);

#define CHANGED(x) (whdd->x != x)

	if ((!whdd->begun) || (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || (!(wFlags & DDF_SAME_DRAW) &&
		 (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) {
		TRACE("Something changed!\n");
		ret = DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,0);
	}

#undef CHANGED

        if ((dxDst == -1) && (dyDst == -1)) {
		dxDst = dxSrc;
		dyDst = dySrc;
	}

	if (!(wFlags & DDF_UPDATE)) {
	    /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
	    if ((lpbi->biCompression == BI_RGB) && (lpbi->biSizeImage == 0))
		    lpbi->biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;

		if (lpbi->biCompression) {
		    DWORD flags = 0;
		
			TRACE("Compression == 0x%08lx\n",lpbi->biCompression);
		
			if (wFlags & DDF_NOTKEYFRAME)
			    flags |= ICDECOMPRESS_NOTKEYFRAME;
		
			ICDecompress(whdd->hic,flags,lpbi,lpBits,whdd->lpbiOut,whdd->lpvbits);
		} else {
		    memcpy(whdd->lpvbits,lpBits,lpbi->biSizeImage);
		}	
	}
	if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
	    SelectPalette(hdc,whdd->hpal,FALSE);

	if (!(StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY)))
	    ret = FALSE;

	GlobalUnlock16(hdd);
	return ret;
}

/**********************************************************************
 *		DrawDibDraw		[MSVIDEO.106]
 */
BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd,             
						  HDC16 hdc,
						  INT16 xDst,
						  INT16 yDst,
						  INT16 dxDst,
						  INT16 dyDst,
						  LPBITMAPINFOHEADER lpbi,
						  LPVOID lpBits,
						  INT16 xSrc,
						  INT16 ySrc,
						  INT16 dxSrc,
						  INT16 dySrc,
						  UINT16 wFlags) {
	return DrawDibDraw(hdd,hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,wFlags);
}

/*************************************************************************
 *		DrawDibStart		[MSVFW32.14]
 */
BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
	FIXME("(0x%08lx,%ld), stub\n",(DWORD)hdd,rate);
	return TRUE;
}

/*************************************************************************
 *		DrawDibStart		[MSVIDEO.118]
 */
BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate) {
	return DrawDibStart(hdd,rate);
}

/*************************************************************************
 *		DrawDibStop		[MSVFW32.15]
 */
BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
	FIXME("(0x%08lx), stub\n",(DWORD)hdd);
	return TRUE;
}

/*************************************************************************
 *		DrawDibStop		[MSVIDEO.119]
 */
BOOL16 DrawDibStop16(HDRAWDIB16 hdd) {
	return DrawDibStop(hdd);
}

/***********************************************************************
 *              DrawDibSetPalette       [MSVFW32.13]   
 */
BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
	WINE_HDD *whdd;

	TRACE("(0x%08lx,0x%08lx)\n",(DWORD)hdd,(DWORD)hpal);

	whdd = GlobalLock16(hdd);
	whdd->hpal = hpal;
	
	if (whdd->begun) {
		SelectPalette(whdd->hdc,hpal,0);
		RealizePalette(whdd->hdc);
	}
	GlobalUnlock16(hdd);
	return TRUE;
}

/***********************************************************************
 *              DrawDibSetPalette       [MSVIDEO.110]
 */
BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal) {
	return DrawDibSetPalette(hdd,hpal);
}

/***********************************************************************
 *              DrawDibGetPalette       [MSVFW32.9]   
 */
HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
	WINE_HDD *whdd;
	HPALETTE ret;

	TRACE("(0x%08lx)\n",(DWORD)hdd);

	whdd = GlobalLock16(hdd);
	ret = whdd->hpal;
	GlobalUnlock16(hdd);
	return ret;
}

/***********************************************************************
 *              DrawDibGetPalette       [MSVIDEO.108]]   
 */
HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd) {
	return (HPALETTE16)DrawDibGetPalette(hdd);
}

/***********************************************************************
 *              DrawDibRealize          [MSVFW32.12]
 */
UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
	WINE_HDD *whdd;
	HPALETTE oldPal;
	UINT ret = 0;

	FIXME("(%d,0x%08lx,%d), stub\n",hdd,(DWORD)hdc,fBackground);
	
	whdd = GlobalLock16(hdd);

	if (!whdd || !(whdd->begun)) {
		ret = 0;
		goto out;
	}
	
	if (!whdd->hpal)
		whdd->hpal = CreateHalftonePalette(hdc);

	oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
	ret = RealizePalette(hdc);
	
 out:
	GlobalUnlock16(hdd);

	TRACE("=> %u\n",ret);
	return ret;
}

/***********************************************************************
 *              DrawDibRealize          [MSVIDEO.112]
 */
UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc, BOOL16 fBackground) {
	return (UINT16)DrawDibRealize(hdd,hdc,fBackground);
}
