// TransmitMsgDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TransmitMsg.h"
#include "TransmitMsgDlg.h"
#include "cm100.h"

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

/////////////////////////////////////////////////////////////////////////////
// CTransmitMsgDlg dialog

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

void CTransmitMsgDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTransmitMsgDlg)
	DDX_Control(pDX, IDC_RTR_CHECK, m_rtr);
	DDX_Control(pDX, IDC_ID_EDIT, m_id);
	DDX_Control(pDX, IDC_MODE_RADIO, m_mode);
	DDX_Control(pDX, IDC_D7_EDIT, m_d7);
	DDX_Control(pDX, IDC_D6_EDIT, m_d6);
	DDX_Control(pDX, IDC_D5_EDIT, m_d5);
	DDX_Control(pDX, IDC_D4_EDIT, m_d4);
	DDX_Control(pDX, IDC_D3_EDIT, m_d3);
	DDX_Control(pDX, IDC_D2_EDIT, m_d2);
	DDX_Control(pDX, IDC_D1_EDIT, m_d1);
	DDX_Control(pDX, IDC_D0_EDIT, m_d0);
	DDX_Control(pDX, IDC_DLEN_COMBO, m_dlen);
	DDX_Control(pDX, IDC_BOARD_NO_COMBO, m_boardno);
	DDX_Control(pDX, IDC_BAUD_COMBO, m_baud);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTransmitMsgDlg, CDialog)
	//{{AFX_MSG_MAP(CTransmitMsgDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_CBN_SELCHANGE(IDC_DLEN_COMBO, OnSelchangeDlenCombo)
	ON_BN_CLICKED(IDC_ACTIVE_BUTTON, OnActiveButton)
	ON_BN_CLICKED(IDC_SEND_BUTTON, OnSendButton)
	ON_BN_CLICKED(IDC_RTR_CHECK, OnRtrCheck)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTransmitMsgDlg message handlers

BOOL CTransmitMsgDlg::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
	//Init all elements on dialog
	m_boardno.SetCurSel(0);
	m_baud.SetCurSel(0);
	m_dlen.SetCurSel(8);
	m_mode.SetCheck(true);
	m_id.SetWindowText("7FF");
	m_id.SetLimitText(8);
	m_d0.SetWindowText("12");
	m_d0.SetLimitText(2);
	m_d1.SetWindowText("34");
	m_d1.SetLimitText(2);
	m_d2.SetWindowText("56");
	m_d2.SetLimitText(2);
	m_d3.SetWindowText("78");
	m_d3.SetLimitText(2);
	m_d4.SetWindowText("90");
	m_d4.SetLimitText(2);
	m_d5.SetWindowText("AB");
	m_d5.SetLimitText(2);
	m_d6.SetWindowText("CD");
	m_d6.SetLimitText(2);
	m_d7.SetWindowText("EF");
	m_d7.SetLimitText(2);
	this->OnSelchangeDlenCombo();
	this->SetWindowText("TransmitMsg --- No board is active");
	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 CTransmitMsgDlg::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 CTransmitMsgDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CTransmitMsgDlg::OnSelchangeDlenCombo() 
{
	// TODO: Add your control notification handler code here
	int i,DataLen;
	CEdit *TempEdit[8]={&m_d0,&m_d1,&m_d2,&m_d3,&m_d4,&m_d5,&m_d6,&m_d7};

	if (m_rtr.GetCheck()) return;
	DataLen=m_dlen.GetCurSel();
	for (i=0;i<8;i++){
		if (i<DataLen) TempEdit[i]->EnableWindow(true);
		else TempEdit[i]->EnableWindow(false);
	}	
}

static BYTE SelectedBoardNo;
static bool IsActiveFlag=false;
void CTransmitMsgDlg::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.
		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("TransmitMsg --- 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;	
}

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

void CTransmitMsgDlg::OnSendButton() 
{
	// TODO: Add your control notification handler code here
	char* endtemp,TempArr[20];
	int i,Ret;
	DWORD TempValue;
	CString TempStr;
	PacketStruct CANMsg;
	CEdit *TempEdit[8]={&m_d0,&m_d1,&m_d2,&m_d3,&m_d4,&m_d5,&m_d6,&m_d7};

	UpdateData(true); //Get parameters from dialog

	m_id.GetWindowText(TempArr,10); //Get message id parameter
	TempValue=strtol(TempArr,&endtemp,16);
	if (m_mode.GetCheck()){ //Check the CAN message mode
		CANMsg.mode=0;
		CANMsg.id=TempValue&0x7ffUL;
	}
	else{
		CANMsg.mode=1;
		CANMsg.id=TempValue&0x1fffffffUL;
	}
	TempStr.Format(_T("%lX"),CANMsg.id);
	m_id.SetWindowText(TempStr); //Set message id parameter back to Edit box

	if (m_rtr.GetCheck()) CANMsg.rtr=1; //Check if the RTR is used or not
	else CANMsg.rtr=0;
	
	CANMsg.len=m_dlen.GetCurSel();  //Get data length parameter

	for (i=0;i<8;i++){
		TempEdit[i]->GetWindowText(TempArr,10);  //Get data parameters
		TempValue=strtol(TempArr,&endtemp,16);
		CANMsg.data[i]=(BYTE)(TempValue&0xff);
		TempStr.Format(_T("%02X"),CANMsg.data[i]);
		TempEdit[i]->SetWindowText(TempStr); //Set data parameters back to Edit box
	}

	Ret=CM100_SendMsg(SelectedBoardNo,1,&CANMsg); //Send CAN message to CAN bus
	if (Ret){
		CString ErrStr;
		ErrStr.Format(_T("Send Message Error, Error Code %d"),Ret);
		MessageBox(ErrStr);
	}
}

void CTransmitMsgDlg::OnRtrCheck() 
{
	// TODO: Add your control notification handler code here
	int i;
	CEdit *TempEdit[8]={&m_d0,&m_d1,&m_d2,&m_d3,&m_d4,&m_d5,&m_d6,&m_d7};

	if (m_rtr.GetCheck()){
		for (i=0;i<8;i++) TempEdit[i]->EnableWindow(false);
	}
	else{
		this->OnSelchangeDlenCombo();
	}
}
