
# A pathname entry box with emacs-style file completion.
#
# Copyright (c) 1993 - 1995 ICEM Technologies GmbH.
# Author:  Wayne A. Christopher, wayne@icemcfd.com
#          ICEM CFD Engineering, Berkeley, California

proc pathentry {what path} {
    if {$what == "on"} {
	bind $path <Key-space> {pathentry_doit %W}
    } else {
	bind $path <Key-space> {}
	catch {destroy .pathentry_popup}
    }
}

proc pathentry_clear {} {catch {destroy .pathentry_popup}}

proc pathentry_doit {ent} {
    pathentry_clear	
    
    set path [$ent get]
    set dir [file dirname $path]
    set file [file tail $path]
    #puts stdout "path $path dir $dir file $file"
    if {![file exists $dir]} {beep; return}
    set poss [glob -nocomplain [format "%s*" $path]]
    #puts stdout "poss $poss"
    if {$poss == ""} {beep; return}
    if {[llength $poss] == 1} {
	if {($poss == $path) && ([file type $poss] == "directory")} \
	    {set poss [format "%s/" $poss]}
	$ent delete 0 end
	$ent insert 0 $poss
	return
    }
    
    # now extract the longest match.
    set poss [lsort $poss]
    set done 0
    set advanced 0
    while {!$done} {
	set pos [string length $path]
	set cc ""
	foreach x $poss {
	    if {[string length $x] <= $pos} {set done 1; break}
	    set y [string index $x $pos]
	    if {($cc != "") && ($cc != $y)} {set done 1; break}
	    set cc $y
	}
	if !$done {
	    set path [format "%s%s" $path $cc]
	    set advanced 1
	}
	#puts stdout "path is $path"
    }
    
    if $advanced {
	$ent delete 0 end
	$ent insert 0 $path
	return
    }
    
    toplevel .pathentry_popup
    wm overrideredirect .pathentry_popup 1
    listbox .pathentry_popup.box -relief raised -borderwidth 2 \
	-geometry 30x[llength $poss] -background #aabbcc
    pack append .pathentry_popup \
	.pathentry_popup.box top
    foreach p $poss {
	set q [file tail $p]
	if {![regsub -all {\.} $q {_} r]} {set r $q}
	.pathentry_popup.box insert end "$q"
    }
    bind .pathentry_popup.box <Button-1> "%W select from \[%W nearest %y\]; \
	pathentry_clicked $ent \[lindex \[selection get\] 0\]"
    
    set path $ent
    set x 0
    set y 0
    while {$path != ""} {
	incr x [winfo x $path]
	incr y [winfo y $path]
	set path [winfo parent $path]
    }
    incr x 100
    incr y [winfo height $ent]
    wm geometry .pathentry_popup "+$x+$y"
}

proc pathentry_clicked {ent comp} {
    destroy .pathentry_popup
    if ![winfo exists $ent] return
    set what [$ent get]
    $ent delete 0 end
    set i [string last / $what]
    if {$i == -1} {
	$ent insert 0 $comp
    } else {
	$ent insert 0 [string range $what 0 $i]$comp
    }
}
