# Copyright (c) 2000, Red Hat, Inc.
# 
# This file is part of Source-Navigator.
# 
# Source-Navigator is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 2, or (at your option)
# any later version.
# 
# Source-Navigator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with Source-Navigator; see the file COPYING.  If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.
# 
# dirdialog.tcl - A directory dialog widget. 
# Copyright (C) 1998 Cygnus Solutions.

itcl_class DirDialog& {
	inherit Toplevel&
	
	constructor {{config ""}} {
		global sn_options

		Toplevel&@@constructor -class Dialog
		on_close "$this cancel"

		$this withdraw

		wm transient $this [winfo toplevel [winfo parent $this]]

		sn_motif_buttons $this bottom 0 \
				[get_indep String ok] \
				[get_indep String cancel]

		$this.button_0 configure -command "$this select"
		$this.button_1 configure -command "$this cancel"

		set tree $this.dirtree
		Tree& $tree \
			-fillselection 0 \
			-selectmode browse \
			-exportselection 0 \
			-font $sn_options(def,default-font) \
			-indentwidth 20 \
			-width $width \
			-height $height \
			-filter "" \
			-plusimage plus_image \
			-minusimage minus_image \
			-unknownimage unknown_image
		pack $tree -side top -expand y -fill both -padx 5 -pady 5
		set treew [$tree tree]
		
		bind $treew <1> "$this expand %x %y"

	        # call glob on the path first so that
	        # a path like ~/foo becomes /home/user/foo
	        set path [glob -nocomplain $initialdir]
	    
	        # If glob does not match anything then the
	        # directory must not exists, just use /
	        if {$path == {}} {
		    set path /
	        }

	        if {[file pathtype $path] != "absolute"} {
		    set path [file join [pwd] $path]  
	        }

	        set pathlist [file split $path]

	        set root [lindex $pathlist 0]
	        set pathlist [lreplace $pathlist 0 0]
	    
	        $treew insert end \
				-text $root \
				-image dir_image \
				-unknown yes

	        display $root 0
	        set parent 0

	        if {[llength $pathlist] > 0} {
			set prefix $root
			foreach dir $pathlist {
				if {$dir == ""} {
					error "empty path element on \"$pathlist\""
				}
				set prefix [file join $prefix $dir]
				set ch [$treew children $parent]
				if {$ch == ""} {
					break
				}
				foreach idx $ch {
					set txt [$treew get $idx]
				        # FIXME : could there be a problem here on Windows
				        # because file names are not case sensitive?
					if {$txt == $dir} {
						display $prefix $idx
						set parent $idx
						break
					}
				}
			}
		}
		$treew selection set $parent

		# Get total number of elements in the tree
		set size [$treew size]

		# Get total number of elements we could display
		set height [$treew cget -height]

		# Figure out what index we should "see", if we can display
		# all the elements just "see" index 0. Otherwise, attempt
		# to show as many items as we can unless the "see" index
		# is below the directory we want to display.

		set see [expr {$size - $height}]
		if {$see < 0} {
			set see 0
		} elseif {$see > $parent} {
			set see $parent
		}
		$treew see -top $see
		
		$this title $title
		
		$this move_to_mouse
		$this take_focus $treew
		
		#make the window to be a dialog window
		catch {@@grab set $this}
		
		tkwait variable $this-dir
		
	}
	destructor {
		foreach v [@@info globals "$this-*"] {
			if {$v != "$this-dir"} {
				catch {uplevel #0 unset $v}
			}
		}
	}
	method config  {args} {
	}
	
	method select {} {
		set idx [$treew curselection]
		if {$idx != ""} {
			set path [build_filepath $treew $idx]
		} else {
			set path ""
		}

		uplevel #0 "set $this-dir \"$path\""
		$this delete
	}
	method cancel {} {
		uplevel #0 "set $this-dir \"\""
		$this delete
	}
	method display {path {parent -1}} {
		global sn_options
		
		set selection $path
		
		set fil_list [sn_glob \
				-dirvar dirnames \
				-dirlevel 1 \
				-ignore $sn_options(def,ignored-directories) \
				$path]
				
		set names ""
		foreach dir $dirnames {
			if {$dir == $path} {
				continue
			}
			lappend names [file tail $dir]
		}
		
		if {$names == ""} {
			$treew itemconfig $parent -unknown 0
			return
		}
		$treew insert end \
				list [@@lsort -dictionary $names] \
				-parent $parent \
				-image dir_image \
				-unknown yes
		$treew itemconfig $parent -unknown 0
		Tree& @@ resize_widget $treew
	}
	
	proc build_filepath {treew y} {
		set file [$treew get $y]
		set parent [$treew itemcget $y -parent]
		while {$parent > -1} {
			set file [file join [$treew get $parent] $file]
			set parent [$treew itemcget $parent -parent]
		}
		return $file
	}

	method expand {x y} {
		set id [$treew identify $x $y]
		set idx [$treew nearest $y]

		if {$id == "view" || $id == "hide"} {
			$treew toggle @$x,$y
			Tree& @@ resize_widget $treew
			return
		}
		if {$id == "text"} {
			return
		}
		set path [build_filepath $treew $idx]
		
		#expand path
		display $path $idx
	}
	
	protected treew .
	protected tree ""
	protected selection ""
	
	public initialdir "/"
	public script ""
	public title [get_indep String SelectDirectory]

	public width 40
	public height 25
}

