(function () {
  var nTimer = setInterval(function () {
    if (window.jQuery) {
      clearInterval(nTimer);

      initEvents();
    }
  }, 100);
})();

function initEvents() {
  $(function () {
    $tooltip = $("#modalTooltip");

    $("a").on("mouseover", function () {
      var $link = $(this);

      var params = {
        name: $(this).text(),
      };

      var request = $.ajax({
        url: dbPediaUrl + "?" + $.param(params),
        method: "GET",
        dataType: "json",
        beforeSend: function (xhr) {
          // $(document.body).css({ cursor: "wait" });

          xhr.setRequestHeader("Authorization", "Bearer " + authToken);
        },
      });

      request.done(function (resp) {
        if (Object.keys(resp).length) {
          $tooltip.find("img").remove();
          $tooltip.find("p").remove();

          if (
            (resp.imgSrc && resp.imgSrc.length) ||
            (resp.birthPlace && resp.birthPlace.length) ||
            (resp.birthDate && resp.birthDate.length) ||
            (resp.location && resp.location.length) ||
            (resp.founder && resp.founder.length) ||
            (resp.companyType && resp.companyType.length) ||
            (resp.numberOfEmployees && resp.numberOfEmployees.length)
          ) {
            var paragraph = document.createElement("p");

            if (resp.imgSrc) {
              var img = new Image();
              img.src = resp.imgSrc;
              $(img).addClass("left-img");
              $(img).appendTo($(paragraph));
            }

            if (resp.birthPlace || resp.birthDate) {
              $(paragraph).append(
                (resp.birthPlace
                  ? "<span class='bold'>Birth place:&nbsp;</span>" +
                    "<span>" +
                    resp.birthPlace +
                    "</span>"
                  : "") +
                  (resp.birthDate
                    ? "<br />" +
                      "<span class='bold'>Birth date:&nbsp;</span>" +
                      "<span>" +
                      resp.birthDate +
                      "</span>"
                    : "")
              );
            }

            if (resp.location || resp.founder || resp.numberOfEmployees) {
              $(paragraph).append(
                (resp.location
                  ? "<span class='bold'>Location:&nbsp;</span>" +
                    "<span>" +
                    resp.location +
                    "</span>"
                  : "") +
                  (resp.founder
                    ? "<br />" +
                      "<span class='bold'>Founder:&nbsp;</span>" +
                      "<span>" +
                      resp.founder +
                      "</span>"
                    : "") +
                  (resp.companyType
                    ? "<br />" +
                      "<span class='bold'>Type:&nbsp;</span>" +
                      "<span>" +
                      resp.companyType +
                      "</span>"
                    : "") +
                  (resp.numberOfEmployees
                    ? "<br />" +
                      "<span class='bold'>Numver of employees:&nbsp;</span>" +
                      "<span>" +
                      resp.numberOfEmployees +
                      "</span>"
                    : "")
              );
            }

            $($tooltip).append($(paragraph));
          }

          if (
            (resp.spouse && resp.spouse.length) ||
            (resp.children && resp.children.length)
          ) {
            $($tooltip).append(
              "<p>" +
                (resp.spouse
                  ? "<span class='bold'>Spouse:&nbsp;</span>" +
                    "<span>" +
                    resp.spouse +
                    "</span>"
                  : "") +
                (resp.children && resp.children.length
                  ? "<br />" +
                    "<span class='bold'>Children:&nbsp;</span>" +
                    "<span>" +
                    (resp.children || []).join(", ") +
                    "</span>"
                  : "") +
                "</p>"
            );
          }

          if (resp.abstract) {
            $($tooltip).append(
              "<p>" +
                "<span class='bold'>Abstract:&nbsp;</span>" +
                (resp.abstract || "").split(".").slice(0, 2).join(".") +
                "</p>"
            );
          }

          if ($($tooltip).children().length) {
            positionAndShow($tooltip, $link);
          }
        }
      });

      request.fail(function (jqXHR, textStatus, errorThrown) {});

      request.always(function () {
        // $(document.body).css({ cursor: "default" });
      });
    });

    $("a").on("mouseout blur click", function () {
      hide($tooltip);
    });

    var scrollHandler = function() {
      if ($tooltip) {
        hide($tooltip);
      }
    }

    $(document).off("scroll", scrollHandler);

    $(document).on("scroll", scrollHandler);

    // the root html element. For window dimensions
    var html = document.getElementsByTagName("html")[0];

    var getMetrics = function (el) {
      var area = getOffset(el);
      return area;
    };

    var getOffset = function (el) {
      var x = el.offsetLeft,
        y = el.offsetTop,
        w = el.offsetWidth,
        h = el.offsetHeight;
      while ((el = el.offsetParent)) {
        x += el.offsetLeft;
        y += el.offsetTop;
      }
      return {
        left: x,
        top: y,
        width: w,
        height: h,
        mid_x: x + w / 2,
        mid_y: y + h / 2,
      };
    };

    // get the tooltip border width
    var getBorderWidth = function () {
      // IE lte 8 case
      if (!window.getComputedStyle) return 1; // EAT THIS AND LIKE IT, IE.

      var s = getComputedStyle($tooltip[0]);

      // if the border is none, the border-width is 0
      if (s.getPropertyValue("border") == "none") {
        return 0;
      } else {
        return parseInt(s.getPropertyValue("border-width"), 10);
      }
    };

    // spacing values
    // margin so that the tooltip is not touching any edges
    var margin = 1;
    // tooltip border width
    var bdw = getBorderWidth();
    // the size of the caret
    var caretSize = 5;
    // caret overlap on the target
    var caretOvr = 0;
    if (caretOvr > 0) caretOvr = caretOvr + margin + bdw;
    // the left offset from the caret midpoint, if the tooltip is wide enough
    var leftOffset = -30;

    function show($tooltip) {
      $tooltip.css("display", "inline-block");
    }

    function hide($tooltip) {
      $tooltip.css("display", "none");
    }

    function positionAndShow($tooltip, $element) {
      // reset tooltip styles
      $tooltip.css({
        position: "fixed",
        "z-index": "9999999",
        "box-sizing": "border-box",
        // width: "auto",
      });

      // show the tooltip now. Must be visible to get dimensions.
      show($tooltip);

      // get tooltip element's metrics
      var tt = getMetrics($tooltip[0]);
      // get the target element's metrics
      // var tgt = angular.copy(element[0].getBoundingClientRect());
      var tgt = $.extend({}, $element[0].getBoundingClientRect());
      if (!tgt.width) {
        tgt.width = tgt.right - tgt.left;
        tgt.height = tgt.top - tgt.bottom;
      }
      tgt.mid_x = tgt.right - tgt.width / 2;
      tgt.mid_y = tgt.bottom - tgt.height / 2;

      // the window's screen dimensions
      var screen = {
        width: html.clientWidth,
        height: html.clientHeight,
      };

      // if the target element is wider than the leftOffset,
      if (leftOffset < tgt.width / 2) {
        // make leftOffset bigger
        leftOffset = -tgt.width / 2;
      }

      // if the tooltip width is too small for the leftOffset
      if (tt.width / 2 < -leftOffset) {
        // reduce leftOffset
        leftOffset = -tt.width / 2;
      }

      // Position left

      // if the tooltip is too wide for the screen
      if (margin + tt.width + margin > screen.width) {
        // make the tooltip full-width
        tt.left = 0 + margin;
        tt.width = screen.width - margin - margin;
      }
      // if the tooltip is less wide than the screen
      else {
        // if there isn't enough space to the right
        if (tgt.mid_x + leftOffset + tt.width + margin > screen.width) {
          tt.left = screen.width - margin - tt.width;
        }
        // if there isn't enough space to the left
        else if (tgt.mid_x + leftOffset < 0 + margin) {
          // place tooltip at left edge
          tt.left = 0 + margin;
          //tt.width = 'auto';
        }
        // if there are no overflow problems
        else {
          // place tooltip at middle of target, offset
          tt.left = tgt.mid_x + leftOffset;
          //tt.width = 'auto';
        }
      }
      $tooltip.css({
        left: tt.left + "px",
        // width: tt.width + "px",
      });
      // recompute the metrics for the tooltip, since we may have changed its width
      tt = getMetrics($tooltip[0]);

      // Position top

      // if there's space above
      if (tgt.top > margin + tt.height + caretSize + margin) {
        // put it above
        tt.top = tgt.top /* - margin*/ - caretSize - tt.height + caretOvr;
        $tooltip.css("top", tt.top + "px");
        // caret arrow goes below
        // $tooltip.removeClass("arr-above");
        // $tooltip.addClass("arr-below");
      } else {
        // put it below. If there's not enough space there either, then too bad
        tt.top = tgt.top + tgt.height /* + margin*/ + caretSize - caretOvr;
        $tooltip.css("top", tt.top + "px");
        // caret arrow goes below
        // $tooltip.addClass("arr-above");
        // $tooltip.removeClass("arr-below");
      }
    }
  });
}
