# $Id$
# Support for backup/restore of "annotations" (XEP-0145)
# for roster items.
# Depends on: annotations.tcl, backup.tcl

namespace eval annobackup {
    # Should probably go after the roster contacts, so we set prio to 60:
    hook::add serialize_roster_hook \
	[namespace current]::serialize_annotations 60
    hook::add deserialize_roster_hook \
	[namespace current]::deserialize_annotations 60
}

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

proc annobackup::serialize_annotations {connid level varName} {
    upvar $level $varName subtags
    global NS

    set xmldata [::plugins::annotations::serialize_notes $connid]

    lappend subtags [jlib::wrapper:createtag privstorage \
	-vars {xmlns jabber:iq:private} \
	-subtags [list $xmldata]]
}

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

proc annobackup::deserialize_annotations {connid data level varName} {
    global NS
    upvar $level $varName handlers

    set notes [list]
    foreach item $data {
	jlib::wrapper:splitxml $item tag vars isempty cdata children
	if {![string equal $tag privstorage]} continue
	set xmlns [jlib::wrapper:getattr $vars xmlns]
	if {![string equal $xmlns $NS(private)]} {
	    return -code error "Bad roster element namespace \"$xmlns\":\
		must be \"$NS(private)\""
	}

	foreach storage $children {
	    jlib::wrapper:splitxml $storage ctag cvars cisempty ccdata cchildren
	    if {![string equal $ctag storage]} continue
	    set xmlns [jlib::wrapper:getattr $cvars xmlns]
	    if {![string equal $xmlns $NS(rosternotes)]} continue
	    
	    set notes [concat $notes $cchildren]
	}
    }

    if {[llength $notes] > 0} {
	lappend handlers [list 60 [namespace code [list \
	    send_notes $connid $notes]]]
    }
}

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

proc annobackup::send_notes {connid notes continuation} {
    set updated 0

    foreach item $notes {
	set added [::plugins::annotations::create_note \
		$connid $item -merge yes]
	set updated [expr {$updated || $added}]
    }

    if {$updated} {
	::plugins::annotations::cleanup_and_store_notes $connid \
	    -command [namespace code [list process_sending_result $continuation]]
    } else {
	eval $continuation
    }
}

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

proc annobackup::process_sending_result {continuation result xmldata} {
    switch -- $result {
	OK {
	    eval $continuation
	}
	default {
	    # TODO check whether do we need to handle TIMEOUT specially
	    NonmodalMessageDlg [epath] \
		-aspect 50000 \
		-icon error \
		-title [::msgcat::mc "Error"] \
		-message [::msgcat::mc "Error restoring annotations: %s" \
		    [error_to_string $xmldata]]
	}
    }
}

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