').addClass('button clear-list')
                            .append(
                                $('
').html(_l('label.clear.list'))
                            )
                        )
                        .append(
                            $('').addClass('button close')
                            .append(
                                $('').html(_l('label.close'))
                            )
                        )
                )
                    .css({
                        position: 'absolute'
                    })
                    .data('notifications-attach-to', $attachTo)
                    .hide();
                if (!$attachTo.hasClass('notifications')) $attachTo.addClass('notifications');
                $attachTo.data('notifications-popup', $popup);
                return $popup;
            },
            show: function($popup, $attachTo) {
                notifications.resetTotal($popup);
                return notifications.popup.reposition($popup, $attachTo)
                    .overlay({
                        closeAction: function() {
                            notifications.popup.hide($popup);
                        }
                    })
                    .fadeIn();
            },
            hide: function($popup) {
                $popup.fadeOut();
            },
            reposition: function($popup, $attachTo) {
                return $popup
                    .css({
                        zIndex: 10000,
                        top: $attachTo.offset().top + $attachTo.height() + 10,
                        left: $attachTo.offset().left - $attachTo.width()
                    });
            }
        }
    };
    /**
     * Define notification widget -- this is basically represented in a
     * notifications icon, that contains a pop-up list of notifications
     */
    $.fn.notifications = function(method, args) {
        var $attachTo = this;
        var $total = $attachTo.find('div.total span');
        var $popup;
        var init = function() {
            $popup = notifications.popup.create($attachTo).appendTo('html body');
        };
        if (method == 'add')
            notifications.add(args, $attachTo.data('notifications-popup'), $total);
        else
            init();
        return this;
    };
    /**
     * Notifications UI helpers
     */
    cloudStack.ui.notifications = {
        add: function(notification, success, successArgs, error, errorArgs) {
            if (!notification) {
                success(successArgs);
                return false;
            };
            var $notifications = $('div.notifications');
            if (!notification.poll) {
                cloudStack.ui.event.call('addNotification', {
                    section: notification.section,
                    desc: notification.desc,
                    interval: 0,
                    poll: function(args) {
                        success(successArgs);
                        args.complete();
                    }
                });
            } else {
                cloudStack.ui.event.call('addNotification', {
                    section: notification.section,
                    desc: notification.desc,
                    interval: notification.interval ? notification.interval : g_queryAsyncJobResultInterval,
                    _custom: notification._custom,
                    poll: function(args) {
                        var complete = args.complete;
                        var notificationError = args.error;
                        notification.poll({
                            _custom: args._custom,
                            complete: function(args) {
                                success($.extend(successArgs, args));
                                complete(args);
                            },
                            error: function(args) {
                                error($.extend(errorArgs, args));
                                notificationError(args);
                            }
                        });
                    }
                });
            }
            return true;
        }
    };
    // Setup notification listener -- accepts same args as
    $(window).bind('cloudStack.addNotification', function(event, data) {
        $('.notifications').notifications('add', data);
    });
    $(document).click(function(event) {
        var $target = $(event.target);
        var $attachTo, $popup;
        // Notifications header area
        if ($target.closest('.notifications').size()) {
            $attachTo = $target.closest('.notifications');
            $popup = $attachTo.data('notifications-popup');
            notifications.popup.show($popup, $attachTo);
            return false;
        }
        // Notification item
        if ($target.is('.notification-box li span')) {
            var $li = $target.closest('.notification-box li');
            $('#navigation ul li').filter(function() {
                return $(this).hasClass($li.data('notification-section'));
            }).click();
            $('div.overlay').click();
            return false;
        }
        // Popup
        if ($target.closest('div.notification-box').size()) {
            $popup = $target.closest('div.notification-box');
            // Clear list
            if ($target.closest('.button.clear-list').size()) {
                notifications.clear($popup);
            }
            // Remove instance item
            else if ($target.hasClass('remove')) {
                notifications.removeItem($popup, $target.closest('li'));
            }
            // Close button
            else if ($target.closest('.button.close')) {
                $('div.overlay').click();
            }
            return false;
        }
        return true;
    });
    $(window).resize(function(event) {
        var $popup = $('div.notification-box:visible');
        if ($popup.size())
            notifications.popup.reposition($popup, $popup.data('notifications-attach-to'));
    });
})(window.jQuery, window.cloudStack, window._l);