﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Glossary.js" company="Wellpoint">
//   Copyright (c) Wellpoint Inc.  All rights reserved.
// </copyright>
// <summary>
//   Contains the logic for displaying glossary definitions in styled tool tips that stay open
//   for a period of time after the mouse leaves the glossary term text.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

(function($) {

  $.GlossaryConstants = {
    // The period of time in milliseconds by which the closure of the tool tip must be delayed
    closureDelay: 750
  };

  $.GlossaryGlobals = {
    // The ID of the timer that is used to delay the closure of the tool tip
    timerId: null
  };

  // Handles the event that is raised when the page is loaded.
  // Creates a specific span element on the page for displaying the styled glossary definition
  // tool tips.
  // Prepares all glossary term dfn elements in the page so that the styled tool tip will be
  // displayed instead of the standard tool tip when the mouse hovers over those elements.
  $(document).ready(function() {
    var toolTipSpan = "<span id='__GlossaryToolTip' class='glossaryToolTip'>" +
      "<span class='tooltip-pointer'><span class='tooltip-pointer-inner'></span></span>" +
      "<span class='tooltip-content'></span></span>";
    $("body").registerGlossaryTerms().append(toolTipSpan);
  });

  // Prepares all glossary term dfn elements contained within the object element so that the
  // styled tool tip will be displayed instead of the standard tool tip when the mouse hovers
  // over those elements.
  // This method is called by the document.ready event handlers to prepare all glossary term dfn
  // elements that are contained in the page when the page is loaded. jQuery functions that load
  // HTML dynamically through AJAX calls should also call this function to prepare any glossary
  // term dfn elements that may be contained within the loaded HTML.
  $.fn.registerGlossaryTerms = function() {
    $("dfn.glossaryTerm[title]", $(this)).each(function() {
      $(this).data("title", $(this).attr("title")).
              removeAttr("title").
              mouseenter(function() {
                $(this).showDefinition();
              }).
              mouseleave(function() {
                $(this).hideDefinition();
              });
    });
    return $(this);
  };

  // Shows the styled definition tool tip associated with the object element after hiding any
  // other glossary definition tool tip that may be either open or in the process of being closed.
  $.fn.showDefinition = function() {
    var $glossaryToolTip = $("#__GlossaryToolTip");
    if ($.GlossaryGlobals.timerId) {
      window.clearTimeout($.GlossaryGlobals.timerId);
      $.GlossaryGlobals.timerId = null;
    }
    $glossaryToolTip.hide();
    var elementOffset = $(this).offset();
    var toolTipTop = elementOffset.top + $(this).height() + 8;
    var toolTipLeft = elementOffset.left;
    $glossaryToolTip.css({ top: toolTipTop, left: toolTipLeft });
    $(".tooltip-content", $glossaryToolTip).text($(this).data("title"));
    $glossaryToolTip.show();
    return $(this);
  };

  // Hides the styled definition tool tip associated with the object element after waiting for
  // a fixed period of time.
  $.fn.hideDefinition = function() {
    var $glossaryToolTip = $("#__GlossaryToolTip");
    var $pointer = $(".tooltip-pointer", $glossaryToolTip);
    $.GlossaryGlobals.timerId = window.setTimeout(function() {
      if ($.GlossaryGlobals.timerId !== null) {
        $.GlossaryGlobals.timerId = null;
        // First hide the pointer part of the tooltip because it does not fade out gracefully
        $pointer.hide();
        // Fading out seems to cause problems if the duration is not set to "fast"
        $glossaryToolTip.fadeOut("fast", function() { $pointer.show(); });
      }
    }, $.GlossaryConstants.closureDelay);
    return $(this);
  };

  // Immediately closes any open glossary definition tool tip.
  $.fn.closeGlossaryDefinition = function() {
    $("#__GlossaryToolTip").hide();
    return $(this);
  };

  // Calls the Glossary web service to process glossary terms in the specified HTML string.
  // If and when the web service call completes successfully, the transformed HTML is loaded into the
  // object element, and all glossary term dfn elements in the loaded content are set to display styled
  // tool tips.
  // If asyncValue is true, the transformation and loading are performed asynchronously. If asyncValue
  // is omitted, the default is false (i.e., synchronous).
  $.fn.transformAndLoad = function(inputHtml, asyncValue) {

    asyncValue = asyncValue === undefined ? false : asyncValue;
    var params = { inputHtml: inputHtml };
    var $targetElement = $(this);
    var transformedHtml = null;

    // Using CallWCFModel function from Global.js
    CallWCFModel(
      "POST",
      "GlossaryService.asmx/Transform",
      JSON.stringify(params),
      function(response) {
        transformedHtml = JSON.parse(response);
        $targetElement.loadTransformedHtml(inputHtml, transformedHtml);
      },
      asyncValue);

    return $(this);
  };

  // Called when the Glossary web service call initiated by the transformAndLoad function completes
  // successfully.
  // Loads the transformed HTML into the object element and prepares all glossary term dfn elements in
  // the loaded content to display styled tool tips.
  $.fn.loadTransformedHtml = function(originalHtml, transformedHtml) {
    var displayHtml = transformedHtml === null ? originalHtml : transformedHtml;
    $(this).html(displayHtml).registerGlossaryTerms();
    return $(this);
  };

})(jQuery);

