/*!
 * jQuery Popup Overlay
 *
 * @version 1.7.3
 * @requires jQuery v1.7.1+
 * @link http://vast-engineering.github.com/jquery-popup-overlay/
 */
;
(function ($) {

  var $window = $(window);
  var options = {};
  var zindexvalues = [];
  var lastclicked = [];
  var scrollbarwidth;
  var bodymarginright = null;
  var opensuffix = '_open';
  var closesuffix = '_close';
  var stack = [];
  var transitionsupport = null;
  var opentimer;
  var iOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);

  var methods = {

    _init: function (el) {
      var $el = $(el);
      var options = $el.data('popupoptions');
      lastclicked[el.id] = false;
      zindexvalues[el.id] = 0;

      if (!$el.data('popup-initialized')) {
        $el.attr('data-popup-initialized', 'true');
        methods._initonce(el);
      }

      if (options.autoopen) {
        setTimeout(function () {
          methods.show(el, 0);
        }, 0);
      }
    },

    _initonce: function (el) {
      var $el = $(el);
      var $body = $('body');
      var $wrapper;
      var options = $el.data('popupoptions');
      var css;

      bodymarginright = parseInt($body.css('margin-right'), 10);
      transitionsupport = document.body.style.webkitTransition !== undefined ||
        document.body.style.MozTransition !== undefined ||
        document.body.style.msTransition !== undefined ||
        document.body.style.OTransition !== undefined ||
        document.body.style.transition !== undefined;

      if (options.type == 'tooltip') {
        options.background = false;
        options.scrolllock = false;
      }

      if (options.backgroundactive) {
        options.background = false;
        options.blur = false;
        options.scrolllock = false;
      }

      if (options.scrolllock) {
        // Calculate the browser's scrollbar width dynamically
        var parent;
        var child;
        if (typeof scrollbarwidth === 'undefined') {
          parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body');
          child = parent.children();
          scrollbarwidth = child.innerWidth() - child.height(99).innerWidth();
          parent.remove();
        }
      }

      if (!$el.attr('id')) {
        $el.attr('id', 'j-popup-' + parseInt((Math.random() * 100000000), 10));
      }

      $el.addClass('popup_content');

      $body.prepend(el);

      $el.wrap('<div id="' + el.id + '_wrapper" class="popup_wrapper" />');

      $wrapper = $('#' + el.id + '_wrapper');

      $wrapper.css({
        opacity: 0,
        visibility: 'hidden',
        position: 'absolute'
      });

      // Make div clickable in iOS
      if (iOS) {
        $wrapper.css('cursor', 'pointer');
      }

      if (options.type == 'overlay') {
        $wrapper.css('overflow', 'auto');
      }

      $el.css({
        opacity: 0,
        visibility: 'hidden',
        display: 'inline-block'
      });

      if (options.setzindex && !options.autozindex) {
        $wrapper.css('z-index', '100001');
      }

      if (!options.outline) {
        $el.css('outline', 'none');
      }

      if (options.transition) {
        $el.css('transition', options.transition);
        $wrapper.css('transition', options.transition);
      }

      // Hide popup content from screen readers initially
      $el.attr('aria-hidden', true);

      if ((options.background) && (!$('#' + el.id + '_background').length)) {

        $body.prepend('<div id="' + el.id + '_background" class="popup_background"></div>');

        var $background = $('#' + el.id + '_background');

        $background.css({
          opacity: 0,
          visibility: 'hidden',
          backgroundColor: options.color,
          position: 'fixed',
          top: 0,
          right: 0,
          bottom: 0,
          left: 0
        });

        if (options.setzindex && !options.autozindex) {
          $background.css('z-index', '100000');
        }

        if (options.transition) {
          $background.css('transition', options.transition);
        }
      }

      if (options.type == 'overlay') {
        $el.css({
          textAlign: 'left',
          position: 'relative',
          verticalAlign: 'middle'
        });

        css = {
          position: 'fixed',
          width: '100%',
          height: '100%',
          top: 0,
          left: 0,
          textAlign: 'center'
        };

        if (options.backgroundactive) {
          css.position = 'relative';
          css.height = '0';
          css.overflow = 'visible';
        }

        $wrapper.css(css);

        // CSS vertical align helper
        $wrapper.append('<div class="popup_align" />');

        $('.popup_align').css({
          display: 'inline-block',
          verticalAlign: 'middle',
          height: '100%'
        });
      }

      // Add WAI ARIA role to announce dialog to screen readers
      $el.attr('role', 'dialog');

      var openelement = (options.openelement) ? options.openelement : ('.' + el.id + opensuffix);

      $(openelement).each(function (i, item) {
        $(item).attr('data-popup-ordinal', i);

        if (!item.id) {
          $(item).attr('id', 'open_' + parseInt((Math.random() * 100000000), 10));
        }
      });

      // Set aria-labelledby (if aria-label or aria-labelledby is not set in html)
      if (!($el.attr('aria-labelledby') || $el.attr('aria-label'))) {
        $el.attr('aria-labelledby', $(openelement).attr('id'));
      }

      // Handler: `close` element
      var closeelement = (options.closeelement) ? options.closeelement : ('.' + el.id + closesuffix);
      $(document).on('click', closeelement, function (e) {
        methods.hide(el);
        e.preventDefault();
      });

      // Show and hide tooltips on hover
      if (options.action == 'hover') {
        options.keepfocus = false;

        // Handler: mouseenter, focusin
        $(openelement).on('mouseenter', function (event) {
          methods.show(el, $(this).data('popup-ordinal'));
        });

        // Handler: mouseleave, focusout
        $(openelement).on('mouseleave', function (event) {
          methods.hide(el);
        });

      } else {

        // Handler: Show popup when clicked on `open` element
        $(document).on('click', openelement, function (event) {
          event.preventDefault();

          var ord = $(this).data('popup-ordinal');
          setTimeout(function () { // setTimeout is to allow `close` method to finish (for issues with multiple tooltips)
            methods.show(el, ord);
          }, 0);
        });
      }

      if (options.detach) {
        $el.hide().detach();
      } else {
        $wrapper.hide();
      }
    },

    /**
     * Show method
     *
     * @param {object} el - popup instance DOM node
     * @param {number} ordinal - order number of an `open` element
     */
    show: function (el, ordinal) {
      var $el = $(el);

      if ($el.data('popup-visible')) return;

      // Initialize if not initialized. Required for: $('#popup').popup('show')
      if (!$el.data('popup-initialized')) {
        methods._init(el);
      }
      $el.attr('data-popup-initialized', 'true');

      var $body = $('body');
      var options = $el.data('popupoptions');
      var $wrapper = $('#' + el.id + '_wrapper');
      var $background = $('#' + el.id + '_background');

      // `beforeopen` callback event
      callback(el, ordinal, options.beforeopen);

      // Remember last clicked place
      lastclicked[el.id] = ordinal;

      // Add popup id to popup stack
      setTimeout(function () {
        stack.push(el.id);
      }, 0);

      // Calculating maximum z-index
      if (options.autozindex) {

        var elements = document.getElementsByTagName('*');
        var len = elements.length;
        var maxzindex = 0;

        for (var i = 0; i < len; i++) {

          var elementzindex = $(elements[i]).css('z-index');

          if (elementzindex !== 'auto') {

            elementzindex = parseInt(elementzindex, 10);

            if (maxzindex < elementzindex) {
              maxzindex = elementzindex;
            }
          }
        }

        zindexvalues[el.id] = maxzindex;

        // Add z-index to the background
        if (options.background) {
          if (zindexvalues[el.id] > 0) {
            $('#' + el.id + '_background').css({
              zIndex: (zindexvalues[el.id] + 1)
            });
          }
        }

        // Add z-index to the wrapper
        if (zindexvalues[el.id] > 0) {
          $wrapper.css({
            zIndex: (zindexvalues[el.id] + 2)
          });
        }
      }

      if (options.detach) {
        $wrapper.prepend(el);
        $el.show();
      } else {
        $wrapper.show();
      }

      opentimer = setTimeout(function () {
        $wrapper.css({
          visibility: 'visible',
          opacity: 1
        });

        $('html').addClass('popup_visible').addClass('popup_visible_' + el.id);
        $el.addClass('popup_content_visible');
      }, 20); // 20ms required for opening animation to occur in FF

      // Disable background layer scrolling when popup is opened
      if (options.scrolllock) {
        $body.css('overflow', 'hidden');
        if ($body.height() > $window.height()) {
          $body.css('margin-right', bodymarginright + scrollbarwidth);
        }
      }

      if (options.backgroundactive) {
        //calculates the vertical align
        $el.css({
          top: (
            $window.height() - (
              $el.get(0).offsetHeight +
              parseInt($el.css('margin-top'), 10) +
              parseInt($el.css('margin-bottom'), 10)
            )
          ) / 2 + 'px',
        });
      }

      $el.css({
        'visibility': 'visible',
        'opacity': 1
      });

      // Show background
      if (options.background) {
        $background.css({
          'visibility': 'visible',
          'opacity': options.opacity
        });

        // Fix IE8 issue with background not appearing
        setTimeout(function () {
          $background.css({
            'opacity': options.opacity
          });
        }, 0);
      }

      $el.data('popup-visible', true);

      // Position popup
      methods.reposition(el, ordinal);

      // Remember which element had focus before opening a popup
      $el.data('focusedelementbeforepopup', document.activeElement);

      // Handler: Keep focus inside dialog box
      if (options.keepfocus) {
        // Make holder div focusable
        $el.attr('tabindex', -1);

        // Focus popup or user specified element.
        // Initial timeout of 50ms is set to give some time to popup to show after clicking on
        // `open` element, and after animation is complete to prevent background scrolling.
        setTimeout(function () {
          if (options.focuselement === 'closebutton') {
            $('#' + el.id + ' .' + el.id + closesuffix + ':first').focus();
          } else if (options.focuselement) {
            $(options.focuselement).focus();
          } else {
            $el.focus();
          }
        }, options.focusdelay);

      }

      // Hide main content from screen readers
      $(options.pagecontainer).attr('aria-hidden', true);

      // Reveal popup content to screen readers
      $el.attr('aria-hidden', false);

      callback(el, ordinal, options.onopen);

      if (transitionsupport) {
        $wrapper.one('transitionend', function () {
          callback(el, ordinal, options.opentransitionend);
        });
      } else {
        callback(el, ordinal, options.opentransitionend);
      }
    },

    /**
     * Hide method
     *
     * @param {object} el - popup instance DOM node
     */
    hide: function (el) {
      if (opentimer) clearTimeout(opentimer);

      var $body = $('body');
      var $el = $(el);
      var options = $el.data('popupoptions');
      var $wrapper = $('#' + el.id + '_wrapper');
      var $background = $('#' + el.id + '_background');

      $el.data('popup-visible', false);


      if (stack.length === 1) {
        $('html').removeClass('popup_visible').removeClass('popup_visible_' + el.id);
      } else {
        if ($('html').hasClass('popup_visible_' + el.id)) {
          $('html').removeClass('popup_visible_' + el.id);
        }
      }

      // Remove last opened popup from the stack
      stack.pop();

      if ($('html').hasClass('popup_content_visible')) {
        $el.removeClass('popup_content_visible');
      }

      if (options.keepfocus) {
        // Focus back on saved element
        setTimeout(function () {
          if ($($el.data('focusedelementbeforepopup')).is(':visible')) {
            $el.data('focusedelementbeforepopup').focus();
          }
        }, 0);
      }

      // Hide popup
      $wrapper.css({
        'visibility': 'hidden',
        'opacity': 0
      });
      $el.css({
        'visibility': 'hidden',
        'opacity': 0
      });

      // Hide background
      if (options.background) {
        $background.css({
          'visibility': 'hidden',
          'opacity': 0
        });
      }

      // Reveal main content to screen readers
      $(options.pagecontainer).attr('aria-hidden', false);

      // Hide popup content from screen readers
      $el.attr('aria-hidden', true);

      // `onclose` callback event
      callback(el, lastclicked[el.id], options.onclose);

      if (transitionsupport && $el.css('transition-duration') !== '0s') {
        $el.one('transitionend', function (e) {

          if (!($el.data('popup-visible'))) {
            if (options.detach) {
              $el.hide().detach();
            } else {
              $wrapper.hide();
            }
          }

          // Re-enable scrolling of background layer
          if (options.scrolllock) {
            setTimeout(function () {
              $body.css({
                overflow: 'visible',
                'margin-right': bodymarginright
              });
            }, 10); // 10ms added for CSS transition in Firefox which doesn't like overflow:auto
          }

          callback(el, lastclicked[el.id], options.closetransitionend);
        });
      } else {
        if (options.detach) {
          $el.hide().detach();
        } else {
          $wrapper.hide();
        }

        // Re-enable scrolling of background layer
        if (options.scrolllock) {
          setTimeout(function () {
            $body.css({
              overflow: 'visible',
              'margin-right': bodymarginright
            });
          }, 10); // 10ms added for CSS transition in Firefox which doesn't like overflow:auto
        }

        callback(el, lastclicked[el.id], options.closetransitionend);
      }

    },

    /**
     * Toggle method
     *
     * @param {object} el - popup instance DOM node
     * @param {number} ordinal - order number of an `open` element
     */
    toggle: function (el, ordinal) {
      if ($(el).data('popup-visible')) {
        methods.hide(el);
      } else {
        setTimeout(function () {
          methods.show(el, ordinal);
        }, 0);
      }
    },

    /**
     * Reposition method
     *
     * @param {object} el - popup instance DOM node
     * @param {number} ordinal - order number of an `open` element
     */
    reposition: function (el, ordinal) {
      var $el = $(el);
      var options = $el.data('popupoptions');
      var $wrapper = $('#' + el.id + '_wrapper');
      var $background = $('#' + el.id + '_background');

      ordinal = ordinal || 0;

      // Tooltip type
      if (options.type == 'tooltip') {
        $wrapper.css({
          'position': 'absolute'
        });

        var $tooltipanchor;
        if (options.tooltipanchor) {
          $tooltipanchor = $(options.tooltipanchor);
        } else if (options.openelement) {
          $tooltipanchor = $(options.openelement).filter('[data-popup-ordinal="' + ordinal + '"]');
        } else {
          $tooltipanchor = $('.' + el.id + opensuffix + '[data-popup-ordinal="' + ordinal + '"]');
        }

        var linkOffset = $tooltipanchor.offset();

        // Horizontal position for tooltip
        if (options.horizontal == 'right') {
          $wrapper.css('left', linkOffset.left + $tooltipanchor.outerWidth() + options.offsetleft);
        } else if (options.horizontal == 'leftedge') {
          $wrapper.css('left', linkOffset.left + $tooltipanchor.outerWidth() - $tooltipanchor.outerWidth() + options.offsetleft);
        } else if (options.horizontal == 'left') {
          $wrapper.css('right', $window.width() - linkOffset.left - options.offsetleft);
        } else if (options.horizontal == 'rightedge') {
          $wrapper.css('right', $window.width() - linkOffset.left - $tooltipanchor.outerWidth() - options.offsetleft);
        } else {
          $wrapper.css('left', linkOffset.left + ($tooltipanchor.outerWidth() / 2) - ($el.outerWidth() / 2) - parseFloat($el.css('marginLeft')) + options.offsetleft);
        }

        // Vertical position for tooltip
        if (options.vertical == 'bottom') {
          $wrapper.css('top', linkOffset.top + $tooltipanchor.outerHeight() + options.offsettop);
        } else if (options.vertical == 'bottomedge') {
          $wrapper.css('top', linkOffset.top + $tooltipanchor.outerHeight() - $el.outerHeight() + options.offsettop);
        } else if (options.vertical == 'top') {
          $wrapper.css('bottom', $window.height() - linkOffset.top - options.offsettop);
        } else if (options.vertical == 'topedge') {
          $wrapper.css('bottom', $window.height() - linkOffset.top - $el.outerHeight() - options.offsettop);
        } else {
          $wrapper.css('top', linkOffset.top + ($tooltipanchor.outerHeight() / 2) - ($el.outerHeight() / 2) - parseFloat($el.css('marginTop')) + options.offsettop);
        }

        // Overlay type
      } else if (options.type == 'overlay') {

        // Horizontal position for overlay
        if (options.horizontal) {
          $wrapper.css('text-align', options.horizontal);
        } else {
          $wrapper.css('text-align', 'center');
        }

        // Vertical position for overlay
        if (options.vertical) {
          $el.css('vertical-align', options.vertical);
        } else {
          $el.css('vertical-align', 'middle');
        }
      }
    }

  };

  /**
   * Callback event calls
   *
   * @param {object} el - popup instance DOM node
   * @param {number} ordinal - order number of an `open` element
   * @param {function} func - callback function
   */
  var callback = function (el, ordinal, func) {
    var openelement = (options.openelement) ? options.openelement : ('.' + el.id + opensuffix);
    var elementclicked = $(openelement + '[data-popup-ordinal="' + ordinal + '"]');
    if (typeof func == 'function') {
      func.call($(el), el, elementclicked);
    }
  };

  // Hide popup if ESC key is pressed
  $(document).on('keydown', function (event) {
    if (stack.length) {
      var elementId = stack[stack.length - 1];
      var el = document.getElementById(elementId);

      if ($(el).data('popupoptions').escape && event.keyCode == 27 && $(el).data('popup-visible')) {
        methods.hide(el);
      }
    }
  });

  // Hide popup if clicked outside of it
  $(document).on('click', function (event) {
    if (stack.length) {
      var elementId = stack[stack.length - 1];
      var el = document.getElementById(elementId);

      if ($(el).data('popupoptions').blur && !$(event.target).parents().andSelf().is('#' + elementId) && $(el).data('popup-visible') && event.which !== 2) {
        methods.hide(el);

        if ($(el).data('popupoptions').type === 'overlay') {
          event.preventDefault(); // iOS will trigger click on the links below the overlay when clicked on the overlay if we don't prevent default action
        }
      }
    }
  });

  // Keep keyboard focus inside of popup
  $(document).on('focusin', function (event) {
    if (stack.length) {
      var elementId = stack[stack.length - 1];
      var el = document.getElementById(elementId);

      if ($(el).data('popupoptions').keepfocus) {
        if (!el.contains(event.target)) {
          event.stopPropagation();
          el.focus();
        }
      }
    }
  });

  /**
   * Plugin API
   */
  $.fn.popup = function (customoptions) {
    return this.each(function () {

      $el = $(this);

      if (typeof customoptions === 'object') { // e.g. $('#popup').popup({'color':'blue'})
        var opt = $.extend({}, $.fn.popup.defaults, customoptions);
        $el.data('popupoptions', opt);
        options = $el.data('popupoptions');

        methods._init(this);

      } else if (typeof customoptions === 'string') { // e.g. $('#popup').popup('hide')
        if (!($el.data('popupoptions'))) {
          $el.data('popupoptions', $.fn.popup.defaults);
          options = $el.data('popupoptions');
        }

        methods[customoptions].call(this, this);

      } else { // e.g. $('#popup').popup()
        if (!($el.data('popupoptions'))) {
          $el.data('popupoptions', $.fn.popup.defaults);
          options = $el.data('popupoptions');
        }

        methods._init(this);

      }

    });
  };

  $.fn.popup.defaults = {
    type: 'overlay',
    autoopen: false,
    background: true,
    backgroundactive: false,
    color: 'black',
    opacity: '0.5',
    horizontal: 'center',
    vertical: 'middle',
    offsettop: 0,
    offsetleft: 0,
    escape: true,
    blur: true,
    setzindex: true,
    autozindex: false,
    scrolllock: false,
    keepfocus: true,
    focuselement: null,
    focusdelay: 50,
    outline: false,
    pagecontainer: null,
    detach: false,
    openelement: null,
    closeelement: null,
    transition: null,
    tooltipanchor: null,
    beforeopen: null,
    onclose: null,
    onopen: null,
    opentransitionend: null,
    closetransitionend: null
  };

})(jQuery);