# =============================================================================
#
# File:		misc_classes.tcl
# Project:	TkDesk
#
# Started:	12.10.94
# Changed:	18.09.96
# Author:	cb
#
# Description:	Several class defs: dsk_history
#
# -----------------------------------------------------------------------------
#
# Sections:
#
# =============================================================================

#
# =============================================================================
#
# Class:	dsk_history
# Desc:		Implements a generic class for managing history lists.
#
# Methods:	add <path>	adds $path to history
#		get		returns the history list
# Procs:	
# Publics:	size		size of history list
#

itcl_class dsk_history {

    constructor {config} {
    }

    destructor {
    }

    #
    # ----- Methods and Procs -------------------------------------------------
    #

    method add {entry {dontmove 0}} {
	global tkdesk

	if {$lock && !$dontmove} {
	    set lock 0
	    return
	}
	
	if {$entry != "/" && $command == "" && $callback == ""} {
	    set entry [string trimright $entry "/"]
	    if {[string first "$tkdesk(configdir)/.trash" $entry] == 0 || \
		    [string first "$tkdesk(configdir)/.shelf" $entry] == 0} {
		return
	    }
	}
	if {[llength $entry] > 1} {
	    set entry [list $entry]
	}
	#puts "to add:   $entry"
	#puts "current:  $list"
	#puts "pointer:  $pointer"
	#puts "dontmove: $dontmove"
	set i [lsearch -exact $list [lindex $entry 0]]
	if {$i > -1} {
	    set list "$entry [lreplace $list $i $i]"
	} else {
	    set list "$entry $list"
	    if {[llength $list] > $size} {
		set list [lrange $list 0 [expr [llength $list] - 2]]
	    }
	}
	#puts "dirbuf:   $dirbuf"
	#puts ""
	set pointer 0
	set changed 1
	return $list
    }

    method get {} {
	return $list
    }

    method forward {} {
	set lock 1
	if {$pointer > 0} {
	    incr pointer -1
	    return [lindex $list $pointer]
	} else {
	    set lock 0
	    dsk_bell
	    return ""
	}
    }

    method back {} {
	global env

	if {$pointer == 0} {
	    # add current directory to history
	    set curdir [dsk_active dir]
	    if {[string first $env(HOME) $curdir] == 0} {
		history add [string_replace $curdir $env(HOME) ~]
	    } else {
		history add $curdir
	    }
	}

	set lock 1
	if {$pointer < [llength $list] - 1} {
	    incr pointer
	    return [lindex $list $pointer]
	} else {
	    set lock 0
	    dsk_bell
	    return ""
	}
    }

    method buildmenu {menu {open ""}} {
	global tkdesk

	if {!$changed && $menu == $last_menu} {
	    return
	}

	catch "$menu delete 0 last"
	set toplevel .[lindex [split $menu .] 1]
	if $tkdesk(sort_history) {
	    set l [lsort $list]
	} else {
	    set l $list
	}
	if {$callback != ""} {
	    foreach entry $l {
		$menu add command -label [_limit_entry $entry] \
		-command "$callback $toplevel \{[dsk_esc $entry \{\}]\}" \
			-font $tkdesk(font,entries)
	    }
	} elseif {$command != ""} {
	    foreach entry $l {
		$menu add command -label [_limit_entry $entry] \
			-command "$command $entry" \
			-font $tkdesk(font,entries)
	    }
	} else {
	    # history of directories
	    if {$open == ""} {
		foreach entry $l {
		    # IMPORTANT: Don't use -directory below (but -dir) !!
		    $menu add command -label [_limit_entry $entry] \
			    -command "$toplevel config -dir \{$entry\}" \
			    -font $tkdesk(font,entries)
		}
	    } else {
		foreach entry $l {
		    $menu add command -label [_limit_entry $entry] \
			    -command "dsk_open_dir $entry" \
			    -font $tkdesk(font,entries)
		}
	    }
	}
	set changed 0
	set last_menu $menu
    }

    method _limit_entry {str} {
	if {[string length $str] > $max_entry_length} {
	    return [string range $str 0 $max_entry_length]...
	} else {
	    return $str
	}
    }

    method changed {} {
	set changed 1
    }

    #
    # ----- Variables ---------------------------------------------------------
    #

    public size 20
    public command ""
    public callback ""

    protected list {}
    protected changed 1
    protected last_menu ""
    protected pointer 0
    protected lock 0
    protected dirbuf ""

    common max_entry_length 50
}

