# $Id: singularity.tcl 1513 2008-10-15 17:39:41Z sergei $
# When a new chat window is about to be opened this plugin
# checks whether any chats with other resources of this chat peer
# are currently opened and closes them all, if any.
# In other words, it ensures that only one chat window per bare
# JID is opened at any given time.
# Written by Konstantin Khomoutov <flatworm@users.sourceforge.net>
# See license.terms for the terms of distribution.
# See README for usage details.

namespace eval singularity {
    variable contexts
    variable options

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

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

    custom::defgroup Singularity \
	[::msgcat::mc "Singularity plugin options.\
	    What this plugin makes is to do cleanup by closing obsolete\
	    chat windows opened for different resources of the same\
	    contact ensuring only one chat window for a contact\
	    is opened at any given time."] \
	-group Plugins \
	-group IFace

    custom::defvar options(enabled) 1 \
	[::msgcat::mc "Allows closing obsolete chat windows\
	    for a contact when a new chat session window\
	    with that contact is about to be opened."] \
	-group Singularity \
	-type boolean

    hook::add open_chat_pre_hook \
	[namespace current]::process_new_chat_opening
    hook::add open_chat_post_hook \
	[namespace current]::restore_chat_context
}

proc singularity::process_new_chat_opening {chatid type} {
    variable options
    if {!$options(enabled) || ![string equal $type chat]} return

    set from [chat::get_jid $chatid]
    set barejid [node_and_server_from_jid $from]
    if {[chat::is_groupchat [chat::chatid \
	[chat::get_connid $chatid] $barejid]]} return

    variable contexts
    upvar 0 contexts(input,$chatid) savedinput
    upvar 0 contexts(history,$chatid) savedhistory
    variable [namespace parent]::history

    set savedinput ""
    set savedhistory [list]

    foreach cid [chat::opened] {
	set jid [chat::get_jid $cid]
	if {![string equal $from $jid] &&
		[string equal $barejid [node_and_server_from_jid $jid]]} {
	    if {$savedinput != ""} { append savedinput \n }
	    append savedinput [[chat::input_win $cid] get 1.0 end-1c]
	    set savedhistory [concat $savedhistory $history(stack,$cid)]
	    chat::close $cid
	}
    }
}

proc singularity::restore_chat_context {chatid type} {
    variable options
    if {!$options(enabled) || ![string equal $type chat]} return

    variable contexts
    upvar 0 contexts(input,$chatid) savedinput
    upvar 0 contexts(history,$chatid) savedhistory
    if {![info exists savedinput]} return

    variable [namespace parent]::history

    [chat::input_win $chatid] insert end $contexts(input,$chatid)
    set history(stack,$chatid) $contexts(history,$chatid)
    set history(pos,$chatid)   0

    unset contexts(input,$chatid) contexts(history,$chatid)
}

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