// TaskDlg.cpp : 実装ファイル
//

#include "stdafx.h"
#include "Task.h"
#include "TaskDlg.h"
#include "CAO_i.c"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CTaskDlg ダイアログ

CTaskDlg::CTaskDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTaskDlg::IDD, pParent),
	m_eng(NULL), m_wss(NULL), m_ws(NULL),
	m_ctrls(NULL), m_ctrl(NULL),
	m_tsk(NULL),m_varStatus(NULL)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTaskDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON_INIT, m_btnInit);
	DDX_Control(pDX, IDC_BUTTON_CONNECT, m_btnConn);
	DDX_Control(pDX, IDC_BUTTON_DISCONNECT, m_btnDisconn);
	DDX_Control(pDX, IDC_BUTTON_START, m_btnStart);
	DDX_Control(pDX, IDC_BUTTON_STOP, m_btnStop);
}

BEGIN_MESSAGE_MAP(CTaskDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BUTTON_INIT, &CTaskDlg::OnBnClickedButtonInit)
	ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CTaskDlg::OnBnClickedButtonConnect)
	ON_BN_CLICKED(IDC_BUTTON_DISCONNECT, &CTaskDlg::OnBnClickedButtonDisconnect)
	ON_BN_CLICKED(IDC_BUTTON_START, &CTaskDlg::OnBnClickedButtonStart)
	ON_BN_CLICKED(IDC_BUTTON_STOP, &CTaskDlg::OnBnClickedButtonStop)
	ON_WM_DESTROY()

END_MESSAGE_MAP()


// CTaskDlg メッセージ ハンドラ

BOOL CTaskDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
	//  Framework は、この設定を自動的に行います。
	SetIcon(m_hIcon, TRUE);			// 大きいアイコンの設定
	SetIcon(m_hIcon, FALSE);		// 小さいアイコンの設定

	// Initialize DCOM
	CoInitialize(NULL);
	
	return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}


// ダイアログに最小化ボタンを追加する場合、アイコンを描画するための
//  下のコードが必要です。ドキュメント/ビュー モデルを使う MFC アプリケーションの場合、
//  これは、Framework によって自動的に設定されます。

void CTaskDlg::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
	{
		CDialog::OnPaint();
	}
}

// ユーザーが最小化したウィンドウをドラッグしているときに表示するカーソルを取得するために、
//  システムがこの関数を呼び出します。
HCURSOR CTaskDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

// ---------------------------------------------------------------
// Initialization
// ---------------------------------------------------------------
void CTaskDlg::OnBnClickedButtonInit()
{
	// Initialize DCOM
	CoInitialize(NULL);
	// Disconnect Robot
	OnBnClickedButtonDisconnect();

	// Create Engine
	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);
	m_ws->get_Controllers(&m_ctrls);

	// Enable command buttons
	m_btnInit.EnableWindow(FALSE);
	m_btnConn.EnableWindow(TRUE);
}


// ---------------------------------------------------------------
// Connect with the Robot
// ---------------------------------------------------------------
void CTaskDlg::OnBnClickedButtonConnect()
{
	OnBnClickedButtonDisconnect();
	HRESULT hr = S_OK;

	// Create object and connect with RC8 controller
	hr = m_ws->AddController(CComBSTR(L""), CComBSTR(L"CaoProv.DENSO.RC8"), CComBSTR(L""), CComBSTR(L"Server=192.168.0.1"), &m_ctrl);
	if(FAILED(hr)) {
		ShowErrorNumber(hr);
		return;
	}

	// Task control with RC8 controller
	hr = m_ctrl->AddTask(CComBSTR(L"Pro1"),CComBSTR(L""), &m_tsk);
	if(FAILED(hr)) {
		ShowErrorNumber(hr);
		return;
	}
	
	// Task class system variable
	hr = m_tsk->AddVariable(CComBSTR(L"@STATUS"), CComBSTR(L""), &m_varStatus);
	if(FAILED(hr)) {
		ShowErrorNumber(hr);
		return;
	}
	
	// Enable command buttons
	m_btnConn.EnableWindow(FALSE);
	m_btnDisconn.EnableWindow(TRUE);
	m_btnStart.EnableWindow(TRUE);
	m_btnStop.EnableWindow(TRUE);
}

// ---------------------------------------------------------------
// disconnect from the Robot
// ---------------------------------------------------------------
void CTaskDlg::OnBnClickedButtonDisconnect()
{		
	// Disconnect from the Task Variable
	if(m_varStatus != NULL) {
		m_varStatus->Release();
		m_varStatus = NULL;
	}

	if(m_tsk != NULL) {
		m_tsk->Release();
		m_tsk = NULL;
	}

	if(m_ctrl != NULL) {
		CComVariant index;
		m_ctrl->get_Index(&index.lVal);
		index.vt = VT_I4;
		m_ctrls->Remove(index);
		m_ctrl->Release();
		m_ctrl = NULL;
	}

	// Enable command buttons
	m_btnConn.EnableWindow(TRUE);
	m_btnDisconn.EnableWindow(FALSE);
	m_btnStart.EnableWindow(FALSE);
	m_btnStop.EnableWindow(FALSE);
}

void CTaskDlg::OnBnClickedButtonStart()
{
	HRESULT hr = S_OK;
	CComVariant vntVal;

	// caoTaskST [0:Task not yet generated (NON_EXISTENT), 1:Hold-stopped, 2:Stopped, 3:Running, 4:Step-stopped]
	hr = m_varStatus->get_Value(&vntVal);
	if(SUCCEEDED(hr)){
		if(vntVal.lVal != 3){
			// Start [1:One cycle execution, 2:Continuous execution, 3:Step forward]
			hr = m_tsk->Start(2, CComBSTR(L""));
			if(FAILED(hr)) {
				ShowErrorNumber(hr);
			}
		}
	}else{
		ShowErrorNumber(hr);
	}
}

void CTaskDlg::OnBnClickedButtonStop()
{
	HRESULT hr = S_OK;
	CComVariant vntVal;

	// caoTaskST [0:Task not yet generated (NON_EXISTENT), 1:Hold-stopped, 2:Stopped, 3:Running, 4:Step-stopped]
	hr = m_varStatus->get_Value(&vntVal);
	if(SUCCEEDED(hr)){
		if(vntVal.lVal == 3){
			// Stop [0:Default stop, 1:Instant stop, 2:Step stop, 3:Cycle stop, 4:Initialized stop]
			hr = m_tsk->Stop(4, CComBSTR(L""));
			if(FAILED(hr)) {
				ShowErrorNumber(hr);
			}
		}
	}else{
		ShowErrorNumber(hr);
	}
}

void CTaskDlg::OnDestroy()
{
	CDialog::OnDestroy();

	//  Delete CaoEngine
	OnBnClickedButtonDisconnect();

	if(m_ctrls != NULL) {
		m_ctrls->Release();
		m_ctrls = NULL;
	}

	if(m_ws != NULL) {
		m_ws->Release();
		m_ws = NULL;
	}

	if(m_wss != NULL) {
		m_wss->Release();
		m_wss = NULL;
	}

	if(m_eng != NULL) {
		m_eng->Release();
		m_eng = NULL;
	}

	// Terminate DCOM
	CoUninitialize();
}

void CTaskDlg::ShowErrorNumber(HRESULT hr)
{
	TCHAR tchVal[9];
	_stprintf_s(tchVal, 9, _T("%x"), hr);
	MessageBox(tchVal, _T("Error Number"), MB_OK);
}



