// TransmitMsgCyclicallyDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TransmitMsgCyclically.h"
#include "TransmitMsgCyclicallyDlg.h"
#include "cm100.h"

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

/////////////////////////////////////////////////////////////////////////////
// CTransmitMsgCyclicallyDlg dialog

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

void CTransmitMsgCyclicallyDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTransmitMsgCyclicallyDlg)
	DDX_Control(pDX, IDC_RTR_CHECK, m_rtr);
	DDX_Control(pDX, IDC_BAUD_COMBO, m_baud);
	DDX_Control(pDX, IDC_BOARD_NO_COMBO, m_boardno);
	DDX_Control(pDX, IDC_TIME_EDIT, m_time);
	DDX_Control(pDX, IDC_MSG_LIST, m_msglist);
	DDX_Control(pDX, IDC_MODE_RADIO, m_mode);
	DDX_Control(pDX, IDC_DLEN_COMBO, m_dlen);
	DDX_Control(pDX, IDC_ID_EDIT, m_id);
	DDX_Control(pDX, IDC_BYTE7_EDIT, m_d7);
	DDX_Control(pDX, IDC_BYTE6_EDIT, m_d6);
	DDX_Control(pDX, IDC_BYTE5_EDIT, m_d5);
	DDX_Control(pDX, IDC_BYTE4_EDIT, m_d4);
	DDX_Control(pDX, IDC_BYTE3_EDIT, m_d3);
	DDX_Control(pDX, IDC_BYTE2_EDIT, m_d2);
	DDX_Control(pDX, IDC_BYTE1_EDIT, m_d1);
	DDX_Control(pDX, IDC_BYTE0_EDIT, m_d0);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTransmitMsgCyclicallyDlg, CDialog)
	//{{AFX_MSG_MAP(CTransmitMsgCyclicallyDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_ACTIVE_BUTTON, OnActiveButton)
	ON_CBN_SELCHANGE(IDC_DLEN_COMBO, OnSelchangeDlenCombo)
	ON_BN_CLICKED(IDC_ADD_BUTTON, OnAddButton)
	ON_BN_CLICKED(IDC_DELETE_BUTTON, OnDeleteButton)
	ON_BN_CLICKED(IDC_ENABLE_BUTTON, OnEnableButton)
	ON_BN_CLICKED(IDC_DISABLE_BUTTON, OnDisableButton)
	ON_BN_CLICKED(IDC_RTR_CHECK, OnRtrCheck)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTransmitMsgCyclicallyDlg message handlers

BOOL CTransmitMsgCyclicallyDlg::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);
	m_time.SetWindowText("10000");
	m_time.SetLimitText(9);
	this->OnSelchangeDlenCombo();

	m_msglist.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); //Init List Control element
	m_msglist.InsertColumn(0,_T("Handle No."),LVCFMT_CENTER,70);
	m_msglist.InsertColumn(1,_T("Mode"),LVCFMT_CENTER,60);
	m_msglist.InsertColumn(2,_T("ID"),LVCFMT_CENTER,70);
	m_msglist.InsertColumn(3,_T("RTR"),LVCFMT_CENTER,35);
	m_msglist.InsertColumn(4,_T("DLen"),LVCFMT_CENTER,40);
	m_msglist.InsertColumn(5,_T("D0"),LVCFMT_CENTER,34);
	m_msglist.InsertColumn(6,_T("D1"),LVCFMT_CENTER,34);
	m_msglist.InsertColumn(7,_T("D2"),LVCFMT_CENTER,34);
	m_msglist.InsertColumn(8,_T("D3"),LVCFMT_CENTER,34);
	m_msglist.InsertColumn(9,_T("D4"),LVCFMT_CENTER,34);
	m_msglist.InsertColumn(10,_T("D5"),LVCFMT_CENTER,34);
	m_msglist.InsertColumn(11,_T("D6"),LVCFMT_CENTER,34);
	m_msglist.InsertColumn(12,_T("D7"),LVCFMT_CENTER,34);
	m_msglist.InsertColumn(13,_T("Time (0.1ms)"),LVCFMT_CENTER,95);
	m_msglist.InsertColumn(14,_T("Status"),LVCFMT_CENTER,48);
	m_msglist.BringWindowToTop();
	this->SetWindowText("TransmitMsgCyclically --- 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 CTransmitMsgCyclicallyDlg::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 CTransmitMsgCyclicallyDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CTransmitMsgCyclicallyDlg::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;
static BYTE Handle[5];
static BYTE CyclicTxMsgCnt;
void CTransmitMsgCyclicallyDlg::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);
		m_msglist.DeleteAllItems();
		CyclicTxMsgCnt=0;
		IsActiveFlag=false;
	}

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

	Ret = CM100_Init(BoardNo,1);  //Init board
	if(Ret){
		MessageBox("Init Board Error!");
		CM100_CloseBoard(BoardNo);
		this->SetWindowText("TransmitMsgCyclically --- 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("TransmitMsgCyclically --- No board is active");
		return;
	}
	SelectedBoardNo=BoardNo;
	TitleStr.Format(_T("TransmitMsgCyclically --- Board %d is active with baud %d K pbs"),BoardNo,BaudMap[Baud]);
	this->SetWindowText(TitleStr);
	IsActiveFlag=true;	
}



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

void CTransmitMsgCyclicallyDlg::OnAddButton() 
{
	// TODO: Add your control notification handler code here
	char* endtemp,TempArr[20];
	int i,Ret;
	DWORD TempValue,MsgID,TimePeriod;
	CString TempStr;
	BYTE Mode,RTR,DataLen,Data[8];
	CEdit *TempEdit[8]={&m_d0,&m_d1,&m_d2,&m_d3,&m_d4,&m_d5,&m_d6,&m_d7};

	if (CyclicTxMsgCnt>4){
		MessageBox("Only 5 cyclic tramsmission messages are allowed");
		return;
	}

	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
		Mode=0;
		MsgID=TempValue&0x7ffUL;
	}
	else{
		Mode=1;
		MsgID=TempValue&0x1fffffffUL;
	}
	TempStr.Format(_T("%lX"),MsgID);
	m_id.SetWindowText(TempStr); //Set message id parameter back to Edit box

	if (m_rtr.GetCheck()) RTR=1; //Check if the RTR is used or not
	else RTR=0;
	
	DataLen=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);
		Data[i]=(BYTE)(TempValue&0xff);
		TempStr.Format(_T("%02X"),Data[i]);
		TempEdit[i]->SetWindowText(TempStr); //Set data parameters back to Edit box
	}

	m_time.GetWindowText(TempArr,10); //Get time period parameter
	TimePeriod=strtol(TempArr,&endtemp,10);
	if (TimePeriod<5) TimePeriod=5;
	TempStr.Format(_T("%lu"),TimePeriod);
	m_time.SetWindowText(TempStr);  //Set time period parameter back to Edit box

	Ret=CM100_AddCyclicTxMsg(SelectedBoardNo,1,Mode,MsgID,RTR,DataLen,Data,TimePeriod,0,&Handle[CyclicTxMsgCnt]); //Add cyclic transmission message
	if (Ret){
		CString ErrStr;
		ErrStr.Format(_T("Add Cyclic Messages Error, Error Code %d"),Ret);
		MessageBox(ErrStr);
		return;
	}
    
	TempStr.Format(_T("        %d        "),Handle[CyclicTxMsgCnt]);

	TempStr.Format(_T("%d"),Handle[CyclicTxMsgCnt]); //Set msglist element
	m_msglist.InsertItem(Handle[CyclicTxMsgCnt],TempStr);
	TempStr.Format(_T("%s"),Mode?"29-bit ID":"11-bit ID");
	m_msglist.SetItemText(Handle[CyclicTxMsgCnt],1,TempStr);
	TempStr.Format(_T("%lX"),MsgID);
	m_msglist.SetItemText(Handle[CyclicTxMsgCnt],2,TempStr);
	TempStr.Format(_T("%c"),RTR?'Y':'N');
	m_msglist.SetItemText(Handle[CyclicTxMsgCnt],3,TempStr);
	TempStr.Format(_T("%d"),DataLen);
	m_msglist.SetItemText(Handle[CyclicTxMsgCnt],4,TempStr);
	for (i=0;i<8;i++){
		if (i<DataLen && !m_rtr.GetCheck()) TempStr.Format(_T("%lX"),Data[i]);
		else TempStr=" ";
		m_msglist.SetItemText(Handle[CyclicTxMsgCnt],5+i,TempStr);
	}
	TempStr.Format(_T("%lu"),TimePeriod);
	m_msglist.SetItemText(Handle[CyclicTxMsgCnt],13,TempStr);
	m_msglist.SetItemText(Handle[CyclicTxMsgCnt],14,"Disable");
	CyclicTxMsgCnt++;
}

void CTransmitMsgCyclicallyDlg::OnDeleteButton() 
{
	// TODO: Add your control notification handler code here
	char* endtemp,TempArr[20];
	BYTE SelectedHandle;
	int Ret,SelectedListNo;
	CString ErrStr;

	if (CyclicTxMsgCnt==0){
		MessageBox("No cyclic tramsmission message can be deleted");
		return;
	}
	SelectedListNo=m_msglist.GetNextItem(-1,LVIS_SELECTED); //Get selected list No
	if (SelectedListNo>CyclicTxMsgCnt || SelectedListNo<0) return;
	m_msglist.GetItemText(SelectedListNo,0,TempArr,20); //Get handle value
	SelectedHandle=(BYTE)(strtol(TempArr,&endtemp,10)&0xff);
	Ret=CM100_DeleteCyclicTxMsg(SelectedBoardNo,1,SelectedHandle); //Delete selected cyclic transmission message
	if (Ret){
		ErrStr.Format(_T("Delete Cyclic Message Error, Error Code=%d"),Ret);
		MessageBox(ErrStr);
		return;
	}
	m_msglist.DeleteItem(SelectedListNo);
	CyclicTxMsgCnt--;
}

void CTransmitMsgCyclicallyDlg::OnEnableButton() 
{
	// TODO: Add your control notification handler code here
	char* endtemp,TempArr[20];
	BYTE SelectedHandle;
	int Ret,SelectedListNo;
	CString ErrStr;
	
	if (CyclicTxMsgCnt==0){
		MessageBox("No cyclic tramsmission message can be enable");
		return;
	}
	SelectedListNo=m_msglist.GetNextItem(-1,LVIS_SELECTED); //Get selected list No
	if (SelectedListNo>CyclicTxMsgCnt || SelectedListNo<0) return;
	m_msglist.GetItemText(SelectedListNo,0,TempArr,20); //Get handle value
	SelectedHandle=(BYTE)(strtol(TempArr,&endtemp,10)&0xff);
	Ret=CM100_EnableCyclicTxMsg(SelectedBoardNo,1,SelectedHandle); //Enable selected cyclic transmission message.
	if (Ret){
		ErrStr.Format(_T("Enable Cyclic Message Error, Error Code=%d"),Ret);
		MessageBox(ErrStr);
		return;
	}
	m_msglist.SetItemText(SelectedListNo,14,"Enable");
}

void CTransmitMsgCyclicallyDlg::OnDisableButton() 
{
	// TODO: Add your control notification handler code here
	char* endtemp,TempArr[20];
	int Ret,SelectedListNo;
	BYTE SelectedHandle;
	CString ErrStr;
	
	if (CyclicTxMsgCnt==0){
		MessageBox("No cyclic tramsmission message can be disable");
		return;
	}
	SelectedListNo=m_msglist.GetNextItem(-1,LVIS_SELECTED); //Get selected list No
	if (SelectedListNo>=CyclicTxMsgCnt || SelectedListNo<0) return;
	m_msglist.GetItemText(SelectedListNo,0,TempArr,20); //Get handle value
	SelectedHandle=(BYTE)(strtol(TempArr,&endtemp,10)&0xff);
	Ret=CM100_DisableCyclicTxMsg(SelectedBoardNo,1,SelectedHandle); //Disable selected cyclic transmission message.
	if (Ret){
		ErrStr.Format(_T("Disable Cyclic Message Error, Error Code=%d"),Ret);
		MessageBox(ErrStr);
		return;
	}
	m_msglist.SetItemText(SelectedListNo,14,"Disable");
}

void CTransmitMsgCyclicallyDlg::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();
	}
}
