// ReceiveMsgDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ReceiveMsg.h"
#include "ReceiveMsgDlg.h"
#include "cm100.h"

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

/////////////////////////////////////////////////////////////////////////////
// CReceiveMsgDlg dialog

CReceiveMsgDlg::CReceiveMsgDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CReceiveMsgDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CReceiveMsgDlg)
	m_status = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CReceiveMsgDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CReceiveMsgDlg)
	DDX_Control(pDX, IDC_MSG_LIST, m_msglist);
	DDX_Control(pDX, IDC_BOARD_NO_COMBO, m_boardno);
	DDX_Control(pDX, IDC_BAUD_COMBO, m_baud);
	DDX_Text(pDX, IDC_STATUS_STATIC, m_status);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CReceiveMsgDlg, CDialog)
	//{{AFX_MSG_MAP(CReceiveMsgDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_ACTIVE_BUTTON, OnActiveButton)
	ON_BN_CLICKED(IDC_RECEIVE_BUTTON, OnReceiveButton)
	ON_BN_CLICKED(IDC_CLEAR_STATUS_BUTTON, OnClearStatusButton)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClearButton)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReceiveMsgDlg message handlers

BOOL CReceiveMsgDlg::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
	m_boardno.SetCurSel(0); //Initial board No combo box
	m_baud.SetCurSel(0);    //Initial baud combo box
	m_status="0x00";        //Initial status static text
	this->SetWindowText("ReceiveMsg --- No board is active");
	UpdateData(FALSE);      //Update the data of status static text
	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 CReceiveMsgDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (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 to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CReceiveMsgDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

static BYTE SelectedBoardNo;
static bool IsActiveFlag=false;
void CReceiveMsgDlg::OnActiveButton() 
{
	// TODO: Add your control notification handler code here
	BYTE BoardNo,Baud;
	int Ret;
	WORD BaudMap[]={10,20,50,125,250,500,800,1000};
	CString TitleStr;
	ConfigStruct Para;

	BoardNo=m_boardno.GetCurSel();
	Baud=m_baud.GetCurSel();
	if (IsActiveFlag){ //If board is active before, close it first.
		KillTimer(12345); //Stop timer event
		CM100_CloseBoard(SelectedBoardNo);
		IsActiveFlag=false;
	}

	Ret=CM100_ActiveBoard(BoardNo); //Active board
	if (Ret){
		MessageBox("Active Board Error!");
		this->SetWindowText("ReceiveMsg --- No board is active");
		return;
	}

	Ret = CM100_Init(BoardNo,1);  //Init board
	if(Ret){
		MessageBox("Init Board Error!");
		CM100_CloseBoard(BoardNo);
		this->SetWindowText("ReceiveMsg --- No board is active");
		return;
	}

	Para.AccMask[0]=0xff; //Set AccMask to 0xffffffff to pass all CAN messages from CAN bus
	Para.AccMask[1]=0xff;
	Para.AccMask[2]=0xff;
	Para.AccMask[3]=0xff;
	Para.AccCode[0]=0x00; //AccCode is useless when AccMask is 0xffffffff
	Para.AccCode[1]=0x00;
	Para.AccCode[2]=0x00;
	Para.AccCode[3]=0x00;
	Para.BaudRate=Baud+1; //Baud=0 for user-defined baud, 1:10K, 2:20K, 3:50K, 4:125K, 5:250K, 6:500K, 7:800K, 8:1M bps
	Para.BT0=0; //BT0 and BT1 are only useful when user-defined baud is used.
	Para.BT1=0;
	Ret = CM100_Config(BoardNo,1,&Para); //Configure board parameters
	if(Ret){
		MessageBox("Configure Board Error!");
		CM100_CloseBoard(BoardNo);
		this->SetWindowText("ReceiveMsg --- No board is active");
		return;
	}
	SelectedBoardNo=BoardNo;
	TitleStr.Format(_T("ReceiveMsg --- Board %d is active with baud %d K pbs"),BoardNo,BaudMap[Baud]);
	this->SetWindowText(TitleStr);
	IsActiveFlag=true;
	SetTimer(12345,500,NULL); //Start timer event per 500 ms
}

static BYTE MaxListCnt;
void CReceiveMsgDlg::OnReceiveButton() 
{
	// TODO: Add your control notification handler code here
	int i,j,MsgCnt,Ret;
	double Timestamp;
	CString ListStr,DataStr;
	PacketStruct CANMsg;

	MsgCnt=CM100_RxMsgCount(SelectedBoardNo,1); //Check the numbers of received CAN messages
	for (i=0;i<MsgCnt;i++){
		Ret=CM100_ReceiveMsg(SelectedBoardNo,1,&CANMsg); //Receive CAN message
		if (Ret){
			CString ErrStr;
			ErrStr.Format(_T("Get Message Error, Error code=%d"),Ret);
			MessageBox(ErrStr);
			break;
		}
		Timestamp=(double)CANMsg.MsgTimeStamps;
		if (CANMsg.rtr){ //if rtr bit is set, data is useless
			ListStr.Format("%03d Time=%8.1fms, Mode:%d, ID:%08lX, RTR:%d, DLen:%d",			
			                MaxListCnt,Timestamp/10,CANMsg.mode,CANMsg.id,CANMsg.rtr,CANMsg.len);
			m_msglist.AddString(ListStr); //Show CAN messages
		}
		else{
			ListStr.Format("%03d Time=%8.1fms, Mode:%d, ID:%08lX, RTR:%d, DLen:%d, Data(hex):",			
			                MaxListCnt,Timestamp/10,CANMsg.mode,CANMsg.id,CANMsg.rtr,CANMsg.len);
			if (CANMsg.len==0){
				ListStr.Format("%s X",ListStr);
			}
			else{
				ListStr.Format("%s[",ListStr);
				for (j=0;j<CANMsg.len;j++){
					if (j<CANMsg.len-1) ListStr.Format("%s%02X,",ListStr,CANMsg.data[j]);
					else ListStr.Format("%s%02X",ListStr,CANMsg.data[j]);
				}
				ListStr.Format("%s]",ListStr);
			}
			m_msglist.AddString(ListStr); //Show CAN messages
		}
		++MaxListCnt;
		if (!MaxListCnt){ //If ListBox buffer is full, clean it
			m_msglist.ResetContent();
		}
	}
}

void CReceiveMsgDlg::OnClearStatusButton() 
{
	// TODO: Add your control notification handler code here
	CM100_ClearDataOverrun(SelectedBoardNo,1);
}

void CReceiveMsgDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	KillTimer(12345);
	if (IsActiveFlag) CM100_CloseBoard(SelectedBoardNo);
	CDialog::OnCancel();
}

void CReceiveMsgDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	BYTE CANStatus;
	CM100_Status(SelectedBoardNo,1,&CANStatus); //Get CAN status
	m_status.Format("0x%02X",CANStatus);
	UpdateData(FALSE);
	CDialog::OnTimer(nIDEvent);
}

void CReceiveMsgDlg::OnClearButton() 
{
	// TODO: Add your control notification handler code here
	m_msglist.ResetContent();
	MaxListCnt=0;
}
