# Tkabber OSD Module
# Author: Jan Hudec
# http://www.ucw.cz/~0rfelyus/twiki/view/Wishlist/TkabberOsdModule

package require msgcat

namespace eval ::osd {
    ::msgcat::mcload [file join [file dirname [info script]] msgs]

    if {![::plugins::is_registered osd]} {
	::plugins::register osd \
			    -namespace [namespace current] \
			    -source [info script] \
			    -description [::msgcat::mc "Whether the OSD plugin is loaded."] \
			    -loadcommand [namespace code load] \
			    -unloadcommand [namespace code unload]
	return
    }

    set options ""
    set delay 5
    set osdfont ""
    set pipe ""
    array set statuses {}
}

proc ::osd::load {} {
    if {![info exists ::osd] || $::osd == ""} {return}

    ::osd::open_osd_cat

    foreach event $::osd {
	switch -- $event {
	    presence { hook::add client_presence_hook ::osd::presence_notify 100 }
	    chat_message { hook::add draw_message_hook ::osd::chat_message_notify 20 }
	    default { debugmsg osd "Unsupported notify type $event" }
	}
    }
}

proc ::osd::unload {} {
    if {![info exists ::osd] || $::osd == ""} {return}

    foreach event $::osd {
	switch -- $event {
	    presence { hook::remove client_presence_hook ::osd::presence_notify 100 }
	    chat_message { hook::remove draw_message_hook ::osd::chat_message_notify 20 }
	    default { debugmsg osd "Unsupported notify type $event" }
	}
    }

    variable pipe
    close $pipe
    set pipe ""
}

proc ::osd::open_osd_cat {} {
    variable pipe
    variable options
    variable delay
    variable osdfont
    if {$pipe != ""} {
	close $pipe
	set pipe ""
    }
    set command "|osd_cat $options -d $delay -a$delay"
    if {$osdfont != ""} {
	append command " -f $osdfont"
    }
    debugmsg osd $command
    set pipe [open $command w]
    fconfigure $pipe -buffering line
}

proc ::osd::try_write {text} {
    variable pipe
    if {[catch {puts $pipe $text}]} {
	osd::open_osd_cat
	if {[catch {puts $pipe $text}]} {
	    debugmsg osd "Can't write to OSD"
	}
    }
}

proc ::osd::presence_notify {xlib from type x args} {
    variable statuses

    if {[catch  { set nick [get_nick $xlib $from chat] }]} {
        set nick "$from" 
    }
    
    if { "$nick"!="$from" } { 
        set thefrom "$nick ($from)" 
    } else { 
        set thefrom "$from" 
    }
    if { "$type"=="" } { set type "available" }

    set status ""
    set show ""
    foreach {attr val} $args {
	switch -- $attr {
	    -status   {set status $val}
	    -show     {set show   $val}
	}
    }

    if {"$status"!=""} { set status " ($status)" }
    if {"$show"!=""} { set type "$type/$show" }

    set newstatus "$thefrom: $type$status"
    
    if {[catch { set oldstatus $statuses($from) } ]} {
        set oldstatus "$newstatus"
    }

    if { "$newstatus"!="$oldstatus" } {
        osd::try_write "$newstatus"
    }

    set statuses($from) "$newstatus"
}

proc ::osd::chat_message_notify {chatid from type body extras} {
    if {[chat::is_our_jid $chatid $from] || ![cequal $type chat]} {
	return
    }

    foreach xelem $extras {
	::xmpp::xml::split $xelem tag xmlns attrs cdata subels
	
	# Don't notify if this 'empty' tag is present. It indicates
	# messages history in chat window.
	if {[string equal $tag ""] && [string equal $xmlns tkabber:x:nolog]} {
	    return
	}
    }

    set nick [get_nick [chat::get_xlib $chatid] $from $type]
    osd::try_write "New message from $nick"
}

proc ::osd::get_nick {xlib jid type} {
    if {[catch {chat::get_nick $xlib $jid $type} nick]} {
	return [chat::get_nick $jid $type]
    } else {
	return $nick
    }
}

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