// ControlDlg.cpp : implementation file

#include "stdafx.h"
#include "Capture.h"
#include "ControlDlg.h"
#include "pantilt.h"
#include "VideoWnd.h"
#include "fwxVideo.h" 
#include "fwx1394API.h"
#include "fwxDCam.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define REMOVED_TIMER_ID 5

#ifdef _PROFILE
	ULONG nFramesProcessed;
#endif

/////////////////////////////////////////////////////////////////////////////
// CControlDlg dialog

CControlDlg::CControlDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CControlDlg::IDD, pParent)
{
	
	//{{AFX_DATA_INIT(CControlDlg)
	nBrightness = 0;
	nFocus = 0;
	nGain = 0;
	nGamma = 0;
	nShutterSpeed = 0;
	nWhiteBalance = 0;
	nZoom = 0;
	nChannel = 0;
    nSaturation = 0;
    nHue = 0;
    nExposure = 0;
    nSharpness = 0;
    nIris = 0;
	bGrayScale = FALSE;
	//}}AFX_DATA_INIT

	pDCam = NULL;
	pVideoFrame = NULL;
	
	nFrameSize[0] = FRAMESIZE_MODE0;
	nFrameSize[1] = FRAMESIZE_MODE1;
	nFrameSize[2] = FRAMESIZE_MODE2;
	nFrameSize[3] = FRAMESIZE_MODE3;
	nFrameSize[4] = FRAMESIZE_MODE4;
	nFrameSize[5] = FRAMESIZE_MODE5;
	nVideoMode = 0;
	
	pFrameData = NULL;
	hDeviceRemovedEvent = NULL;
	bInitialized = FALSE;
	bPaused = FALSE;
	bReallocateIsoResources = FALSE;
	pVideoThread = NULL;

	hStopVideoThreadEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
	for (UINT i = 0; i < ISO_VIDEO_FRAMES; i++)
		hFrameCompleteEvent[i] = NULL;
}


void CControlDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CControlDlg)
	DDX_Control(pDX, IDC_STIRIS, m_stIris);
	DDX_Control(pDX, IDC_SLIRIS, m_slIris);
	DDX_Control(pDX, IDC_STSAT, m_stSaturation);
	DDX_Control(pDX, IDC_SLSAT, m_slSaturation);
	DDX_Control(pDX, IDC_CBVIDEOMODE, m_cbVideoMode);
	DDX_Control(pDX, IDC_CBFRAMERATE, m_cbFrameRate);
	DDX_Control(pDX, IDC_VIDEO, m_VideoWnd);
	DDX_Control(pDX, IDC_STWB, m_stWhiteBalance);
	DDX_Control(pDX, IDC_STSHUTTER, m_stShutterSpeed);
	DDX_Control(pDX, IDC_STHUE, m_stHue);
	DDX_Control(pDX, IDC_STGAMMA, m_stGamma);
	DDX_Control(pDX, IDC_STGAIN, m_stGain);
	DDX_Control(pDX, IDC_STFOCUS, m_stFocus);
	DDX_Control(pDX, IDC_STBRIGHT, m_stBrightness);
	DDX_Control(pDX, IDC_STZOOM, m_stZoom);
    DDX_Control(pDX, IDC_STEXP, m_stExposure);
    DDX_Control(pDX, IDC_STSHARP, m_stSharpness);
	DDX_Control(pDX, IDC_SLWBALANCE, m_slWhiteBalance);
	DDX_Control(pDX, IDC_SLSPEED, m_slShutterSpeed);
	DDX_Control(pDX, IDC_SLHUE, m_slHue);
	DDX_Control(pDX, IDC_SLGAMMA, m_slGamma);
	DDX_Control(pDX, IDC_SLGAIN, m_slGain);
	DDX_Control(pDX, IDC_SLFOCUS, m_slFocus);
	DDX_Control(pDX, IDC_SLBRIGHT, m_slBrightness);
	DDX_Control(pDX, IDC_SLZOOM, m_slZoom);
    DDX_Control(pDX, IDC_SLEXP, m_slExposure);
    DDX_Control(pDX, IDC_SLSHARP, m_slSharpness);
	DDX_Control(pDX, IDC_CKGSCALE, m_ckGScale);
	DDX_Control(pDX, IDC_STDCAM, m_stDCam);
	DDX_Control(pDX, IDC_EDITCHANNEL, m_editChannel);
	DDX_Control(pDX, IDC_STTS, m_stTS);
	DDX_Control(pDX, IDC_STTP, m_stTP);
	DDX_Control(pDX, IDC_STPS, m_stPS);
	DDX_Control(pDX, IDC_STPP, m_stPP);
	DDX_Control(pDX, IDC_EDITPS, m_editPS);
	DDX_Control(pDX, IDC_EDITTS, m_editTS);
	DDX_Control(pDX, IDC_EDITTP, m_editTP);
	DDX_Control(pDX, IDC_EDITPP, m_editPP);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CControlDlg, CDialog)
	//{{AFX_MSG_MAP(CControlDlg)
	ON_BN_CLICKED(IDC_BTNAPP, OnBtnapp)
	ON_BN_CLICKED(IDC_BTNATP, OnBtnatp)
	ON_BN_CLICKED(IDC_BTNATS, OnBtnats)
	ON_BN_CLICKED(IDC_BTNAPS, OnBtnaps)
	ON_BN_CLICKED(IDC_BTNSTART, OnBtnstart)
	ON_BN_CLICKED(IDC_BTNRESET, OnBtnreset)
	ON_BN_CLICKED(IDC_BTNCPP, OnBtncpp)
	ON_BN_CLICKED(IDC_BTNCTP, OnBtnctp)
	ON_BN_CLICKED(IDC_BTNCPS, OnBtncps)
	ON_BN_CLICKED(IDC_BTNCTS, OnBtncts)
	ON_WM_CLOSE()
	ON_CBN_SELCHANGE(IDC_CBVIDEOMODE, OnSelchangeCbvideomode)
	ON_BN_CLICKED(IDC_BTN_APPLY, OnBtnApply)
	ON_WM_HSCROLL()
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BTNSTOP, OnBtnstop)
	ON_BN_CLICKED(IDC_BTNPAUSE, OnBtnpause)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CControlDlg message handlers


void CControlDlg::OnBtnapp() 
{	
	if (PanTilt.GetRun() == 0)
	{
		m_editPP.GetWindowText(nPP);
		outPP.Format("pp%s", nPP);

		if (PanTilt.Running(outPP))
		{
			inPP = PanTilt.ReadData("pp");
			m_stPP.SetWindowText(inPP);
			PanTilt.Stopping();
		}
		else
			AfxMessageBox("Unable to open the port.");
	}
	else
		PanTilt.Stopping();
}

void CControlDlg::OnBtnatp() 
{
	if (PanTilt.GetRun() == 0)
	{
		m_editTP.GetWindowText(nTP);
		outTP.Format("tp%s", nTP);

		if (PanTilt.Running(outTP))
		{
			inTP = PanTilt.ReadData("tp");
			m_stTP.SetWindowText(inTP);
			PanTilt.Stopping();
		}
		else
			AfxMessageBox("Unable to open the port.");
	}
	else
		PanTilt.Stopping();
}

void CControlDlg::OnBtnats() 
{
	if (PanTilt.GetRun() == 0)
	{
		m_editTS.GetWindowText(nTS);
		outTS.Format("ts%s", nTS);

		if (PanTilt.Running(outTS))
		{
			inTS = PanTilt.ReadData("ts");
			m_stTS.SetWindowText(inTS);
			PanTilt.Stopping();
		}
		else
			AfxMessageBox("Unable to open the port.");
	}
	else
		PanTilt.Stopping();
}

void CControlDlg::OnBtnaps() 
{
	if (PanTilt.GetRun() == 0)
	{
		m_editPS.GetWindowText(nPS);
		outPS.Format("ps%s", nPS);

		if (PanTilt.Running(outPS))
		{
			inPS = PanTilt.ReadData("ps");
			m_stPS.SetWindowText(inPS);
			PanTilt.Stopping();
		}
		else
			AfxMessageBox("Unable to open the port.");
	}
	else
		PanTilt.Stopping();
}

void CControlDlg::OnBtnreset() 
{
	if (PanTilt.GetRun() == 0)
	{
		if (PanTilt.Running("r"))
		{
			inPP = "";
			outPP = "";
			m_editPP.SetWindowText(outPP);
			m_stPP.SetWindowText(inPP);

			inTP = "";
			outTP = "";
			m_editTP.SetWindowText(outTP);
			m_stTP.SetWindowText(inTP);

			inPS = "";
			outPS = "";
			m_editPS.SetWindowText(outPS);
			m_stPS.SetWindowText(inPS);

			inTS = "";
			outTS = "";
			m_editTS.SetWindowText(outTS);
			m_stTS.SetWindowText(inTS);

			PanTilt.Stopping();
		}
		else 
		{
			AfxMessageBox("Unable to open the port.");
		}
	}
	else
	{
		PanTilt.Stopping();
	}
}

void CControlDlg::OnBtncpp() 
{
	if (PanTilt.GetRun() == 0)
	{
		if (PanTilt.Running("pp"))
		{
			inPP = PanTilt.ReadData("pp");
			m_stPP.SetWindowText(inPP);
			PanTilt.Stopping();
		}
		else
			AfxMessageBox("Unable to open the port.");
	}
	else
		PanTilt.Stopping();
}

void CControlDlg::OnBtnctp() 
{
	if (PanTilt.GetRun() == 0)
	{
		if (PanTilt.Running("tp"))
		{
			inTP = PanTilt.ReadData("tp");
			m_stTP.SetWindowText(inTP);
			PanTilt.Stopping();
		}
		else
			AfxMessageBox("Unable to open the port.");
	}
	else
		PanTilt.Stopping();
}

void CControlDlg::OnBtncps() 
{
	if (PanTilt.GetRun() == 0)
	{
		if (PanTilt.Running("ps"))
		{
			inPS = PanTilt.ReadData("ps");
			m_stPS.SetWindowText(inPS);
			PanTilt.Stopping();
		}
		else
			AfxMessageBox("Unable to open the port.");
	}
	else
		PanTilt.Stopping();
}

void CControlDlg::OnBtncts() 
{
	if (PanTilt.GetRun() == 0)
	{
		if (PanTilt.Running("ts"))
		{
			inTS = PanTilt.ReadData("ts");
			m_stTS.SetWindowText(inTS);
			PanTilt.Stopping();
		}
		else
			AfxMessageBox("Unable to open the port.");
	}
	else
		PanTilt.Stopping();	
}

void CControlDlg::OnBtnstart() 
{
	if (bPaused)
	{
		if (pVideoThread)
		{
			pVideoThread->ResumeThread();
			bPaused = FALSE;
		}
	}
	else
	{
		if (StartVideo())
			bPaused = FALSE;
	}
}

BOOL CControlDlg::OnInitDialog() 
{
	CString szMsg;
	CDialog::OnInitDialog();

	pVideoProcess = new CVideoProcess;
	if (!pVideoProcess)
		return FALSE;

	m_VideoWnd.pVideoProcess = pVideoProcess;
	bInitialized = FALSE;
	
	//open the camera and initialize
	GUID.GUIDHi = 0x08004602;
	GUID.GUIDLo = 0x000302BA;

	fwxInitialize();

	if ((pDCam = (CfwxDCam *) DCam.Open(GUID.GUIDHi, GUID.GUIDLo)))
	{
		CString szVendorName = DCam.GetVendorName();
		CString szModelName = DCam.GetModelName();
		if (!szVendorName.IsEmpty() && !szModelName.IsEmpty())
			szTitle = szVendorName + " " + szModelName;
		m_stDCam.SetWindowText(szTitle);
		hDeviceRemovedEvent = DCam.GetDeviceRemovedEvent();

		//setup the default type of video
		if (DCam.SetCameraPower(TRUE) && DCam.SetVFormat(0) &&
			DCam.SetVMode(nVideoMode) && DCam.SetVFrameRate(4) &&
			DCam.SetIsoChannelSpeed(0, 0))
		{
			//allocate the video frame buffer for mode 0
			pVideoFrame = new BYTE[nFrameSize[nVideoMode]];

			//allocate the Iso resources
			if (pVideoFrame && DCam.AllocateIsoResources(ISO_VIDEO_FRAMES, &pFrameData))
			{
				//get the handles for the frame complete named events
				for (UINT i = 0; i < ISO_VIDEO_FRAMES; i++)
					hFrameCompleteEvent[i] = DCam.GetFrameCompleteEvent(i);

				//initialize the video window
				if (m_VideoWnd.Initialize(0))
				{
					//everything was initialized
					bInitialized = TRUE;
					nRemovedTimerID = SetTimer(REMOVED_TIMER_ID, 500, NULL);
				}
			}
			else
			{
				AfxMessageBox("Error trying to allocate Iso resources.");
			}
		}
		else
		{
			AfxMessageBox("Error trying to initilaize camera settings.");
		}
	}
	else
	{
		szTitle = "Undetected Camera";
		m_stDCam.SetWindowText(szTitle);
		AfxMessageBox("Open camera device error.");
	}
	
	if (PanTilt.GetRun() == 0)
	{
		if (PanTilt.Running("pp"))
		{
			inPP = "";
			outPP = "";
			m_editPP.SetWindowText(outPP);
			m_stPP.SetWindowText(inPP);

			inTP = "";
			outTP = "";
			m_editTP.SetWindowText(outTP);
			m_stTP.SetWindowText(inTP);

			inPS = "";
			outPS = "";
			m_editPS.SetWindowText(outPS);
			m_stPS.SetWindowText(inPS);

			inTS = "";
			outTS = "";
			m_editTS.SetWindowText(outTS);
			m_stTS.SetWindowText(inTS);

			//set the ranges on the slider controls
			m_slBrightness.SetRange(0, 100);
			m_slFocus.SetRange(0, 100);
			m_slGain.SetRange(0, 100);
			m_slGamma.SetRange(0, 100);
			m_slHue.SetRange(0, 100);
            m_slSaturation.SetRange(0, 100);
			m_slShutterSpeed.SetRange(0, 100);
			m_slWhiteBalance.SetRange(0, 100);
			m_slZoom.SetRange(0, 100);
            m_slSharpness.SetRange(0, 100);
            m_slExposure.SetRange(0, 100);
            m_slIris.SetRange(0, 100);
			
			SetDCam(&DCam);

			if (pDCam)
			{
				SyncControls();
				CheckFeatures();
			}

			PanTilt.Stopping();

		}
		else 
		{
			AfxMessageBox("Unable to open the port.");
		}
	}
	else
	{
		PanTilt.Stopping();
	}

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}



void CControlDlg::OnOK() 
{
	if (PanTilt.GetRun() == 1)
		PanTilt.Stopping();	

	nShutDown = 1;
	//stop the timers
	KillTimer(nRemovedTimerID);

	//stop the threads
	SetEvent(hStopVideoThreadEvent);
	Sleep(100);

	//make sure the video was stopped
	StopVideo();

	//make sure the iso resources are free
	DCam.FreeIsoResources();
	
	fwxTerminate();

	CDialog::OnOK();
}

void CControlDlg::OnCancel() 
{
	if (PanTilt.GetRun() == 1)
		PanTilt.Stopping();	

	nShutDown = 1;
	//stop the timers
	KillTimer(nRemovedTimerID);

	//stop the threads
	SetEvent(hStopVideoThreadEvent);
	Sleep(100);

	//make sure the video was stopped
	StopVideo();

	//make sure the iso resources are free
	DCam.FreeIsoResources();
	
	fwxTerminate();

	CDialog::OnCancel();
}

void CControlDlg::SetDCam(CfwxDCam *dcam)
{
	pDCam = dcam;

	if (pDCam)
	{
		m_slZoom.EnableWindow(TRUE);
		m_slBrightness.EnableWindow(TRUE);
		m_slFocus.EnableWindow(TRUE);
		m_slGain.EnableWindow(TRUE);
		m_slGamma.EnableWindow(TRUE);
		m_slHue.EnableWindow(TRUE);
        m_slSaturation.EnableWindow(TRUE);
		m_slShutterSpeed.EnableWindow(TRUE);
		m_slWhiteBalance.EnableWindow(TRUE);
        m_slExposure.EnableWindow(TRUE);
        m_slSharpness.EnableWindow(TRUE);
        m_slIris.EnableWindow(TRUE);

		//get the hardware max and min values
		nBrightnessMin = pDCam->InqFeatureElement(CfwxDCam::Brightness, CfwxDCam::MIN_Value);
		nBrightnessMax = pDCam->InqFeatureElement(CfwxDCam::Brightness, CfwxDCam::MAX_Value);
		nFocusMin = pDCam->InqFeatureElement(CfwxDCam::Focus, CfwxDCam::MIN_Value);
		nFocusMax = pDCam->InqFeatureElement(CfwxDCam::Focus, CfwxDCam::MAX_Value);
		nGainMin = pDCam->InqFeatureElement(CfwxDCam::Gain, CfwxDCam::MIN_Value);
		nGainMax = pDCam->InqFeatureElement(CfwxDCam::Gain, CfwxDCam::MAX_Value);
		nGammaMin = pDCam->InqFeatureElement(CfwxDCam::Gamma, CfwxDCam::MIN_Value);
		nGammaMax = pDCam->InqFeatureElement(CfwxDCam::Gamma, CfwxDCam::MAX_Value);
		nShutterSpeedMin = pDCam->InqFeatureElement(CfwxDCam::Shutter, CfwxDCam::MIN_Value);
		nShutterSpeedMax = pDCam->InqFeatureElement(CfwxDCam::Shutter, CfwxDCam::MAX_Value);
		nWhiteBalanceMin = pDCam->InqFeatureElement(CfwxDCam::White_Balance, CfwxDCam::MIN_Value);
		nWhiteBalanceMax = pDCam->InqFeatureElement(CfwxDCam::White_Balance, CfwxDCam::MAX_Value);
		nZoomMin = pDCam->InqFeatureElement(CfwxDCam::Zoom, CfwxDCam::MIN_Value);
		nZoomMax = pDCam->InqFeatureElement(CfwxDCam::Zoom, CfwxDCam::MAX_Value);
        nHueMin = pDCam->InqFeatureElement(CfwxDCam::Hue, CfwxDCam::MIN_Value);
		nHueMax = pDCam->InqFeatureElement(CfwxDCam::Hue, CfwxDCam::MAX_Value);
        nSaturationMin = pDCam->InqFeatureElement(CfwxDCam::Saturation, CfwxDCam::MIN_Value);
		nSaturationMax = pDCam->InqFeatureElement(CfwxDCam::Saturation, CfwxDCam::MAX_Value);
        nExposureMin = pDCam->InqFeatureElement(CfwxDCam::Exposure, CfwxDCam::MIN_Value);
		nExposureMax = pDCam->InqFeatureElement(CfwxDCam::Exposure, CfwxDCam::MAX_Value);
        nSharpnessMin = pDCam->InqFeatureElement(CfwxDCam::Sharpness, CfwxDCam::MIN_Value);
		nSharpnessMax = pDCam->InqFeatureElement(CfwxDCam::Sharpness, CfwxDCam::MAX_Value);
        nIrisMin = pDCam->InqFeatureElement(CfwxDCam::Iris, CfwxDCam::MIN_Value);
        nIrisMax = pDCam->InqFeatureElement(CfwxDCam::Iris, CfwxDCam::MAX_Value);

		SyncControls();
		CheckFeatures();
	}
}

void CControlDlg::CheckFeatures()
{
	//setup the modes that the camera supports
	m_cbFrameRate.ResetContent();
	m_cbVideoMode.ResetContent();

	if (pDCam)
	{
		int idx = 0;
		Quadlet q;

		if (pDCam->InqVideoMode(0, &q))
		{
			if (q & 0x80000000)
			{
				m_cbVideoMode.InsertString(idx, "0 - 160x120x24");
				m_cbVideoMode.SetItemData(idx, 0);
				idx++;
			}

			if (q & 0x40000000)
			{
				m_cbVideoMode.InsertString(idx, "1 - 320x240x16");
				m_cbVideoMode.SetItemData(idx, 1);
				idx++;
			}

			if (q & 0x20000000)
			{
				m_cbVideoMode.InsertString(idx, "2 - 640x480x12");
				m_cbVideoMode.SetItemData(idx, 2);
				idx++;
			}

			if (q & 0x10000000)
			{
				m_cbVideoMode.InsertString(idx, "3 - 640x480x16");
				m_cbVideoMode.SetItemData(idx, 3);
				idx++;
			}

			if (q & 0x08000000)
			{
				m_cbVideoMode.InsertString(idx, "4 - 640x480x24");
				m_cbVideoMode.SetItemData(idx, 4);
				idx++;
			}

			if (q & 0x04000000)
			{
				m_cbVideoMode.InsertString(idx, "5 - 640x480x8");
				m_cbVideoMode.SetItemData(idx, 5);
				idx++;
			}
		}
	}

	//check the camera to see if it supports the slider controls
	if (pDCam)
	{
		if (pDCam->InqFeature(CfwxDCam::Zoom) <= 0)
		{
			m_slZoom.EnableWindow(FALSE);
		}
		else
		{
			m_slZoom.EnableWindow(TRUE);
		}

		if (pDCam->InqFeature(CfwxDCam::Brightness) <= 0)
		{
			m_slBrightness.EnableWindow(FALSE);
		}
		else
		{
			m_slBrightness.EnableWindow(TRUE);
		}

		if (pDCam->InqFeature(CfwxDCam::Focus) <= 0)
		{
			m_slFocus.EnableWindow(FALSE);
		}
		else
		{
			m_slFocus.EnableWindow(TRUE);
		}
		
		if (pDCam->InqFeature(CfwxDCam::Gain) <= 0)
		{
			m_slGain.EnableWindow(FALSE);
		}
		else
		{
			m_slGain.EnableWindow(TRUE);
		}

		if (pDCam->InqFeature(CfwxDCam::Gamma) <= 0)
		{
			m_slGamma.EnableWindow(FALSE);
		}
		else
		{
			m_slGamma.EnableWindow(TRUE);
		}

		if (pDCam->InqFeature(CfwxDCam::Shutter) <= 0)
		{
			m_slShutterSpeed.EnableWindow(FALSE);
		}
		else
		{
			m_slShutterSpeed.EnableWindow(TRUE);
		}

		if (pDCam->InqFeature(CfwxDCam::White_Balance) <= 0)
		{
			m_slWhiteBalance.EnableWindow(FALSE);
		}
		else
		{
			m_slWhiteBalance.EnableWindow(TRUE);
		}

        if (pDCam->InqFeature(CfwxDCam::Hue) <= 0)
		{
			m_slHue.EnableWindow(FALSE);
		}
		else
		{
			m_slHue.EnableWindow(TRUE);
		}

        if (pDCam->InqFeature(CfwxDCam::Saturation) <= 0)
		{
			m_slSaturation.EnableWindow(FALSE);
		}
		else
		{
			m_slSaturation.EnableWindow(TRUE);
		}

        if (pDCam->InqFeature(CfwxDCam::Exposure) <= 0)
		{
			m_slExposure.EnableWindow(FALSE);
		}
		else
		{
			m_slExposure.EnableWindow(TRUE);
		}

        if (pDCam->InqFeature(CfwxDCam::Sharpness) <= 0)
		{
			m_slSharpness.EnableWindow(FALSE);
		}
		else
		{
			m_slSharpness.EnableWindow(TRUE);
		}

        if (pDCam->InqFeature(CfwxDCam::Iris) <= 0)
		{
			m_slIris.EnableWindow(FALSE);
		}
		else
		{
			m_slIris.EnableWindow(TRUE);
		}
	}
}

BOOL CControlDlg::SyncControls()
{
	//get the current control settings from the camera
	USHORT value = 0;

	if (pDCam->InqFeature(CfwxDCam::Zoom) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Zoom, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nZoom = ((value - nZoomMin) * 100) / (nZoomMax - nZoomMin);
		else
			AfxMessageBox("Unable to get Zoom Control value");

		//check for a valid value
		if (nZoom < 0)
			nZoom = 0;
		else
		{
			if (nZoom > 100)
				nZoom = 100;
		}

		//update the slider and static box
		m_slZoom.SetPos(nZoom);	
		szZoom.Format("%d", nZoom);
		m_stZoom.SetWindowText(szZoom);
		
	}

	if (pDCam->InqFeature(CfwxDCam::Brightness) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Brightness, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nBrightness = ((value - nBrightnessMin) * 100) / (nBrightnessMax - nBrightnessMin);
		else
			AfxMessageBox("Unable to get Brightness Control value");

		//check for a valid value
		if (nBrightness < 0)
			nBrightness = 0;
		else
		{
			if (nBrightness > 100)
				nBrightness = 100;
		}

		//update the slider and static box
		m_slBrightness.SetPos(nBrightness);	
		szBrightness.Format("%d", nBrightness);
		m_stBrightness.SetWindowText(szBrightness);
	}

	if (pDCam->InqFeature(CfwxDCam::Focus) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Focus, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nFocus = ((value - nFocusMin) * 100) / (nFocusMax - nFocusMin);
		else
			AfxMessageBox("Unable to get Focus Control value");

		//check for a valid value
		if (nFocus < 0)
			nFocus = 0;
		else
		{
			if (nFocus > 100)
				nFocus = 100;
		}

		//update the slider and static box
		m_slFocus.SetPos(nFocus);
		szFocus.Format("%d", nFocus);
		m_stFocus.SetWindowText(szFocus);
	}

	if (pDCam->InqFeature(CfwxDCam::Gain) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Gain, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nGain = ((value - nGainMin) * 100) / (nGainMax - nGainMin);
		else
			AfxMessageBox("Unable to get Gain Control value");

		//check for a valid value
		if (nGain < 0)
			nGain = 0;
		else
		{
			if (nGain > 100)
				nGain = 100;
		}

		//update the slider and static box
		m_slGain.SetPos(nGain);	
		szGain.Format("%d", nGain);
		m_stGain.SetWindowText(szGain);
	}

	if (pDCam->InqFeature(CfwxDCam::Gamma) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Gamma, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nGamma = ((value - nGammaMin) * 100) / (nGammaMax - nGammaMin);
		else
			AfxMessageBox("Unable to get Gamma Control value");

		//check for a valid value
		if (nGamma < 0)
			nGamma = 0;
		else
		{
			if (nGamma > 100)
				nGamma = 100;
		}

		//update the slider and static box
		m_slGamma.SetPos(nGamma);	
		szGamma.Format("%d", nGamma);
		m_stGamma.SetWindowText(szGamma);
	}

	if (pDCam->InqFeature(CfwxDCam::Shutter) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Shutter, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nShutterSpeed = ((value - nShutterSpeedMin) * 100) / (nShutterSpeedMax - nShutterSpeedMin);
		else
			AfxMessageBox("Unable to get Shutter Speed Control value");

		//check for a valid value
		if (nShutterSpeed < 0)
			nShutterSpeed = 0;
		else
		{
			if (nShutterSpeed > 100)
				nShutterSpeed = 100;
		}

		//update the slider and static box
		m_slShutterSpeed.SetPos(nShutterSpeed);	
		szShutterSpeed.Format("%d", nShutterSpeed);
		m_stShutterSpeed.SetWindowText(szShutterSpeed);
	}

	if (pDCam->InqFeature(CfwxDCam::White_Balance) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::White_Balance, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nWhiteBalance = ((value - nWhiteBalanceMin) * 100) / (nWhiteBalanceMax - nWhiteBalanceMin);
		else
			AfxMessageBox("Unable to get White Balance Control value");

		//check for a valid value
		if (nWhiteBalance < 0)
			nWhiteBalance = 0;
		else
		{
			if (nWhiteBalance > 100)
				nWhiteBalance = 100;
		}

		//update the slider and static box
		m_slWhiteBalance.SetPos(nWhiteBalance);	
		szWhiteBalance.Format("%d", nWhiteBalance);
		m_stWhiteBalance.SetWindowText(szWhiteBalance);
	}

    if (pDCam->InqFeature(CfwxDCam::Hue) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Hue, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nHue = ((value - nHueMin) * 100) / (nHueMax - nHueMin);
		else
			AfxMessageBox("Unable to get Hue Control value");

		//check for a valid value
		if (nHue < 0)
			nHue = 0;
		else
		{
			if (nHue > 100)
				nHue = 100;
		}

		//update the slider and static box
		m_slHue.SetPos(nHue);	
		szHue.Format("%d", nHue);
		m_stHue.SetWindowText(szHue);
	}

    if (pDCam->InqFeature(CfwxDCam::Saturation) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Saturation, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nSaturation = ((value - nSaturationMin) * 100) / (nSaturationMax - nSaturationMin);
		else
			AfxMessageBox("Unable to get Saturation Control value");

		//check for a valid value
		if (nSaturation < 0)
			nSaturation = 0;
		else
		{
			if (nSaturation > 100)
				nSaturation = 100;
		}

		//update the slider and static box
		m_slSaturation.SetPos(nSaturation);	
		szSaturation.Format("%d", nSaturation);
		m_stSaturation.SetWindowText(szSaturation);
	}

    if (pDCam->InqFeature(CfwxDCam::Sharpness) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Sharpness, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nSharpness = ((value - nSharpnessMin) * 100) / (nSharpnessMax - nSharpnessMin);
		else
			AfxMessageBox("Unable to get Sharpness Control value");

		//check for a valid value
		if (nSharpness < 0)
			nSharpness = 0;
		else
		{
			if (nSharpness > 100)
				nSharpness = 100;
		}

		//update the slider and static box
		m_slSharpness.SetPos(nSharpness);	
		szSharpness.Format("%d", nSharpness);
		m_stSharpness.SetWindowText(szSharpness);
	}

    if (pDCam->InqFeature(CfwxDCam::Exposure) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Exposure, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nExposure = ((value - nExposureMin) * 100) / (nExposureMax - nExposureMin);
		else
			AfxMessageBox("Unable to get Exposure Control value");

		//check for a valid value
		if (nExposure < 0)
			nExposure = 0;
		else
		{
			if (nExposure > 100)
				nExposure = 100;
		}

		//update the slider and static box
		m_slExposure.SetPos(nExposure);	
		szExposure.Format("%d", nExposure);
		m_stExposure.SetWindowText(szExposure);
	}

    if (pDCam->InqFeature(CfwxDCam::Iris) > 0)
	{
		if ((value = pDCam->GetFeatureControl(CfwxDCam::Iris, CfwxDCam::Value)) >= 0)
			//calculate the % from the value
			nIris = ((value - nIrisMin) * 100) / (nIrisMax - nIrisMin);
		else
			AfxMessageBox("Unable to get Iris Control value");

		//check for a valid value
		if (nIris < 0)
			nIris = 0;
		else
		{
			if (nIris > 100)
				nIris = 100;
		}

		//update the slider and static box
		m_slIris.SetPos(nIris);	
		szIris.Format("%d", nIris);
		m_stIris.SetWindowText(szIris);
	}

	//set the camera to whatever the camera channel is
	if ((value = pDCam->GetIsoChannel()) >= 0)
		nChannel = value;
	else
		nChannel = 0;

	//set the video mode to whatever the camera is set to
	CString szVal;

	if ((value = pDCam->GetVMode()) >= 0)
	{
		szVal.Format("%d", value);
		m_cbVideoMode.SetCurSel(m_cbVideoMode.FindString(-1, szVal));
	}
	else
		m_cbVideoMode.SetCurSel(0);

	//setup the fps combo box with valid entries
	OnSelchangeCbvideomode();

	if ((value = pDCam->GetVFrameRate()) >= 0)
	{
		switch(value)
		{
		case 0:
			szVal = "1.";
			break;

		case 1:
			szVal = "3.";
			break;

		case 2:
			szVal = "7.";
			break;

		case 3:
			szVal = "15";
			break;

		case 5:
			szVal = "60";
			break;

		case 4:
		default:
			szVal = "30";
			break;
		}

		int idx = m_cbFrameRate.FindString(-1, szVal);
		if (idx != CB_ERR)
			m_cbFrameRate.SetCurSel(idx);
		else
			m_cbFrameRate.SetCurSel(0);
	}
	else
		m_cbFrameRate.SetCurSel(0);

	//update the static boxes
	UpdateData(FALSE);
	
	return true;

}

BOOL CControlDlg::SetZoomValue(int val)
{
	if (val < 0)
		//we must get the position from the slider control itself
		nZoom = m_slZoom.GetPos();
	else
		//o.w. just use the value parameter
		nZoom = val;

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nZoomMin + ((nZoomMax - nZoomMin + 1) * nZoom/100);
	if (value < nZoomMin)
		value = nZoomMin;
	
	if (value > nZoomMax)
		value = nZoomMax;

	//set the Zoom value of the camera and the interface
	m_slZoom.SetPos(nZoom);	
	szZoom.Format("%d", nZoom);
	m_stZoom.SetWindowText(szZoom);
	return pDCam->SetFeatureControl(CfwxDCam::Zoom, CfwxDCam::Value, value);
}

BOOL CControlDlg::SetFocusValue(int val)
{
	if (val < 0)
		//we must get the position from the slider control itself
		nFocus = m_slFocus.GetPos();
	else
		//o.w. just use the value parameter
		nFocus = val;

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nFocusMin + ((nFocusMax - nFocusMin + 1) * nFocus/100);
	if (value < nFocusMin)
		value = nFocusMin;
	
	if (value > nFocusMax)
		value = nFocusMax;

	//set the Focus value of the camera and the interface
	m_slFocus.SetPos(nFocus);
	szFocus.Format("%d", nFocus);
	m_stFocus.SetWindowText(szFocus);
	return pDCam->SetFeatureControl(CfwxDCam::Focus, CfwxDCam::Value, value);
	
}

BOOL CControlDlg::SetBrightnessValue(int val)
{
	if (val < 0)
		//we must get the position from the slider control itself
		nBrightness = m_slBrightness.GetPos();
	else
		//o.w. just use the value parameter
		nBrightness = val;

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nBrightnessMin + ((nBrightnessMax - nBrightnessMin + 1) * nBrightness/100);
	if (value < nBrightnessMin)
		value = nBrightnessMin;
	
	if (value > nBrightnessMax)
		value = nBrightnessMax;

	//set the brightness value of the camera and the interface
	m_slBrightness.SetPos(nBrightness);	
	szBrightness.Format("%d", nBrightness);
	m_stBrightness.SetWindowText(szBrightness);
    //pDCam->SetFeatureControl(CfwxDCam::Brightness, CfwxDCam::AM_Mode, 1);
	return pDCam->SetFeatureControl(CfwxDCam::Brightness, CfwxDCam::Value, value);
}

BOOL CControlDlg::SetShutterSpeed(int val)
{
	if (val < 0)
		//we must get the position from the slider control itself
		nShutterSpeed = m_slShutterSpeed.GetPos();
	else
		//o.w. just use the value parameter
		nShutterSpeed = val;

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nShutterSpeedMin + ((nShutterSpeedMax - nShutterSpeedMin + 1) * nShutterSpeed/100);
	if (value < nShutterSpeedMin)
		value = nShutterSpeedMin;
	
	if (value > nShutterSpeedMax)
		value = nShutterSpeedMax;

	//set the ShutterSpeed value of the camera and the interface
	m_slShutterSpeed.SetPos(nShutterSpeed);	
	szShutterSpeed.Format("%d", nShutterSpeed);
	m_stShutterSpeed.SetWindowText(szShutterSpeed);
	//pDCam->SetFeatureControl(CfwxDCam::Shutter, CfwxDCam::AM_Mode, 1);
	return pDCam->SetFeatureControl(CfwxDCam::Shutter, CfwxDCam::Value, value);
}

BOOL CControlDlg::SetWhiteBalance(int val)
{
    BOOL b;
	if (val < 0)
		//we must get the position from the slider control itself
		nWhiteBalance = m_slWhiteBalance.GetPos();
	else
		//o.w. just use the value parameter
		nWhiteBalance = val;

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nWhiteBalanceMin + ((nWhiteBalanceMax - nWhiteBalanceMin + 1) * nWhiteBalance/100);
	if (value < nWhiteBalanceMin)
		value = nWhiteBalanceMin;
	
	if (value > nWhiteBalanceMax)
		value = nWhiteBalanceMax;

	//set the WhiteBalance value of the camera and the interface
	m_slWhiteBalance.SetPos(nWhiteBalance);	
	szWhiteBalance.Format("%d", nWhiteBalance);
	m_stWhiteBalance.SetWindowText(szWhiteBalance);
	pDCam->SetFeatureControl(CfwxDCam::White_Balance, CfwxDCam::AM_Mode, 1);
	b = pDCam->SetFeatureControl(CfwxDCam::White_Balance, CfwxDCam::Value, value);
    return b;
}

BOOL CControlDlg::SetGammaValue(int val)
{
	if (val < 0)
		//we must get the position from the slider control itself
		nGamma = m_slGamma.GetPos();
	else
		//o.w. just use the value parameter
		nGamma = val;

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nGammaMin + ((nGammaMax - nGammaMin + 1) * nGamma/100);
	if (value < nGammaMin)
		value = nGammaMin;
	
	if (value > nGammaMax)
		value = nGammaMax;

	//set the Gamma value of the camera and the interface
	m_slGamma.SetPos(nGamma);	
	szGamma.Format("%d", nGamma);
	m_stGamma.SetWindowText(szGamma);
    //pDCam->SetFeatureControl(CfwxDCam::Gamma, CfwxDCam::AM_Mode, 1);
	return pDCam->SetFeatureControl(CfwxDCam::Gamma, CfwxDCam::Value, value);
}

BOOL CControlDlg::SetGainValue(int val)
{
	if (val < 0)
		//we must get the position from the slider control itself
		nGain = m_slGain.GetPos();
	else
		//o.w. just use the value parameter
		nGain = val; //text string???

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nGainMin + ((nGainMax - nGainMin + 1) * nGain/100);
	if (value < nGainMin)
		value = nGainMin;
	
	if (value > nGainMax)
		value = nGainMax;

	//set the Gain value of the camera and the interface
	m_slGain.SetPos(nGain);	
	szGain.Format("%d", nGain);
	m_stGain.SetWindowText(szGain);
    //pDCam->SetFeatureControl(CfwxDCam::Gain, CfwxDCam::AM_Mode, 1);
	return pDCam->SetFeatureControl(CfwxDCam::Gain, CfwxDCam::Value, value);
}

BOOL CControlDlg::SetHue(int val)
{
    if (val < 0)
		//we must get the position from the slider control itself
		nHue = m_slHue.GetPos();
	else
		//o.w. just use the value parameter
		nHue = val; //text string???

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nHueMin + ((nHueMax - nHueMin + 1) * nHue/100);
	if (value < nHueMin)
		value = nHueMin;
	
	if (value > nHueMax)
		value = nHueMax;

	//set the Hue value of the camera and the interface
	m_slHue.SetPos(nHue);	
	szHue.Format("%d", nHue);
	m_stHue.SetWindowText(szHue);
    //pDCam->SetFeatureControl(CfwxDCam::Hue, CfwxDCam::AM_Mode, 1);
	return pDCam->SetFeatureControl(CfwxDCam::Hue, CfwxDCam::Value, value);

}

BOOL CControlDlg::SetSaturation(int val)
{
    if (val < 0)
		//we must get the position from the slider control itself
		nSaturation = m_slSaturation.GetPos();
	else
		//o.w. just use the value parameter
		nSaturation = val; 
	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nSaturationMin + ((nSaturationMax - nSaturationMin + 1) * nSaturation/100);
	if (value < nSaturationMin)
		value = nSaturationMin;
	
	if (value > nSaturationMax)
		value = nSaturationMax;

	//set the Saturation value of the camera and the interface
	m_slSaturation.SetPos(nSaturation);	
	szSaturation.Format("%d", nSaturation);
	m_stSaturation.SetWindowText(szSaturation);
    //pDCam->SetFeatureControl(CfwxDCam::Saturation, CfwxDCam::AM_Mode, 1);
	return pDCam->SetFeatureControl(CfwxDCam::Saturation, CfwxDCam::Value, value);

}

BOOL CControlDlg::SetSharpness(int val)
{
    if (val < 0)
		//we must get the position from the slider control itself
		nSharpness = m_slSharpness.GetPos();
	else
		//o.w. just use the value parameter
		nSharpness = val; //text string???

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nSharpnessMin + ((nSharpnessMax - nSharpnessMin + 1) * nSharpness/100);
	if (value < nSharpnessMin)
		value = nSharpnessMin;
	
	if (value > nSharpnessMax)
		value = nSharpnessMax;

	//set the Sharpness value of the camera and the interface
	m_slSharpness.SetPos(nSharpness);	
	szSharpness.Format("%d", nSharpness);
	m_stSharpness.SetWindowText(szSharpness);
    //pDCam->SetFeatureControl(CfwxDCam::Sharpness, CfwxDCam::AM_Mode, 1);
	return pDCam->SetFeatureControl(CfwxDCam::Sharpness, CfwxDCam::Value, value);

}

/*BOOL CControlDlg::SetExposure(int val)
{
    if (val < 0)
		//we must get the position from the slider control itself
		nExposure = m_slExposure.GetPos();
	else
		//o.w. just use the value parameter
		nExposure = val; //text string???

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nExposureMin + ((nExposureMax - nExposureMin + 1) * nExposure/100);
	if (value < nExposureMin)
		value = nExposureMin;
	
	if (value > nExposureMax)
		value = nExposureMax;

	//set the Exposure value of the camera and the interface
	m_slExposure.SetPos(nExposure);	
	szExposure.Format("%d", nExposure);
	m_stExposure.SetWindowText(szExposure);
    //pDCam->SetFeatureControl(CfwxDCam::Exposure, CfwxDCam::AM_Mode, 1);
	return pDCam->SetFeatureControl(CfwxDCam::Exposure, CfwxDCam::Value, value);

}*/

BOOL CControlDlg::SetIris(int val)
{
    if (val < 0)
		//we must get the position from the slider control itself
		nIris = m_slIris.GetPos();
	else
		//o.w. just use the value parameter
		nIris = val; //text string???

	if (!UpdateData(FALSE))
		return false;

	//calculate the % of the hardware min and max value
	USHORT value = nIrisMin + ((nIrisMax - nIrisMin + 1) * nIris/100);
	if (value < nIrisMin)
		value = nIrisMin;
	
	if (value > nIrisMax)
		value = nIrisMax;

	//set the Iris value of the camera and the interface
	m_slIris.SetPos(nIris);	
	szIris.Format("%d", nIris);
	m_stIris.SetWindowText(szIris);
    //pDCam->SetFeatureControl(CfwxDCam::Iris, CfwxDCam::AM_Mode, 1);
	return pDCam->SetFeatureControl(CfwxDCam::Iris, CfwxDCam::Value, value);
}

int CControlDlg::GetZoomValue()
{
	return nZoom;
}

int CControlDlg::GetBrightnessValue()
{
	return nBrightness;
}

int CControlDlg::GetFocusValue()
{
	return nFocus;
}

int CControlDlg::GetShutterSpeed()
{
	return nShutterSpeed;
}

int CControlDlg::GetWhiteBalance()
{
	return nWhiteBalance;
}

int CControlDlg::GetGammaValue()
{
	return nGamma;
}

int CControlDlg::GetGainValue()
{
	return nGain;
}

int CControlDlg::GetHueValue()
{
    return nHue;
}

int CControlDlg::GetSaturationValue()
{
    return nSaturation;
}

int CControlDlg::GetSharpness()
{
    return nSharpness;
}

int CControlDlg::GetExposure()
{
    return nExposure;
}

int CControlDlg::GetIris()
{
    return nIris;
}

int CControlDlg::GetChannel()
{
	return nChannel;
}

void CControlDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// the slider controls send WM_HSCROLL messages here when their posision changes
	if ((nSBCode == TB_THUMBPOSITION) || (nSBCode == TB_THUMBTRACK))
	{
		ChangeControl ((CSliderCtrl *) pScrollBar, nPos);
	}
	else
	{
		if ((nSBCode == TB_LINEUP) || (nSBCode == TB_LINEDOWN) ||
			(nSBCode == TB_PAGEUP) || (nSBCode == TB_PAGEDOWN) ||
			(nSBCode == TB_TOP) || (nSBCode == TB_BOTTOM) ||
			(nSBCode == TB_ENDTRACK))
		{
			ChangeControl((CSliderCtrl *) pScrollBar, -1);
		}
	}
	
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CControlDlg::ChangeControl(CSliderCtrl *pSliderCtrl, int pos)
{
	if (pSliderCtrl == &m_slBrightness)
	{
		SetBrightnessValue(pos);
	}
	else
	{
		if (pSliderCtrl == &m_slFocus)
		{
			SetFocusValue(pos);
		}
		else
			if (pSliderCtrl == &m_slGain)
			{
				SetGainValue(pos);
			}
			else
				if (pSliderCtrl == &m_slGamma)
				{
					SetGammaValue(pos);
				}
				else
					if (pSliderCtrl == &m_slHue)
					{
						SetHue(pos);
					}
					else
						if (pSliderCtrl == &m_slShutterSpeed)
						{
							SetShutterSpeed(pos);
						}
						else
							if (pSliderCtrl == &m_slWhiteBalance)
							{
								SetWhiteBalance(pos);
							}
							else
								if (pSliderCtrl == &m_slZoom)
								{
									SetZoomValue(pos);
								}
                                else
                                    if (pSliderCtrl == &m_slSaturation)
                                    {
                                        SetSaturation(pos);
                                    }
                                    else
                                        if (pSliderCtrl == &m_slExposure)
                                        {
                                            //SetExposure(pos);
                                        }
                                        else
                                            if (pSliderCtrl == &m_slSharpness)
                                            {
                                                SetSharpness(pos);
                                            }
                                            else
                                                if (pSliderCtrl == &m_slIris)
                                                {
                                                    SetIris(pos);
                                                }
	}								
}

void CControlDlg::OnClose() 
{
	nShutDown = 1;
	//stop the timers
	KillTimer(nRemovedTimerID);

	//stop the threads
	SetEvent(hStopVideoThreadEvent);
	Sleep(100);

	//make sure the video was stopped
	StopVideo();

	//make sure the iso resources are free
	DCam.FreeIsoResources();
	
	fwxTerminate();
	CDialog::OnClose();
}

void CControlDlg::OnSelchangeCbvideomode() 
{
	// save the current frame rate
	int nRate = m_cbFrameRate.GetItemData(m_cbFrameRate.GetCurSel());

	m_cbFrameRate.ResetContent();

	// get the frame rate supported for the current video mode
	if (pDCam)
	{
		Quadlet q;
		if (pDCam->InqVideoFrameRate(0, m_cbVideoMode.GetCurSel(), &q))
		{
			int idx = 0;
			if (q & 0x80000000)
			{
				m_cbFrameRate.InsertString(idx, "1.875fps");
				m_cbFrameRate.SetItemData(idx, 0);
				idx++;
			}

			if (q & 0x40000000)
			{
				m_cbFrameRate.InsertString(idx, "3.75fps");
				m_cbFrameRate.SetItemData(idx, 1);
				idx++;
			}

			if (q & 0x20000000)
			{
				m_cbFrameRate.InsertString(idx, "7.5fps");
				m_cbFrameRate.SetItemData(idx, 2);
				idx++;
			}

			if (q & 0x10000000)
			{
				m_cbFrameRate.InsertString(idx, "15fps");
				m_cbFrameRate.SetItemData(idx, 3);
				idx++;
			}

			if (q & 0x08000000)
			{
				m_cbFrameRate.InsertString(idx, "30fps");
				m_cbFrameRate.SetItemData(idx, 4);
				idx++;
			}

			if (q & 0x04000000)
			{
				m_cbFrameRate.InsertString(idx, "60fps");
				m_cbFrameRate.SetItemData(idx, 5);
				idx++;
			}
		}
	}
	
	//try to restore the original frame rate
	CString szRate;
	switch(nRate)
	{
	case 0:
		szRate = "1.";
		break;
	case 1:
		szRate = "3.";
		break;
	case 2:
		szRate = "7.";
		break;
	case 3:
		szRate = "15";
		break;
	case 5:
		szRate = "60";
		break;
	case 4:
	default:
		szRate = "30";
		break;
	}

	int idx = m_cbFrameRate.FindString(-1, szRate);
	if (idx != CB_ERR)
		m_cbFrameRate.SetCurSel(idx);
	else
		m_cbFrameRate.SetCurSel(0);
}

void CControlDlg::OnBtnApply() 
{
	//get camera settings
	if (!UpdateData(TRUE))
		return;
	
	//change video mode
	if (!ChangeVideoMode((UINT) m_cbVideoMode.GetItemData(m_cbVideoMode.GetCurSel())))
		AfxMessageBox("Could not change video mode.");

	//change frame rate
	if (!ChangeFrameRate((UINT) m_cbFrameRate.GetItemData(m_cbFrameRate.GetCurSel())))
		AfxMessageBox("Could not change frame rate.");

	//change channel ???

	//change color mode
	bool check = FALSE;
	if (m_ckGScale.GetCheck() == 1)
	{
		//wants gray
		check = TRUE;
		ChangeColor(check);
	}
}

BOOL CControlDlg::ChangeChannel(UINT nChannel)
{
	if ((nChannel < 0) || (nChannel > 63))
	{
		AfxMessageBox("Invalid Channel.");
		return FALSE;
	}

	int chl = DCam.GetIsoChannel();
	if ((chl >= 0) && (chl == (int)nChannel))
		return TRUE; // Don't need to do anything else

	// See if the camera is currently transmitting
	int xmit = DCam.GetIsoTransmit();
	if (xmit < 0)
	{
		AfxMessageBox("Error reading camera while changing the channel.");
		return FALSE;	// An error occurred
	}

	if (xmit > 0)	// If the camera is transmitting
	{
		// Stop the video transmission
		if (!StopVideo())
		{
			return FALSE;
		}
	}

	// Get the current camera speed
	int nSpeed = DCam.GetIsoSpeed();
	if (nSpeed < 0)
		nSpeed = 0;

	// Change the camera channel
	if (!DCam.SetIsoChannelSpeed(nChannel, nSpeed))
	{
		AfxMessageBox("Could not change the channel.");
		return FALSE;
	}

	if (xmit > 0)	// If the camera was transmitting
	{
		// Restart the video transmission
		if (!StartVideo())
		{
			DCam.FreeIsoResources();
			for(int i=0; i < ISO_VIDEO_FRAMES; i++)
				hFrameCompleteEvent[i] = NULL;
			return FALSE;
		}
	}

	return TRUE;
}

BOOL CControlDlg::ChangeVideoMode(UINT nMode)
{
	if ((nMode < 0) || (nMode > 5))
	{
		AfxMessageBox("Invalid Video Mode.");
		return FALSE;
	}

	int mode = DCam.GetVMode();
	if ((mode >= 0) && (mode == (int)nMode))
		return TRUE; // Don't need to do anything else

	// See if the camera is currently transmitting
	int xmit = DCam.GetIsoTransmit();
	if (xmit < 0)
	{
		AfxMessageBox("Error reading camera while changing the video mode.");
		return FALSE;	// An error occurred
	}

	if (xmit > 0)	// If the camera is transmitting
	{
		// Stop the video transmission
		if (!StopVideo())
		{
			return FALSE;
		}
	}

	// Change the camera video mode
	if (!DCam.SetVMode(nMode))
	{
		AfxMessageBox("Could not change the video mode.");
		return FALSE;
	}
	else
	{
		bReallocateIsoResources = TRUE;
		nVideoMode = nMode;
	}

	// Delete the current video frame buffer
	delete []pVideoFrame;
	// Allocate a new buffer to hold the new frame size
	pVideoFrame = new BYTE[nFrameSize[nVideoMode]];

	// Get the current width and height of the video window
	CRect vrect;
	m_VideoWnd.GetWindowRect(&vrect);
	int xadj = vrect.right - vrect.left;
	int yadj = vrect.bottom - vrect.top;

	// Re-initialize the video window, this will adjust size to fit mode
	if (!m_VideoWnd.Initialize(nMode))
	{
		// Close this dialog if initialization of the videownd failed
		AfxMessageBox("Could not open video window.");
		return FALSE;
	}

	if (xmit > 0)	// If the camera was transmitting
	{
		// Restart the video transmission
		if (!StartVideo())
		{
			DCam.FreeIsoResources();
			for(int i=0; i < ISO_VIDEO_FRAMES; i++)
				hFrameCompleteEvent[i] = NULL;
			return FALSE;
		}
	}

	return TRUE;
}

BOOL CControlDlg::ChangeFrameRate(UINT nRate)
{
	if ((nRate < 1) || (nRate > 5))
	{
		AfxMessageBox("Invalid Frame Rate.");
		return FALSE;
	}

	int rate = DCam.GetVFrameRate();
	if ((rate >= 0) && (rate == (int)nRate))
		return TRUE; // Don't need to do anything else

	// See if the camera is currently transmitting
	int xmit = DCam.GetIsoTransmit();
	if (xmit < 0)
	{
		AfxMessageBox("Error reading camera while changing the frame rate.");
		return FALSE;	// An error occurred
	}

	if (xmit > 0)	// If the camera is transmitting
	{
		// Stop the video transmission
		if (!StopVideo())
		{
			return FALSE;
		}
	}

	// Change the camera video frame rate
	if (!DCam.SetVFrameRate(nRate))
	{
		AfxMessageBox("Could not change the frame rate.");
		return FALSE;
	}
	else
		bReallocateIsoResources = TRUE;

	if (xmit > 0)	// If the camera was transmitting
	{
		// Restart the video transmission
		if (!StartVideo())
		{
			DCam.FreeIsoResources();
			for(int i=0; i < ISO_VIDEO_FRAMES; i++)
				hFrameCompleteEvent[i] = NULL;
			return FALSE;
		}
	}

	return TRUE;
}

BOOL CControlDlg::ChangeColor(BOOL bColor)
{
	if (bColor)
	{
		if (!pVideoProcess->fwxSelectColorPalette())
		{
			AfxMessageBox("Error trying to change to color mode.");
			return FALSE;
		}
	}
	else
	{
		if (!pVideoProcess->fwxSelectGrayPalette())
		{
			AfxMessageBox("Error trying to change to grayscale mode.");
			return FALSE;
		}
	}

	return TRUE;
}

BOOL CControlDlg::Reconnect()
{
	CString szMsg, szError;
	//try to reestablish connection to this device
	szMsg = "This device has been removed from the bus.\nCheck the connection and select retry to reconnect.";
	while (AfxMessageBox(szMsg, MB_ICONSTOP|MB_RETRYCANCEL|MB_DEFBUTTON2) == IDRETRY)
	{
		if (DCam.Open(GUID.GUIDHi, GUID.GUIDLo))
			return TRUE;
		else
		{
			szError = fwxGetErrorText(DCam.GetLastError());
			AfxMessageBox(szError);
		}
	}
	return FALSE;
}

BOOL CControlDlg::StartVideo()
{
	CString szMsg;
	UINT nFrames = ISO_VIDEO_FRAMES;
	//the bus driver will not support multiple frames in 640x480 modes
	if (nVideoMode >= 2)
		nFrames = 1;

	if (bReallocateIsoResources)
	{
		//the video mode or framerate changed
		//we have to reallocate the correct amount of iso resources
		if (!StopVideo())
			return FALSE;

		if (!DCam.FreeIsoResources())
		{
			AfxMessageBox("Error trying to free Iso resources.");
			return FALSE;
		}
		else
		{
			for (UINT i = 0; i <ISO_VIDEO_FRAMES; i++)
				hFrameCompleteEvent[i] = NULL;
		}

		if (!DCam.AllocateIsoResources(nFrames, &pFrameData))
		{
			AfxMessageBox("error trying to allocate Iso resources.");
			return FALSE;
		}
		else
		{
			for (UINT i = 0; i < nFrames; i++)
				hFrameCompleteEvent[i] = DCam.GetFrameCompleteEvent(0);
		}

		bReallocateIsoResources = FALSE;
	}

	if (!DCam.SetIsoTransmit(TRUE))
	{
		AfxMessageBox("Error trying to start the camera transmission.");
		return FALSE;
	}

	//start the video thread
	if (pVideoThread == NULL)
	{
		ResetEvent(hStopVideoThreadEvent);
		VideoThreadArg.pFrameData = pFrameData;
		VideoThreadArg.pVideoFrame = pVideoFrame;
		VideoThreadArg.nFrameSize = nFrameSize[nVideoMode];
		VideoThreadArg.nFrames = nFrames;
		VideoThreadArg.nVideoMode = nVideoMode;
		VideoThreadArg.hStopVideoEvent = hStopVideoThreadEvent;
		for (int i = 0; i < ISO_VIDEO_FRAMES; i++)
			VideoThreadArg.hFrameCompleteEvent[i] = hFrameCompleteEvent[i];

		VideoThreadArg.pVideoProcess = pVideoProcess;
		VideoThreadArg.pThis = this;

#ifdef _PROFILE
		nFramesProcessed = 0;
		StartTick = ::GetTickCount();
#endif
		nShutDown = 0;
		pVideoThread = AfxBeginThread(ProcessVideoThread, &VideoThreadArg, THREAD_PRIORITY_TIME_CRITICAL);

	}
	return TRUE;
}

BOOL CControlDlg::StopVideo(void)
{
	// Stop the video thread
	if (pVideoThread)
	{
		SetEvent(hStopVideoThreadEvent);
#ifdef _PROFILE
		StopTick = ::GetTickCount();
#endif
		Sleep(20);
		pVideoThread = NULL;
	}

	// Stop the camera's transmission
	if( pVideoFrame == NULL )
		return FALSE;
	if (!DCam.SetIsoTransmit(FALSE))
	{
		AfxMessageBox("Error trying to stop the camera transmission.");
		return FALSE;
	}

	return TRUE;
}

void CControlDlg::OnTimer(UINT nIDEvent) 
{
	DWORD waitResult;
	switch (nIDEvent)
	{
	case REMOVED_TIMER_ID:
		waitResult = WaitForSingleObject(hDeviceRemovedEvent, 5);
		if (waitResult == WAIT_OBJECT_0)
		{
			KillTimer(nRemovedTimerID);
			ResetEvent(hDeviceRemovedEvent);
			if (!Reconnect())
				OnClose();
			else
				nRemovedTimerID = SetTimer(REMOVED_TIMER_ID, 500, NULL);
		}
		return;
		break;
	default:
		break;
	}
	
	CDialog::OnTimer(nIDEvent);
}

void CControlDlg::OnBtnstop() 
{
	if (StopVideo())
		bPaused = FALSE;

#ifdef _PROFILE
	float fSeconds = (float) (StopTick - StartTick) / 1000;
	CString szMsg;

	szMsg.Format("Driver frames processed:%d\nDriver frame rate:%dfps\nApp frames processed:%d\nApp frame rate:%d fps", 
		DCam.GetDriverFramesReceived(),
		(int) (DCam.GetDriverFramesReceived() / fSeconds + 0.5f), nFramesProcessed, 
		(int) (nFramesProcessed / fSeconds + 0.5f));
	AfxMessageBox(szMsg);

	nFramesProcessed = 0;
#endif
}

void CControlDlg::OnBtnpause() 
{
	if (!bPaused)
	{
		if (pVideoThread)
			pVideoThread->SuspendThread();

		bPaused = TRUE;
		
		//ask if the user wants to save the bitmap
		CFileDialog fdlg(FALSE, "bmp", "Capture.bmp");
		if (fdlg.DoModal() == IDOK)
		{
			TCHAR fname[256];
			strcpy(fname, fdlg.GetPathName());
			pVideoProcess->fwxSaveTrueBitmap(nVideoMode, pVideoFrame, fname);
		}
	}
	else
	{
		if (pVideoThread)
			pVideoThread->ResumeThread();
		bPaused = FALSE;
	}
}


UINT CControlDlg::ProcessVideoThread(LPVOID pParam)
{
	UINT i;
	BYTE *pData;
	SVideoThreadArg *pArg = (SVideoThreadArg *) pParam;
	//FILE *fp;
	//char name[] = "yuv";

	if ((pArg->pFrameData == NULL) || (pArg->pVideoFrame == NULL) || 
		(pArg->nFrameSize == 0) || (pArg->nFrames == 0))
		AfxEndThread(1);

	if ( !pArg->pVideoProcess->fwxValidateParam( ) ) 
		AfxEndThread(1);

	while( !pArg->pThis->nShutDown)
	{
		// Loop through the number of frames
		for(i=0; i < pArg->nFrames; i++)
		{
			// Check to see if the thread should stop
			if (WaitForSingleObject(pArg->hStopVideoEvent, 0) == WAIT_OBJECT_0)
				AfxEndThread(0);

			pData = ((BYTE *)pArg->pFrameData) + (i * (pArg->nFrameSize));

			// If we have an event handle and there are multiple frames, then
			// wait until the frame is ready to be read.  If we timeout, then
			// just go to next frame
			if( i > 10 ) 
				AfxEndThread(0);

			if (( pArg->hFrameCompleteEvent[i] != NULL) && (pArg->nFrames > 1))
				if (WaitForSingleObject(pArg->hFrameCompleteEvent[i], 10000) != WAIT_OBJECT_0)
					continue;

			// Process the frame
			//YUV file
			memcpy(pArg->pVideoFrame, pData, pArg->nFrameSize);
			
			//fp = fopen(name, "ab");
			//fwrite(pData, pArg->nFrameSize, 1, fp);
			//fclose(fp);

			pArg->pVideoProcess->fwxProcessFrame(pArg->nVideoMode, pArg->pVideoFrame);
			if (!ResetEvent( pArg->hFrameCompleteEvent[i] ))  
			{ 
				AfxEndThread(0);
			}


#ifdef _PROFILE
			nFramesProcessed++;
#endif
		}
	}

	return 0;
}




