

namespace eval PostRangesTable {
    variable values
    variable DefinedTables 
    variable combo
    variable PanedWindow
}

proc PostRangesTable::Create { { w .gid.postrangestable } } {
    variable DefinedTables
    variable combo
    variable PanedWindow
    
    InitWindow $w [_ "Results ranges table"] PostRangesTableWindowGeom PostRangesTable::Create

    label $w.l1 -text [_ "Table will be applied to current result"]

    label $w.l2 -text [_ "Name:"]
    set combo($w) [ComboBox $w.cb1 -textvariable PostRangesTable::values($w,name) -values \
		       [array names DefinedTables] -modifycmd [list PostRangesTable::FillTable $w]]

    focus $w.cb1

    set bbox [ButtonBox $w.bbox -spacing 0 -padx 1 -pady 1 -homogeneous 0]
    $bbox add -image [imagefrom check.gif] -width 15 \
	-highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
	-helptext [_ "Clean values fields"] -command "PostRangesTable::ButtonAction $w clean"
    $bbox add -image [imagefrom erase-cross.gif] -width 15 \
	-highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
	-helptext [_ "Delete table from window"] -command "PostRangesTable::ButtonAction $w delete"
    $bbox add -image [imagefrom save15.gif] -width 15 \
	-highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
	-helptext [_ "Export tables to a file"] -command "PostRangesTable::ButtonAction $w export"
    $bbox add -image [imagefrom open15.gif] -width 15 \
	-highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 -padx 1 -pady 1 \
	-helptext [_ "Import previusly exported tables"] -command \
	"PostRangesTable::ButtonAction $w import"

    set sw [ScrolledWindow $w.sw]
    set sf [ScrollableFrame $sw.sf -constrainedwidth 1]
    $sw setwidget $sf
    set f [$sf getframe]

    set pw [PanedWindow $f.pw -side top -pad 0]
    set PanedWindow($w) $pw

    set labels [list [_ "Minimum"] [_ "Maximum"] [_ "Name"]]

    for { set j 0 } { $j < 3 } { incr j } {
	set pane [$pw add -weight 1]
	label $pane.l -text [lindex $labels $j] -relief raised -bd 1
	grid $pane.l -sticky ew
	grid columnconf $pane 0 -weight 1
    }

    set i 0
    while 1 {
	if { ![info exists PostRangesTable::values($w,$i,0)] && $i >= 7 } { break }
	for { set j 0 } { $j < 3 } { incr j } {
	    set pane [$pw getframe $j]
	    entry $pane.e$i -textvariable \
		PostRangesTable::values($w,$i,$j) -bd 0 \
		-highlightthickness 1 -highlightbackground grey90
	    grid $pane.e$i -sticky ewn
	    grid rowconf $pane $i -weight 0
	}
	incr i
    }
    SetTabBindings $w $pw

    for { set j 0 } { $j < 3 } { incr j } {
	set pane [$pw getframe $j]
	grid rowconf $pane $i -weight 1
    }

    if { ![info exists ::GidPriv(arrow_up_vsmall.gif)] } {
	set ::GidPriv(arrow_up_vsmall.gif) [image create photo -file [file join \
		$::GIDDEFAULT bitmaps arrow_up_vsmall.gif]]
    }
    if { ![info exists ::GidPriv(arrow_down_vsmall.gif)] } {
	set ::GidPriv(arrow_down_vsmall.gif) [image create photo -file [file join \
		$::GIDDEFAULT bitmaps arrow_down_vsmall.gif]]
    }

    Button $f.b1 -image $::GidPriv(arrow_down_vsmall.gif) -relief link -command \
	    "PostRangesTable::IncreaseDecreaseItems $w $pw increase"
    Button $f.b2 -image $::GidPriv(arrow_up_vsmall.gif) -relief link -command \
	    "PostRangesTable::IncreaseDecreaseItems $w $pw decrease"

    grid $pw -sticky nsew -columnspan 2
    grid $f.b1 $f.b2 -sticky w -padx 3 -pady 3
    grid columnconf $f 1 -weight 1
    grid rowconf $f 0 -weight 1

    frame $w.buts -bg [CCColorActivo [$w cget -bg]]

    button $w.buts.apply -text [_ "Apply"] -width 8 -command "PostRangesTable::ApplyTable $w"
    button $w.buts.close -text [_ "Close"] -width 8 -command "destroy $w"

    grid $w.buts.apply -padx 3 -pady 3 -row 0 -column 0
    grid $w.buts.close -padx 3 -pady 3 -row 0 -column 1
    
    grid $w.l1    -      -  -sticky w
    grid $w.l2 $w.cb1 $bbox -sticky w -pady 3
    grid $sw      -     -   -sticky nsew -padx 3 -pady 3
    grid $w.buts  -     -   -sticky nsew
    grid conf $w.cb1    -sticky ew
    grid columnconf $w 1 -weight 1
    grid rowconf $w 2 -weight 1
}

proc PostRangesTable::ButtonAction { w what } {
    variable values
    variable DefinedTables
    variable combo

    switch $what {
	clean {
	    foreach i [array names values $w,*] {
		set values($i) ""
		unset values($i)
	    }
	}
	delete {
	    set name $values($w,name)
	    if { ![info exists DefinedTables($name)] } {
		WarnWin [_ "Select first a an already defined table"] $w
		return
	    }
	    set retval [tk_dialogRAMFull .gid.tempwinw [_ "Dialog window"] \
		            [_ "Are you sure to delete table '%s' from window?" $name] \
		            "" "" gidquestionhead 0 [_ "Yes"] [_ "No"]]
	    if { $retval == 1 } { return }
	    unset DefinedTables($name)
	    $combo($w) configure -values [array names DefinedTables]
	    ButtonAction $w clean
	}
	import {
	    set file [Browser-ramR file read $w [_ "Import results table"]]
	    if { $file == "" } { return }
	    if { [catch { set fileid [open $file r] }] } {
		WarnWin [_ "Could not open file '%s' to read" $file] $w
		return
	    }
	    PostRangesTable::ImportTables $fileid
	    close $fileid
	    $combo($w) configure -values [array names DefinedTables]
	    if { [llength [array names DefinedTables]] > 0 } {
		$combo($w) setvalue first
		FillTable $w
	    }
	}
	export {
	    set err [catch [list CheckTable $w] table]

	    if { $err } {
		WarnWin $table $w
		return
	    }
	    set DefinedTables([lindex $table 0]) [lrange $table 1 end]

	    if { ![info exists DefinedTables] || [array names DefinedTables] == "" } {
		WarnWin [_ "There are no tables to export. Use button 'Apply' before exporting"] $w
		return
	    }
	    set file [Browser-ramR file write $w [_ "Export results table"]]
	    if { $file == "" } { return }
	    
	    if { [catch { set fileid [open $file w] }] } {
		WarnWin [_ "Could not open file '%s' to write" $file] $w
		return
	    }
	    foreach i [array names DefinedTables] {
		WriteTable $fileid $i $DefinedTables($i)
	    }
	    close $fileid
	}
    }
}

proc PostRangesTable::SetTabBindings { w pw } {

    set i 0
    while 1 {
	for { set j 0 } { $j < 3 } { incr j } {
	    set pane [$pw getframe $j]
	    if { ![winfo exists $pane.e$i] } { return }
	    if { $j == 0 } {
		set prevpane [$pw getframe 2]
		set previ [expr $i-1]
	    } else {
		set prevpane [$pw getframe [expr $j-1]]
		set previ $i
	    }
	    if { [winfo exists $prevpane.e$previ] } {
		bind $pane.e$i <<PrevWindow>> "[list tkTabToWindow $prevpane.e$previ] ;break"
	    }
	    if { $j == 2 } {
		set nextpane [$pw getframe 0]
		set nexti [expr $i+1]
	    } else {
		set nextpane [$pw getframe [expr $j+1]]
		set nexti $i
	    }
	    if { [winfo exists $nextpane.e$nexti] } {
		bind $pane.e$i <Tab> "[list tkTabToWindow $nextpane.e$nexti] ;break"
	    }
	    if { $i > 0 && $j == 0 } {
		set paneMax [$pw getframe 1]
		set prevmaxentry $paneMax.e[expr $i-1]
		bind $pane.e$i <FocusIn> [join [list [list if { [%W get] == "" } \
		    "%W insert end \[$prevmaxentry get]"] [list %W selection range 0 end]] ";"]
	    }
	}
	incr i
    }
}

proc PostRangesTable::IncreaseDecreaseItems { w pw what } {
    variable values

    set i 0
    set pane [$pw getframe 0]
    while { [winfo exists $pane.e$i] } { incr i }
    if { $what == "increase" } {
	for { set j 0 } { $j < 3 } { incr j } {
	    set pane [$pw getframe $j]
	    entry $pane.e$i -textvariable \
		PostRangesTable::values($w,$i,$j) -bd 0 \
		-highlightthickness 1 -highlightbackground grey90
	    grid $pane.e$i -sticky ewn
	    grid rowconf $pane $i -weight 0
	}
	incr i
	for { set j 0 } { $j < 3 } { incr j } {
	    set pane [$pw getframe $j]
	    grid rowconf $pane $i -weight 1
	}
    } else {
	incr i -1
	for { set j 0 } { $j < 3 } { incr j } {
	    set pane [$pw getframe $j]
	    destroy $pane.e$i
	    unset values($w,$i,$j)
	}
    }
    SetTabBindings $w $pw
    after idle PanedWindow::_realize $pw \[winfo width $pw] \[winfo height $pw]
}

proc PostRangesTable::FillTable { w } {
    variable values
    variable DefinedTables
    variable PanedWindow

    set name $values($w,name)

    set i 0
    foreach "min max name" $DefinedTables($name) {
	if { ![info exists values($w,$i,0)] } {
	    IncreaseDecreaseItems $w $PanedWindow($w) increase
	}
	set values($w,$i,0) $min
	set values($w,$i,1) $max
	set values($w,$i,2) $name
	incr i
    }
    while { [info exists values($w,$i,0)] } {
	IncreaseDecreaseItems $w $PanedWindow($w) decrease
    }
}

proc PostRangesTable::CheckTable { w } {
    variable values

    if { [string trim $values($w,name)] == "" } {
	error  [_ "Error: it is necessary to enter a table name"]
    }
    set table [list [string trim $values($w,name)]]
 
    set NumCols 0
    set i 0
    while { [info exists PostRangesTable::values($w,$i,0)] } {
	if { [string trim $PostRangesTable::values($w,$i,0)] == "" && \
		 [string trim $PostRangesTable::values($w,$i,1)] == "" && \
		 [string trim $PostRangesTable::values($w,$i,2)] == "" } {
	    incr i
	    continue
	}
	if { [string trim $PostRangesTable::values($w,$i,0)] == "" } {
	    lappend table ""
	} elseif { [string is double -strict $PostRangesTable::values($w,$i,0)] } {
	    lappend table $PostRangesTable::values($w,$i,0)
	} else {
	    error [_ "Error in row %s: Minimum must be a number or void" [expr $i+1]]
	}
	if { [string trim $PostRangesTable::values($w,$i,1)] == "" } {
	    if { [lindex $table end] == "" } {
		error [_ "Error in row %s: Both Minimum and Maximum cannot be void" [expr $i+1]]
	    }
	    lappend table ""
	} elseif { [string is double -strict $PostRangesTable::values($w,$i,1)] } {
	    lappend table $PostRangesTable::values($w,$i,1)
	} else {
	    error [_ "Error in row %s: Maximum must be a number or -" [expr $i+1]]
	}
	if { [string trim $PostRangesTable::values($w,$i,2)] == "" } {
	    error [_ "Error in row %s: it is necessary to enter a name" [expr $i+1]]
	}
	lappend table [string trim $PostRangesTable::values($w,$i,2)]
	incr NumCols
	incr i
    }
    if { $NumCols == 0 } {
	error [_ "Error: table is void"]
    }
    return $table
}

proc PostRangesTable::ApplyTable { w } {
    variable values
    variable DefinedTables
    variable combo

    set err [catch [list CheckTable $w] table]

    if { $err } {
	WarnWin $table $w
	return
    }
    set dir [lindex [.central.s info Project] 9]
    set file [file join $dir table]
    set fout [open $file w]

    WriteTable $fout [lindex $table 0] [lrange $table 1 end]
    close $fout

    .central.s process escape escape escape escape 
    .central.s process Results ContOptions AddRangeTable \"$file\"

    set DefinedTables([lindex $table 0]) [lrange $table 1 end]
    $combo($w) configure -values [array names DefinedTables]
}

proc PostRangesTable::WriteTable { fout name contents } {

    puts $fout "ResultRangesTable \"$name\""
    foreach "min max name" $contents {
	puts $fout "$min - $max : \"$name\""
    }
    puts $fout "End ResultRangesTable"
}

proc PostRangesTable::ImportTables { fin } {
    variable DefinedTables

    set rex {ResultRangesTable\s+\"([^\"]+)\"(.*)End\s+ResultRangesTable}
    set rex2 {(\S*)\s+-\s+(\S*)\s+:\s+\"([^\"]+)\"}
    foreach "- name rest" [regexp -all -inline $rex [read $fin]] {
	set contents ""
	foreach "- min max namein" [regexp -all -inline $rex2 $rest] {
	    lappend contents $min $max $namein
	}
	set DefinedTables($name) $contents
    }
}