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

# insert prefix at beginning of lines of text
proc mf_insertprefix { txt } {
    global mf mfp

    $mfp(tmptxt) delete 1.0 end
    $mfp(tmptxt) insert end $txt
    scan [$mfp(tmptxt) index end] %d numLines
    for {set i 1} {$i <= $numLines} {incr i} {
	 $mfp(tmptxt) insert $i.0 $mf(prefix)
    }
}

# record out going message in user defined mail folder
proc mf_recordmsg { txt } {
    global mf mfp

    if {$mf(record)==""} {return 1}

    set date [exec date "+%a %h %d %T 19%y"]
# IF YOUR MAILER STORES MESSAGE WITH DIFFERENT FIRST LINE, YOU WILL
# NEED TO HACK THE LINE BELOW
    $txt insert 1.0 "From $mfp(user) $date\n"
    $txt insert end "\n"
    set rid [open $mf(record) a+]
    puts $rid [$txt get 1.0 end]
    close $rid

    return 1
}

# forward selected message to asked for user
proc mf_forward { } {
    global mf mfp env

    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 sendto [tkgetstring "Forward message to:" $mfp(top) {} $xpos $ypos]
    set sendto [mf_getaddress $sendto]
    if {![llength $sendto]} {return 0}

    mf_insertprefix [$mfp(mesg) get 2.0 end]

    if {$mf(headers) != ""} {$mfp(tmptxt) insert 1.0 "$mf(headers)\n"}
    $mfp(tmptxt) insert 1.0 "Subject: $mfp(cursubj)\nTo: $sendto\n"
    if {[file exists $mf(signature)]} {
	$mfp(tmptxt) insert end "\n[exec cat $mf(signature)]"
    }
    set cmd {exec $mf(deliver) << \[$mfp(tmptxt) get 1.0 end\] &}
    if {[catch "eval $cmd" res]} {
	mf_mailerror $res
	return 0
    }
    mf_recordmsg $mfp(tmptxt)

    $mfp(mstat) configure -text "Mail forwarded to $sendto"
    focus $mfp(mesg)
    return 1
}

proc mf_reply { {type 0} } {
    global mf mfp

    if {$type > 0} {set incmesg 1} else {set incmesg 0}
    if {$type == 2} {set from ""} else {set from $mfp(curfrom)}

    if {[string match {[Rr][Ee]:} [string range $mfp(cursubj) 0 2]]} {
	mf_compose $from $mfp(cursubj) $mfp(curnum) {} $mfp(curcc) $incmesg
    } else {
	mf_compose $from "Re: $mfp(cursubj)" $mfp(curnum) {} $mfp(curcc) $incmesg
    }
}

proc mf_insertfile { filename mfc } {
    global mf mfp

    if {![llength $filename]} {return 1}

    if {![file exists $filename]} {
	mf_mailerror "File $filename does not exist."
	return 0
    }

    if {$mfp(ins_encode) && $mfp(ins_compress)} {
	set cmd "exec cat $filename | $mf(compress) | $mf(encoder) [exec basename $filename].$mf(compress_suffix)"
    } elseif {$mfp(ins_encode)} {
	set cmd "exec $mf(encoder) $filename [exec basename $filename]"
    } else {
	set cmd "exec cat $filename"
    }

    if {$mfp(ins_prefix)} {
        mf_insertprefix "[eval $cmd]\n"
	$mfc.comp.txt insert insert [$mfp(tmptxt) get 1.0 end]
    } else {
    	$mfc.comp.txt insert insert "[eval $cmd]\n"
    }
    focus $mfc.comp.txt
    $mfc.comp.txt yview -pickplace insert
    return 1
}

proc mf_insertset { fs } {
    global mf mfp

    set mfp(ins_compress) 0
    set mfp(ins_encode) 0
    set mfp(ins_prefix) 0

    frame $fs.ins
    checkbutton $fs.ins.encode -text "Uuencode" -variable mfp(ins_encode) \
	-command {if {$mfp(ins_compress) && !$mfp(ins_encode)} {set mfp(ins_compress) 0}}
    checkbutton $fs.ins.compress -text "Compress" -variable mfp(ins_compress) \
	-command {if {!$mfp(ins_encode) && $mfp(ins_compress)} {set mfp(ins_encode) 1}}
    checkbutton $fs.ins.prefix -text "Prefix" -variable mfp(ins_prefix)

    pack append $fs.ins $fs.ins.encode {left fillx} \
	$fs.ins.compress {left fillx} $fs.ins.prefix {left fillx}
    pack after $fs.file $fs.ins {top}
}

proc mf_insertmessages { mfc } {
    set xpos [expr [winfo rootx $mfc]+[winfo width $mfc]/3]
    set ypos [expr [winfo rooty $mfc]+[winfo height $mfc]/3]
    mf_insertmesg [tkgetstring {Message numbers to insert:} $mfc \
	{} $xpos $ypos] $mfc
}

proc mf_altedit { tw } {
    global mf mfp

    set tfile [tmpfile tkmail]
    if {![regsub -all {%F} $mf(altedit) "$tfile" tcmd]} {
        set tcmd "$mf(altedit) $tfile"
    }
    
    set cmd "exec cat > $tfile << \\\[$tw get 1.0 end\\\]"
    if {[catch "eval $cmd" res]} {
        mf_mailerror $res
        return 0
    }

    $tw configure -state disabled
    set cmd "exec $mfp(tkmaillib)/altedit.tk \\\{[winfo name .]\\\} \
		  $tw $tfile {$tcmd} &"
    if {[catch "eval $cmd" res]} {
        mf_mailerror $res
        return 0
    }

}

proc mf_togglecc { mfc } {
    global mf mfp

    if {$mf(showcc)} {
        bind $mfc.subj.ent <Tab> "focus $mfc.cc.ent"
        bind $mfc.subj.ent <Return> "focus $mfc.cc.ent"
        pack after $mfc.subj $mfc.cc {top fillx} \
            $mfc.bcc {top fillx}
    } else {
        bind $mfc.subj.ent <Tab> "focus $mfc.comp.txt"
        bind $mfc.subj.ent <Return> "focus $mfc.comp.txt"
	pack unpack $mfc.cc
	pack unpack $mfc.bcc
    }

}

proc mf_insertmesg {mesgs mfc {mfile ""}} {
    global mf mfp

    if {![llength $mfile]} {set mfile $mfp(file)}

    foreach ndx $mesgs {

	set res [mf_mailcmd "$ndx"]
	if {$res == ""} {
	    mf_mailerror "Error getting message $ndx in $mfp(file)"
	    return 0
	} else {
	    mf_insertprefix $res
	    $mfc.comp.txt insert insert "\n[$mfp(tmptxt) get 1.0 end]\n"
	}

    }
    focus $mfc.comp.txt
    $mfc.comp.txt yview "insert-5l"
    return 1
}

proc mf_sendmesg { mfc } {
    global mf mfp env

    # check if there are any headers in text widget and
    # insert a blank line if not
    set line [$mfc.comp.txt get 1.0 "1.0 lineend"]
    if {![regexp {^[!-~]*:[ -~]*} $line trash]} {
	$mfc.comp.txt insert 1.0 "\n"
    }

    set sendto [$mfc.to.ent get]
    set sendto [mf_getaddress $sendto]
    set subject [$mfc.subj.ent get]
    if {![llength $sendto] || ![llength $subject]} {
	mf_mailerror "No To: or Subject: given!"
	return 0
    }
    if {$mf(showcc)} {
	set sendalso [$mfc.bcc.ent get]
	if {$sendalso != ""} {
	    set sendalso [mf_getaddress $sendalso]
	    $mfc.comp.txt insert 1.0 "Bcc: $sendalso\n"
	}
	set sendalso [$mfc.cc.ent get]
	if {$sendalso != ""} {
	    set sendalso [mf_getaddress $sendalso]
	    foreach addr $mf(alternates) {
		regsub -all $addr $sendalso {} sendalso
	    }
	    $mfc.comp.txt insert 1.0 "Cc: $sendalso\n"
	}
    }

    $mfc.comp.txt insert 1.0 "Subject: $subject\nTo: $sendto\n"
    set cmd {exec $mf(deliver) << \[$mfc.comp.txt get 1.0 end\] &}
    if {[catch "eval $cmd" res]} {
	mf_mailerror $res
	return 0
    }

    if {$mfp(dorecord)} {mf_recordmsg $mfc.comp.txt}
    if {$mf(savesend)} { set mfp(savesendtxt) [$mfc.comp.txt get 1.0 end] }

    destroy $mfc
    $mfp(mstat) configure -text "Mail sent to $sendto"
    focus $mfp(mesg)
    return 1
}

proc mf_cancelmesg { mfc } {
    global mf mfp

    if {$mf(savesend)} { set mfp(savesendtxt) [$mfc.comp.txt get 1.0 end] }

    destroy $mfc
    $mfp(mstat) configure -text "Compose cancelled"
    focus $mfp(mesg)
    return 1
}

# sendto: address for To: field
# subject: text for Subject: field
# mesg: number of message that was selected when compose called
# headers: headers to put into text
# curcc: addresses for Cc: field
# incmesg: 1 to include current mesg, 2 to copy whatever is in mfp(tmptxt)
proc mf_compose { {sendto "" } {subject ""} {mesg ""} {headers ""} \
		  {curcc ""} {incmesg 0} } {
    global mf mfp

    set cnt 0
    while {[winfo exists .mfc${cnt}]} {incr cnt}
    set mfc .mfc${cnt}

    toplevel $mfc -class TkCompose
    wm iconbitmap $mfc "@$mf(writebmp)"
    wm iconname $mfc "Compose"
    wm title $mfc "Compose ($mfc)"
    wm geometry $mfc $mf(compgeom)
    wm minsize $mfc 400 400
    wm protocol $mfc WM_DELETE_WINDOW mf_cancelmesg

    frame $mfc.menu -relief raised -bd 2
    menubutton $mfc.menu.file -text {File} -menu $mfc.menu.file.m
    menubutton $mfc.menu.edit -text {Edit} -menu $mfc.menu.edit.m

    menu $mfc.menu.file.m
    $mfc.menu.file.m add command -label {Insert File . . .} -accelerator {[i]} \
        -command "fileselect mf_insertfile {File:} 0 mf_insertset $mfc $mfc"
    $mfc.menu.file.m add command -label {Insert Messages . . .} \
	-accelerator {[m]} -command "mf_insertmessages $mfc"
    $mfc.menu.file.m add separator
    $mfc.menu.file.m add command -label {Send} -accelerator {[s]} \
        -command "mf_sendmesg $mfc"
    $mfc.menu.file.m add command -label {Cancel} -accelerator {[q]} \
        -command "mf_cancelmesg $mfc"
    $mfc.menu.file.m add separator
    $mfc.menu.file.m add command -label {Alternate Editor} -accelerator {[a]} \
        -command "mf_altedit $mfc.comp.txt"

    menu $mfc.menu.edit.m
    $mfc.menu.edit.m add command -label {Cut} -accelerator {[x]} \
        -command "mf_cutedit $mfc.comp.txt"
    $mfc.menu.edit.m add command -label {Copy} -accelerator {[c]} \
        -command "mf_copyedit $mfc.comp.txt"
    $mfc.menu.edit.m add command -label {Paste} -accelerator {[v]} \
        -command "mf_pasteedit $mfc.comp.txt"
    $mfc.menu.edit.m add separator
    if {$mf(ispell)} {
        $mfc.menu.edit.m add command -label {Ispell} \
            -command "tkispell_text $mfc.comp.txt"
    }
    $mfc.menu.edit.m add command -label {TCL Evaluate Sel} \
	-command {
	    if {[catch {eval [selection_if_any]} res]} {
		mf_mailerror $res
		return 0
	    }
	}
    $mfc.menu.edit.m add command -label {UNIX Pipe Sel . . .} \
	-command "mf_pipesel $mfc.comp.txt"
    $mfc.menu.edit.m add separator
    $mfc.menu.edit.m add checkbutton -label "Show Cc/Bcc" \
	-variable mf(showcc) -command "mf_togglecc $mfc"
    if {$mf(record) != ""} {
        set mfp(dorecord) 1
        $mfc.menu.edit.m add checkbutton -label "Record Mesg" \
		    -variable mfp(dorecord)
    } else {
	set mfp(dorecord) 0
    }


    pack append $mfc.menu $mfc.menu.file {left} $mfc.menu.edit {left}

    frame $mfc.to
    label $mfc.to.lbl -text "To:" -width 8 -anchor w
    entry $mfc.to.ent -relief sunken
    label $mfc.to.dum -text " " -width 1
    pack append $mfc.to $mfc.to.lbl {left} \
	$mfc.to.ent {left pady 8 expand fillx} $mfc.to.dum {left}
    $mfc.to.ent insert end $sendto
    bind $mfc.to.ent <Tab> "focus $mfc.subj.ent"
    bind $mfc.to.ent <Return> "focus $mfc.subj.ent"

    frame $mfc.subj
    label $mfc.subj.lbl -text "Subject:" -width 8 -anchor w
    entry $mfc.subj.ent -relief sunken
    label $mfc.subj.dum -text " " -width 1
    pack append $mfc.subj $mfc.subj.lbl {left} \
	$mfc.subj.ent {left pady 8 expand fillx} $mfc.subj.dum {left}
    $mfc.subj.ent insert end $subject

    if {$mf(showcc)} {
	bind $mfc.subj.ent <Tab> "focus $mfc.cc.ent"
	bind $mfc.subj.ent <Return> "focus $mfc.cc.ent"
    } else {
	bind $mfc.subj.ent <Tab> "focus $mfc.comp.txt"
	bind $mfc.subj.ent <Return> "focus $mfc.comp.txt"
    }

    frame $mfc.cc
    label $mfc.cc.lbl -text "Cc:" -width 8 -anchor w
    entry $mfc.cc.ent -relief sunken
    label $mfc.cc.dum -text " " -width 1
    pack append $mfc.cc $mfc.cc.lbl {left} \
	$mfc.cc.ent {left pady 8 expand fillx} $mfc.cc.dum {left}
    $mfc.cc.ent insert end $curcc
    bind $mfc.cc.ent <Tab> "focus $mfc.bcc.ent"
    bind $mfc.cc.ent <Return> "focus $mfc.bcc.ent"

    frame $mfc.bcc
    label $mfc.bcc.lbl -text "Bcc:" -width 8 -anchor w
    entry $mfc.bcc.ent -relief sunken
    label $mfc.bcc.dum -text " " -width 1
    pack append $mfc.bcc $mfc.bcc.lbl {left} \
	$mfc.bcc.ent {left pady 8 expand fillx} $mfc.bcc.dum {left}
    bind $mfc.bcc.ent <Tab> "focus $mfc.comp.txt"
    bind $mfc.bcc.ent <Return> "focus $mfc.comp.txt"

    frame $mfc.comp
    scrollbar $mfc.comp.yscroll -command "$mfc.comp.txt yview" -relief raised
    text $mfc.comp.txt \
	-yscroll "bind_textscrollset $mfc.comp.yscroll $mfc.comp.txt" \
	-relief sunken -bd 2 -font $mf(tfont) -bg $mf(tcolor) -fg $mf(fcolor)

    bind $mfc.comp.txt <Meta-KeyPress-i> "$mfc.menu.file.m invoke 0"
    bind $mfc.comp.txt <Meta-KeyPress-m> "$mfc.menu.file.m invoke 1"
    bind $mfc.comp.txt <Meta-KeyPress-s> "$mfc.menu.file.m invoke 3"
    bind $mfc.comp.txt <Meta-KeyPress-q> "$mfc.menu.file.m invoke 4"
    bind $mfc.comp.txt <Meta-KeyPress-a> "$mfc.menu.file.m invoke 6"
    bind $mfc.comp.txt <Meta-Tab> "focus $mfc.to.ent"

    if {$mf(leftscroll)} {
	pack append $mfc.comp $mfc.comp.yscroll {left filly} \
	    $mfc.comp.txt {left expand fill}
    } else {
	pack append $mfc.comp $mfc.comp.txt {left expand fill} \
	    $mfc.comp.yscroll {left filly}
    }

    frame $mfc.bb
    button $mfc.bb.mesg -text "Insert Message" -command "mf_insertmesg $mesg $mfc $mfp(file)"
    button $mfc.bb.file -text "Insert File" -command "$mfc.menu.file.m invoke 0"
    button $mfc.bb.alt -text "Alt Editor" -command "$mfc.menu.file.m invoke 6"
    button $mfc.bb.send -text "Send" -command "$mfc.menu.file.m invoke 3"
    button $mfc.bb.cancel -text "Cancel" -command "$mfc.menu.file.m invoke 4"

    pack append $mfc.bb $mfc.bb.mesg {left expand fill} \
	$mfc.bb.file {left expand fill} \
	$mfc.bb.alt {left expand fill} \
	$mfc.bb.send {left expand fill} \
	$mfc.bb.cancel {left expand fill}

    if {$mf(showcc)} {
	pack append $mfc $mfc.menu {top fillx} $mfc.to {top fillx} \
	    $mfc.subj {top fillx} $mfc.cc {top fillx} \
	    $mfc.bcc {top fillx} $mfc.comp {top expand fill} \
	    $mfc.bb {top fillx}
    } else {
	pack append $mfc $mfc.menu {top fillx} $mfc.to {top fillx} \
	    $mfc.subj {top fillx} $mfc.comp {top expand fill} \
	    $mfc.bb {top fillx}
    }

    if {[info proc mf_compose_hook]!=""} {
	mf_compose_hook $mfc
    }

    # Put in text requested
    if {[llength $headers] != 0} {$mfc.comp.txt insert end "$headers\n"}
    if {$incmesg != 3} {
	if {[llength $mf(headers)] != 0} {
	    $mfc.comp.txt insert end "$mf(headers)\n"
	}
	if {$incmesg==1} {mf_insertmesg $mesg $mfc $mfp(file)}
	if {$incmesg==2} {
	    $mfc.comp.txt insert end "\n[$mfp(tmptxt) get 1.0 end]\n"
	}
	set tndx [$mfc.comp.txt index end]
	if {[file exists $mf(signature)]} {
	    $mfc.comp.txt insert end "\n[exec cat $mf(signature)]"
	}
	$mfc.comp.txt mark set insert $tndx
    }
    $mfc.comp.txt yview -pickplace insert
    
    if {[$mfc.to.ent get]==""} {
	focus $mfc.to.ent
    } else {
	focus $mfc.comp.txt
    }

    if {$mf(autoaltedit)} {$mfc.menu.file.m invoke 6}
}

