# watcher.tcl --
#
# This file contains code which handles the watcher window.
#
#
#  TkRat software and its included text is Copyright 1996, 1997, 1998
#  by Martin Forssen.
#
#  Postilion software and its included text and images
#  Copyright (C) 1998, 1999, 2000 Nic Bernstein
#
#  The full text of the legal notices is contained in the files called
#  COPYING and COPYRIGHT.TkRat, included with this distribution.
#
#  This program 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
#  of the License, or (at your option) any later version.
# 
#  This program 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 this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

# WatcherInit --
#
# Builds the watcher window, but unmaps it. The watcher is then ready
# to popup.
#
# Arguments:
# handler -	The folder handler to which this watcher is connected

proc WatcherInit {handler} {
    global idCnt option
    upvar #0 $handler fh

    # Create toplevel
    set w .$handler.watcher
    set fh(watcher_w) $w
    set fh(watcher_list) $w.list
    toplevel $w -class Postilion
    wm title $w $option(watcher_name)

    # Populate window
    frame $w.info
    label $w.info.name -textvariable ${handler}(folder_name) \
	    -font $option(watcher_font) -relief raised -bd 1 -anchor w
    label $w.info.size -textvariable ${handler}(watcher_size) \
	    -font $option(watcher_font) -width 11 -relief raised -bd 1
    pack $w.info.size -side right
    pack $w.info.name -fill x -expand 1
    pack $w.info -side top -fill x -expand 1
    scrollbar $w.scroll \
	      -relief raised \
	      -bd 1 \
	      -highlightthickness 0 \
	      -command "$w.list yview"
    listbox $fh(watcher_list) \
	    -yscroll "$w.scroll set" \
	    -relief raised \
	    -bd 1 \
	    -font $option(watcher_font) \
	    -exportselection false \
	    -highlightthickness 0
    # Scroll mouse support added by Stephen Ryan 14 Oct 1999
    bind $w.list <5> [list $w.list yview scroll 5 units]
    bind $w.list <4> [list $w.list yview scroll -5 units]
    bind $w.list <Shift-5> [list $w.list yview scroll 1 units]
    bind $w.list <Shift-4> [list $w.list yview scroll -1 units]
    bind $w.list <Control-5> [list $w.list yview scroll 1 pages]
    bind $w.list <Control-4> [list $w.list yview scroll -1 pages]
    Size $fh(watcher_list) watcher
    pack $w.scroll -side right -fill y
    pack $w.list -side left -expand 1 -fill both
    set fh(watcher_list) $w.list
    Place $w watcher

    foreach b {<1> <B1-Motion> <ButtonRelease-1> <Shift-1> <Control-1>
	       <B1-Leave> <B1-Enter> <space> <Select> <Control-Shift-space>
	       <Shift-Select> <Control-slash> <Control-backslash>} {
	bind $w.list $b {break}
    }
    bind $w.list <ButtonRelease-1>	"WatcherWakeMaster $handler"
    bind $w.info.name <ButtonRelease-1>	"WatcherWakeMaster $handler"
    bind $w.info.size <ButtonRelease-1>	"WatcherWakeMaster $handler"
    bind $w.list <ButtonRelease-3>	"WatcherSleep $handler"
    bind $w.info.name <ButtonRelease-3>	"WatcherSleep $handler"
    bind $w.info.size <ButtonRelease-3>	"WatcherSleep $handler"
    bind $w.info.name <Destroy>		"unset ${handler}(watcher_w)"
    wm withdraw $w
}


# WatcherSleep --
#
# Unmaps the watcher window if it was mapped. This should be called
# whenever the folder window is unmapped.
#
# Arguments:
# handler -	The folder handler to which this watcher is connected

proc WatcherSleep {handler} {
    upvar #0 $handler fh
    if {[info exists fh(watcher_w)] && [winfo ismapped $fh(watcher_w)]} {
	wm withdraw $fh(watcher_w)
	regsub {[0-9]+x[0-9]+} [wm geom $fh(watcher_w)] {} fh(watcher_geom)
    }
}


# WatcherDoRound --
#
# Check if any new mail has arrived, and if is has call WatcherPopup.
#
# Arguments:
# handler -	The folder handler to which this watcher is connected
# type    -	The type of folder for time lookup

proc WatcherDoRound {handler type} {
    global option t
    upvar #0 $handler fh

    # Check for changes
    if [info exists fh(folder_handler)] {
	if ![catch {$fh(folder_handler) update 0 $fh(folder_sort)} result] {
	    if {1 == $result} {
		if {1 == [llength [info commands RatUP_Bell]]} {
		    if [catch {RatUP_Bell} text] {
			Popup "$t(bell_cmd_failed): $text"
		    }
		} else {
		    for {set i 0} {$i < $option(watcher_bell)} {incr i} {
			after 200
			bell
		    }
		}
		
		if { $option(watcher_enable) && ![winfo ismapped $fh(toplevel)]} {
		    WatcherPopup $handler
		}
		Sync $handler 0
	    }
	} else {
	    RatLog 4 $result
	    Quit $handler
	    return
	}
    }

    # Schedule next round
    foreach timePair $option(watcher_time) {
	if ![string compare [lindex $timePair 0] $type] {
	    set time [expr 1000*[lindex $timePair 1]]
	    set fh(after_id) [after $time WatcherDoRound $handler $type]
	}
    }
}


# WatcherPopup --
#
# New mail has arrived so we need to populate and popup the watcher window.
#
# Arguments:
# handler -	The folder handler to which this watcher is connected

proc WatcherPopup {handler} {
    global option
    upvar #0 $handler fh

    # Make sure that we have a window to pop up
    if ![info exists fh(watcher_w)] {
	WatcherInit $handler
    }

    # Some window managers (at least I think its them) like to move
    # the watcher while it is iconified. This tries to fix that.
    if [info exists fh(watcher_geom)] {
	wm geometry $fh(watcher_w) $fh(watcher_geom)
    }

    # Populate listbox
    $fh(watcher_list) delete 0 end
    switch $option(watcher_show) {
    new {
	    set fullList [$fh(folder_handler) list $option(watcher_format)]
	    set i 0
	    foreach elem [$fh(folder_handler) list %S] {
		if [regexp N $elem] {
		    $fh(watcher_list) insert end [lindex $fullList $i]
		}
		incr i
	    }
	}
    default {
	    eval "$fh(watcher_list) insert 0 \
		    [$fh(folder_handler) list $option(watcher_format)]"
	}
    }
    set lines [$fh(watcher_list) size]
    set height $option(watcher_max_height)
    if {$lines > $height} {
	set lines $height
	if { -1 == [lsearch -exact \
		[pack slaves $fh(watcher_w)] $fh(watcher_w).scroll]} {
	    pack $fh(watcher_w).scroll -side right -fill y
	}
    } elseif { -1 != [lsearch -exact \
		[pack slaves $fh(watcher_w)] $fh(watcher_w).scroll]} {
	pack forget $fh(watcher_w).scroll
    }
    if !$lines {
	set lines 1
    }
    $fh(watcher_list) configure -height $lines
    $fh(watcher_list) see [expr [$fh(watcher_list) size]-1]
    set info [$fh(folder_handler) info]
    set fh(watcher_size) "[lindex $info 1]/[RatMangleNumber [lindex $info 2]]"

    set oldfocus [focus]
    wm deiconify $fh(watcher_w)
    focus $oldfocus
}


# WatcherWakeMaster --
#
# The user wants us to wake the master up, so do that.
#
# Arguments:
# handler -	The folder handler to which this watcher is connected

proc WatcherWakeMaster {handler} {
    upvar #0 $handler fh

    FolderSelectNext seen $handler 1
    wm deiconify $fh(toplevel)
}
