#include <atlbase.h>
#include <windows.h>
#include <dshow.h>
#include <stdio.h>
#include <qedit.h>
#include <initguid.h>
#include <vfw.h>
#include <mtype.h>
#include <ks.h>
#include "..\..\Include\ieibt878.h"
#include "playcap.h"
#include "resource.h"

#define UPDATE_TIMER	1

IKsPropertySet *g_pKPS = NULL;
IBaseFilter *g_pSrcFilter = NULL;
BYTE g_Time = 0xFF;
BOOL g_AutoStop = TRUE;
BOOL g_Timer = FALSE;

void CloseInterfaces()
{
	SAFE_RELEASE(g_pKPS);
	SAFE_RELEASE(g_pSrcFilter);
}

HRESULT FindCaptureDevice()
{
	USES_CONVERSION;
	HRESULT hr;
	CComPtr <ICreateDevEnum> pDevEnum;
	hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void ** ) &pDevEnum);
	if (FAILED(hr))
		return hr;
	CComPtr <IEnumMoniker> pClassEnum;
	hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
	if (FAILED(hr))
		return hr;
	if (pClassEnum == NULL) {
		MessageBox(0, TEXT("No IVC-200 with WDT was detected!\r\n\r\n")
			TEXT("This demo program requires at least one IVC-200 with WDT\r\n")
			TEXT("to be installed and working properly. The program will now close."),
			TEXT("Warning"), MB_OK | MB_ICONWARNING);
		return E_FAIL;
	}
	pClassEnum->Reset();
	while (1) {
		CComPtr <IMoniker> pMoniker;
		ULONG cFetched;
		if (S_OK != pClassEnum->Next(1, &pMoniker, &cFetched))
			break;
		CComPtr <IPropertyBag> pBag;
		hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **) &pBag);
		if (SUCCEEDED(hr)) {
			CComVariant var;
			var.vt = VT_BSTR;
			hr = pBag->Read(L"FriendlyName", &var, NULL);
			if (hr == S_OK) {
				char szText[64];
				wsprintf(szText, "%s", W2T(var.bstrVal));
				if (strstr(szText, "IVC-200 Video") && (strlen(szText) > 14) && (strlen(szText) < 21)) {
					hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**) &g_pSrcFilter);
					if (SUCCEEDED(hr)) {
						hr = g_pSrcFilter->QueryInterface(IID_IKsPropertySet, (void **) &g_pKPS);
						if (SUCCEEDED(hr)) {
							KSPROPERTY_CUSTOMBT848_WDT_S tc;
							ULONG ret = 0;
							HRESULT hr;
							ZeroMemory(&tc, sizeof(tc));
							hr = g_pKPS->Set(PROPSETID_CUSTOMBT848, KSPROPERTY_CUSTOMBT848_WDT,
								INSTANCE_DATA_OF_PROPERTY_PTR(&tc),
								INSTANCE_DATA_OF_PROPERTY_SIZE(tc),
								&tc,
								sizeof(tc));
							if (SUCCEEDED(hr)) {
								g_Time = 0;
								break;
							}
						}
						CloseInterfaces();
					}
				}
			}
		}
	}
	if (g_Time == 0xFF) {
		MessageBox(0, TEXT("No IVC-200 with WDT was detected!\r\n\r\n")
			TEXT("This demo program requires at least one IVC-200 with WDT\r\n")
			TEXT("to be installed and working properly. The program will now close."),
			TEXT("Warning"), MB_OK | MB_ICONWARNING);
		return E_FAIL;
	}
	return S_OK;
}

BOOL APIENTRY WDTPageProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) {
		case WM_INITDIALOG:
			SendDlgItemMessage(hDlg, IDC_CHECK2, BM_SETCHECK, (WPARAM) BST_CHECKED, 0);
			SendDlgItemMessage(hDlg, IDC_CHECK1, BM_SETCHECK, (WPARAM) BST_CHECKED, 0);
			if (g_Time == 0) {
				SendDlgItemMessage(hDlg, IDC_RADIO2, BM_SETCHECK, (WPARAM) BST_CHECKED, 0);
				SetWindowText(GetDlgItem(hDlg, IDC_EDIT2), "1");
				EnableWindow(GetDlgItem(hDlg, IDC_CHECK1), FALSE);
				EnableWindow(GetDlgItem(hDlg, IDC_EDIT2), FALSE);
				SetFocus(GetDlgItem(hDlg, IDC_RADIO2));
			}
			else {
				char temp[8];
				sprintf(temp, "%d", g_Time);
				SetWindowText(GetDlgItem(hDlg, IDC_EDIT2), temp);
				SendDlgItemMessage(hDlg, IDC_RADIO1, BM_SETCHECK, (WPARAM) BST_CHECKED, 0);
				SetFocus(GetDlgItem(hDlg, IDC_EDIT2));
			}
			return FALSE;

		case WM_TIMER:
			if (wParam == ID_UPDATETIMER && g_Timer) {
				HRESULT hr;
				KSPROPERTY_CUSTOMBT848_WDT_S tc;
				ZeroMemory(&tc, sizeof(tc));
				tc.bWDTTime = g_Time;
				hr = g_pKPS->Set(PROPSETID_CUSTOMBT848, KSPROPERTY_CUSTOMBT848_WDT,
					INSTANCE_DATA_OF_PROPERTY_PTR(&tc),
					INSTANCE_DATA_OF_PROPERTY_SIZE(tc),
					&tc,
					sizeof(tc));
				if (FAILED(hr))
					MessageBox(hDlg, "Failure to access WDT!", "Warning", MB_OK | MB_ICONWARNING);
			}
			return TRUE;

		case WM_COMMAND:
			switch (GET_WM_COMMAND_ID(wParam, lParam)) {
				case IDCANCEL:
				case IDC_CANCEL:
					EndDialog(hDlg, 1);
					return TRUE;

				case IDC_OK:
					EnableWindow(GetDlgItem(hDlg, IDC_OK), FALSE);
					if (IsDlgButtonChecked(hDlg, IDC_RADIO1) == BST_CHECKED) {
						char temp[8];
						GetWindowText(GetDlgItem(hDlg, IDC_EDIT2), temp, sizeof(temp));
						KSPROPERTY_CUSTOMBT848_WDT_S tc;
						ZeroMemory(&tc, sizeof(tc));
						tc.bWDTTime = atoi(temp);
						if (tc.bWDTTime > 0xF0 || tc.bWDTTime == 0x00)
							MessageBox(hDlg, "WDT time-out period must be between 1 and 240!", "Warning", MB_OK | MB_ICONWARNING);
						else {
							g_Time = tc.bWDTTime;
							if (IsDlgButtonChecked(hDlg, IDC_CHECK2) == BST_CHECKED)
								g_AutoStop = TRUE;
							else
								g_AutoStop = FALSE;
							if (IsDlgButtonChecked(hDlg, IDC_CHECK1) == BST_CHECKED) {
								if (g_Timer)
									KillTimer(hDlg, ID_UPDATETIMER);
								SetTimer(hDlg, ID_UPDATETIMER, ((g_Time * 60 - 5) * 1000), NULL);
								g_Timer = TRUE;
							}
							else {
								if (g_Timer) {
									g_Timer = FALSE;
									KillTimer(hDlg, ID_UPDATETIMER);
								}
							}
							HRESULT hr;
							hr = g_pKPS->Set(PROPSETID_CUSTOMBT848, KSPROPERTY_CUSTOMBT848_WDT,
								INSTANCE_DATA_OF_PROPERTY_PTR(&tc),
								INSTANCE_DATA_OF_PROPERTY_SIZE(tc),
								&tc,
								sizeof(tc));
							if (FAILED(hr))
								MessageBox(hDlg, "Failure to access WDT!", "Warning", MB_OK | MB_ICONWARNING);
						}
					}
					else {
						KSPROPERTY_CUSTOMBT848_WDT_S tc;
						ZeroMemory(&tc, sizeof(tc));
						g_Time = 0;
						HRESULT hr;
						hr = g_pKPS->Set(PROPSETID_CUSTOMBT848, KSPROPERTY_CUSTOMBT848_WDT,
							INSTANCE_DATA_OF_PROPERTY_PTR(&tc),
							INSTANCE_DATA_OF_PROPERTY_SIZE(tc),
							&tc,
							sizeof(tc));
						if (FAILED(hr))
							MessageBox(hDlg, "Failure to access WDT!", "Warning", MB_OK | MB_ICONWARNING);
						if (g_Timer) {
							g_Timer = FALSE;
							KillTimer(hDlg, ID_UPDATETIMER);
						}
					}
					EnableWindow(GetDlgItem(hDlg, IDC_OK), TRUE);
					return TRUE;
				
				case IDC_RADIO1:
					EnableWindow(GetDlgItem(hDlg, IDC_CHECK1), TRUE);
					EnableWindow(GetDlgItem(hDlg, IDC_EDIT2), TRUE);
					SetFocus(GetDlgItem(hDlg, IDC_EDIT2));
					return TRUE;

				case IDC_RADIO2:
					EnableWindow(GetDlgItem(hDlg, IDC_CHECK1), FALSE);
					EnableWindow(GetDlgItem(hDlg, IDC_EDIT2), FALSE);
					return TRUE;

			}
			break;

		case WM_DESTROY:
			if (g_Timer) {
				g_Timer = FALSE;
				KillTimer(hDlg, ID_UPDATETIMER);
			}
			if (g_AutoStop) {
				KSPROPERTY_CUSTOMBT848_WDT_S tc;
				ZeroMemory(&tc, sizeof(tc));
				HRESULT hr;
				hr = g_pKPS->Set(PROPSETID_CUSTOMBT848, KSPROPERTY_CUSTOMBT848_WDT,
					INSTANCE_DATA_OF_PROPERTY_PTR(&tc),
					INSTANCE_DATA_OF_PROPERTY_SIZE(tc),
					&tc,
					sizeof(tc));
				if (FAILED(hr))
					MessageBox(hDlg, "Failure to access WDT!", "Warning", MB_OK | MB_ICONWARNING);
			}
			break;

		default:
			break;
	}
	return FALSE;
}

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hInstP, LPTSTR lpCmdLine, int nCmdShow)
{
	if (FAILED(CoInitialize(NULL)))
		exit(1);
	if (FAILED(FindCaptureDevice())) {
		CoUninitialize();
		exit(1);
		//g_Time = 0x0F;
	}
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_WDT), 0, (DLGPROC) WDTPageProc);
	CloseInterfaces();
	CoUninitialize();
	return 0;
}
