#include <clip.h>

/////////////////////////////////////////////////////////////////////////////
#define APPNAME	"CVIDWIN"
#define XSCALE	2
#define YSCALE	2
/////////////////////////////////////////////////////////////////////////////
BITMAPINFO* pBMI;
HWND MainWnd;
LRESULT CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CHAR:
		if(wParam == 'q') {
			DestroyWindow(hWnd);
			return 0;
		}
		return 0;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}
int
DoMsg()
{
	MSG msg;
	while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
		if(msg.message == WM_QUIT) {
			return 0;
		}
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return 1;
}
void
InitUI()
{
	int i;
	BITMAPINFOHEADER* bi;
	RGBQUAD* rgb;
	HINSTANCE hInst;
	WNDCLASS wc;
	RECT rcWin;
	RECT rcCli;
	int ncW;
	int ncH;

	pBMI = (BITMAPINFO*)calloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256, 1);
	bi = &pBMI->bmiHeader;
	rgb = &pBMI->bmiColors[0];
	bi->biSize = sizeof(BITMAPINFOHEADER);
	bi->biWidth = cvid_driver.surface.w;
	bi->biHeight = -cvid_driver.surface.h;
	bi->biPlanes = 1;
	bi->biBitCount = 8;
	for(i = 0; i < 256; i++) {
		if(i < 16) {
			rgb[i].rgbRed   = ~(i|(i<<4));
			rgb[i].rgbGreen = ~(i|(i<<4));
			rgb[i].rgbBlue  = ~(i|(i<<4));
		} else {
			rgb[i].rgbRed   = 255;
			rgb[i].rgbGreen = 0;
			rgb[i].rgbBlue  = 255;
		}
	}

	hInst = GetModuleHandle(NULL);
	//
	memset(&wc, 0, sizeof wc);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInst;
	wc.hCursor = LoadCursor(NULL, IDC_CROSS);
	wc.lpszClassName = APPNAME;
	RegisterClass(&wc);
	//
	MainWnd = CreateWindow(APPNAME, APPNAME,
		WS_OVERLAPPED,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hInst, NULL);
	//
	GetWindowRect(MainWnd, &rcWin);
	GetClientRect(MainWnd, &rcCli);
	ncW = (rcWin.right - rcWin.left) - (rcCli.right - rcCli.left);
	ncH = (rcWin.bottom - rcWin.top) - (rcCli.bottom - rcCli.top);
	MoveWindow(MainWnd, 0, 0,
		ncW + bi->biWidth  * XSCALE,
		ncH - bi->biHeight * YSCALE, 0);
	//
	ShowWindow(MainWnd, SW_SHOW);
	UpdateWindow(MainWnd);
}

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

//#define FNAME	"C:/Home/Share/Movie/cinepak.avi"	/* 非インターリーブ (rec無し) */
//#define FNAME	"C:/Home/Share/Movie/06121cin.avi"	/* インターリーブ (rec有り) */
//#define FNAME	"C:/Home/Share/Movie/test2.avi"
//#define FNAME	"C:/Home/Share/Movie/op640-hc.avi"
//#define FNAME	"C:/Home/Share/Movie/op640-lc.avi"
//#define FNAME	"C:/Home/Share/Movie/op640-bw.avi"
//#define FNAME	"C:/Home/Share/Movie/op640-mb.avi"
//#define FNAME	"C:/Home/Share/Movie/op640-mc.avi"
#define FNAME	"C:/Home/Share/Movie/op640-OK.avi"
//#define FNAME	"C:/Home/Share/Movie/ED640-hc.avi"
//#define FNAME	"C:/Home/Share/Movie/ED640-lc.avi"

#if 0
int
main(int argc, char* argv[])
{
//{{Test
//	cvid_enum(FNAME);
//}}or{{
	cvid_init(FNAME, 1);
	while(cvid_update()) { printf("*"); }
	cvid_free();
//}}Test
	printf("OK\n");
	getchar();
}
#else
int
main(int argc, char* argv[])
{
	const char* fname = FNAME;
	int msec;
	int t0;
	int t1;
	HDC hDC;
	RECT rc;

	if(argc >= 1 + 1) fname = argv[1];
	cvid_init(fname, -1);
	InitUI();

	msec = 1000 * cvid_driver.strh.dwScale / cvid_driver.strh.dwRate;

	t0 = GetTickCount();
	hDC = GetDC(MainWnd);
	GetClientRect(MainWnd, &rc);
	for(;;) {
		if(!DoMsg()) {
			break;
		}

		cvid_update();
		StretchDIBits(hDC,
			rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
			0, 0, pBMI->bmiHeader.biWidth, -pBMI->bmiHeader.biHeight,
			cvid_driver.surface.vbuff,
			pBMI,
			DIB_RGB_COLORS,
			SRCCOPY);

		for(;;) {
			t1 = GetTickCount();
			if(t1 - t0 >= msec) break;
			Sleep(0);
		}
		t0 += msec;
	}
	ReleaseDC(MainWnd, hDC);
}
#endif
