#!/usr/local/bin/wish
global env gv

set gv(version)		"File Manager (Version 0.3 14may96)"
set gv(program)		fm
set gv(iconname)	[string toupper $gv(program)]
set gv(top)		.$gv(program)
set gv(author)		"John van Gulik"

proc errmess { pw {msg ""} } {
	global env gv
	pack [label .errmess -text $msg] -side top -expand true -fill both
	pack [button .ok -text "OK" -command "destroy .ok"] -side top
	tkwait window .ok
}

##############################################################################
#####	Set the required environment variables
##############################################################################

if {[info exists env(HOME)] && $env(HOME)=="/"} {set env(HOME) "/root"}

if {$tcl_platform(platform)=="windows"} {
	if {![info exists env(TKAPPS)]} {
		set env(TKAPPS) /TKAPPS
	}
	if {![file isdirectory $env(TKAPPS)]} {
		errmess . "Directory $env(TKAPPS) not found"
		exit 1
	}
} elseif {$tcl_platform(platform)=="unix"} {
	if {![info exists env(TKAPPS)]} {
		if {[file isdirectory $env(HOME)/TKAPPS]} {
			set env(TKAPPS) $env(HOME)/TKAPPS
		} elseif {[file isdirectory /opt/TKAPPS]} {
			set env(TKAPPS) /opt/TKAPPS
		} elseif {[file isdirectory /apps/TKAPPS]} {
			set env(TKAPPS) /apps/TKAPPS
		} else {
			set env(TKAPPS) /usr/local/TKAPPS
		}
	}
	if {![file isdirectory $env(TKAPPS)]} {
		errmess . "Directory $env(TKAPPS) not found"
		exit 1
	}
} else {
	errmess . "This application is not supported under $tcl_platform(platform)"
	exit 1
}

set auto_path [linsert $auto_path 0 $env(TKAPPS)/lib]

#wm withdraw .

bind all <Any-Button> {focus %W}

standard_startup $gv(program) $gv(version)

##############################################################################
#####	Set required variables and options
##############################################################################

##############################################################################
#####	SUBROUTINES
##############################################################################

proc fm_view { w } {
	global env gv

	set dir $gv($w.directory)

	set indexlist [$w.file.f.list curselection]
	if {[llength $indexlist]<1} {return}

	foreach index [lsort -decreasing $indexlist] {
		set file [$w.file.f.list get $index]
		set filename $dir/$file
		regsub -all {[/]+} $filename {/} filename
		if {[catch {viewfile $filename} res]} {
			errmess $w "Error viewing $filename\n$res"
		}
	}

	return
}

proc fm_edit { w } {
	global env gv

	set dir $gv($w.directory)

	set indexlist [$w.file.f.list curselection]
	if {[llength $indexlist]<1} {return}

	foreach index [lsort -decreasing $indexlist] {
		set file [$w.file.f.list get $index]
		set filename $dir/$file
		regsub -all {[/]+} $filename {/} filename
		if {[catch {viewfile $filename {} vedit} res]} {
			errmess $w "Error editing $filename\n$res"
		}
	}

	return
}

proc fm_delete { w } {
	global env gv

	set dir $gv($w.directory)

	set indexlist [$w.file.f.list curselection]
	if {[llength $indexlist]<1} {return}

	set flag n
	foreach index [lsort -decreasing $indexlist] {
		set file [$w.file.f.list get $index]
		set filename $dir/$file
		regsub -all {[/]+} $filename {/} filename
		if {$flag=="n"} {
			if {![yesno $w "Delete file $filename ?"]} {
				continue
			}
		}
		if {[catch {f_delete $filename} res]} {
			errmess $w "Error deleting $filename\n$res"
		} else {
			$w.file.f.list delete $index
			update idletasks
		}
	}

	return
}

proc fm_rename { w } {
	global env gv

	set dir $gv($w.directory)

	set indexlist [$w.file.f.list curselection]
	if {[llength $indexlist]<1} {return}

	foreach index $indexlist {
		set file [$w.file.f.list get $index]
		set filename $dir/$file
		regsub -all {[/]+} $filename {/} filename
		set new [getstring $w "Enter new filename :" $filename]
		if {$new==""} {continue}
		if {[catch {f_rename $filename $new} res]} {
			errmess $w "Error renaming $filename to $newname\n$res"
		}
	}

	filebox_fill $w $dir

	return
}

proc fm_copy { w } {
	global env gv

	set dir $gv($w.directory)

	set indexlist [$w.file.f.list curselection]
	if {[llength $indexlist]<1} {return}

	foreach index $indexlist {
		set file [$w.file.f.list get $index]
		set filename $dir/$file
		regsub -all {[/]+} $filename {/} filename
		set new [getstring $w "Enter new filename :" $filename]
		if {$new==""} {continue}
		if {[catch {f_copy $filename $new} res]} {
			errmess $w "Error copying $filename to $newname\n$res"
		}
	}

	filebox_fill $w $dir

	return
}

proc fm_create { w } {
	global env gv

	set dir $gv($w.directory)

	set gv($w.entry) [string trim $gv($w.entry)]
	foreach file [split $gv($w.entry)] {
		set filename $dir/$file
		regsub -all {[/]+} $filename {/} filename
		if {[catch {f_touch $filename} res]} {
			errmess $w $res
		}
	}

	filebox_fill $w $dir

	return
}

proc fm_mkdir { w } {
	global env gv

	set dir $gv($w.directory)

	set gv($w.entry) [string trim $gv($w.entry)]
	foreach file [split $gv($w.entry)] {
		set filename $dir/$file
		regsub -all {[/]+} $filename {/} filename
		if {[catch {f_mkdir $filename} res]} {
			errmess $w $res
		}
	}

	filebox_fill $w $dir

	return
}

proc fm_rmdir { w } {
	global env gv

	set dir $gv($w.directory)

	set indexlist [$w.file.d.list curselection]
	if {[llength $indexlist]<1} {return}

	foreach index $indexlist {
		set file [$w.file.d.list get $index]
		set filename $dir/$file
		regsub -all {[/]+} $filename {/} filename
		if {[catch {f_rmdir $filename} res]} {
			errmess $w $res
		}
	}

	filebox_fill $w $dir

	return
}

proc filebox { pw {host "File"} {directory ""} } {
	global env gv

	set count 0
	while {[winfo exists $pw.f$count]} {incr count}
	set w $pw.f$count

	pack [frame $w -bd 2 -relief sunken] \
		-side left -expand true -fill both

	pack [frame $w.but] \
		-side top -fill x
	pack [button $w.but.refresh -text "Refresh" \
		-command "filebox_fill $w \$gv($w.directory)"] \
		-side left -expand true -fill x
	pack [button $w.but.open -text "View" \
		-command "fm_view $w"] \
		-side left -expand true -fill x
	pack [button $w.but.edit -text "Edit" \
		-command "fm_edit $w"] \
		-side left -expand true -fill x
	pack [button $w.but.delete -text "Delete" \
		-command "fm_delete $w"] \
		-side left -expand true -fill x
	pack [button $w.but.rename -text "Rename" \
		-command "fm_rename $w"] \
		-side left -expand true -fill x
	pack [button $w.but.copy -text "Copy" \
		-command "fm_copy $w"] \
		-side left -expand true -fill x
	pack [button $w.but.create -text "Create" \
		-command "fm_create $w"] \
		-side left -expand true -fill x
	pack [button $w.but.mkdir -text "Mkdir" \
		-command "fm_mkdir $w"] \
		-side left -expand true -fill x
	pack [button $w.but.rmdir -text "Rmdir" \
		-command "fm_rmdir $w"] \
		-side left -expand true -fill x
	if {$pw!=$gv(top)} {
		pack [button $w.but.close -text "Close" \
			-command "destroy $pw"] \
			-side left
	}

	pack [frame $w.lab] \
		-side top -fill x
	pack [label $w.lab.lab -text "$host :"] \
		-side left
	pack [entry $w.lab.ent -relief sunken -textvariable gv($w.entry)] \
		-side left -expand true -fill x

	pack [label $w.fileinfo -textvariable gv($w.fileinfo)] \
		-side top -fill x

	pack [frame $w.file] \
		-side top -expand true -fill both
	pack [frame $w.file.t] \
		-side top -fill x
	pack [label $w.file.t.lab -text "Current Directory : "] \
		-side left
	pack [label $w.file.t.dir -textvariable gv($w.directory)] \
		-side left -fill x

	pack [frame $w.file.d] \
		-side left -expand true -fill both
	pack [label $w.file.d.lab -text "Directories"] \
		-side top -fill x
	pack [scrollbar $w.file.d.scroll \
		-command "$w.file.d.list yview"] \
		-side left -fill y
	pack [listbox $w.file.d.list -relief sunken -width 30 -height 30 \
		-yscroll "$w.file.d.scroll set" \
		-selectmode extended -exportselection true] \
		-side left -expand true -fill both

	pack [frame $w.file.f] \
		-side left -expand true -fill both
	pack [label $w.file.f.lab -text "Files"] \
		-side top -fill x
	pack [scrollbar $w.file.f.scroll \
		-command "$w.file.f.list yview"] \
		-side left -fill y
	pack [listbox $w.file.f.list -relief sunken -width 30 -height 30 \
		-yscroll "$w.file.f.scroll set" \
		-selectmode extended -exportselection true] \
		-side left -expand true -fill both

	pack [frame $w.fileb] \
		-side top -fill x
	pack [button $w.fileb.home -text [lang "Home" "FRENCH"] \
		-command "filebox_fill $w $env(HOME)" ] \
		-side left -expand true -fill both
	pack [checkbutton $w.fileb.hidden -text [lang "Hidden files" "FRENCH"] \
		-variable gv($w.hidden) -onvalue "true" -offvalue "false" -relief raised \
		-command "filebox_fill $w \$gv($w.directory)" ] \
		-side left -expand true -fill both

	# directory box bindings
	bind $w.file.d.list <Double-1> \
		"filebox_fill $w \"\$gv($w.directory)/\[%W get \[%W nearest %y\]\]\""
	bind $w.file.d.list <Return> \
		"filebox_fill $w \"\$gv($w.directory)/\[%W get \[%W index active\]\]\""
#	bind $w.file.d.list <Enter> "focus %W"
	bind $w.file.d.list <Delete> "fm_rmdir $w"
	bind $w.file.d.list <Right> \
		"focus $w.file.f.list ; \
		$w.file.f.list selection clear 0 end ; \
		$w.file.f.list selection set active"
	bind $w.file.f.list <Left> \
		"focus $w.file.d.list ; \
		$w.file.d.list selection clear 0 end ; \
		$w.file.d.list selection set active"

	# file box bindings
	bind $w.file.f.list <1> \
		"set gv($w.entry) \[%W get \[%W nearest %y\]\] ; \
		set gv($w.fileinfo) \[file_info \$gv($w.directory)/\$gv($w.entry)\]"
	bind $w.file.f.list <Double-1> \
		"set gv($w.entry) \[%W get \[%W nearest %y\]\] ; \
		set gv($w.fileinfo) \[file_info \$gv($w.directory)/\$gv($w.entry)\] ; \
		filebox_select $w"
	bind $w.file.f.list <Return> \
		"set gv($w.entry) \[%W get \[%W index active\]\] ; \
		set gv($w.fileinfo) \[file_info \$gv($w.directory)/\$gv($w.entry)\] ; \
		filebox_select $w"
#	bind $w.file.f.list <Enter> "focus %W"
	bind $w.file.f.list <Delete> "fm_delete $w"
	bind $w.file.d.list <Right> \
		"focus $w.file.f.list ; \
		$w.file.f.list selection clear 0 end ; \
		$w.file.f.list selection set active"
	bind $w.file.f.list <Left> \
		"focus $w.file.d.list ; \
		$w.file.d.list selection clear 0 end ; \
		$w.file.d.list selection set active"

	filebox_fill $w $directory

	set gv($w.stayup) true
	set gv($w.command) "viewfile"
}

proc fm_newwin { } {
	global env gv

	set cnt 0
	while {[winfo exists $gv(top).w$cnt]} {incr cnt}

	set w $gv(top).w$cnt

	toplevel $w
	wm iconname	$w "$gv(iconname) ($cnt)"
	wm iconbitmap	$w @$env(TKAPPS)/bitmaps/$gv(program).xbm
	wm iconmask	$w @$env(TKAPPS)/bitmaps/$gv(program).msk
	wm title	$w "$gv(version) ($cnt)"
	wm minsize	$w 100 100
	wm protocol	$w WM_DELETE_WINDOW "destroy $w"

	pack [label $w.help] \
		-side bottom -fill x
	bind_help $w.help $w.help \
		[lang "Help text" "Texte d'aide"]

	filebox $w
}

##############################################################################
#####	MAIN PROGRAM
##############################################################################

toplevel	$gv(top)
wm iconname	$gv(top) $gv(iconname)
wm iconbitmap	$gv(top) @$env(TKAPPS)/bitmaps/$gv(program).xbm
wm iconmask	$gv(top) @$env(TKAPPS)/bitmaps/$gv(program).msk
wm title	$gv(top) $gv(version)
wm minsize	$gv(top) 100 100
wm protocol	$gv(top) WM_DELETE_WINDOW exit

pack [label $gv(top).help] \
	-side bottom -fill x
bind_help $gv(top).help $gv(top).help \
	[lang "Help text" "Texte d'aide"]

pack [frame $gv(top).b1] \
        -side top -fill x
pack [menubutton $gv(top).b1.file -menu $gv(top).b1.file.m \
	-text [lang "File..." "Fichier..."] ] \
        -side left -fill y
pack [button $gv(top).b1.new -text "New Window" \
	-command {fm_newwin}] \
        -side left
pack [label $gv(top).b1.status -textvariable gv(status) ] \
        -side left -expand true -fill x
pack [button $gv(top).b1.iconify -text [lang "Iconify" "Minimiser"] \
	-command "wm iconify $gv(top)"] \
        -side left
pack [button $gv(top).b1.exit -text [lang "Exit" "Abandonner"] \
	-command "exit"] \
        -side left

bind_help $gv(top).b1.file $gv(top).help \
        [lang "Standard file menu" "Menu standard du fichier"]
bind_help $gv(top).b1.status $gv(top).help \
        [lang "Status messages" "Messages d'tat"]
bind_help $gv(top).b1.iconify $gv(top).help \
        [lang "Iconify window" "Minimiser cette fentre"]
bind_help $gv(top).b1.exit $gv(top).help \
        [lang "Close this window" "Fermer cette fentre"]

menu $gv(top).b1.file.m
$gv(top).b1.file.m add command -label [lang "Help" "Aide"] \
	-command "help $env(TKAPPS)/help/$gv(program)"
$gv(top).b1.file.m add command -label [lang "Fonts/Colors" "Fontes/Couleurs"] \
	-command "background tkcustom $gv(program)"
$gv(top).b1.file.m add command -label [lang "Iconify" "Minimiser"] \
	-command "wm iconify $gv(top)"
$gv(top).b1.file.m add command -label [lang "Exit" "Abandonner"] \
	-command "exit"


filebox $gv(top)

wm withdraw .
if {[winfo exists .startup]} {destroy .startup}
if {[info exists gv(startup.id)]} {image delete $gv(startup.id)}

