set gnuplot_cmd "pgnuplot.exe"
set baudrate2 115200
set com_port2 "\\\\.\\COM1"

set pot 2048


proc log {str} {

	$::console insert end "$str\n" 
	$::console see end
}

##########################pour énumérer les ports série###################################
if {$::tcl_platform(platform) == "windows"}	{
 package require registry
}

 proc get_serial_ports { } {
    set serial_base "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM"
    if {[catch { set values [ registry values $serial_base ]}]} {
		set values {}
	}
	
    set result {}

    foreach valueName $values {
		if {[catch {set newvalue [ registry get $serial_base $valueName ]}]==0} {
			lappend result  $newvalue
		}
	   # à commenter (l'usb est un device VCP0)
	   #puts $valueName
    }

    return $result
 }

proc choose_com { } {
	global com_port2 choosecomres comports
	set choosecomres none
	toplevel .choosecom
	wm title .choosecom "Open Com"
	ttk::frame .choosecom.le
	ttk::label .choosecom.le.l -text "Choose serial Port" -width 25 
	set comports [get_serial_ports]
	set com_porttmp $com_port2
	ttk::combobox .choosecom.le.e -textvariable com_porttmp -values $comports -width 25
	pack configure .choosecom.le.l -side left
	pack configure .choosecom.le.e -side left  -fill x 
	pack configure .choosecom.le -side top -fill x 
	ttk::frame .choosecom.okcancel
	ttk::button .choosecom.okcancel.ok -text {OK} -command { 
		if {[lsearch -exact $comports $com_porttmp]!=-1} {
				set com_port2 "\\\\.\\$com_porttmp"
			} else {
				set com_port2 $com_porttmp
			}
		destroy .choosecom
		set choosecomres OK
	}
	ttk::button .choosecom.okcancel.done -text {Cancel} -command {
		destroy .choosecom
		set choosecomres cancel
	}
	pack configure .choosecom.okcancel.ok -fill x -side left -expand 1
	pack configure .choosecom.okcancel.done -fill x -side right -expand 1
	pack configure .choosecom.okcancel -fill x -expand 1 -side bottom
	vwait com_port2
	return $choosecomres
}



proc open_com2 { } {
    global com_port2 baudrate2 tty2
	catch { close $tty2 }
	
	if {$::tcl_platform(platform) == "windows"}	{
		set comports [get_serial_ports]
		if {[lsearch -exact $comports $com_port2]!=-1} {
			set com_port "\\\\.\\$com_port2"
		} else {
			set com_port $com_port2
		}
	} else { 
		set com_port $com_port2
	}
	if {[catch {	
		set tty2 [open $com_port r+ ]
		fconfigure $tty2  -translation {binary}  -pollinterval 1 -buffering none -blocking 0 -mode $baudrate2,n,8,1
		fileevent $tty2 readable [ list Reader $tty2 ]
		set config_file [open  "aq.cfg" w]
		puts $config_file $com_port2
		close $config_file
		log "$com_port2 Opened"
	}]} {
			tk_messageBox -type ok -message "Cannot open serial port $com_port2" -title "Error"
	}
}

proc close_com2 { } {
    global tty2
    close $tty2
}

proc puts_tty2 {arg} {
    global tty2
    puts $tty2 $arg
    flush $tty2
}

proc puts_tty_noCR2 {arg} {
    global tty2
    puts -nonewline $tty2 $arg
    flush $tty2
}



#serial port handler
proc Reader { file } {
#called each time that the serial port is readable
	set char ""
	set char [read $file 1]
	while {$char !=""} {
	  binary scan $char c char_int
	  lappend ::numread [expr $char_int&0xff]
	  set char  [read $file 1] 
	}
	if {[llength $::numread]>=4} {
		set ::dlength [expr [lindex $::numread 1]*256 + [lindex $::numread 0]]
		set ::nvars [expr [lindex $::numread 3]*256 + [lindex $::numread 2]]
		if ($::nvars<256) {
			#446 avec DMA
			if {([llength $::numread]+2)>=$::dlength*2} {plot}
		} else {
			#401 bitwise
			set ::nvars [expr $::nvars - 256]
			if {([llength $::numread]+2)>=$::dlength} {plot_bits}
		}
	}
}

proc plot { } {	
	log "Ploting..."
	foreach {LSB MSB} $::numread {
		lappend intread [expr $MSB*256+$LSB]
	}
	set dlength [lindex $intread 0]
	set nvars [lindex $intread 1]
	log "$dlength samples, $nvars variables"
	set fileout [open "data.csv" w ]
	for {set i 0} {$i<$dlength} {incr i} {
		puts -nonewline $fileout [lindex $intread [expr $i+2]]
		if {[expr ($i+1)%$nvars]==0} { puts $fileout ""} else {puts -nonewline $fileout " "}
	}
	set ::numread {}
	close $fileout
}

proc plot_bits { } {
	global cmdfileid
	log "Ploting..."
	
	log "$::dlength samples, $::nvars variables"
	set fileout [open "data.csv" w ]
	set gplout [open "data.gpl" w ]
	for {set i 0} {$i<$::dlength} {incr i} {
		set byte [lindex $::numread [expr $i+4]]
		for {set j 0} {$j<$::nvars} {incr j} {
			puts -nonewline $fileout [expr ($byte>>$j)&1]
			puts -nonewline $gplout [expr ($byte>>$j)&1]
			if {[expr ($j+1)%$::nvars]==0} { puts $fileout ""} else {puts -nonewline $fileout ";"}
			if {[expr ($j+1)%$::nvars]==0} { puts $gplout ""} else {puts -nonewline $gplout " "}
		}
	}
	set ::numread {}
	close $fileout
	close $gplout
	if {$::tcl_platform(platform) == "windows"}	{
		set homedir [info script]
		set gnuplotcmd [file attributes [file join $homedir $::gnuplot_cmd] -shortname]
		
		set testfile [file join $homedir gpltest.gpl]
		if {[file exists $testfile]} {
			catch {file delete $testfile} 
		}
		if {[info exists cmdfileid]==0} { 
			set cmdfileid [open "|$gnuplotcmd -" w] 
		} else {
			puts $cmdfileid "set print \"$testfile\""
			puts $cmdfileid "print \"test\""
			puts $cmdfileid "set print"
			flush $cmdfileid
			after 5
			if {[file exists $testfile]} {
				catch {file delete $testfile}
			} else {
				catch {close $cmdfileid }
				set cmdfileid [open "|$gnuplotcmd -" w] 
			}
		}
		puts $cmdfileid "set output"
		puts $cmdfileid "set terminal windows"
		puts $cmdfileid "load 'cmd.gpl'"
		flush $cmdfileid
	}
}

proc setpot {val} {
	log "Potentiometer = $val"
	puts_tty_noCR2 "$val\n"
	after 10
}

#on regarde si on a un fichier de configuration
if {[file exists "aq.cfg"]} {
		set config_file [open  "aq.cfg" r]
		gets $config_file com_port2
		close $config_file
} 


set ::numread {}

ttk::labelframe .sp -text "Serial port"

if {$::tcl_platform(platform) != "windows" } {
	ttk::entry .sp.en -width 20 -textvariable com_port2
} else {
	set comports [get_serial_ports]
	ttk::combobox .sp.en -textvariable com_port2 -values $comports -width 25 -postcommand {
		set comports [get_serial_ports]
		.sp.en configure -values $comports
	}
}

ttk::button .sp.bt -width 20 -text Open -command {
	catch {close_com2}
	if {[catch {open_com2}]} {
		tk_messageBox -type ok -message "Cannot open serial port" -title "Error"
	}
}
pack .sp.en -side left -fill x -expand true
pack .sp.bt -side right -fill x -expand true

ttk::labelframe .sc -text "Potentiometer"
#ttk::entry .sc.en -width 5 -textvariable pot
scale .sc.sc -from 0 -to 4095 -variable pot -digits 1 -orient horizontal -command {setpot}
pack .sc.sc -side right -fill x -expand true


set console [text .console -height 15 -width 15]

pack .sp -side top -fill x -expand true
pack .sc -side top -fill x -expand true
pack .console -side bottom -fill x -expand true