').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 : 5000,
          _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);