extern unsigned char szBuff[101];
extern DWORD dwBytesRead;
extern DWORD dwBytesWrite;

int front_left_ticks=0;
int front_right_ticks=0;
int rear_left_ticks=0;
int rear_right_ticks=0;
int engine_ticks=0;
static char state='i';	//logging, new, pause
#define state_iddle		'i'
#define state_new_log	'n'
#define state_stop		's'
#define state_resume	'r'

char log_filename[60];
char experiment_name[60];

char cam1_folder[60];
char cam2_folder[60];
char cam3_folder[60];

FILE * log_File;
bool log_event=FALSE;

#define log_buffer_length	300
char log_buffer_1[log_buffer_length];
char log_buffer_2[log_buffer_length];
char log_buffer_3[log_buffer_length];

char log_buffer_avr[log_buffer_length];

#define	huge_buffer_length	4*10000	//4MB
char huge_buffer_1[huge_buffer_length];
char huge_buffer_2[huge_buffer_length];
int active_huge_buffer=1;
BOOL change_buffer=FALSE;

//http://www.songho.ca/misc/timer/timer.html
LARGE_INTEGER frequency;        // ticks per second
LARGE_INTEGER tstart, t1, t2, t3;           // ticks
double elapsedTime=0,elapsedTimeBeg=0;
double time_buffer[100];
int time_counter=0;
int iTimerID;

// Global readings
double		dataAI[16];
#define		ni_sampling_frequency	100

TaskHandle  taskHandle=0;

//Time info
time_t rawtime;
struct tm * timeinfo;

//igni
int engine_ignitions_per_rpm=4;

int front_left_rpm=0;	double front_left_rpm_dummy=0,front_left_rpm_buf[5];
int front_right_rpm=0;	double front_right_rpm_dummy=0,front_right_rpm_buf[5];
int rear_left_rpm=0;	double rear_left_rpm_dummy=0,rear_left_rpm_buf[5];
int rear_right_rpm=0;	double rear_right_rpm_dummy=0,rear_right_rpm_buf[5],temp_buf[5];
int engine_rpm=0;		double engine_rpm_dummy=0,engine_rpm_buf[5];
double	car_speed=0;	double car_speed_dummy=0,car_speed_buf[5];				//km/h

//Trackbar variables
double wheel_radius=defined_wheel_radius;
double steering_a=535,	steering_b=1312;//1495;
double handbrake_a=1,	handbrake_b=0;

//-----------------Nice the gui somehow--------------
#define forgeting_sum(last,previous) (double)(last*0.65+previous[0]*0.2+previous[1]*0.1+previous[2]*0.05)

void shift_values(double last,double previous[]) {
	//previous[3]=previous[2];
	previous[2]=previous[1];
	previous[1]=previous[0];
	previous[0]=last;
}

//Analog to digital variables

//Front accelerometer
double	acc_fx=0,	acc_fy=0,	acc_fz=0;
//IMU accelerometer
double	acc_mx=0,	acc_my=0,	acc_mz=0;
double	x_rate=0,	y_rate=0;
double	x_angle=0.0,	y_angle=0;
//Rear accelerometer
double	acc_rx=0,	acc_ry=0,	acc_rz=0;

//Torque sensor
double steering_torque=0;

//Handbrake position
double handbrake_position=0;

//Steering angle
double steering_angle=0;

//Brakes
double front_brake=0;
double rear_brake=0;

//Latest, Octomber 2009
int sample_number=0;
int sample_number_when_image_asked;
//----------------Serial port Start------------------------------
int chars_read=0;
unsigned char tx_data[32];
HANDLE hSerial;
unsigned char read_data_buffer[31];
bool	serial_packet_arrived=FALSE;	
bool	valid_packet=TRUE;
int		bytes_read_till_now=0;

//----------------VBOX Serial port Start----------------------------
//#define vbox_port "COM1"
int chars_read_vbox=0;
HANDLE hSerial_vbox;
unsigned char read_data_buffer_vbox[31];

char szBuff_vbox[201];
DWORD dwBytesRead_vbox;

char log_filename_avr[60];
FILE * log_File_avr;
char	vbox_port[30];

HANDLE initiate_serial_vbox(int argc, char* argv)
{
	int match=12;
	char comport[80];
	//vbox_port=
	strcpy_s(comport,vbox_port);
	printf("VBOX comport = %s\n",comport);
	
	HANDLE hSerial;
//	hSerial = CreateFile(comport,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
	hSerial = CreateFile(comport,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); //http://forums.msdn.microsoft.com/en/vcgeneral/thread/fe930513-fa09-48cc-bd51-d77fda017d7b/
	

	if(hSerial==INVALID_HANDLE_VALUE){
		if(GetLastError()==ERROR_FILE_NOT_FOUND){
		//serial port does not exist. Inform user.
			printf("serial port does not exist\n");
		}
		printf("some other error occurred\n");
	//some other error occurred. Inform user.
	}


	DCB dcbSerialParams = {0};
	dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
	if (!GetCommState(hSerial, &dcbSerialParams)) {
		printf("error getting state\n");
		//error getting state
	}
	dcbSerialParams.BaudRate=CBR_115200;
	dcbSerialParams.ByteSize=8;
	dcbSerialParams.StopBits=ONESTOPBIT;
	dcbSerialParams.Parity=NOPARITY;
	if(!SetCommState(hSerial, &dcbSerialParams)){
		printf("error setting serial port state\n");
		//error setting serial port state
	}
	
	COMMTIMEOUTS timeouts={0};
	timeouts.ReadIntervalTimeout=MAXDWORD;//http://www.mombu.com/microsoft/windows-programmer-win32/t-non-blocking-serial-reads-in-winxp-109667.html
	timeouts.ReadTotalTimeoutConstant=0;//50;
	timeouts.ReadTotalTimeoutMultiplier=0;//10;
	timeouts.WriteTotalTimeoutConstant=0;
	timeouts.WriteTotalTimeoutMultiplier=0;
	if(!SetCommTimeouts(hSerial, &timeouts)){
		printf("Timeout error occureed. Inform user\n");
	//printf("error occureed. Inform user")
	}
	
	return hSerial;
}

void write_read_serial_vbox(HANDLE hSerial_vbox){

	if(!ReadFile(hSerial_vbox, szBuff_vbox, 200, &dwBytesRead_vbox, NULL)){
		//error occurred. Report to user.
		//printf("Read error\n");				
	}
	//printf("%s",szBuff_vbox);
	//if(dwBytesRead_vbox>0)
		//if(log_File_vbox)
			//fputs (szBuff_vbox,log_File_vbox);
}


//---------------October Additions----------------------
//---------------Image Capture---------------------------
static CvMemStorage* storage = 0;

//-----------------Capture Variables--------------------
CvCapture* capture0=0, *capture1 = 0;
IplImage *frame0,*frame1, *frame2;
IplImage* big_image;
//-----------------------------------------------------

//#define camera_offset	0//If there is a webcam on the laptop then camera_offset should be 1
#define capture_width_defined	320
#define capture_height_defined	240

int	capture_width=capture_width_defined;
int capture_height=capture_height_defined;

int camera_offset=0;
int connected_cams=0;

//----------------Thread Definition-------------------
char thread_message[60];
BOOL thread_status=TRUE;
BOOL consume_data=FALSE;

DWORD WINAPI thread_function(PVOID arg) {
    //printf("Thread_function started. Arg was %s\n", (char *)arg);
	
	LARGE_INTEGER time_counter_1,time_counter_2;
	double time_passed=0;
	QueryPerformanceCounter(&time_counter_1);
	
	/*
	if(connected_cams>(0+camera_offset))
		frame0 = cvRetrieveFrame( capture0 );
	if(connected_cams>(1+camera_offset))
		frame1 = cvRetrieveFrame( capture1 );
	*/
	QueryPerformanceCounter(&time_counter_2);
	time_passed = (time_counter_2.QuadPart - time_counter_1.QuadPart) * 1000.0 / frequency.QuadPart;
	//printf("Grab Retrieve time=%f\n",time_passed);


	thread_status=TRUE;
	consume_data=TRUE;
    return 100;
}