# mail.tk - support file for TkMail (accessed through tclIndex)
#
# $Header: /a/juno/u1/ra/raines/src/tk/tkmail/mail.tk,v 1.5 1993/09/03 16:52:49 raines Exp $

proc mf_quickdecode { tw } {
    global mf mfp env

    set bndx [TextSearch $tw {^begin [0-9]* } 1.0 0]
    if {$bndx == 0} {
	mf_mailerror "Can't find uuencode beginning."
	return 0
    }
    set endx [TextSearch $tw "^end" $bndx 0]
    if {$endx == 0} {
	mf_mailerror "Can't find uuencode ending."
	return 0
    }
    set bndx [$tw index "$bndx linestart"]
    set endx [$tw index "$endx lineend + 1 c"]

    set tdir [pwd]
    cd $mf(pipedir)
    set cmd "exec uudecode << \\\[$tw get $bndx $endx\\\]\n"
    if {[catch "eval $cmd" res]} {
        mf_mailerror $res
        return 0
    }
    cd $tdir

    set file [lrange [$tw get $bndx "$bndx lineend"] 2 end]
    $mfp(mstat) configure -text "Uudecoded $file"
    return 1
}

proc mf_searchtxt { tw getnew } {
    global mf mfp

    set xpos [expr [winfo rootx $mfp(top)]+[winfo width $mfp(top)]/3]
    set ypos [expr [winfo rooty $mfp(top)]+[winfo height $mfp(top)]/3]
    if {$getnew || $mfp(searchstr) == ""} {
	set mfp(searchstr) [tkgetstring "Search for:" [winfo toplevel $tw] \
	    $mfp(searchstr) $xpos $ypos]
	if {$mfp(searchstr) == ""} {return 0 }
    }
    focus $tw

    if {![TextSearch $tw $mfp(searchstr) [$tw index insert]]} {
	eval $mf(beep); return 0
    }
    return 1
}

proc mf_delmesg { } {
    global mf mfp

    set dsel [$mfp(head) curselection]
    if {$dsel == ""} {
        eval $mf(beep)
        flush stderr
        $mfp(mstat) configure -text "No messages to delete"
        return 0
    }
    set ndx [lindex $dsel 0]

    foreach tndx [lreverse $dsel] {    
	lappend mfp(delmesg) [mf_head2num $tndx]
	$mfp(head) delete $tndx
	if {[$mfp(head) size] == 0} {
	    set mfp(curnum) 0
	    mf_dispmesg ""
	    return 1
	}
    }

    if {$ndx < [$mfp(head) size]} {
        $mfp(head) select from $ndx
    } else {
        $mfp(head) select from [expr [$mfp(head) size]-1]
    }
    set mfp(curnum) [mf_head2num [$mfp(head) cursingle]]
    mf_dispmesg $mfp(curnum)
    $mfp(head) yview -pickplace $ndx

    return 1
}

proc mf_undelete { } {
    global mf mfp

    set mfp(delmesg) ""
    mf_setupfolder $mfp(file) $mfp(curnum)
    return 1
}

proc mf_checkfile {filename} {
    global mf mfp

    if {![file writable [file dirname $filename]]} {
        mf_mailerror "Directory [file dirname $filename] not writable or doesn't exist"
	return 0
    }

    if {[file exists $filename]} {

        if {![file writable $filename]} {
	    mf_mailerror "File $filename not writable"
	    return 0
	}
	set xpos [expr [winfo rootx $mfp(top)]+[winfo width $mfp(top)]/3]
	set ypos [expr [winfo rooty $mfp(top)]+[winfo height $mfp(top)]/3]
	if {![tkgetokay "Append to existing file ($filename)?" $mfp(top) $xpos $ypos]} {
	    return 0
	}
    }
    return 1
}

proc mf_save { filename type } {
    global mf mfp

    if {![mf_checkfile $filename]} { return 0 }
    case $type {
	{ mesg } {
	    set res [mf_mailcmd "s [$mfp(head) curselection 1] $filename"]
	    if {$res == ""} {
		mf_mailerror "Error saving message(s) to $file
		return 0
	    } }
	{ sel } { 
		set fid [open $filename a]
		puts $fid "\n[selection get]"
		close $fid }
        default { mf_mailerror "Invalid save type"; return 0}
    }

    $mfp(mstat) configure -text $res
    return 1
}

proc mf_copymesg { filename } {
    global mf mfp
    
    if {![file exists $filename]} {
	set xpos [expr [winfo rootx $mfp(top)]+[winfo width $mfp(top)]/3]
	set ypos [expr [winfo rooty $mfp(top)]+[winfo height $mfp(top)]/3]
	if {[tkgetokay "Create new folder ($filename)?" $mfp(top) $xpos $ypos]} {
	    set cmd "exec touch $filename"
	    if {[catch "eval $cmd" res]} {
		mf_mailerror $res
		return 0
	    }
	} else {
	    return 0
	}
    }

    set res [mf_mailcmd "s [$mfp(head) curselection 1] $filename"]
    if {$res == ""} {
	mf_mailerror "Error saving messages to $filename"
	return 0
    }
    $mfp(mstat) configure -text $res
    return 1
}

proc mf_movemesg { filename } {
    global mf mfp
    
    if {![file exists $filename]} {
	set xpos [expr [winfo rootx $mfp(top)]+[winfo width $mfp(top)]/3]
	set ypos [expr [winfo rooty $mfp(top)]+[winfo height $mfp(top)]/3]
	if {[tkgetokay "Create new folder ($filename)?" $mfp(top) $xpos $ypos]} {
	    set cmd "exec touch $filename"
	    if {[catch "eval $cmd" res]} {
		mf_mailerror $res
		return 0
	    }
	} else {
	    return 0
	}
    }

    set res [mf_mailcmd "s [$mfp(head) curselection 1] $filename"]
    if {$res == ""} {
	mf_mailerror "Error moving messages to $filename"
	return 0
    }

    $mfp(mstat) configure -text $res
    mf_delmesg
    return 1
}

proc mf_print { type } {
    global mf mfp

    set xpos [expr [winfo rootx $mfp(top)]+[winfo width $mfp(top)]/3]
    set ypos [expr [winfo rooty $mfp(top)]+[winfo height $mfp(top)]/3]
    set pcmd [tkgetstring "Print command (use %F for filename):" $mfp(top) \
	$mf(print) $xpos $ypos]
    if {![llength $pcmd]} {return 0}
    set mf(print) $pcmd

    set tfile [tmpfile tkmail]
    if {![file writable $tfile]} {
        mf_mailerror "File $tfile not writable"
	return 0
    }
    case $type {
	{ mesg } { exec cat > $tfile << [$mfp(mesg) get 1.0 end]}
	{ sel } { exec cat > $tfile << [selection get] }
	default { 
	    mf_mailerror "Invalid print type"; return 0 }
    }

    if {![regsub -all {%F} $pcmd "$tfile" pcmd]} {
        set pcmd "$pcmd $tfile" 
    }
    set cmd {exec $pcmd}
    if {[catch "eval $cmd" res]} {
	mf_mailerror $res
	return 0
    }
    $mfp(mstat) configure -text $res

    set cmd {exec /bin/rm $tfile}
    if {[catch "eval $cmd" res]} {
	mf_mailerror $res
	return 0
    }
    
    return 1
}

proc mf_disphelp {section} {
    global mf mfp
    set w $mfp(top)_help

    if { ![winfo exists $w] } {
	toplevel $w
	wm transient $w $mfp(top)
	wm title $w "TkMail v$mfp(version) Help"
        text $w.txt -cursor left_ptr -relief sunken \
	    -yscroll "bind_textscrollset $w.scr $w.txt" \
	    -font $mf(tfont) -bg $mf(tcolor)
	scrollbar $w.scr -command "$w.txt yview" -relief raised
	button $w.close -text "Close" \
	    -command "wm withdraw $w; focus $mfp(head)"
	pack append $w $w.close {bottom fillx} $w.scr {left filly} \
		$w.txt {left expand fill}

        bind $w.txt <Meta-c> "$w.close invoke"		
    } else { wm deiconify $w }

    $w.txt configure -state normal
    $w.txt delete 0.0 end
    $w.txt insert end $mfp(readme)
    $w.txt configure -state disabled

    if {$section != "TOP"} {TextSearch $w.txt ^$section}
    focus $w.txt
}    

proc mf_dispopt { } {
    global mf mfp
    set w $mfp(top)_opt

    if { ![winfo exists $w] } {
	toplevel $w
	wm transient $w $mfp(top)
	wm title $w "TkMail v$mfp(version) Options"
        text $w.txt -cursor left_ptr -relief sunken \
	    -yscroll "bind_textscrollset $w.scr $w.txt" \
	    -font $mf(tfont) -bg $mf(tcolor)
	scrollbar $w.scr -command "$w.txt yview" -relief raised
	frame $w.bb
	button $w.bb.accept -text "Accept" \
	    -command "mf_evalopt $w 0; wm withdraw $w"
	button $w.bb.save -text "Accept & Save" \
	    -command "mf_evalopt $w 1; wm withdraw $w"
	button $w.bb.cancel -text "Cancel" \
	    -command "grab release $w; wm withdraw $w"
	pack append $w.bb $w.bb.accept { left expand fillx } \
		$w.bb.save { left expand fillx } \
		$w.bb.cancel { left expand fillx }
	pack append $w $w.bb {bottom expand fillx} $w.scr {left filly} \
		$w.txt {left expand fill}

	bind $w.txt <Meta-a> "$w.bb.accept invoke"
	bind $w.txt <Meta-s> "$w.bb.save invoke"
	bind $w.txt <Meta-c> "$w.bb.cancel invoke"

    } else { wm deiconify $w }

    after 200 grab set $w
    $w.txt delete 0.0 end
    $w.txt insert end [info body mf_defaultset]

    scan [$w.txt index end] %d numLines
    for {set i 0} {$i <= $numLines} {incr i} {
	set line [$w.txt get $i.0 "$i.0 lineend"]
	if {[string first "  set mf" $line] != -1} {
	    set var [lindex $line 1]
	    set val [eval "set $var"]
	    $w.txt delete $i.0 "$i.0 lineend"
	    $w.txt insert $i.0 "  set $var {$val}"
	}
    }
    focus $w.txt
}    

proc mf_evalopt { w {save 0} } {
    global mf mfp env

    grab release $w
    eval [$w.txt get 1.0 end]

    if {$save} {
	set varlist ""

	$w.txt delete 1.0 end
	if {[file exists $mfp(setfile)]} {

	    $w.txt insert 1.0 [exec cat $mfp(setfile)]
	    scan [$w.txt index end] %d numLines
	    for {set i 0} {$i <= $numLines} {incr i} {
		set line [$w.txt get $i.0 "$i.0 lineend"]
		if {[regexp {([ \t]*)set[ \t]*(mf\(([0-9a-z_]*)\))} \
			    $line trash sp var name]} {
		    set val [eval "set $var"]
		    lappend varlist $name
		    $w.txt delete $i.0 "$i.0 lineend"
		    $w.txt insert $i.0 "${sp}set $var {$val}"
		}
	    }

	} else {
	    set mfp(setfile) $env(HOME)/.tkmail
        }

	foreach name [array names mf] {
	    if {[lsearch $varlist $name] == -1} {
		set val [eval "set mf($name)"]
		$w.txt insert end "\n  set mf($name) {$val}"
	    }
	}
	$w.txt insert end "\n"
	exec cat > $mfp(setfile) << [$w.txt get 1.0 end]
    }

    mf_setupfolder $mfp(file) [$mfp(head) cursingle]
    $mfp(head) configure -height $mf(headheight) \
	-font $mf(tfont) -bg $mf(tcolor)
    $mfp(top).mesg.txt configure -font $mf(tfont) -bg $mf(tcolor) \
	-fg $mf(fcolor)

    focus $mfp(mesg)
    return 1
}

proc mf_pipesel { tw } {
    global mf mfp env

    set tmp [pwd]

    set xpos [expr [winfo rootx $mfp(top)]+[winfo width $mfp(top)]/3]
    set ypos [expr [winfo rooty $mfp(top)]+[winfo height $mfp(top)]/3]
    set cmd [tkgetstring "Pipe Command:" $mfp(top) {} $xpos $ypos mf_pipeselset]
    if {$cmd == ""} { return 0 }
    cd $mf(pipedir)
    set cmd "exec $cmd << \\\[selection_if_any\\\]"
    if {[catch "eval $cmd" res]} {
        mf_mailerror $res
        return 0
    }

    $mfp(mstat) configure -text "Pipe command: $cmd"
    if {$mf(pipe_res) == 1} {
        if {![catch "set tndx [$tw index sel.first]"]} {
	    $tw delete sel.first sel.last
	} else { set tndx [$tw index insert] }
	$tw insert $tndx "$res\n"
    } elseif {$mf(pipe_res) == 2} {
        if {[catch "set tndx [$tw index sel.last+1c]"]} {
            set tndx [$tw index insert ]
        }
        $tw insert $tndx "$res\n"
    }
	
    cd $tmp
    return 1
}

proc mf_pipeselset { sw } {
    global mf mfp env

    set mf(pipe_res) 0

    frame $sw.pipe
    label $sw.pipe.lbl -text "Do what with results?" -pady 5
    radiobutton $sw.pipe.discard -text "Discard" -variable mf(pipe_res) \
	-value 0
    radiobutton $sw.pipe.replace -text "Replace" -variable mf(pipe_res) \
	-value 1
    radiobutton $sw.pipe.append -text "Append" -variable mf(pipe_res) \
	-value 2

    frame $sw.pdir
    label $sw.pdir.lbl -text "Execute in what directory?" -pady 5
    entry $sw.pdir.ent -relief sunken -textvariable mf(pipedir)

    pack append $sw.pipe $sw.pipe.lbl {top fillx}  \
	$sw.pipe.discard {left fillx} \
        $sw.pipe.replace {left fillx} $sw.pipe.append {left fillx}
    pack append $sw.pdir $sw.pdir.lbl {top fillx} \
	$sw.pdir.ent {top fillx}
    pack after $sw.ent $sw.pipe {top} $sw.pdir {top expand fillx}
}

