# $Id: rosterx.tcl 1150 2007-07-09 17:10:45Z sergei $
#
# Roster Item Exchange Support (XEP-0093 and XEP-0144)
#

namespace eval rosterx {}

###############################################################################

proc rosterx::process_x {rowvar bodyvar f x connid from id type replyP} {
    upvar 2 $rowvar row
    upvar 2 $bodyvar body

    set rosterx 0
    foreach xa $x {
	jlib::wrapper:splitxml $xa tag vars isempty chdata children

	set xmlns [jlib::wrapper:getattr $vars xmlns]
	switch -- $xmlns \
	    $::NS(rosterx) {
		set rosterx 1
		foreach child $children {
		    process_x_rosterx $f $child $row $connid $from
		    incr row
		}
	    } \
	    $::NS(xroster) {
		if {$rosterx} break
		foreach child $children {
		    process_x_xroster $f $child $row $connid $from
		    incr row
		}
	    }
	}

    return
}

hook::add message_process_x_hook [namespace current]::rosterx::process_x 60

###############################################################################

proc rosterx::process_x_rosterx {f x row connid from} {
    jlib::wrapper:splitxml $x tag vars isempty chdata children

    set jid [jlib::wrapper:getattr $vars jid]
    set name [jlib::wrapper:getattr $vars name]
    set action [jlib::wrapper:getattr $vars action]

    if {$jid == ""} return

    if {$name != ""} {
        set desc "$name ($jid)"
    } else {
        set desc $jid
    }

    label $f.luser$row -text [::msgcat::mc "Attached user:"]
    set cb [button $f.user$row -text $desc \
                -command [list [namespace current]::process_user $connid $jid \
			       $name "$from asked me to add you to my roster."]]
    grid $f.luser$row -row $row -column 0 -sticky e
    grid $f.user$row  -row $row -column 1 -sticky ew
}

###############################################################################

proc rosterx::process_x_xroster {f x row connid from} {
    jlib::wrapper:splitxml $x tag vars isempty chdata children

    set jid [jlib::wrapper:getattr $vars jid]
    set name [jlib::wrapper:getattr $vars name]

    if {$jid == ""} return

    if {$name != ""} {
        set desc "$name ($jid)"
    } else {
        set desc $jid
    }

    label $f.luser$row -text [::msgcat::mc "Attached user:"]
    set cb [button $f.user$row -text $desc \
                -command [list [namespace current]::process_user $connid $jid \
                               $name "$from asked me to add you to my roster."]]
    grid $f.luser$row -row $row -column 0 -sticky e
    grid $f.user$row  -row $row -column 1 -sticky ew
}

###############################################################################

proc rosterx::process_user {connid jid name body} {
    jlib::send_presence -to $jid \
			-type subscribe \
			-stat $body \
			-connection $connid

    set vars [list jid $jid]
    if {$name != ""} {
	lappend vars name $name
    }

    jlib::send_iq set \
        [jlib::wrapper:createtag query \
             -vars [list xmlns $::NS(roster)] \
             -subtags [list [jlib::wrapper:createtag item \
                                     -vars $vars]]] \
	-connection $connid
}

###############################################################################

proc rosterx::send_users_dialog {connid user} {
    global send_uc

    set jid [get_jid_of_user $connid $user]

    if {[cequal $jid ""]} {
        set jid $user
    }

    set gw .contacts
    catch { destroy $gw }

    if {[catch { set nick [roster::get_label $connid $user] }]} {
	if {[catch { set nick [chat::get_nick $connid \
					      $user groupchat] }]} {
	    set nick $user
	}
    }

    set choices {}
    set balloons {}
    foreach c [jlib::connections] {
	foreach choice [roster::get_jids $c] {
	    if {[roster::itemconfig $c $choice -isuser]} {
		lappend choices [list $c $choice] [roster::get_label $c $choice]
		lappend balloons [list $c $choice] $choice
	    }
	}
    }
    if {[llength $choices] == 0} {
        MessageDlg ${gw}_err -aspect 50000 -icon info \
	    -message [::msgcat::mc "No users in roster..."] -type user \
	    -buttons ok -default 0 -cancel 0
        return
    }

    CbDialog $gw [format [::msgcat::mc "Send contacts to %s"] $nick] \
	[list [::msgcat::mc "Send"] \
	      [list [namespace current]::send_users $gw $connid $jid] \
	      [::msgcat::mc "Cancel"] \
	      [list destroy $gw]] \
	send_uc $choices $balloons
}

###############################################################################

proc rosterx::add_menu_item {m connid jid} {
    $m add command \
	   -label [::msgcat::mc "Send users..."] \
           -command [list [namespace current]::send_users_dialog $connid $jid]
}

hook::add roster_create_groupchat_user_menu_hook \
    [namespace current]::rosterx::add_menu_item 45
hook::add chat_create_user_menu_hook \
    [namespace current]::rosterx::add_menu_item 45
hook::add roster_jid_popup_menu_hook \
    [namespace current]::rosterx::add_menu_item 45
hook::add message_dialog_menu_hook \
    [namespace current]::rosterx::add_menu_item 45
hook::add search_popup_menu_hook \
    [namespace current]::rosterx::add_menu_item 45

###############################################################################

proc rosterx::send_users {gw connid jid} {
    global send_uc

    set sf [$gw getframe].sw.sf
    set choices {}
    foreach uc [array names send_uc] {
        if {$send_uc($uc)} {
            lappend choices $uc
        }
    }

    destroy $gw

    set subtags {}
    set body [::msgcat::mc "Contact Information"]
    foreach choice $choices {
	lassign $choice con uc
	lappend subtags [roster::item_to_xml $con $uc]
	set nick [roster::get_label $con $uc]
        append body "\n$nick - xmpp:$uc"
    }

    message::send_msg $jid -type normal -body $body \
	-xlist [list \
		    [jlib::wrapper:createtag x \
			 -vars [list xmlns $::NS(rosterx)] \
	                 -subtags $subtags] \
		    [jlib::wrapper:createtag x \
			 -vars [list xmlns $::NS(xroster)] \
	                 -subtags $subtags]] \
	-connection $connid
}

###############################################################################

disco::register_feature $::NS(rosterx)

