// WiiRemoteDlg.cpp : implementation file
//

#include "stdafx.h"
#include "WiiRemote.h"
#include "WiiRemoteDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


CString IntToHex(const int i)
{
	CString s;
	s.Format(_T("%.8X"), i);
	return s;
}

CString IntToHex(const __int64 i)
{
	CString s;
	s.Format(_T("%.4X%.8X"), static_cast<INT32>((i >> 32) & 0x00000FFFF),
		static_cast<INT32>(i) & 0xFFFFFFFF);
	return s;
}

__int64 StrToInt64(const CString& s)
{
	return _tcstoi64(s, NULL, 16);
}

CString FormatFloat(const double v)
{
	CString s;
	s.Format(_T("%.2f"), v);
	return s;
}

CString IntToStr(const int i)
{
	CString s;
	s.Format(_T("%d"), i);
	return s;
}

// CWiiRemoteDlg dialog




CWiiRemoteDlg::CWiiRemoteDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CWiiRemoteDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CWiiRemoteDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_DEVICES, lvDevices);
	DDX_Control(pDX, IDC_STATIC_BATT_LEVEL, laBattLevel);
	DDX_Control(pDX, IDC_CHECK_LED_1, cbLed1);
	DDX_Control(pDX, IDC_CHECK_LED_2, cbLed2);
	DDX_Control(pDX, IDC_CHECK_LED_3, cbLed3);
	DDX_Control(pDX, IDC_CHECK_LED_4, cbLed4);
	DDX_Control(pDX, IDC_CHECK_A, cbA);
	DDX_Control(pDX, IDC_CHECK_B, cbB);
	DDX_Control(pDX, IDC_CHECK_PLUS, cbPlus);
	DDX_Control(pDX, IDC_CHECK_HOME, cbHome);
	DDX_Control(pDX, IDC_CHECK_MINUS, cbMinus);
	DDX_Control(pDX, IDC_CHECK_ONE, cbOne);
	DDX_Control(pDX, IDC_CHECK_TWO, cbTwo);
	DDX_Control(pDX, IDC_CHECK_UP, cbUp);
	DDX_Control(pDX, IDC_CHECK_DOWN, cbDown);
	DDX_Control(pDX, IDC_CHECK_LEFT, cbLeft);
	DDX_Control(pDX, IDC_CHECK_RIGHT, cbRight);
	DDX_Control(pDX, IDC_STATIC_X, laX);
	DDX_Control(pDX, IDC_STATIC_Y, laY);
	DDX_Control(pDX, IDC_STATIC_Z, laZ);
	DDX_Control(pDX, IDC_STATIC_IR_MODE, laIrMode);
	DDX_Control(pDX, IDC_STATIC_SENSOR_0_POS, laSensor0Position);
	DDX_Control(pDX, IDC_STATIC_SENSOR_0_SIZE, laSensor0Size);
	DDX_Control(pDX, IDC_STATIC_SENSOR_0_FOUND, laSensor0Found);
	DDX_Control(pDX, IDC_STATIC_SENSOR_1_POS, laSensor1Position);
	DDX_Control(pDX, IDC_STATIC_SENSOR_1_SIZE, laSensor1Size);
	DDX_Control(pDX, IDC_STATIC_SENSOR_1_FOUND, laSensor1Found);
	DDX_Control(pDX, IDC_STATIC_SENSOR_2_POS, laSensor2Position);
	DDX_Control(pDX, IDC_STATIC_SENSOR_2_SIZE, laSensor2Size);
	DDX_Control(pDX, IDC_STATIC_SENSOR_2_FOUND, laSensor2Found);
	DDX_Control(pDX, IDC_STATIC_SENSOR_3_POS, laSensor3Position);
	DDX_Control(pDX, IDC_STATIC_SENSOR_3_SIZE, laSensor3Size);
	DDX_Control(pDX, IDC_STATIC_SENSOR_3_FOUND, laSensor3Found);
	DDX_Control(pDX, IDC_STATIC_IR_SENSIOTIVITY, laIrSensitivity);
	DDX_Control(pDX, IDC_STATIC_STATE, laNunchukState);
	DDX_Control(pDX, IDC_STATIC_NUNCHUK_X, laNunchukX);
	DDX_Control(pDX, IDC_STATIC_NUNCHUK_Y, laNunchukY);
	DDX_Control(pDX, IDC_STATIC_NUNCHUK_Z, laNunchukZ);
	DDX_Control(pDX, IDC_STATIC_NUNCHUK_JOY_X, laNunchukJoyX);
	DDX_Control(pDX, IDC_STATIC_NUNCHUK_JOY_Y, laNunchukJoyY);
	DDX_Control(pDX, IDC_CHECKNUNCHUK_C, cbNunchukC);
	DDX_Control(pDX, IDC_CHECK_NUNCHUK_Z, cbNunchukZ);
	DDX_Control(pDX, IDC_STATIC_BALANCE_BOARD_STATE, laBalanceBoardState);
	DDX_Control(pDX, IDC_STATIC_BB_TR, laBbTopRight);
	DDX_Control(pDX, IDC_STATIC_BB_TL, laBbTopLeft);
	DDX_Control(pDX, IDC_STATIC_BB_BR, laBbBottomRight);
	DDX_Control(pDX, IDC_STATIC_BB_BL, laBbBottomLeft);
	DDX_Control(pDX, IDC_LIST_LOG, lbLog);
}

BEGIN_MESSAGE_MAP(CWiiRemoteDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CWiiRemoteDlg::OnBnClickedButtonConnect)
	ON_BN_CLICKED(IDC_BUTTON_DISCONNECT, &CWiiRemoteDlg::OnBnClickedButtonDisconnect)
	ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CWiiRemoteDlg::OnBnClickedButtonClear)
	ON_BN_CLICKED(IDC_BUTTON_GET_STATUS, &CWiiRemoteDlg::OnBnClickedButtonGetStatus)
	ON_BN_CLICKED(IDC_BUTTON_GET_LEDS, &CWiiRemoteDlg::OnBnClickedButtonGetLeds)
	ON_BN_CLICKED(IDC_BUTTON_SET_LEDS, &CWiiRemoteDlg::OnBnClickedButtonSetLeds)
	ON_BN_CLICKED(IDC_BUTTON_ENABLE_ACCEL, &CWiiRemoteDlg::OnBnClickedButtonEnableAccel)
	ON_BN_CLICKED(IDC_BUTTON_DISABLE_ACCEL, &CWiiRemoteDlg::OnBnClickedButtonDisableAccel)
	ON_BN_CLICKED(IDC_BUTTON_IR_ENABLE, &CWiiRemoteDlg::OnBnClickedButtonIrEnable)
	ON_BN_CLICKED(IDC_BUTTON_IR_DISABLE, &CWiiRemoteDlg::OnBnClickedButtonIrDisable)
	ON_BN_CLICKED(IDC_BUTTON_RUMBLE_ON, &CWiiRemoteDlg::OnBnClickedButtonRumbleOn)
	ON_BN_CLICKED(IDC_BUTTON_RUMBLE_OFF, &CWiiRemoteDlg::OnBnClickedButtonRumbleOff)
	ON_BN_CLICKED(IDC_BUTTON_DISCOVER, &CWiiRemoteDlg::OnBnClickedButtonDiscover)
END_MESSAGE_MAP()


// CWiiRemoteDlg message handlers

BOOL CWiiRemoteDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here

	lvDevices.InsertColumn(0, _T("Address"), 0, 150);
	lvDevices.InsertColumn(1, _T("Name"), 0, 150);
	lvDevices.SetExtendedStyle(lvDevices.GetExtendedStyle() | LVS_EX_FULLROWSELECT);

	__hook(&CwclBluetoothManager::OnDiscoveringStarted, &wclBluetoothManager,
		&CWiiRemoteDlg::wclBluetoothManagerDiscoveringStarted);
	__hook(&CwclBluetoothManager::OnDeviceFound, &wclBluetoothManager,
		&CWiiRemoteDlg::wclBluetoothManagerDeviceFound);
	__hook(&CwclBluetoothManager::OnDiscoveringCompleted, &wclBluetoothManager,
		&CWiiRemoteDlg::wclBluetoothManagerDiscoveringCompleted);

	__hook(&CwclWiiRemoteClient::OnConnect, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientConnect);
	__hook(&CwclWiiRemoteClient::OnDisconnect, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientDisconnect);
	__hook(&CwclWiiRemoteClient::OnStatusChanged, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientStatusChanged);
	__hook(&CwclWiiRemoteClient::OnButtonsChanged, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientButtonsChanged);
	__hook(&CwclWiiRemoteClient::OnAccelChanged, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientAccelChanged);
	__hook(&CwclWiiRemoteClient::OnIrChanged, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientIrChanged);
	__hook(&CwclWiiRemoteClient::OnExtensionAttached, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientExtensionAttached);
	__hook(&CwclWiiRemoteClient::OnExtensionDetached, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientExtensionDetached);
	__hook(&CwclWiiRemoteClient::OnNunchukChanged, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientNunchukChanged);
	__hook(&CwclWiiRemoteClient::OnBalanceBoardChanged, &wclWiiRemoteClient,
		&CWiiRemoteDlg::wclWiiRemoteClientBalanceBoardChanged);
	
	wclBluetoothManager.Open();
	ClearAccel();
	ClearIr();
	ClearExtensions();

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CWiiRemoteDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CWiiRemoteDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CWiiRemoteDlg::OnDestroy()
{
	CDialog::OnDestroy();

	// TODO: Add your message handler code here

	wclWiiRemoteClient.Disconnect();
	wclBluetoothManager.Close();

	// On Visual Studio 2015 and above the __unhook() poroduces warning C4458
	// We we have to supress it. By some reason it can not be disabled by pragma
	// so we disabled it in the project settings.
	__unhook(&wclWiiRemoteClient);
	__unhook(&wclBluetoothManager);
}

CwclBluetoothRadio* CWiiRemoteDlg::GetRadio() const
{
	CwclBluetoothRadio* Radio;
	int Res = wclBluetoothManager.GetClassicRadio(Radio);
	if (Res != WCL_E_SUCCESS)
	{
		AfxMessageBox(_T("Get working radio failed"));
		return NULL;
	}
	return Radio;
}

void CWiiRemoteDlg::wclBluetoothManagerDiscoveringStarted(void* Sender,
	CwclBluetoothRadio* const Radio)
{
	UNREFERENCED_PARAMETER(Sender);
	UNREFERENCED_PARAMETER(Radio);

	lvDevices.DeleteAllItems();
	Trace(_T("Discovering started"));
}

void CWiiRemoteDlg::wclBluetoothManagerDeviceFound(void* Sender,
	CwclBluetoothRadio* const Radio, const __int64 Address)
{
	UNREFERENCED_PARAMETER(Sender);
	UNREFERENCED_PARAMETER(Radio);

	int Item = lvDevices.GetItemCount();
	lvDevices.InsertItem(Item, IntToHex(Address));
	lvDevices.SetItemText(Item, 1, _T(""));
}

void CWiiRemoteDlg::wclBluetoothManagerDiscoveringCompleted(void* Sender,
	CwclBluetoothRadio* const Radio, const int Error)
{
	UNREFERENCED_PARAMETER(Sender);

	for (int i = 0; i < lvDevices.GetItemCount(); i++)
	{
		__int64 Address = StrToInt64(lvDevices.GetItemText(i, 0));
		
		tstring Name;
		int Res = Radio->GetRemoteName(Address, Name);
		if (Res != WCL_E_SUCCESS)
			lvDevices.SetItemText(i, 1, _T("Error: 0x") + IntToHex(Res));
		else
			lvDevices.SetItemText(i, 1, Name.c_str());
	}
	
	Trace(_T("Discovering completed with result"), Error);
}
void CWiiRemoteDlg::OnBnClickedButtonConnect()
{
	if (wclWiiRemoteClient.State != csDisconnected)
	{
		AfxMessageBox(_T("Wii Remote is connected"));
		return;
	}
	
	CwclBluetoothRadio* Radio = GetRadio();
	if (Radio != NULL)
	{
		POSITION Pos = lvDevices.GetFirstSelectedItemPosition();
		if (Pos == NULL)
			AfxMessageBox(_T("Select device"));
		else
		{
			wclWiiRemoteClient.Address = StrToInt64(lvDevices.GetItemText(lvDevices.GetNextSelectedItem(Pos), 0));
			int Res = wclWiiRemoteClient.Connect(Radio);
			if (Res != WCL_E_SUCCESS)
				AfxMessageBox(_T("Unable connect: 0x") + IntToHex(Res));
		}
	}
}

void CWiiRemoteDlg::OnBnClickedButtonDisconnect()
{
	int Res = wclWiiRemoteClient.Disconnect();
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Unable disconnect: 0x") + IntToHex(Res));
}

void CWiiRemoteDlg::wclWiiRemoteClientConnect(void* Sender, const int Error)
{
	UNREFERENCED_PARAMETER(Sender);

	if (Error != WCL_E_SUCCESS)
		Trace(_T("Connection failed"), Error);
	else
	{
		Trace(_T("Connected"));
		SetLeds();
	}
}

void CWiiRemoteDlg::wclWiiRemoteClientDisconnect(void* Sender, const int Reason)
{
	UNREFERENCED_PARAMETER(Sender);

	Trace(_T("Disconnected. Reason"), Reason);
	
	laBattLevel.SetWindowText(_T("0.00"));
	cbLed1.SetCheck(FALSE);
	cbLed2.SetCheck(FALSE);
	cbLed3.SetCheck(FALSE);
	cbLed4.SetCheck(FALSE);
	
	cbA.SetCheck(FALSE);
	cbB.SetCheck(FALSE);
	cbPlus.SetCheck(FALSE);
	cbHome.SetCheck(FALSE);
	cbMinus.SetCheck(FALSE);
	cbOne.SetCheck(FALSE);
	cbTwo.SetCheck(FALSE);
	cbUp.SetCheck(FALSE);
	cbDown.SetCheck(FALSE);
	cbLeft.SetCheck(FALSE);
	cbRight.SetCheck(FALSE);
	
	ClearAccel();
	ClearIr();
	ClearExtensions();
}

void CWiiRemoteDlg::wclWiiRemoteClientStatusChanged(void* Sender, const double Batt, 
	const wclWiiRemoteLeds& Leds)
{
	UNREFERENCED_PARAMETER(Sender);

	Trace(_T("Status changed"));
	
	laBattLevel.SetWindowText(FormatFloat(Batt));
	
	cbLed1.SetCheck(Leds.Led1 == true);
	cbLed2.SetCheck(Leds.Led2 == true);
	cbLed3.SetCheck(Leds.Led3 == true);
	cbLed4.SetCheck(Leds.Led4 == true);
}

void CWiiRemoteDlg::OnBnClickedButtonClear()
{
	lbLog.ResetContent();
}

void CWiiRemoteDlg::Trace(const CString& Msg)
{
	lbLog.AddString(Msg);
}

void CWiiRemoteDlg::Trace(const CString& Msg, const int Res)
{
	Trace(Msg + _T(": 0x") + IntToHex(Res));
}

void CWiiRemoteDlg::OnBnClickedButtonGetStatus()
{
	int Res = wclWiiRemoteClient.GetStatus();
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Get status failed; 0x") + IntToHex(Res));
}

void CWiiRemoteDlg::OnBnClickedButtonGetLeds()
{
	if (wclWiiRemoteClient.State != csConnected)
		AfxMessageBox(_T("Not connected"));
	else
	{
		cbLed1.SetCheck(wclWiiRemoteClient.Leds.Led1 == true);
		cbLed2.SetCheck(wclWiiRemoteClient.Leds.Led2 == true);
		cbLed3.SetCheck(wclWiiRemoteClient.Leds.Led3 == true);
		cbLed4.SetCheck(wclWiiRemoteClient.Leds.Led4 == true);
	}
}

void CWiiRemoteDlg::OnBnClickedButtonSetLeds()
{
	SetLeds();
}

void CWiiRemoteDlg::SetLeds()
{
	int Res = wclWiiRemoteClient.SetLeds(cbLed1.GetCheck() == TRUE, cbLed2.GetCheck() == TRUE,
		cbLed3.GetCheck() == TRUE, cbLed4.GetCheck() == TRUE);
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Set LEDs failed: 0x") + IntToHex(Res));
}

void CWiiRemoteDlg::wclWiiRemoteClientButtonsChanged(void* Sender,
	const wclWiiRemoteButtons& Buttons)
{
	UNREFERENCED_PARAMETER(Sender);

	cbA.SetCheck(Buttons.A == true);
	cbB.SetCheck(Buttons.B == true);
	cbPlus.SetCheck(Buttons.Plus == true);
	cbHome.SetCheck(Buttons.Home == true);
	cbMinus.SetCheck(Buttons.Minus == true);
	cbOne.SetCheck(Buttons.One == true);
	cbTwo.SetCheck(Buttons.Two == true);
	cbUp.SetCheck(Buttons.Up == true);
	cbDown.SetCheck(Buttons.Down == true);
	cbLeft.SetCheck(Buttons.Left == true);
	cbRight.SetCheck(Buttons.Right == true);
}

void CWiiRemoteDlg::wclWiiRemoteClientAccelChanged(void* Sender, const wclWiiRemoteAccel& Accel)
{
	UNREFERENCED_PARAMETER(Sender);

	laX.SetWindowText(IntToStr(Accel.Values.X));
	laY.SetWindowText(IntToStr(Accel.Values.Y));
	laZ.SetWindowText(IntToStr(Accel.Values.Z));
}

void CWiiRemoteDlg::OnBnClickedButtonEnableAccel()
{
	int Res = wclWiiRemoteClient.EnableAccel();
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Enable accelerometer failed: 0x") + IntToHex(Res));
}

void CWiiRemoteDlg::OnBnClickedButtonDisableAccel()
{
	int Res = wclWiiRemoteClient.DisableAccel();
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Disable accelerometer failed: 0x") + IntToHex(Res));
	else
		ClearAccel();
}

void CWiiRemoteDlg::wclWiiRemoteClientIrChanged(void* Sender, const wclWiiRemoteIrSensors& Ir)
{
	UNREFERENCED_PARAMETER(Sender);

	switch (Ir.Mode)
	{
		case wiiIrOff:
			ClearIr();
			break;
		case wiiIrBasicMode:
			laIrMode.SetWindowText(_T("Basic"));
			break;
		case wiiIrExtendedMode:
			laIrMode.SetWindowText(_T("Extended"));
			break;
		case wiiIrFullMode:
			laIrMode.SetWindowText(_T("Full"));
			break;
		default:
			laIrMode.SetWindowText(_T("Unknown"));
			break;
	}
	
	if (Ir.Mode != wiiIrOff)
	{
		switch (Ir.Sensitivity)
		{
			case wiiIrLevelOff:
				laIrSensitivity.SetWindowText(_T("Off"));
				break;
			case wiiIrLevel1:
				laIrSensitivity.SetWindowText(_T("Level 1"));
				break;
			case wiiIrLevel2:
				laIrSensitivity.SetWindowText(_T("Level 2"));
				break;
			case wiiIrLevel3:
				laIrSensitivity.SetWindowText(_T("Level 3"));
				break;
			case wiiIrLevel4:
				laIrSensitivity.SetWindowText(_T("Level 4"));
				break;
			case wiiIrLevel5:
				laIrSensitivity.SetWindowText(_T("Level 5"));
				break;
			case wiiIrLevelMax:
				laIrSensitivity.SetWindowText(_T("Maximum"));
				break;
			default:
				laIrSensitivity.SetWindowText(_T("Unknown"));
				break;
		}
		
		if (Ir.Sensors[0].Found)
		{
			laSensor0Position.SetWindowText(IntToStr(Ir.Sensors[0].Position.X) + _T("; ") +
				IntToStr(Ir.Sensors[0].Position.Y));
			laSensor0Size.SetWindowText(IntToStr(Ir.Sensors[0].Size));
			laSensor0Found.SetWindowText(_T("True"));
		}
		else
		{
			laSensor0Position.SetWindowText(_T("0; 0"));
			laSensor0Size.SetWindowText(_T("0"));
			laSensor0Found.SetWindowText(_T("False"));
		}
		
		if (Ir.Sensors[1].Found)
		{
			laSensor1Position.SetWindowText(IntToStr(Ir.Sensors[1].Position.X) + _T(": ") +
				IntToStr(Ir.Sensors[1].Position.Y));
			laSensor1Size.SetWindowText(IntToStr(Ir.Sensors[1].Size));
			laSensor1Found.SetWindowText(_T("True"));
		}
		else
		{
			laSensor1Position.SetWindowText(_T("0; 0"));
			laSensor1Size.SetWindowText(_T("0"));
			laSensor1Found.SetWindowText(_T("False"));
		}
		
		if (Ir.Sensors[2].Found)
		{
			laSensor2Position.SetWindowText(IntToStr(Ir.Sensors[2].Position.X) + _T(": ") +
				IntToStr(Ir.Sensors[2].Position.Y));
			laSensor2Size.SetWindowText(IntToStr(Ir.Sensors[2].Size));
			laSensor2Found.SetWindowText(_T("True"));
		}
		else
		{
			laSensor2Position.SetWindowText(_T("0; 0"));
			laSensor2Size.SetWindowText(_T("0"));
			laSensor2Found.SetWindowText(_T("False"));
		}
		
		if (Ir.Sensors[3].Found)
		{
			laSensor3Position.SetWindowText(IntToStr(Ir.Sensors[3].Position.X) + _T(": ") +
				IntToStr(Ir.Sensors[3].Position.Y));
			laSensor3Size.SetWindowText(IntToStr(Ir.Sensors[3].Size));
			laSensor3Found.SetWindowText(_T("True"));
		}
		else
		{
			laSensor3Position.SetWindowText(_T("0; 0"));
			laSensor3Size.SetWindowText(_T("0"));
			laSensor3Found.SetWindowText(_T("False"));
		}
	}
}

void CWiiRemoteDlg::ClearAccel()
{
	laX.SetWindowText(_T("0"));
	laY.SetWindowText(_T("0"));
	laZ.SetWindowText(_T("0"));
}

void CWiiRemoteDlg::ClearIr()
{
	laIrMode.SetWindowText(_T("Off"));
	laIrSensitivity.SetWindowText(_T("Off"));
	
	laSensor0Position.SetWindowText(_T("0; 0"));
	laSensor0Size.SetWindowText(_T("0"));
	laSensor0Found.SetWindowText(_T("False"));
	
	laSensor1Position.SetWindowText(_T("0; 0"));
	laSensor1Size.SetWindowText(_T("0"));
	laSensor1Found.SetWindowText(_T("False"));
	
	laSensor2Position.SetWindowText(_T("0; 0"));
	laSensor2Size.SetWindowText(_T("0"));
	laSensor2Found.SetWindowText(_T("False"));
	
	laSensor3Position.SetWindowText(_T("0; 0"));
	laSensor3Size.SetWindowText(_T("0"));
	laSensor3Found.SetWindowText(_T("False"));
}

void CWiiRemoteDlg::OnBnClickedButtonIrEnable()
{
	int Res = wclWiiRemoteClient.SetIrSensitivity(wiiIrLevelMax);
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Enable IR failed: 0x") + IntToHex(Res));
}

void CWiiRemoteDlg::OnBnClickedButtonIrDisable()
{
	int Res = wclWiiRemoteClient.SetIrSensitivity(wiiIrLevelOff);
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Disable IR failed: 0x") + IntToHex(Res));
	else
		ClearIr();
}

void CWiiRemoteDlg::OnBnClickedButtonRumbleOn()
{
	int Res = wclWiiRemoteClient.SetRumble(true);
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Set Rumble ON failed; 0x") + IntToHex(Res));
}

void CWiiRemoteDlg::OnBnClickedButtonRumbleOff()
{
	int Res = wclWiiRemoteClient.SetRumble(false);
	if (Res != WCL_E_SUCCESS)
		AfxMessageBox(_T("Set Rumble OFF failed; 0x") + IntToHex(Res));
}

void CWiiRemoteDlg::wclWiiRemoteClientExtensionAttached(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	CString Ext;
	switch (wclWiiRemoteClient.Extension)
	{
		case wiiNoExtension:
			Ext = _T("wiiNoExtension");
			break;
		case wiiNunchuk:
			Ext = _T("wiiNunchuk");
			laNunchukState.SetWindowText(_T("Attached"));
			break;
		case wiiClassicController:
			Ext = _T("wiiClassicController");
			break;
		case wiiGuitar:
			Ext = _T("wiiGuitar");
			break;
		case wiiDrums:
			Ext = _T("wiiDrums");
			break;
		case wiiBalanceBoard:
			Ext = _T("wiiBalanceBoard");
			laBalanceBoardState.SetWindowText(_T("Attached"));
			break;
		default:
			Ext = _T("Unknonw");
			break;
	}
	
	Trace(_T("Extension attached: ") + Ext);
}

void CWiiRemoteDlg::wclWiiRemoteClientExtensionDetached(void* Sender)
{
	UNREFERENCED_PARAMETER(Sender);

	Trace(_T("Extension detached"));
	ClearExtensions();
}

void CWiiRemoteDlg::wclWiiRemoteClientNunchukChanged(void* Sender, const wclWiiRemoteNunchuk& Nunchuk)
{
	UNREFERENCED_PARAMETER(Sender);

	laNunchukX.SetWindowText(IntToStr(Nunchuk.Accel.Values.X));
	laNunchukY.SetWindowText(IntToStr(Nunchuk.Accel.Values.Y));
	laNunchukZ.SetWindowText(IntToStr(Nunchuk.Accel.Values.Z));
	
	laNunchukJoyX.SetWindowText(IntToStr(Nunchuk.Joystick.X));
	laNunchukJoyY.SetWindowText(IntToStr(Nunchuk.Joystick.Y));
	
	cbNunchukC.SetCheck(Nunchuk.C == true);
	cbNunchukZ.SetCheck(Nunchuk.Z == true);
}

void CWiiRemoteDlg::ClearNunchuk()
{
	laNunchukState.SetWindowText(_T("Detached"));
	
	laNunchukX.SetWindowText(_T("0"));
	laNunchukY.SetWindowText(_T("0"));
	laNunchukZ.SetWindowText(_T("0"));
	
	laNunchukJoyX.SetWindowText(_T("0"));
	laNunchukJoyY.SetWindowText(_T("0"));
	
	cbNunchukC.SetCheck(FALSE);
	cbNunchukZ.SetCheck(FALSE);
}

void CWiiRemoteDlg::ClearExtensions()
{
	ClearNunchuk();
	ClearBalanceBoard();
}

void CWiiRemoteDlg::ClearBalanceBoard()
{
	laBalanceBoardState.SetWindowText(_T("Detached"));
	
	laBbTopRight.SetWindowText(_T("0"));
	laBbTopLeft.SetWindowText(_T("0"));
	laBbBottomRight.SetWindowText(_T("0"));
	laBbBottomLeft.SetWindowText(_T("0"));
}

void CWiiRemoteDlg::wclWiiRemoteClientBalanceBoardChanged(void* Sender, const wclWiiRemoteBalanceBoard& Board)
{
	UNREFERENCED_PARAMETER(Sender);

	laBbTopRight.SetWindowText(FormatFloat(Board.SensorsKg.TopRight));
	laBbTopLeft.SetWindowText(FormatFloat(Board.SensorsKg.TopLeft));
	laBbBottomRight.SetWindowText(FormatFloat(Board.SensorsKg.BottomRight));
	laBbBottomLeft.SetWindowText(FormatFloat(Board.SensorsKg.BottomLeft));
}

void CWiiRemoteDlg::OnBnClickedButtonDiscover()
{
	  CwclBluetoothRadio* Radio = GetRadio();
	  if (Radio != NULL)
	  {
		  int Res = Radio->Discover(10, dkClassic);
		  if (Res != WCL_E_SUCCESS)
			  AfxMessageBox(_T("Discover failed; 0x") + IntToHex(Res));
	  }
}
