﻿
// GetWdtSignalDataDlg.cpp : 実装ファイル
//

#include "stdafx.h"
#include "GetWdtSignalData.h"
#include "GetWdtSignalDataDlg.h"
#include "afxdialogex.h"

#include "CAO_i.c"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CGetWdtSignalDataDlg ダイアログ



CGetWdtSignalDataDlg::CGetWdtSignalDataDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_GETWDTSIGNALDATA_DIALOG, pParent)
	, m_cstrCmbMacAddr(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	m_eng = NULL;
	m_wss = NULL;
	m_ws = NULL;
	m_ctrl = NULL;
	m_varSignal = NULL;
	m_varTimeStamp = NULL;
}

void CGetWdtSignalDataDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, BTN_CANCEL, m_btnCancel);
	DDX_Control(pDX, BTN_CONNECT, m_btnConnect);
	DDX_Control(pDX, BTN_DISCONNECT, m_btnDisconnect);
	DDX_Control(pDX, BTN_GET_VALUE, m_btnGetValue);
	DDX_Control(pDX, BTN_SELECT, m_btnSelect);
	DDX_Control(pDX, COMBO_MAC_ADDRESS, m_cmbMacAddr);
	DDX_Control(pDX, IDC_BTN_GET_VARIABLE_NAMES, m_btnGetVariableNames);
	DDX_Text(pDX, EDITBOX_BLUE, m_edtBlue);
	DDX_Text(pDX, EDITBOX_BUZZER, m_edtBuzzer);
	DDX_Text(pDX, EDITBOX_FAILURE_COUNT, m_edtFailureCount);
	DDX_Text(pDX, EDITBOX_GREEN, m_edtGreen);
	DDX_Text(pDX, EDITBOX_INTERVAL, m_edtInterval);
	DDX_Control(pDX, EDITBOX_IPADDRESS, m_edtIpAddr);
	DDX_IPAddress(pDX, EDITBOX_IPADDRESS, m_dwIpAddr);
	DDX_Text(pDX, EDITBOX_LQI, m_edtLqi);
	DDX_Text(pDX, EDITBOX_PORT, m_edtPort);
	DDX_Text(pDX, EDITBOX_RED, m_edtRed);
	DDX_Text(pDX, EDITBOX_TIMESTAMP, m_edtTimeStamp);
	DDX_Text(pDX, EDITBOX_WHITE, m_edtWhite);
	DDX_Text(pDX, EDITBOX_YELLOW, m_edtYellow);
	DDX_CBString(pDX, COMBO_MAC_ADDRESS, m_cstrCmbMacAddr);
}

BEGIN_MESSAGE_MAP(CGetWdtSignalDataDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(BTN_CONNECT, &CGetWdtSignalDataDlg::OnBnClickedConnect)
	ON_BN_CLICKED(BTN_DISCONNECT, &CGetWdtSignalDataDlg::OnBnClickedDisconnect)
	ON_BN_CLICKED(BTN_SELECT, &CGetWdtSignalDataDlg::OnBnClickedSelect)
	ON_BN_CLICKED(BTN_CANCEL, &CGetWdtSignalDataDlg::OnBnClickedCancel)
	ON_BN_CLICKED(BTN_GET_VALUE, &CGetWdtSignalDataDlg::OnBnClickedGetValue)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BTN_GET_VARIABLE_NAMES, &CGetWdtSignalDataDlg::OnBnClickedBtnGetVariableNames)
END_MESSAGE_MAP()


// CGetWdtSignalDataDlg メッセージ ハンドラー

BOOL CGetWdtSignalDataDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
	//  Framework は、この設定を自動的に行います。
	SetIcon(m_hIcon, TRUE);			// 大きいアイコンの設定
	SetIcon(m_hIcon, FALSE);		// 小さいアイコンの設定

	CoInitialize(NULL);

	// Initial value
	m_edtPort = L"10001";
	m_edtInterval = L"1000";
	m_edtFailureCount = L"3";
	CWnd::UpdateData(false);
	m_edtIpAddr.SetWindowTextW(L"192.168.0.1");
	//m_edtIpAddr.SetWindowTextW(L"127.0.0.1");

	return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}

// ダイアログに最小化ボタンを追加する場合、アイコンを描画するための
//  下のコードが必要です。ドキュメント/ビュー モデルを使う MFC アプリケーションの場合、
//  これは、Framework によって自動的に設定されます。

void CGetWdtSignalDataDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 描画のデバイス コンテキスト

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// クライアントの四角形領域内の中央
		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;

		// アイコンの描画
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

// ユーザーが最小化したウィンドウをドラッグしているときに表示するカーソルを取得するために、
//  システムがこの関数を呼び出します。
HCURSOR CGetWdtSignalDataDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CGetWdtSignalDataDlg::OnBnClickedConnect()
{
	// Create CAO Engine
	HRESULT hr = CoCreateInstance(CLSID_CaoEngine, NULL, CLSCTX_LOCAL_SERVER, IID_ICaoEngine, (void**)&m_eng);
	m_eng->get_Workspaces(&m_wss);
	m_wss->Item(CComVariant(0L), &m_ws);

	// Create Option
	CString strIP;
	m_edtIpAddr.GetWindowTextW(strIP);
	CComBSTR bstrOption(L"Conn=eth:" + strIP + L":" + m_edtPort);
	bstrOption.Append(L",Interval=" + m_edtInterval);
	bstrOption.Append(L",FailureCount=" + m_edtFailureCount);

	hr = m_ws->AddController(CComBSTR(L"WDR"), CComBSTR(L"CaoProv.PATLITE.WDR"), CComBSTR(L""), bstrOption, &m_ctrl);
	if (FAILED(hr))
	{
		ShowErrorMessage(hr, L"AddController");
	}

	m_btnConnect.EnableWindow(false);
	m_btnDisconnect.EnableWindow(true);
	m_btnGetVariableNames.EnableWindow(true);
	m_cmbMacAddr.EnableWindow(true);
	m_btnSelect.EnableWindow(true);
	m_btnCancel.EnableWindow(false);
	m_btnGetValue.EnableWindow(false);
}


void CGetWdtSignalDataDlg::OnBnClickedDisconnect()
{
	OnBnClickedCancel();

	if (m_ctrl)
	{
		if (m_ws)
		{
			CComVariant vntCtrlName;
			CComPtr<ICaoControllers> ctrls;

			m_ws->get_Controllers(&ctrls);

			vntCtrlName.vt = VT_BSTR;
			m_ctrl->get_Name(&vntCtrlName.bstrVal);

			ctrls->Remove(vntCtrlName);
		}

		m_ctrl->Release();
		m_ctrl = NULL;
	}

	m_btnConnect.EnableWindow(true);
	m_btnDisconnect.EnableWindow(false);
	m_btnGetVariableNames.EnableWindow(false);
	m_cmbMacAddr.EnableWindow(false);
	m_btnSelect.EnableWindow(false);
	m_btnCancel.EnableWindow(false);
	m_btnGetValue.EnableWindow(false);
}

void CGetWdtSignalDataDlg::OnBnClickedBtnGetVariableNames()
{
	m_cmbMacAddr.ResetContent();

	CComVariant vntVariableNames;
	HRESULT hr = m_ctrl->get_VariableNames(CComBSTR(L""), &vntVariableNames);
	if (FAILED(hr))
	{
		ShowErrorMessage(hr, L"get_VariableNames");
	}

	// In the case of no wdt
	if (vntVariableNames.vt == VT_EMPTY)
	{
		return;
	}

	ULONG ulElemNum = vntVariableNames.parray->rgsabound->cElements;

	CComVariant* vntData;
	SafeArrayAccessData(vntVariableNames.parray, (void**)&vntData);

	CString cstrVariableName;

	// Skip TimeStamp variable
	for (size_t i = 0; i < ulElemNum; i+=2)
	{
		cstrVariableName = _com_util::ConvertBSTRToString(vntData[i].bstrVal);
		m_cmbMacAddr.AddString(cstrVariableName);
	}

	SafeArrayUnaccessData(vntVariableNames.parray);
}

void CGetWdtSignalDataDlg::OnBnClickedSelect()
{
	CWnd::UpdateData(true);
	if (m_cstrCmbMacAddr == L"")
	{
		MessageBox(L"Select WDT Mac Address", L"Error");
		return;
	}

	CComBSTR bstrMacAddr(m_cstrCmbMacAddr);
	
	// Signal variable
	HRESULT hr = m_ctrl->AddVariable(bstrMacAddr, CComBSTR(L""), &m_varSignal);
	if (FAILED(hr))
	{
		ShowErrorMessage(hr, L"AddVariable(Signal variable)");
	}

	// TimeStamp variable
	CComBSTR bstrTimeStampVar(L"TimeStamp_");
	bstrTimeStampVar.Append(bstrMacAddr);
	hr = m_ctrl->AddVariable(bstrTimeStampVar, CComBSTR(L""), &m_varTimeStamp);
	if (FAILED(hr))
	{
		ShowErrorMessage(hr, L"AddVariable(TimeStamp variable)");
	}

	m_btnSelect.EnableWindow(false);
	m_btnCancel.EnableWindow(true);
	m_btnGetValue.EnableWindow(true);
}


void CGetWdtSignalDataDlg::OnBnClickedCancel()
{
	if (m_ctrl)
	{
		CComVariant vntVarName;
		CComPtr<ICaoVariables> variables;

		m_ctrl->get_Variables(&variables);
		vntVarName.vt = VT_BSTR;

		if (m_varSignal) {
			m_varSignal->get_Name(&vntVarName.bstrVal);
			variables->Remove(vntVarName);
			m_varSignal->Release();
			m_varSignal = NULL;
		}

		if (m_varTimeStamp) {
			m_varTimeStamp->get_Name(&vntVarName.bstrVal);
			variables->Remove(vntVarName);
			m_varTimeStamp->Release();
			m_varTimeStamp = NULL;
		}

		m_btnSelect.EnableWindow(true);
		m_btnCancel.EnableWindow(false);
		m_btnGetValue.EnableWindow(false);
	}
}


void CGetWdtSignalDataDlg::OnBnClickedGetValue()
{
	CComVariant vntValue;
	HRESULT hr = m_varSignal->get_Value(&vntValue);
	INT* iData;

	// Get signal variable
	if (SUCCEEDED(hr))
	{
		SafeArrayAccessData(vntValue.parray, (void**)&iData);
		SetSignal(iData);
		SafeArrayUnaccessData(vntValue.parray);
	}
	else 
	{
		ShowErrorMessage(hr, L"get_Value(Signal Varible)");
	}

	// Get timestamp variable
	hr = m_varTimeStamp->get_Value(&vntValue);
	if (SUCCEEDED(hr))
	{
		SetTimeStamp(vntValue.date);
	}
	else
	{
		ShowErrorMessage(hr, L"get_Value(TimeStamp Variable)");
	}

	CWnd::UpdateData(false);
}



void CGetWdtSignalDataDlg::OnDestroy()
{
	CDialogEx::OnDestroy();

	OnBnClickedDisconnect();

	if (m_ws)
	{
		m_ws->Release();
		m_ws = NULL;
	}

	if (m_wss)
	{
		m_wss->Release();
		m_wss = NULL;
	}

	if (m_eng)
	{
		m_eng->Release();
		m_eng = NULL;
	}

	CoUninitialize();

}

void CGetWdtSignalDataDlg::ShowErrorMessage(HRESULT hr, CString cstrTarget)
{
	CString strMsg;
	strMsg.Format(_T("%X"), hr);
	cstrTarget.Append(L':' + strMsg);
	MessageBox(cstrTarget, _T("Error"));
}

void CGetWdtSignalDataDlg::SetSignal(INT * iData)
{
	CString cstrValue;

	// Red
	cstrValue.Format(L"%d", iData[0]);
	m_edtRed = cstrValue;

	// Yellow
	cstrValue.Format(L"%d", iData[1]);
	m_edtYellow = cstrValue;
	
	// Green
	cstrValue.Format(L"%d", iData[2]);
	m_edtGreen = cstrValue;
	
	// Blue
	cstrValue.Format(L"%d", iData[3]);
	m_edtBlue = cstrValue;
	
	// White
	cstrValue.Format(L"%d", iData[4]);
	m_edtWhite = cstrValue;
	
	// Buzzer
	cstrValue.Format(L"%d", iData[5]);
	m_edtBuzzer = cstrValue;
	
	// LQI
	cstrValue.Format(L"%d", iData[6]);
	m_edtLqi = cstrValue;
}

void CGetWdtSignalDataDlg::SetTimeStamp(double dDate)
{
	SYSTEMTIME systime;
	VariantTimeToSystemTime(dDate, &systime);

	CString strTime;
	strTime.Format(L"%d/%d/%d %d:%d:%d", systime.wMonth, systime.wDay, systime.wYear, systime.wHour, systime.wMinute, systime.wSecond);
	m_edtTimeStamp = strTime;
}
