#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "callbacks.h"
#include "interface.h"
#include "support.h"
//#include <string.h>
#include <cssl.h>
//#include <sys/wait.h>
#define PORTNAMELEN 20
#define PORTPATH	"/dev/"


int GetBaudRate   (GString rate);
gint BeforeWrite  (void);
gint BeforeRead   (void);
gint BeforeWriteRead(void);
void RunWrite     (Info info);
void RunRead	  (Info info);
void RunWriteRead (void);
void *WriteThread (void *arg);
void *ReadThread  (void *arg);
void initialInfo(Info *info, gint method);

extern Trans DTransfer;


int msleep(unsigned long milisec)
{
	struct timespec req={0};
	time_t sec=(int)(milisec/1000);
	milisec=milisec-(sec*1000);
	req.tv_sec=sec;
	req.tv_nsec=milisec*1000000L;
	while(nanosleep(&req,&req)==-1)
		continue;
	return 1;
}

//---------------------------------------------------------//
/*
	Check parameters before Do Write function.
	Check:
			baudrate -- default 9600
			filename -- -1 no filename
			usbline	 -- -2 no usbline
			ttyline  -- -3 no ttyline

	return 0 as no problem
*/
gint BeforeWrite(void)
{
	// 
	// ttyS#  at least 5 characters
	gint ret = 0;
	gint len=0;
	
	if ( NULL == DTransfer.filename )
		ret = -1;
	
	len = strlen(DTransfer.usbline);
	if ( len < 5) ret = -2;
	
		
	return ret ;
}
void PrintInfo( Info info)
{
	printf("info.filename: %s\n", info.filename);
	printf("info.line : %s \n", info.line);
	printf("info.baudrate : %d\n", info.baudrate);
	printf("info.filesize: %d\n", info.filesize);
	
}
//---------------------------------------------------------//

void RunWrite(Info info)
{
	
	
	pthread_t runThread[2];	// usb write, tty read
	GThread          *Thread1, *Thread2;
	GError           *err1 = NULL ;
	GError           *err2 = NULL ;
	int res;
	void *thread_result;
	struct stat file_status;
	
		
	printf("create read thread now \n");
	

	if( !g_thread_supported() )
	{
		g_thread_init(NULL);
		gdk_threads_init();                   // Called to initialize internal mutex "gdk_threads_mutex".
		printf("g_thread supported\n");
	}
	else
	{
		printf("g_thread NOT supported\n");
	}

	
	if( (Thread2 = g_thread_create((GThreadFunc)WriteThread, (void *)&info, TRUE, &err2)) == NULL)
	{
		printf("Thread create failed: %s!!\n", err2->message );
		g_error_free ( err2 ) ;
	}

	g_thread_join(Thread2);
	
	MessageBox("write finished");
	printf("---------\n");
	exit(22);
	
}
//---------------------------------------------------------//

void RunRead(Info info)
{
	gchar err[256];
	
	pthread_t runThread[2];	// usb write, tty read
	GThread          *Thread1, *Thread2;
	GError           *err1 = NULL ;
	GError           *err2 = NULL ;
	int res;
	void *thread_result;
	struct stat file_status;
		
	printf("-------- Run Read () ---------------\n");
	
	
	if( !g_thread_supported() )
	{
		g_thread_init(NULL);
		gdk_threads_init();                   // Called to initialize internal mutex "gdk_threads_mutex".
		printf("g_thread supported\n");
	}
	else
	{
		printf("g_thread NOT supported\n");
	}
	
	
	printf("create read thread now \n");
	
	if( (Thread1 = g_thread_create((GThreadFunc)ReadThread, (void *)&info, TRUE, &err1)) == NULL)
	{
		printf("Thread create failed: %s!!\n", err1->message );
		g_error_free ( err1 ) ;
	}
	

	g_thread_join(Thread1);
	
	
	MessageBox("Read finished");
	printf("------Run Read End ---\n");
	exit(11);
	
}
//---------------------------------------------------------//

void *WriteThread( void *information )
{
	//int fd;
	FILE *rfile;
	gchar *buffer=NULL;
	void *tmp;
	char portpath[20];
	char ending[]={ 'e','n','d','e','d'};
	int readfilelen;
	int stop =0;
	int index=0;
	char err[256];
	int lastpacketsize;
	int lastpacket;
	int loopcount=0;
	tagVal  fileVal;
	char filesizechar[4]={0,0,0,0};
	Info	*info = (Info *) information;
	cssl_t *serial;
	GIOChannel *writefile;
	
	printf("\nbeginning of Write Thread \n");
 	
	PrintInfo( *info);
	
	
	cssl_start();
	printf("baudrate is :%d \n", info->baudrate );
	sprintf(portpath, "%s%s",PORTPATH, info->line);
		
	printf("portpath is :%s \n", portpath);
	
	serial=cssl_open(	portpath,
						NULL,
	  					1, 
						info->baudrate,
	  					8,0,1);

	if (!serial) {
		printf("----- no serial\n");
		printf("%s\n in write",cssl_geterrormsg());
		return -1;
	}
	
	printf("1111111111111\n");
	rfile = fopen( info->filename, "r"); 
	if ( rfile == NULL){
		perror("not able to open file to read ");
		goto WriteThread_err;
	}
	
	buffer = g_malloc( info->filesize );
	if ( buffer == NULL){
		perror("not able to allocate enough buffer");
		goto WriteThread_err;
	}
	bzero(buffer, info->filesize);
	
	readfilelen = fread ( buffer, 1,info->filesize, rfile);
	printf("fread() return %d \n", readfilelen);
	fclose(rfile);
	
	
	lastpacketsize = info->filesize % TRANSFERSIZE;
	lastpacket = info->filesize / TRANSFERSIZE;
	int byteleft = info->filesize-lastpacketsize;
	printf(" bytes left is %d \n", byteleft);
	
	gint delay = 0;
	
	if ( DTransfer.method == ReadType || DTransfer.method == WriteType) 
		delay = 1;
	if ( (DTransfer.method == ReadType) &&  (info->baudrate > 4800))
		delay = 2;
	
	if ( (DTransfer.method == WriteReadType) && (info->baudrate > 4800) )
		delay = 3;
	
	if ( (DTransfer.method == WriteType) && (info->baudrate > 4800) )
		delay = 4;
	
	if ( (DTransfer.method == WriteReadType) && (info->baudrate <= 4800) )
			delay = 5;
	
		
	while( !stop ) { // read 250 each time
		
		if ( 1 == delay){printf("                       delay\n");	msleep(10);}
		if ( 2 == delay){printf("                       delay\n");	msleep(10);}
		if ( 3 == delay){printf("                       delay\n");	msleep(150);}
		if ( 4 == delay){printf("                       delay\n");	msleep(20);}
		if ( 5 == delay){printf("                       delay\n");	msleep(150);}	
		
		if ( index == byteleft ){
			cssl_drain(serial);
			printf("last packet is : %d\n", lastpacketsize);
			cssl_putdata(serial, buffer+index, lastpacketsize);
			cssl_drain(serial);
			stop = 1;
			break;
		}// if
		cssl_putdata(serial, buffer+index,TRANSFERSIZE );
		
		index +=TRANSFERSIZE;
		printf("   getpid() : %d                        index now is :%d \n", getpid(), index);
		
		cssl_drain(serial);
		while( gtk_events_pending())
			gtk_main_iteration();
	}//while
	
	cssl_drain(serial);
	
	
	cssl_drain(serial);
	printf("write thread is giong to end\n");
	usleep(20000);
	
	
WriteThread_err:

	cssl_close(serial);
	cssl_stop();
	
	//close(fd);
	g_free(buffer);
	buffer = NULL;
	//pthread_exit(0);
	g_thread_exit(1);
	printf("-------------------\n");
}
static void handle_error( GError *error)
{
	if ( error != NULL)
	{
		g_printf(error->message);
		g_clear_error(&error);	
		
	}
	
}
void *ReadThread( void *information )
{
	int fd;
	
	int stop =0;
	int readLen=0;
	struct stat file_status;
	
	char portpath[20];
	int packetsize=0;
	int bytesleft=0;
	int index=0;
	double difTime;
	tagVal fileVal;
	char filesizechar[4];
	//time_t startTime, endTime;
	Info *info = (Info *) information;
	gchar *rBuffer=NULL;
	FILE *fdsave;
	cssl_t *serial;
	GError *error=NULL;
	GIOChannel *writefile;
	
	
	printf("beginning of Read Thread\n");
	PrintInfo(*info);
	
		
	cssl_start();
	
	sprintf(portpath, "%s%s",PORTPATH, info->line);
	serial=cssl_open( portpath,
					  NULL,
	   				  0,
		  			  info->baudrate,8,0,1);

	if (!serial) {
		printf("%s in Read\n",cssl_geterrormsg());
		return -1;
	}
	
	printf("file name going to be saved is :%s\n ", info->filename);
	
	printf("going to allocate %d in read \n", info->filesize);
	
	
	
	rBuffer = g_malloc( info->filesize );
	if ( NULL == rBuffer){
		cssl_close(serial);
		cssl_stop();
	
			
		fclose(fdsave);
		perror("not able to allocate memory for Read");
		return;
	}
	bzero(rBuffer, info->filesize);
	
	if ( DTransfer.method == ReadType){
		time(&DTransfer.time.ReadBegin);
	}
	
	bytesleft = info->filesize % TRANSFERSIZE;
	int endingsize = info->filesize - bytesleft;
	readLen=0;
	packetsize=0;
	while(!stop){
       
	  if ( endingsize <= packetsize  ){
		  cssl_settimeout(serial, 100);
		readLoop:
			readLen = cssl_getdata(serial, rBuffer+packetsize, bytesleft);
			if ( readLen == -1 ){ stop =1; break;}
			packetsize +=readLen;
			if ( packetsize >= info->filesize){
				stop = 1;
				printf("reading %d and now is :%d, break while \n", readLen,packetsize);
				break;
			}
			printf("reading in loop \n");
			bytesleft -= readLen;
			goto readLoop;
			
		}
		
		//readLen = cssl_getdata(serial,rBuffer+packetsize,TRANSFERSIZE );
		readLen = cssl_getdata(serial,rBuffer+packetsize,64 );
		if ( readLen == -1 ){ stop =1; break;}
		packetsize += readLen;
		printf("reading %d and now is :%d and pid is : %d \n", readLen,packetsize, getpid());
		
		if ( info->filesize == packetsize )
		{
			stop = 1;
			printf("ending == packetsize \n");
			break;
		}
		if ( packetsize >= info->filesize){stop=1; break;}
		
	
		while( gtk_events_pending())
			gtk_main_iteration();
		
	}// while
	
	printf("reading %d and now is :%d after while\n", readLen,packetsize);
	
	printf("finished in %s \n", info->line);
	printf("file name is :%s \n", info->filename);
	cssl_close(serial);
	cssl_stop();
	int i;
	
	
	gsize bytewritten;
	
	writefile = g_io_channel_new_file( info->filename, "w+",&error);
	if ( writefile == NULL){
		perror("fail to create new io channel");
		g_free(rBuffer);
		pthread_exit(0);
	}
	//g_io_channel_write_chars( writefile, rBuffer, fileVal.lnum, &bytewritten, NULL);
	g_io_channel_write( writefile, rBuffer, packetsize, &bytewritten);
	printf("bytes written is :%d\n", bytewritten);
	g_io_channel_flush(writefile, &error);
	handle_error(error);
	g_io_channel_close(writefile);
	
	g_free(rBuffer);
	rBuffer = NULL;
	//pthread_exit(0);
	g_thread_exit(2);

}


//---------------------------------------------------------//
/*
	Check parameters before Do Write function.
	Check:
			baudrate -- default 9600
			filename -- -1 no filename
			usbline	 -- -2 no usbline
			ttyline  -- -3 no ttyline

	return 0 as no problem
*/
gint BeforeRead(void)
{
	gint ret = 0;
	gint len=0;
	
	len = strlen(DTransfer.usbline);
	if ( len < 5) ret = -2;
	
	
	
	return ret;
}

//---------------------------------------------------------//
/*
	Check parameters before Do Write function.
	Check:
			baudrate -- default 9600
			filename -- -1 no filename
			filename2 -- -2 no filename2
			usbline	 -- -3 no usbline
			ttyline  -- -4 no ttyline

	return 0 as no problem
*/
gint BeforeWriteRead(void)
{
	gint ret = 0;
	gint len=0;
	if ( NULL == DTransfer.filename )
		ret = -1;
	
	if ( NULL == DTransfer.filename2)
		ret = -2;
	
	len = strlen(DTransfer.usbline);
	if ( len < 5) ret = -3;
	
	
	
	return ret;
}
//---------------------------------------------------------//
/*
	initialInfo construct the transfer information
	before passing the arguments to thread
	
	method:
		0: WriteRead_Read
		1: WriteRead_Write
		-1: Write, Read

*/
void initialInfo(Info *info, gint method)
{
	gchar err[256];
	struct stat file_status;
	
	if ( DTransfer.method != ReadType){
		
		if(stat(DTransfer.filename, &file_status) != 0){
			g_sprintf(err,"could not stat %s size", DTransfer.filename);
			perror(err);
			return;
		}
		
		DTransfer.filesize = file_status.st_size;
		
		info->filesize = DTransfer.filesize;
	}
	
	if ( DTransfer.method == WriteType){
		info->line = g_strdup( DTransfer.usbline);
		info->filename = g_strdup( DTransfer.filename);
	}
	else if ( DTransfer.method == ReadType){
		info->line = g_strdup( DTransfer.usbline);
		info->filename = g_strdup( DTransfer.filename);
	}
	else{
		GString tname;
		tname.str = g_strdup(DTransfer.filename);
		
		// info	
		// WriteRead_Read section, usb read
		if ( method == 0){
			info->line = g_strdup( DTransfer.usbline);
			info->filename = g_strdup( DTransfer.filename);
			
		}
		else if (method == 1){  // WriteRead_write, usb write
			info->line = g_strdup( DTransfer.usbline);
			info->filename = g_strdup( DTransfer.filename2);
		}
	}
	info->baudrate = DTransfer.baudrate;
	
	
}
//---------------------------------------------------------//

void
on_btn_Write_clicked                   (GtkButton       *button,
                                        gpointer         user_data)
{
	gchar out[256];
	Info info, info2;
	GtkWidget *entryStart, *entryEnd;
	gchar timestr[6];
	gchar timestr2[5];
	entryStart = lookup_widget( GTK_WIDGET(button), "lbl_WriteStartTime");	
	entryEnd = lookup_widget( GTK_WIDGET(button), "lbl_WriteEndTime");	
		
	gint ok_before_write;
	DTransfer.method = WriteType;
	GTimer *writetime =g_timer_new();
	ok_before_write = BeforeWrite();
	if ( 0 == ok_before_write){
		/* record start time     */
		
		
		initialInfo( &info ,-1);
		RunWrite( info);
		
		/*  record end time      */
		g_timer_stop(writetime);
		gdouble timeelapsed;
		gulong timefriction;
		timeelapsed = g_timer_elapsed(writetime, &timefriction);
		
		gtk_label_set_text( GTK_LABEL(entryStart), g_ascii_dtostr(timestr, 6, timeelapsed));
		gtk_label_set_text( GTK_LABEL(entryEnd), g_ascii_dtostr(timestr2, 5, timefriction));
				
		printf("---- btn_Write_cliecked END ---\n");
		return;
	}//if
	
	switch (ok_before_write)
	{
		
		case -1:
			g_sprintf(out,"fail: %s", "no file name");
			MessageBox(out);
			break;
		case -2:
			g_sprintf(out,"fail: %s", "no usbline ");
			MessageBox(out);
			break;
		case -3:
			g_sprintf(out,"fail: %s", "no ttyline");
			MessageBox(out);
			break;
		
		
		
	}
	
}

//---------------------------------------------------------//
void
on_bnt_Read_clicked (GtkButton       *button,
                     gpointer         user_data)
{
	gchar out[256];
	gint ok_before_read;
	Info info;
	GtkWidget *entryStart, *entryEnd, *entryfilename,*entrysize;
	gchar *filesizestr;
	long filesize;
	gchar *endptr;
	
	gchar timestr[6];
	gchar timestr2[5];
	entryStart = lookup_widget( GTK_WIDGET(button), "lbl_ReadStartTime");	
	entryEnd = lookup_widget( GTK_WIDGET(button), "lbl_ReadEndTime");	
	entryfilename = lookup_widget( GTK_WIDGET(button), "txt_ReadFile");	
			
	entrysize = lookup_widget( GTK_WIDGET(button), "txt_ReadSize");	
	filesizestr = gtk_entry_get_text(entrysize); 
	DTransfer.filename = gtk_entry_get_text(entryfilename); 
	filesize = strtol( filesizestr, &endptr, 10);
	printf("file is %s \n", DTransfer.filename);
	printf(" filesize is : %d\n", filesize);
	
    DTransfer.filesize = filesize;
	
	GTimer *writetime =g_timer_new();
		
	
	ok_before_read = BeforeRead();
	if ( 0 == ok_before_read){
		
		DTransfer.method = ReadType;
		initialInfo( &info, -1);
		RunRead(info);
		
		g_timer_stop(writetime);
		gdouble timeelapsed;
		gulong timefriction;
		timeelapsed = g_timer_elapsed(writetime, &timefriction);
		
		gtk_label_set_text( GTK_LABEL(entryStart), g_ascii_dtostr(timestr, 6, timeelapsed));
		gtk_label_set_text( GTK_LABEL(entryEnd), g_ascii_dtostr(timestr2, 5, timefriction));
		
		return;
	}//if
	
	switch (ok_before_read)
	{
		
		case -1:
			g_sprintf(out,"fail: %s", "no file name");
			MessageBox(out);
			break;
		case -2:
			g_sprintf(out,"fail: %s", "no usbline ");
			MessageBox(out);
			break;
		case -3:
			g_sprintf(out,"fail: %s", "no ttyline");
			MessageBox(out);
			break;
		
		
		
	}
}

//---------------------------------------------------------//

void
on_window1_destroy                     (GtkObject       *object,
                                        gpointer         user_data)
{
	if ( NULL != DTransfer.filename)
		g_free( DTransfer.filename);
	if ( NULL != DTransfer.filename2)
		g_free( DTransfer.filename2);
	
	gtk_main_quit();
}
//---------------------------------------------------------//

void
on_btn_WriteRead_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{
	gchar out[256];
	gint ok_before_writeread;
	Info info, info2, info_1, info2_1;
	GtkWidget *entryStart, *entryEnd, *entryfilename,*entrysize;
	time_t startTime, endTime;
	double difTime;
	gint ret;
	gchar timestr[6];
	gchar timestr2[5];
	
	entryStart = lookup_widget( GTK_WIDGET(button), "lbl_WriteRead_StartTime");	
	entryEnd = lookup_widget( GTK_WIDGET(button), "lbl_WriteRead_EndTime");	
	
	DTransfer.method = WriteReadType;
	ok_before_writeread = BeforeWriteRead();
	GTimer *writetime =g_timer_new();
	if ( 0 == ok_before_writeread){
		
		time(&startTime);
		
		initialInfo( &info, 0);
		initialInfo ( &info_1, 1);
		pid_t pid;

		pid = fork();
		
		if ( pid == -1 ){
			g_error("Error: The fork() failed!");
			exit(1);
			
		}
		else if ( pid == 0 ){
			RunWrite( info_1, info2_1);
			printf("------------------------------------- child finished \n");
			
			_exit(0); /*In practice, this is only important when you fork(); the child process must exit with _exit() rather than exit() to avoid shutting down GTK+ in the parent.   */
			
		}
		else {
			int childExitStatus;
			RunRead( info, info2);
			printf("+++++++++++++++++++++++++++++++++++++++++++++++++++ parent finished \n");
			wait( pid, &childExitStatus, 0);
			
			time(&endTime);
			difTime = difftime(endTime, startTime);
			printf("dif time is: %5.5f \n", difTime);
			
			//gtk_label_set_text( GTK_LABEL(entryStart), g_ascii_dtostr(timestr, 6,difTime ));
			//gtk_label_set_text( GTK_LABEL(entryEnd), g_ascii_dtostr(timestr2, 5,0 ));
			
		}
		g_timer_stop(writetime);
		gdouble timeelapsed;
		gulong timefriction;
		timeelapsed = g_timer_elapsed(writetime, &timefriction);
		gtk_label_set_text( GTK_LABEL(entryStart), g_ascii_dtostr(timestr, 6,timeelapsed ));
		gtk_label_set_text( GTK_LABEL(entryEnd), g_ascii_dtostr(timestr2, 5,timefriction ));
		
		
		return;
	}//if
	
	switch (ok_before_writeread)
	{
		
		case -1:
			g_sprintf(out,"fail: %s", "no Read File name");
			MessageBox(out);
			break;
		case -2:
			g_sprintf(out,"fail: %s", "no Write File name ");
			MessageBox(out);
			break;
		case -3:
			g_sprintf(out,"fail: %s", "no usbline");
			MessageBox(out);
			break;
		
		case -4:
			g_sprintf(out,"fail: %s", "no ttyline");
			MessageBox(out);
			break;
		
	}

}

//---------------------------------------------------------//
void
on_chk_LoopBack_toggled                (GtkToggleButton *togglebutton,
                                        gpointer         user_data)
{

}

//---------------------------------------------------------//
void
on_combobox1_changed                   (GtkComboBox     *combobox,
                                        gpointer         user_data)
{
	
	GString rate;
	
	rate.str = gtk_combo_box_get_active_text  (combobox);
	DTransfer.baudrate = GetBaudRate(rate);
	
}

//---------------------------------------------------------//

void
on_cbo_UsbTty_changed   (GtkComboBox     *combobox,
							gpointer         user_data)
{
	GString portstr;
		
	portstr.str = gtk_combo_box_get_active_text  (combobox);
	g_strlcpy(DTransfer.usbline, portstr.str, PORTNAMELEN);
	
}

//---------------------------------------------------------//
void
on_cbo_Tty_changed  (GtkComboBox     *combobox,
					 gpointer         user_data)
{
	GString portstr;
	
	portstr.str = gtk_combo_box_get_active_text  (combobox);
	g_strlcpy(DTransfer.ttyline, portstr.str, PORTNAMELEN);
	
		
}


	
//---------------------------------------------------------//

void on_btn_WriteOpen_clicked (GtkButton       *button,
								gpointer         win)
{
	GtkWidget *dialog;
	GtkWidget *entry, *entry2;
	struct stat file_status;
	gchar err[256];
	gdouble filesize;
	gchar sizestr[10];
	
	entry = lookup_widget( GTK_WIDGET(button), "txt_FileName");
	entry2 = lookup_widget( GTK_WIDGET(button), "txt_WriteSize");
	dialog = gtk_file_chooser_dialog_new ("Open File",
										  (GtkWindow *)win,
										  GTK_FILE_CHOOSER_ACTION_OPEN,
										  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
										  GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
										  NULL);

	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
	{
		if ( DTransfer.filename != NULL)
			g_free(DTransfer.filename);
		DTransfer.filename = NULL;
		DTransfer.filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
		gtk_entry_set_text( GTK_ENTRY(entry), DTransfer.filename);
		
		
		if(stat(DTransfer.filename, &file_status) != 0){
			g_sprintf(err,"could not stat %s size", DTransfer.filename);
			perror(err);
			return;
		}
	
		filesize = file_status.st_size;
		
		
		gtk_entry_set_text( GTK_ENTRY(entry2), g_ascii_dtostr(sizestr, 10, filesize));
	}

	gtk_widget_destroy (dialog);
}

//---------------------------------------------------------//
void on_btn_WriteRead_ReadOpen_clicked(GtkButton       *button,
										gpointer         win)
{
	GtkWidget *dialog;
	GtkWidget *entry;

	entry = lookup_widget( GTK_WIDGET(button), 
						   "txt_WriteRead_Read");
	
	dialog = gtk_file_chooser_dialog_new ("Open File",
										(GtkWindow *)win,
										GTK_FILE_CHOOSER_ACTION_OPEN,
										GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
										GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
										NULL);

	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
	{
		if ( DTransfer.filename != NULL )
			g_free(DTransfer.filename);	
		DTransfer.filename = NULL;
		DTransfer.filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
		gtk_entry_set_text( GTK_ENTRY(entry), DTransfer.filename);
		
		
		
	}

	gtk_widget_destroy (dialog);
}

//---------------------------------------------------------//
void on_btn_WriteRead_WriteOpen_clicked(GtkButton       *button,
										GtkWindow *         win)
{
	GtkWidget *dialog;
	GtkWidget *entry;

	entry = lookup_widget( GTK_WIDGET(button), "txt_WriteRead_Write");
	

	dialog = gtk_file_chooser_dialog_new ("Open File",
										//(GtkWindow *)win,
										 win,
										GTK_FILE_CHOOSER_ACTION_OPEN,
										GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
										GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
										NULL);
	
	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
	{
		if ( DTransfer.filename != NULL)
			g_free(DTransfer.filename2);	
		DTransfer.filename2 = NULL;
		DTransfer.filename2 = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
		gtk_entry_set_text( GTK_ENTRY(entry), DTransfer.filename2);
		
		
		
	}

	gtk_widget_destroy (dialog);
	
	
}

//---------------------------------------------------------//
void on_btn_ReadOpen_clicked(GtkButton       *button,
							 gpointer         win)
{
	GtkWidget *dialog;
	GtkWidget *entry;

	entry = lookup_widget( GTK_WIDGET(button), "txt_ReadFile");
	
	dialog = gtk_file_chooser_dialog_new ("Open File",
										(GtkWindow *)win,
										GTK_FILE_CHOOSER_ACTION_OPEN,
										GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 										GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
										NULL);

	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
	{
		if ( DTransfer.filename != NULL)
			g_free(DTransfer.filename);
		DTransfer.filename = NULL;
		DTransfer.filename= gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
		gtk_entry_set_text( GTK_ENTRY(entry), DTransfer.filename);
		
		
		
	}

	gtk_widget_destroy (dialog);
}

//---------------------------------------------------------//
int GetBaudRate( GString rate)
{
	if ( 0 == g_strcasecmp( rate.str, "1200"))
		return 1200;
	
	if ( 0 == g_strcasecmp( rate.str, "2400"))
		return 2400;
	
	if ( 0 == g_strcasecmp( rate.str, "4800"))
		return 4800;
	
	if ( 0 == g_strcasecmp( rate.str, "9600"))
		return 9600;
	
	if ( 0 == g_strcasecmp( rate.str, "38400"))
		return 38400;
	
	if ( 0 == g_strcasecmp( rate.str, "57600"))
		return 57600;
	
	if ( 0 == g_strcasecmp( rate.str, "115200"))
		return 115200;
	
	
	
}

//---------------------------------------------------------//
/*
	when switch page, clear the DTransfer data structure

*/
void
on_notebook1_switch_page               (GtkNotebook     *notebook,
                                        GtkNotebookPage *page,
                                        guint            page_num,
                                        gpointer         user_data)
{
	GtkWidget *entry;
	switch ( page_num)
	{
		case 0:
			entry = lookup_widget( GTK_WIDGET(notebook), "txt_FileName");
			//gtk_entry_set_text(entry, "this is write");
				
			break;
			
		case 1:
			entry = lookup_widget( GTK_WIDGET(notebook), "txt_ReadFile");
			//gtk_entry_set_text(entry, "this is Read");
			
			break;
		case 2:
			entry = lookup_widget( GTK_WIDGET(notebook), "txt_WriteRead_Read");
			//gtk_entry_set_text(entry, "this is writeread read");
			
			break;
		
	}
	
}


void
on_txt_WriteSize_changed               (GtkEditable     *editable,
                                        gpointer         user_data)
{

}


void
on_txt_ReadSize_changed                (GtkEditable     *editable,
                                        gpointer         user_data)
{

}

