/*
 * Copyright 2000 Eric Pouech 
 *
 */

#include <stdio.h>
#include <string.h>

#include "winbase.h"
#include "windef.h"
#include "winnls.h"
#include "wingdi.h"
#include "winuser.h"
#include "vfw.h"
#include "wine/mmsystem16.h"
#include "digitalv.h"
#include "commctrl.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(mci);

typedef struct {
   DWORD	dwStyle;
   MCIDEVICEID	mci;
   LPSTR	lpName;
   HWND		hWnd;
   UINT		uTimer;
} MCIWndInfo;

static LRESULT WINAPI	MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2);

#define CTL_PLAYSTOP	0x3200
#define CTL_MENU	0x3201
#define CTL_TRACKBAR	0x3202

/***********************************************************************
 *		MCIWndRegisterClass		[MSVFW32.@]
 */
BOOL WINAPI MCIWndRegisterClass(HINSTANCE hInst)
{
   WNDCLASSA		wc;

   /* since window creation will also require some common controls, init them */
   InitCommonControls();

   wc.style = 0;
   wc.lpfnWndProc = MCIWndProc;
   wc.cbClsExtra = 0;
   wc.cbWndExtra = sizeof(MCIWndInfo*);
   wc.hInstance = hInst;
   wc.hIcon = 0;
   wc.hCursor = 0;
   wc.hbrBackground = 0;
   wc.lpszMenuName = NULL;
   wc.lpszClassName = "MCIWndClass";

   return RegisterClassA(&wc);

}

/***********************************************************************
 *		MCIWndCreate		[MSVFW32.@]
 *		MCIWndCreateA		[MSVFW32.@]
 */
HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
			   DWORD dwStyle, LPCSTR szFile)
{
   DWORD	wndStyle;
   MCIWndInfo*	mwi;
   
   TRACE("%x %x %lx %s\n", hwndParent, hInstance, dwStyle, szFile);

   MCIWndRegisterClass(hInstance);

   mwi = HeapAlloc(GetProcessHeap(), 0, sizeof(*mwi));
   if (!mwi) return 0;

   mwi->dwStyle = dwStyle;
   mwi->lpName = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(szFile) + 1), szFile);
   mwi->uTimer = 0;

   wndStyle = ((hwndParent) ? (WS_CHILD|WS_BORDER) : WS_OVERLAPPEDWINDOW) |
              WS_VISIBLE | (dwStyle & 0xFFFF0000);

   if (CreateWindowExA(0, "MCIWndClass", NULL, wndStyle, 
		       CW_USEDEFAULT, CW_USEDEFAULT, 
		       CW_USEDEFAULT, CW_USEDEFAULT, 
		       hwndParent, (HMENU)0, hInstance, mwi))
      return mwi->hWnd;
   
   HeapFree(GetProcessHeap(), 0, mwi->lpName);
   HeapFree(GetProcessHeap(), 0, mwi);
   return 0;
}

/***********************************************************************
 *		MCIWndCreateW				[MSVFW32.@]
 */
HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
			   DWORD dwStyle, LPCWSTR szFile)
{
   FIXME("%x %x %lx %s\n", hwndParent, hInstance, dwStyle, debugstr_w(szFile));

   MCIWndRegisterClass(hInstance);

   return 0;
}

static DWORD MCIWND_GetStatus(MCIWndInfo* mwi)
{
   MCI_DGV_STATUS_PARMSA	mdsp;
   
   memset(&mdsp, 0, sizeof(mdsp));
   mdsp.dwItem = MCI_STATUS_MODE;
   if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp))
      return MCI_MODE_NOT_READY;
   if (mdsp.dwReturn == MCI_MODE_STOP && mwi->uTimer) {
      TRACE("Killing timer\n");
      KillTimer(mwi->hWnd, 0);
      mwi->uTimer = 0;
   }
   return mdsp.dwReturn;
}

static DWORD MCIWND_Get(MCIWndInfo* mwi, DWORD what)
{
   MCI_DGV_STATUS_PARMSA	mdsp;
      
   memset(&mdsp, 0, sizeof(mdsp));
   mdsp.dwItem = what;
   if (mciSendCommandA(mwi->mci, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD)&mdsp))
      return 0;
   return mdsp.dwReturn;
}

static void MCIWND_SetText(MCIWndInfo* mwi)
{
   char	buffer[1024];

   if (mwi->dwStyle & MCIWNDF_SHOWNAME) {
      strcpy(buffer, mwi->lpName);
   } else {
      *buffer = 0;
   }

   if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
      if (*buffer) strcat(buffer, " ");
      strcat(buffer, "(");
   }

   if (mwi->dwStyle & MCIWNDF_SHOWPOS) {
      sprintf(buffer + strlen(buffer), "%ld", MCIWND_Get(mwi, MCI_STATUS_POSITION));
   }

   if ((mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) == (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
      strcat(buffer, " - ");
   }

   if (mwi->dwStyle & MCIWNDF_SHOWMODE) {
      switch (MCIWND_GetStatus(mwi)) {
      case MCI_MODE_NOT_READY: 	strcat(buffer, "not ready");	break;
      case MCI_MODE_PAUSE:	strcat(buffer, "paused");	break;
      case MCI_MODE_PLAY:	strcat(buffer, "playing");	break;
      case MCI_MODE_STOP:	strcat(buffer, "stopped");	break;
      case MCI_MODE_OPEN:	strcat(buffer, "open");		break;
      case MCI_MODE_RECORD:	strcat(buffer, "recording");	break;
      case MCI_MODE_SEEK:	strcat(buffer, "seeking");	break;
      default:			strcat(buffer, "???");		break;
      }
   }
   if (mwi->dwStyle & (MCIWNDF_SHOWPOS|MCIWNDF_SHOWMODE)) {
      strcat(buffer, " )");
   }
   TRACE("=> '%s'\n", buffer);
   SetWindowTextA(mwi->hWnd, buffer);
}

static void MCIWND_Create(HWND hWnd, LPCREATESTRUCTA cs)
{
   MCI_DGV_OPEN_PARMSA	mdopn;
   MCI_DGV_RECT_PARMS	mdrct;
   MMRESULT		mmr;
   int			cx, cy;
   HWND			hChld;
   MCIWndInfo* 		mwi = (MCIWndInfo*)cs->lpCreateParams;

   SetWindowLongA(hWnd, 0, (LPARAM)mwi);
   mwi->hWnd = hWnd;

   /* now open MCI player for AVI file */
   memset(&mdopn, 0, sizeof(mdopn));
   mdopn.lpstrElementName = mwi->lpName;
   mdopn.dwStyle = WS_VISIBLE|WS_CHILD;
   mdopn.hWndParent = hWnd;

   mmr = mciSendCommandA(0,  MCI_OPEN, MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN_WS, (LPARAM)&mdopn);
   if (mmr) {
      MessageBoxA(GetTopWindow(hWnd), "Cannot open file", "MciWnd", MB_OK);
      return;
   }
   mwi->mci = mdopn.wDeviceID;
  
   /* grab AVI window size */
   memset(&mdrct, 0, sizeof(mdrct));
   mmr = mciSendCommandA(mwi->mci,  MCI_WHERE, MCI_DGV_WHERE_DESTINATION, (LPARAM)&mdrct);
   if (mmr) {
      WARN("Cannot get window rect\n");
      return;
   }
   cx = mdrct.rc.right - mdrct.rc.left;
   cy = mdrct.rc.bottom - mdrct.rc.top;

   AdjustWindowRect(&mdrct.rc, GetWindowLongA(hWnd, GWL_STYLE), FALSE);
   SetWindowPos(hWnd, 0, 0, 0, mdrct.rc.right - mdrct.rc.left, 
		mdrct.rc.bottom - mdrct.rc.top + 32, SWP_NOMOVE|SWP_NOZORDER);

   /* adding the other elements: play/stop button, menu button, status */
   hChld = CreateWindowExA(0, "BUTTON", "Play", WS_CHILD|WS_VISIBLE, 0, cy, 32, 32, 
			   hWnd, (HMENU)CTL_PLAYSTOP, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
   TRACE("Get Button1: %04x\n", hChld);
   hChld = CreateWindowExA(0, "BUTTON", "Menu", WS_CHILD|WS_VISIBLE, 32, cy, 32, 32, 
			   hWnd, (HMENU)CTL_MENU, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
   TRACE("Get Button2: %04x\n", hChld);
   hChld = CreateWindowExA(0, TRACKBAR_CLASSA, "", WS_CHILD|WS_VISIBLE, 64, cy, cx - 64, 32, 
			   hWnd, (HMENU)CTL_TRACKBAR, GetWindowLongA(hWnd, GWL_HINSTANCE), 0L);
   TRACE("Get status: %04x\n", hChld);
   SendMessageA(hChld, TBM_SETRANGEMIN, 0L, 0L);
   SendMessageA(hChld, TBM_SETRANGEMAX, 1L, MCIWND_Get(mwi, MCI_STATUS_LENGTH));

   /* FIXME: no need to set it if child window */
   MCIWND_SetText(mwi);
}

static void MCIWND_Paint(MCIWndInfo* mwi, WPARAM wParam)
{
   HDC 		hdc;
   PAINTSTRUCT	ps;

   hdc = (wParam) ? (HDC)wParam : BeginPaint(mwi->hWnd, &ps);
   /* something to do ? */
   if (!wParam) EndPaint(mwi->hWnd, &ps);
}

static void MCIWND_ToggleState(MCIWndInfo* mwi)
{
   MCI_GENERIC_PARMS	mgp;
   MCI_DGV_PLAY_PARMS	mdply;

   memset(&mgp, 0, sizeof(mgp));
   memset(&mdply, 0, sizeof(mdply));

   switch (MCIWND_GetStatus(mwi)) {
   case MCI_MODE_NOT_READY:
   case MCI_MODE_RECORD:
   case MCI_MODE_SEEK:
   case MCI_MODE_OPEN:
      TRACE("Cannot do much...\n");
      break;
   case MCI_MODE_PAUSE:
      mciSendCommandA(mwi->mci, MCI_RESUME, MCI_WAIT, (LPARAM)&mgp);
      break;
   case MCI_MODE_PLAY:
      mciSendCommandA(mwi->mci, MCI_PAUSE, MCI_WAIT, (LPARAM)&mgp);
      break;
   case MCI_MODE_STOP:
      mdply.dwFrom = 0L;
      mciSendCommandA(mwi->mci, MCI_PLAY, MCI_FROM, (LPARAM)&mdply);
      mwi->uTimer = SetTimer(mwi->hWnd, 0, 333, 0L);
      TRACE("Timer=%u\n", mwi->uTimer);
      break;
   }
}

static LRESULT MCIWND_Command(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam)
{
   switch (LOWORD(wParam)) {
   case CTL_PLAYSTOP:	MCIWND_ToggleState(mwi);	break;
   case CTL_MENU:
   case CTL_TRACKBAR:
   default:
      MessageBoxA(0, "ooch", "NIY", MB_OK);
   }
   return 0L;
}

static void MCIWND_Timer(MCIWndInfo* mwi, WPARAM wParam, LPARAM lParam)
{
   TRACE("%ld\n", MCIWND_Get(mwi, MCI_STATUS_POSITION));
   SendDlgItemMessageA(mwi->hWnd, CTL_TRACKBAR, TBM_SETPOS, 1, MCIWND_Get(mwi, MCI_STATUS_POSITION));
   MCIWND_SetText(mwi);
}

static void MCIWND_Close(MCIWndInfo* mwi)
{
   MCI_GENERIC_PARMS	mgp;

   memset(&mgp, 0, sizeof(mgp));

   mciSendCommandA(mwi->mci, MCI_CLOSE, 0, (LPARAM)&mgp);
}

static LRESULT WINAPI	MCIWndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2)
{
   MCIWndInfo*	mwi = (MCIWndInfo*)GetWindowLongA(hWnd, 0);

   if (mwi || wMsg == WM_CREATE) {
      switch (wMsg) {
      case WM_CREATE:
	 MCIWND_Create(hWnd, (CREATESTRUCTA*)lParam2);
	 return 0;
      case WM_DESTROY:
	 MCIWND_Close(mwi);
	 HeapFree(GetProcessHeap(), 0, mwi->lpName);
	 HeapFree(GetProcessHeap(), 0, mwi);
	 break;
      case WM_PAINT:
	 MCIWND_Paint(mwi, lParam1);
	 break;
      case WM_COMMAND:
	 return MCIWND_Command(mwi, lParam1, lParam2);
      case WM_TIMER:
	 MCIWND_Timer(mwi, lParam1, lParam2);
	 return TRUE;
      }
   }

   return DefWindowProcA(hWnd, wMsg, lParam1, lParam2);
}

