/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

(function(window, angular, undefined){
  'use strict';

  var module = angular.module('nsPopover', []);
  var $el = angular.element;
  var isDef = angular.isDefined;
  var $popovers = [];
  var globalId = 0;

  module.provider('nsPopover', function () {
    var defaults = {
      template: '',
      theme: 'ns-popover-list-theme',
      plain: 'false',
      trigger: 'click',
      triggerPrevent: true,
      angularEvent: '',
      scopeEvent: '',
      container: 'body',
      placement: 'bottom|left',
      timeout: 1.5,
      hideOnInsideClick: false,
      hideOnOutsideClick: true,
      hideOnButtonClick: true,
      mouseRelative: '',
      popupDelay: 0
    };

    this.setDefaults = function(newDefaults) {
      angular.extend(defaults, newDefaults);
    };

    this.$get = function () {
      return {
        getDefaults: function () {
          return defaults;
        }
      };
    };
  });

  module.directive('nsPopover', ['nsPopover','$rootScope','$timeout','$templateCache','$q','$http','$compile','$document','$parse',
    function(nsPopover, $rootScope, $timeout, $templateCache, $q, $http, $compile, $document, $parse) {
      return {
        restrict: 'A',
        scope: true,
        link: function(scope, elm, attrs) {
          var defaults = nsPopover.getDefaults();

          var options = {
            template: attrs.nsPopoverTemplate || defaults.template,
            theme: attrs.nsPopoverTheme || defaults.theme,
            plain: toBoolean(attrs.nsPopoverPlain || defaults.plain),
            trigger: attrs.nsPopoverTrigger || defaults.trigger,
            triggerPrevent: attrs.nsPopoverTriggerPrevent || defaults.triggerPrevent,
            angularEvent: attrs.nsPopoverAngularEvent || defaults.angularEvent,
            scopeEvent: attrs.nsPopoverScopeEvent || defaults.scopeEvent,
            container: attrs.nsPopoverContainer || defaults.container,
            placement: attrs.nsPopoverPlacement || defaults.placement,
            timeout: attrs.nsPopoverTimeout || defaults.timeout,
            hideOnInsideClick: toBoolean(attrs.nsPopoverHideOnInsideClick || defaults.hideOnInsideClick),
            hideOnOutsideClick: toBoolean(attrs.nsPopoverHideOnOutsideClick || defaults.hideOnOutsideClick),
            hideOnButtonClick: toBoolean(attrs.nsPopoverHideOnButtonClick || defaults.hideOnButtonClick),
            mouseRelative: attrs.nsPopoverMouseRelative,
            popupDelay: attrs.nsPopoverPopupDelay || defaults.popupDelay,
            group: attrs.nsPopoverGroup
          };

          if (options.mouseRelative) {
            options.mouseRelativeX = options.mouseRelative.indexOf('x') !== -1;
            options.mouseRelativeY = options.mouseRelative.indexOf('y') !== -1;
          }

          var displayer_ = {
            id_: undefined,

            /**
             * Set the display property of the popover to 'block' after |delay| milliseconds.
             *
             * @param delay {Number}  The time (in seconds) to wait before set the display property.
             * @param e {Event}  The event which caused the popover to be shown.
             */
            display: function(delay, e) {
              // Disable popover if ns-popover value is false
              if ($parse(attrs.nsPopover)(scope) === false) {
                return;
              }

              $timeout.cancel(displayer_.id_);

              if (!isDef(delay)) {
                delay = 0;
              }

              // hide any popovers being displayed
              if (options.group) {
                $rootScope.$broadcast('ns:popover:hide', options.group);
              }

              displayer_.id_ = $timeout(function() {
                $popover.isOpen = true;
                $popover.css('display', 'block');

                // position the popover accordingly to the defined placement around the
                // |elm|.
                var elmRect = getBoundingClientRect(elm[0]);

                // If the mouse-relative options is specified we need to adjust the
                // element client rect to the current mouse coordinates.
                if (options.mouseRelative) {
                  elmRect = adjustRect(elmRect, options.mouseRelativeX, options.mouseRelativeY, e);
                }

                move($popover, placement_, align_, elmRect, $triangle);

                if (options.hideOnInsideClick) {
                  // Hide the popover without delay on the popover click events.
                  $popover.on('click', insideClickHandler);
                }
                if (options.hideOnOutsideClick) {
                  // Hide the popover without delay on outside click events.
                  $document.on('click', outsideClickHandler);
                }
                if (options.hideOnButtonClick) {
                  // Hide the popover without delay on the button click events.
                  elm.on('click', buttonClickHandler);
                }
              }, delay*1000);
            },

            cancel: function() {
              $timeout.cancel(displayer_.id_);
            }
          };

          var hider_ = {
            id_: undefined,

            /**
             * Set the display property of the popover to 'none' after |delay| milliseconds.
             *
             * @param delay {Number}  The time (in seconds) to wait before set the display property.
             */
            hide: function(delay) {
              $timeout.cancel(hider_.id_);

              // delay the hiding operation for 1.5s by default.
              if (!isDef(delay)) {
                delay = 1.5;
              }

              hider_.id_ = $timeout(function() {
                $popover.off('click', insideClickHandler);
                $document.off('click', outsideClickHandler);
                elm.off('click', buttonClickHandler);
                $popover.isOpen = false;
                displayer_.cancel();
                $popover.css('display', 'none');
              }, delay*1000);
            },

            cancel: function() {
              $timeout.cancel(hider_.id_);
            }
          };

          var $container = $document.find(options.container);
          if (!$container.length) {
            $container = $document.find('body');
          }

          var $triangle;
          var placement_;
          var align_;

          globalId += 1;

          var $popover = $el('<div id="nspopover-' + globalId +'"></div>');
          $popovers.push($popover);

          var match = options.placement
              .match(/^(top|bottom|left|right)$|((top|bottom)\|(center|left|right)+)|((left|right)\|(center|top|bottom)+)/);

          if (!match) {
            throw new Error('"' + options.placement + '" is not a valid placement or has a invalid combination of placements.');
          }

          placement_ = match[6] || match[3] || match[1];
          align_ = match[7] || match[4] || match[2] || 'center';

          $q.when(loadTemplate(options.template, options.plain)).then(function(template) {
            template = angular.isString(template) ?
                template :
                template.data && angular.isString(template.data) ?
                    template.data :
                    '';

            $popover.html(template);

            if (options.theme) {
              $popover.addClass(options.theme);
            }

            // Add classes that identifies the placement and alignment of the popver
            // which allows the customization of the popover based on its position.
            $popover
                .addClass('ns-popover-' + placement_ + '-placement')
                .addClass('ns-popover-' + align_ + '-align');

            $compile($popover)(scope);

            scope.$on('$destroy', function() {
              $popover.remove();
            });

            scope.hidePopover = function() {
              hider_.hide(0);
            };

            scope.$on('ns:popover:hide', function(ev, group) {
              if (options.group === group) {
                scope.hidePopover();
              }
            });

            $popover
                .css('position', 'absolute')
                .css('display', 'none');

            //search for the triangle element - works in ie8+
            $triangle = $popover[0].querySelectorAll('.triangle');
            //if the element is found, then convert it to an angular element
            if($triangle.length){
              $triangle = $el($triangle);
            }

            $container.append($popover);
          });

          if (options.angularEvent) {
            $rootScope.$on(options.angularEvent, function() {
              hider_.cancel();
              displayer_.display(options.popupDelay);
            });
          } else if (options.scopeEvent) {
            scope.$on(options.scopeEvent, function() {
              hider_.cancel();
              displayer_.display($popover, options.popupDelay);
            });
          } else {
            elm.on(options.trigger, function(e) {
              if (false !== options.triggerPrevent) {
                e.preventDefault();
              }
              hider_.cancel();
              displayer_.display(options.popupDelay, e);
            });
          }

          elm
              .on('mouseout', function() {
                hider_.hide(options.timeout);
              })
              .on('mouseover', function() {
                hider_.cancel();
              });

          $popover
              .on('mouseout', function(e) {
                hider_.hide(options.timeout);
              })
              .on('mouseover', function() {
                hider_.cancel();
              });

          /**
           * Move the popover to the |placement| position of the object located on the |rect|.
           *
           * @param popover {Object} The popover object to be moved.
           * @param placement {String} The relative position to move the popover - top | bottom | left | right.
           * @param align {String} The way the popover should be aligned - center | left | right.
           * @param rect {ClientRect} The ClientRect of the object to move the popover around.
           * @param triangle {Object} The element that contains the popover's triangle. This can be null.
           */
          function move(popover, placement, align, rect, triangle) {
            var popoverRect = getBoundingClientRect(popover[0]);
            var top, left;

            var positionX = function() {
              if (align === 'center') {
                return Math.round(rect.left + rect.width/2 - popoverRect.width/2);
              } else if(align === 'right') {
                return rect.right - popoverRect.width;
              }
              return rect.left;
            };

            var positionY = function() {
              if (align === 'center') {
                return Math.round(rect.top + rect.height/2 - popoverRect.height/2);
              } else if(align === 'bottom') {
                return rect.bottom - popoverRect.height;
              }
              return rect.top;
            };

            if (placement === 'top') {
              top = rect.top - popoverRect.height;
              left = positionX();
            } else if (placement === 'right') {
              top = positionY();
              left = rect.right;
            } else if (placement === 'bottom') {
              top = rect.bottom;
              left = positionX();
            } else if (placement === 'left') {
              top = positionY();
              left = rect.left - popoverRect.width;
            }

            popover
                .css('top', top.toString() + 'px')
                .css('left', left.toString() + 'px');

            if (triangle) {
              if (placement === 'top' || placement === 'bottom') {
                left = rect.left + rect.width / 2 - left;
                triangle.css('left', left.toString() + 'px');
              } else {
                top = rect.top + rect.height / 2 - top;
                triangle.css('top', top.toString()  + 'px');
              }
            }
          }

          /**
           * Adjust a rect accordingly to the given x and y mouse positions.
           *
           * @param rect {ClientRect} The rect to be adjusted.
           */
          function adjustRect(rect, adjustX, adjustY, ev) {
            // if pageX or pageY is defined we need to lock the popover to the given
            // x and y position.
            // clone the rect, so we can manipulate its properties.
            var localRect = {
              bottom: rect.bottom,
              height: rect.height,
              left: rect.left,
              right: rect.right,
              top: rect.top,
              width: rect.width
            };

            if (adjustX) {
              localRect.left = ev.pageX;
              localRect.right = ev.pageX;
              localRect.width = 0;
            }

            if (adjustY) {
              localRect.top = ev.pageY;
              localRect.bottom = ev.pageY;
              localRect.height = 0;
            }

            return localRect;
          }

          function getBoundingClientRect(elm) {
            var w = window;
            var doc = document.documentElement || document.body.parentNode || document.body;
            var x = (isDef(w.pageXOffset)) ? w.pageXOffset : doc.scrollLeft;
            var y = (isDef(w.pageYOffset)) ? w.pageYOffset : doc.scrollTop;
            var rect = elm.getBoundingClientRect();

            // ClientRect class is immutable, so we need to return a modified copy
            // of it when the window has been scrolled.
            if (x || y) {
              return {
                bottom:rect.bottom+y,
                left:rect.left + x,
                right:rect.right + x,
                top:rect.top + y,
                height:rect.height,
                width:rect.width
              };
            }
            return rect;
          }

          function toBoolean(value) {
            if (value && value.length !== 0) {
              var v = ("" + value).toLowerCase();
              value = (v == 'true');
            } else {
              value = false;
            }
            return value;
          }

          /**
           * Load the given template in the cache if it is not already loaded.
           *
           * @param template The URI of the template to be loaded.
           * @returns {String} A promise that the template will be loaded.
           * @remarks If the template is null or undefined a empty string will be returned.
           */
          function loadTemplate(template, plain) {
            if (!template) {
              return '';
            }

            if (angular.isString(template) && plain) {
              return template;
            }

            return $templateCache.get(template) || $http.get(template, { cache : true });
          }

          function insideClickHandler() {
            if ($popover.isOpen) {
              hider_.hide(0);
            }
          }

          function outsideClickHandler(e) {
            if ($popover.isOpen && e.target !== elm[0]) {
              var id = $popover[0].id;
              if (!isInPopover(e.target)) {
                hider_.hide(0);
              }
            }

            function isInPopover(el) {
              if (el.id === id) {
                return true;
              }

              var parent = angular.element(el).parent()[0];

              if (!parent) {
                return false;
              }

              if (parent.id === id) {
                return true;
              }
              else {
                return isInPopover(parent);
              }
            }
          }

          function buttonClickHandler() {
            if ($popover.isOpen) {
              hider_.hide(0);
            }
          }
        }
      };
    }
  ]);
})(window, window.angular);
