# stripes.tcl --
#
#       "Stripes" chat plugin for Tkabber -- colorizes background of
#       whole messages in chat windows.
#
# Author: Konstantin Khomoutov <flatworm@users.sourceforge.net>
#
# See license.terms for the terms of distribution.
# See README for usage details.

# Color for odd and even messages can be tuned separately
# using the Tk option database (or XRDB) like this:
# option add *Chat.oddBackground  gray77
# option add *Chat.evenBackground gray84

package require msgcat

namespace eval stripes {
    variable state

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

    if {![::plugins::is_registered stripes]} {
        ::plugins::register stripes \
            -namespace [namespace current] \
            -source [info script] \
            -description [::msgcat::mc \
                "Whether the Stripes plugin is loaded."]\n[::msgcat::mc \
                "This plugin paints backgrounds of even and odd messages\
                    in chat windows with different colors."] \
            -loadcommand [namespace code load] \
            -unloadcommand [namespace code unload]
        return
    }
}

proc stripes::load {} {
    hook::add open_chat_post_hook [namespace current]::setup_chat_window
    hook::add close_chat_post_hook [namespace current]::cleanup_state
    hook::add draw_message_post_hook [namespace current]::on_message_drawn

    foreach chatid [chat::opened] {
        setup_chat_window $chatid ?
    }
}

proc stripes::unload {} {
    foreach chatid [chat::opened] {
        cleanup_chat_window $chatid
    }

    hook::remove open_chat_post_hook [namespace current]::setup_chat_window
    hook::remove close_chat_post_hook [namespace current]::cleanup_state
    hook::remove draw_message_post_hook [namespace current]::on_message_drawn
}

proc stripes::setup_chat_window {chatid type} {
    set cw [::chat::chat_win $chatid]
    set mw [::chat::winid $chatid]

    set bgodd [option get $mw oddBackground Chat]
    if {$bgodd != ""} {
        $cw tag configure odd -background $bgodd
        $cw tag lower odd
    }
    set bgeven [option get $mw evenBackground Chat]
    if {$bgeven != ""} {
        $cw tag configure even -background $bgeven
        $cw tag lower even
    }

    variable state
    set state($chatid,last) [$cw index {end - 1 char}]
    set state($chatid,tag) odd
}

proc stripes::cleanup_state {chatid} {
    variable state
    unset state($chatid,last)
    unset state($chatid,tag)
}

proc stripes::cleanup_chat_window {chatid} {
    set cw [::chat::chat_win $chatid]
    $cw tag delete odd even

    cleanup_state $chatid
}

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

    variable state
    upvar 0 state($chatid,last) last
    upvar 0 state($chatid,tag)  tag

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

    set now [$cw index {end - 1 char}]
    if {[$cw compare $last < $now]} {
        $cw tag add $tag $last $now
        if {[string equal $tag even]} {
            set tag odd
        } else {
            set tag even
        }
    }

    set last $now
}

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