#include "FitCANBus.h"
#include <future>
#include <chrono>
#include <assert.h>
#include <iostream>

using namespace std;

FitCANBus* FitCANBusTest;

void writeMessage(DWORD canid, FITAPI::CFitekCanBusControl::CanFrameFormat type, int rtr) {
	int count = 0;

	FITAPI::CFitekCanBusControl::CanFrameInfor msg;
	msg.type = type;
	msg.rtr = rtr;
	msg.data_len = 8;
	for (int i = 0; i < 8; i++) {
		msg.data[i] = i + ((count & 0xf) << 4);
	}
	msg.id = canid;
	FitCANBusTest->writeMessage(&msg);
}

typedef enum {
	IDX_CMD = 0,
	IDX_CAN_NAME,
	IDX_CAN_RATE,
	IDX_CAN_ID,
	IDX_CAN_BITS,
	IDX_CAN_FILTERS_MODE,
	IDX_CAN_ACR_FILTERS,
	IDX_CAN_AMR_FILTERS,
} ARGV_DEF;

void main(int argc, char *argv[])
{
	char* canbus;
	int baudrate;
	DWORD canid = 0x18ea0000;
	int t = 29;
	int filtermode = 1; // single filter
	DWORD acr = 0;
	DWORD amr = 0xFFFFFFFF;
	
	if (argc <= IDX_CAN_RATE) {
		printf_s("\n==== Arguments and default value ====\n");
		printf_s("<CAN_Name> <CAN_baudRate> <CANID> <CANID_Bits> <Filter_Mode> <ACR> <AMR>\n");
		printf_s("\t<CAN_Name> is must to setup.\n");
		printf_s("\t<CAN_baudRate> is must to setup.\n");
		printf_s("\t<CANID> (hex) = %x\n", canid);
		printf_s("\t<CANID_Bits> = %d\n", t);
		printf_s("\t<Filter_Mode> = %d\n", filtermode);
		printf_s("\t<ACR> and <AMR>\n");
		printf_s("EX:> FitCANBus.exe COM3 250 12345678 29 1 0 FFFFFFFF\n");
		exit(-1);
	}
	canbus = argv[IDX_CAN_NAME];
	baudrate = strtol(argv[IDX_CAN_RATE], NULL, 10) * 1000;
	if (argc > IDX_CAN_ID)
		canid = strtol(argv[IDX_CAN_ID], NULL, 16);
	if (argc > IDX_CAN_BITS)
		t = strtol(argv[IDX_CAN_BITS], NULL, 10);
	if (argc > IDX_CAN_FILTERS_MODE)
		filtermode = strtol(argv[IDX_CAN_FILTERS_MODE], NULL, 10);
	if (argc > IDX_CAN_ACR_FILTERS)
		acr = strtoul(argv[IDX_CAN_ACR_FILTERS], NULL, 16);
	if (argc > IDX_CAN_AMR_FILTERS)
		amr = strtoul(argv[IDX_CAN_AMR_FILTERS], NULL, 16);
	printf_s("para_num=%d, bus=%s, baudrate=%d, CANID=%d(0x%X), type=%d, filtermode=%d, acr=%x, amr=%x\n",
		argc, canbus, baudrate, canid, canid, t, filtermode, acr, amr);
	
	FITAPI::CFitekCanBusControl::CanFrameFormat type;
	switch (t) {
	case 11:
		type = FITAPI::CFitekCanBusControl::CanFrameFormat::CP_11Bit;
		break;
	case 29:
		type = FITAPI::CFitekCanBusControl::CanFrameFormat::CP_29Bit;
		break;
	default:
		printf_s("Parameters type error\n");
		exit(-1);
	}

	FitCANBusTest = new FitCANBus(canbus);
	if (FitCANBusTest->init(baudrate) < 0)
		goto exit;
	if (FitCANBusTest->startReading(filtermode, acr, amr))
		goto exit;
	if (FitCANBusTest->FintekCanbus_SetId(canid, type))
		goto exit;
	async(writeMessage, canid, type, 0);
	char tmp[MAX_PATH];
	scanf_s("%s", &tmp);
	
exit:
	
	delete FitCANBusTest;
}
