# postcomp.tcl --
#
# This file contains the code which handles the composing of messages
# from within the compose window
#
#  Postilion software and its included text and images
#  Copyright (C) 1998 Nic Bernstein
#
#  The full text of the legal notices is contained in the file called
#  COPYING, 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.

# PostComposeReply --
#
# Build a reply to the given message and let the user add his text
#
# Arguments:
# handler -     The parent compose session
# fhandler -    The parent folder window
# edit_text -   '1' if we should place the cursor in the text field.
# who      -    Whether to reply to sender or all
# quote    -    Whether to quote the original body or not (1=no)
proc PostComposeReply {handler fhandler edit_text who quote} {
    global t option b
    upvar #0 $handler mh
    upvar #0 $fhandler fh

    # Get the current message from the active folder window
    set mh(curmsg) $fh(current)

    # Select from mulitple messages, if necessary
    set msg [ComposeChoose $mh(curmsg) $t(reply_to_which)]

    # Bail if there is nothing to reply to
    if ![string length $msg] {
	return
    }

    # Get a handler to a reply buffer
    set reply [$msg reply all]
    upvar #0 $reply rh

    # Set the fields for the active compose buffer to the reply buffer
    if [info exists rh(to)] {
	set w $mh(headerFrame).to_entry.t
	set mh(to) $rh(to)
	$w insert end $mh(to)
	ComposeHandleHE $w $mh(to_handler)
    }
    if [info exists rh(subject)] {
	set mh(subject) $rh(subject)
    }
    if [info exists rh(in_reply_to)] {
	set mh(in_reply_to) $rh(in_reply_to)
    }
    set pos [$mh(toplevel).body.text index insert]
    if !{$quote} {
	if [info exists rh(data)] {
	    if ![catch {$fh(text) index sel.first} top] {
		set bot [$fh(text) index sel.last]
		set data [string range $rh(data) 0 [string first "\n" $rh(data)]]
		for {set i [expr int($top)]} {$i<$bot} {incr i} {
		    if {$i == [expr int($top)]} {
			set data "$data$option(reply_lead) [$fh(text) get sel.first $i.end] \n"
		    } elseif {$i == [expr int($bot)]} {
			set data "$data$option(reply_lead) [$fh(text) get $i.0 $bot] \n"
		    } else {
			set data "$data$option(reply_lead) [$fh(text) get $i.0 $i.end] \n"
		    }
		}
		set mh(data) $data
	    } else {
		set mh(data) $rh(data)
	    }
	    $mh(toplevel).body.text insert $pos $mh(data) noWrap
	    if { 1 == $edit_text } {
		$mh(toplevel).body.text mark set insert end
	    } else {
		$mh(toplevel).body.text mark set insert $pos}
	} else {
	    $mh(toplevel).body.text mark set insert $pos
	}
    }

    # Set the answer flag for this compose session
    set mh(answer) 1

    if [string compare $who all] {
	# Reconfigure the button to serve the Reply-All function
	$mh(toplevel).buttons.reply configure \
	    -command "PostReplyAll $handler $reply"
	set b($mh(toplevel).buttons.reply) reply_all
	if $option(image_buttons) {
	    $mh(toplevel).buttons.reply configure -image rallbut
	} else {
	    $mh(toplevel).buttons.reply configure -text $t(reply_all)
	}
	RatBind $mh(toplevel) compose_key_replys {}
	RatBind $mh(toplevel) compose_key_replya "PostReplyAll $handler $reply"
	RatBind $mh(toplevel) compose_key_replyq {}
	RatBind $mh(toplevel) compose_key_replyqa {}
    } else {
	PostReplyAll $handler $reply
	RatBind $mh(toplevel) compose_key_replys {}
	RatBind $mh(toplevel) compose_key_replya {}
	RatBind $mh(toplevel) compose_key_replyq {}
	RatBind $mh(toplevel) compose_key_replyqa {}
    }

    $mh(toplevel).buttons.forward configure -state disabled

    return
}

# PostReplyAll --
#
# Add the cc: and bcc: records from a message to the active compose buffer
#
# Arguments:
# handler -     the handler for the compose session
# reply -       The handler for the reply buffer
proc PostReplyAll { handler reply } {
    upvar #0 $reply rh
    upvar #0 $handler mh

    if [info exists rh(cc)] {
	set w $mh(headerFrame).cc_entry.t
	set mh(cc) $rh(cc)
	if [winfo exists $w] {
	    $w insert end $mh(cc)
	    ComposeHandleHE $w $mh(cc_handler)
	}
    }

    # Disable further action by the reply button
    RatBind $mh(toplevel) compose_key_replya {}
    $mh(toplevel).buttons.reply configure -state disabled
}

# PostComposeForwardInline --
#
# Forward a message and keep the first part inline if it is a text part.
#
# Arguments:
# handler -     Handler for the active compose session
# fhandler -    Handler for the active folder browser
# msg -		Message to forward

proc PostComposeForwardInline { handler fhandler } {
    global idCnt option t
    upvar #0 $handler mh
    upvar #0 $fhandler fh

    set mh(curmsg) $fh(current)
    set msg [ComposeChoose $mh(curmsg) $t(forward_which)]
    if ![string length $msg] {
	return 0
    }

    foreach header [$msg headers full] {
	set name [string tolower [lindex $header 0]]
	switch $name {
	    subject	{ set mh(subject) "Fwd: [lindex $header 1]" }
	    description	{ set hd(description) [lindex $header 1] }
	}
	if { -1 != [lsearch [string tolower $option(show_header_selection)] \
			$name]} {
	    regsub -all -- - $name _ name
	    set inline_header($name) [lindex $header 1]
	}
    }

    # Find if there is a bodypart which we can inline (a text part)
    set body [$msg body]
    set type [string tolower [$body type]]
    set inline {}
    set attach $body
    if { (![string compare text [lindex $type 0]]
	    && ![string compare plain [lindex $type 1]])
	|| (![string compare message [lindex $type 0]]
		&& ![string compare rfc822 [lindex $type 1]])} {
	set inline $body
	set attach {}
    } elseif {![string compare multipart [lindex $type 0]]} {
	set children [$body children]
	set type [string tolower [[lindex $children 0] type]]
	if {![string compare text [lindex $type 0]]
		&& ![string compare plain [lindex $type 1]]} {
	    set inline [lindex $children 0]
	    set attach [lrange $children 1 end]
	} else {
	    set inline {}
	    set attach $children
	}
    }

    # Now we are ready to start constructing the new message
    set bhandler composeM[incr idCnt]
    upvar #0 $bhandler bh
    set mh(body) $bhandler
    set bh(type) text
    set bh(subtype) plain
    if [string length $inline] {
	set bh(encoding) [$inline encoding]
	set bh(parameter) [$inline params]
	set bh(id) [$inline id]
	set bh(description) [$inline description]
	set preface "\n\n$option(forwarded_message)\n"
	set length 5
	foreach f $option(show_header_selection) {
	    if { $length < [string length $f]} {
		set length [string length $f]
	    }
	}
	foreach field $option(show_header_selection) {
	    regsub -all -- - [string tolower $field] _ f
	    if [info exists inline_header($f)] {
		if [info exists t($f)] {
		    set name $t($f)
		} else {
		    set name $field
		}
		set preface [format "%s%${length}s: %s\n" $preface $name \
			$inline_header($f)]
	    }
	}
	set mh(data) "${preface}\n[$inline data 0]"
    }
    foreach child $attach {
	set chandler composeC[incr idCnt]
	upvar #0 $chandler ch
	lappend bh(children) $chandler

	set type [string tolower [$child type]]
	set ch(type) [lindex $type 0]
	set ch(subtype) [lindex $type 1]
	set ch(encoding) [$child encoding]
	set ch(parameter) [$child params]
	set ch(id) [$child id]
	set ch(description) [$child description]
	if {![info exists mh(data)] && ![string compare text $ch(type)]} {
	    set mh(data) [$child data 0]
	} else {
	    set ch(filename) [RatTildeSubst $option(send_cache)/rat.[RatGenId]]
	    set fileh [open $ch(filename) w 0600]
	    $child saveData $fileh 1 0
	    close $fileh
	    set ch(removeFile) 1
	    lappend mh(attachmentList) $chandler
	    if ![catch {info exists $mh(attachmentListWindow)}] {
		$mh(attachmentListWindow) insert end $ch(description)
	    }
	}
    }
    if [info exists mh(data)] {
	set pos [$mh(toplevel).body.text index insert]
	$mh(toplevel).body.text insert $pos $mh(data) noWrap
	$mh(toplevel).body.text mark set insert $pos
    }

    # Disable the reply and forward buttons
    $mh(toplevel).buttons.reply configure -state disabled
    $mh(toplevel).buttons.forward configure -state disabled

    return
}

proc PostReqDSN {handler} {
    upvar #0 $handler mh
    set $mh(request_dsn) 1
    $mh(toplevel).buttons.recp configure -state disabled
}

proc PostPGPEncrypt {handler} {
    upvar #0 $handler mh
    set mh(pgp_encrypt) 1
    $mh(toplevel).buttons.crypt configure -state disabled
}

proc PostPGPSign {handler} {
    upvar #0 $handler mh
    set mh(pgp_sign) 1
    $mh(toplevel).buttons.sign configure -state disabled
}
