# $Id: quotelastmsg.tcl 1513 2008-10-15 17:39:41Z sergei $
# "Quote last message" chat plugin for Tkabber --
# Allows to copy message located at the bottom of the
# conversation log in the chat window to the input box
# of that chat window.
#
# Written by Konstantin Khomoutov <flatworm@users.sourceforge.net>
# See license.terms for the terms of distribution.
# See README for usage details.

event add <<QuoteLastMessage>> <Alt-q>
event add <<QuoteLastMessage>> <Meta-q>

namespace eval quotelastmsg {
    variable state
    variable options

    ::msgcat::mcload [file join [file dirname [info script]] msgs]

    custom::defgroup Plugins [::msgcat::mc "Plugins options."] -group Tkabber

    custom::defgroup {Quote Last Message} \
	[::msgcat::mc "Quote Last Message plugin options.\
	    This plugin provides a way to copy a message located\
	    at the bottom of a chat window conversation log\
	    to the input box of that chat window."] \
	-group Plugins \
	-group Chat

    custom::defvar options(format) {>> %m} \
	[::msgcat::mc "Format string used to quote the message.\
	    Format specifer \"%m\" is replaced by the whole message\
	    being quoted. Format specifier \"%%\" is replaced by\
	    a single character \"%\"."] \
	-group {Quote Last Message} \
	-type string

    hook::add open_chat_post_hook \
	[namespace current]::setup_chat_window
    hook::add draw_message_post_hook \
	[namespace current]::on_message_drawn
}

proc quotelastmsg::setup_chat_window {chatid type} {
    variable state

    set iw [::chat::input_win $chatid]
    bind $iw <<QuoteLastMessage>> [list [namespace current]::quote $chatid]

    set cw [::chat::chat_win $chatid]
    set state($cw,last) 1.0
    bind $cw <Destroy> +[list [namespace current]::cleanup $cw %W]
}

proc quotelastmsg::cleanup {w1 w2} {
    if {![string equal $w1 $w2]} return

    variable state
    unset state($w1,last)
}

proc quotelastmsg::on_message_drawn {chatid from type body x} {
    if {![chat::is_opened $chatid]} return

    set cw [::chat::chat_win $chatid]

    variable state
    upvar 0 state($cw,last) last

    set now [$cw index {end - 1 char}]
    if {[$cw compare $last < $now]} {
	$cw tag delete lastmsg
	$cw tag add lastmsg $last $now
    }

    set last $now
}

proc quotelastmsg::quote chatid {
    variable options

    set cw [::chat::chat_win $chatid]
    set iw [::chat::input_win $chatid]

    set range [$cw tag prevrange lastmsg end]
    if {$range == ""} return
    lassign $range x y
    $iw insert end [string map \
	[list %% % %m [$cw get $x $y]] $options(format)]
    $iw see end
}

# vim:ts=8:sw=4:sts=4:noet
