# $Id: recentstatus.tcl 92 2008-01-08 23:12:00Z kostix $
# "Recent Status" -- plugin for Tkabber.
# This plugin subverts the standard Tkabber's entry widget for
# managing user's availability status message by a combobox
# widget which maintains the history of status messages;
# this history is preserved across Tkabber restarts.
# Written by Konstantin Khomoutov <flatworm@users.sourceforge.net>
# See INSTALL for installation procedure.
# See README for details on usage.
# See license.terms for info on terms of usage and distribution.

namespace eval recentstatus {
	variable history
	variable options

	package require msgcat
	::msgcat::mcload [file join [file dir [info script]] msgs]

	custom::defvar history [list] \
		[::msgcat::mc "History of availability status messages"] \
		-type list \
		-group Hidden

	custom::defgroup Plugins [::msgcat::mc "Plugins options."] \
		-group Tkabber
	custom::defgroup {Recent Status} \
		[::msgcat::mc "Recent Status plugin options.\
			This plugin keeps the history of avalability status messages\
			entered manually by the user and allows to select\
			them from a drop-down list.\
			The history is preserved across restarts."] \
		-group Plugins

	custom::defvar options(maxhistorysize) 5 \
		[::msgcat::mc "Maximum number of status messages to keep.\
			If the history size reaches this threshold,\
			the oldest message will be deleted automatically\
			when a new one is recorded."] \
		-type integer -group {Recent Status}

	hook::add finload_hook [namespace current]::subvert_presence_widget
}

proc recentstatus::subvert_presence_widget {} {
	variable history

	set w .presence.status

	set pinfo [pack info $w]
	set var [$w cget -textvariable]
	set cmd [bind $w <Return>]

	destroy $w

	ComboBox $w -textvariable $var -values $history
	$w bind <Return> $cmd
	$w bind <Return> +[list [namespace current]::save_availability_status $w]
	$w bind <Button-3> [list [namespace current]::show_context_menu $w]

	eval [concat [list pack $w] $pinfo]

	trace add variable ::userstatus write \
		[list [namespace current]::on_status_change $w]
}

proc recentstatus::save_availability_status {w} {
	variable history
	variable options

	set avstatus [$w cget -text]
	if {$avstatus == ""} return

	set ix [$w getvalue]
	if {$ix >= 0} {
		set history [linsert [lreplace $history $ix $ix] end $avstatus]
	} elseif {[llength $history] < $options(maxhistorysize)} {
		lappend history $avstatus
	} else {
		set history [linsert [lrange $history 1 end] end $avstatus]
	}

	$w configure -values $history
}

proc recentstatus::on_status_change {w n1 n2 op} {
	save_availability_status $w
}

proc recentstatus::show_context_menu {w} {
	set m $w.menu

	if {![winfo exists $m]} {
		menu $m -title [::msgcat::mc "History of availability status messages"]
		$m add command \
			-label [::msgcat::mc "Clear history"] \
			-command [list [namespace current]::clear_history $w]
	}

	tk_popup $m [winfo pointerx $w] [winfo pointery $w]
}

proc recentstatus::clear_history {w} {
	variable history

	set history [list]
	$w configure -values $history
}

