(function($) {
    $.fn.bookmark = function (callback) {
        var serverRequest = null;
        
        return this.each(function () {
            var elem = $(this);
            
            function clickBookmark() {
                // Prevent multiple concurent calls
                if (serverRequest !== null) {
                    serverRequest.abort();
                }
                // Generic AJAX call
                serverRequest = $.post($(this).attr('href'), { js: true }, insertBookmarks, 'json');
                
                if (callback) {
                    callback(this);
                };
                
                return false;
            }
            
            function insertBookmarks(data) {
                serverRequest = null;
                if (data.html) {
                    elem.after(data.html);
                    var newElem = elem.next();
                    elem.remove();
                    elem = newElem;
                    $('a', elem).click(clickBookmark);
                } else if (data.redirection) {
                    window.location = data.redirection;
                }
                
                if (data.message) {
                    message_engine.alert('', data.message);
                }
            }
            
            $('a', elem).click(clickBookmark);
        });
    };
})(jQuery);
