﻿// --------------------------------------------------------
// <copyright file="CommonControls.js" company="Wellpoint">
//   Copyright (c) Wellpoint Inc.  All rights reserved.
// </copyright>
// --------------------------------------------------------


// <summary>
// Client script used by the CommonContentControl control
// </summary>
var commonContentControl = {
  // Declares the message types that this control will accept
  // This variable is used to setup the control with the observer
  acceptedMessagesTypes: 'SetCommonContentBlock;SetCommonContentData',
  controlIdentifier: 'commoncontentcontrol',
  isInitialized: false,
  regexPlaceholder: new RegExp("\{[0]\}")
};

// Handle messages from other controls
commonContentControl.handleObserverNotification = function(message) {
  var messagedata = JSON.parse(message);
  switch (messagedata.messagetype) {
    case 'SetCommonContentBlock':
      commonContentControl.setBlock(messagedata.controlid, messagedata.block);
      break;
    case 'SetCommonContentData':
      commonContentControl.setData(messagedata.controlid, messagedata.key, messagedata.value);
      break;
  }
};

// Save the current block to the hidden input and update the content
commonContentControl.setBlock = function(controlid, block) {
  if (!block) {
    block = "";
  }
  var blockStorage = $("#" + controlid + " .CommonContentBlockStorage");
  if (block != blockStorage.val()) {
    blockStorage.val(block);
    $("#" + controlid).slideUp('fast', function() {
      commonContentControl.requestContent({ controlid: controlid, block: block });
    });
  }
};

// Change one of the filter values and get new data
commonContentControl.setFilterValue = function(controlid, key, value, callback) {
  var filterStorage = $("#" + controlid + " .ContentFilterStorage");
  var filter = JSON.parse(filterStorage.val());
  filter[key] = value;
  filterStorage.val(JSON.stringify(filter));

  var blockStorage = $("#" + controlid + " .CommonContentBlockStorage");
  var block = blockStorage.val();
  $("#" + controlid).slideUp('fast', function() {
    commonContentControl.requestContent({ controlid: controlid, block: block }, callback);
  });
};

// Save some data to the control
commonContentControl.setData = function(controlid, key, value) {
  var dataStorage = $("#" + controlid + " .CommonContentDataStorage");
  if (dataStorage.length < 1) {
    alert("Can't find control: '" + controlid + "'");
  }
  var datastring = dataStorage.val();
  var data;
  try {
    data = JSON.parse(datastring);
  } catch (ex) {
    alert("Can't parse old common content data: '" + datastring + "'");
    return;
  }
  data[key] = value;
  dataStorage.val(JSON.stringify(data));
  commonContentControl.processData(controlid);
};

commonContentControl.processData = function(controlid) {
    var dataStorage = $("#" + controlid + " .CommonContentDataStorage");
    var datastring = dataStorage.val();
    var data;
    try {
        data = JSON.parse(datastring);
    } catch (ex) {
        //alert("Can't parse common content data: '" + datastring + "'");
    }
    if ((data != null) && ($.isEmptyObject(data) == false) && (data["PlaceholderKey"] !== null)) {
        commonContentControl.processPlaceholder(controlid, data["PlaceholderKey"]);
    } else {
        // Content has a placeholder, but we have no data - use blank
        if (commonContentControl.hasSavedOriginalContent(controlid)) {
            var origContent = commonContentControl.getOriginalContent(controlid);
            if (origContent.match(commonContentControl.regexPlaceholder) != null) {
                commonContentControl.processPlaceholder(controlid, "");
            }
        } else {
            var content = commonContentControl.getContent(controlid);
            if (content.match(commonContentControl.regexPlaceholder) != null) {
                commonContentControl.processPlaceholder(controlid, "");
            }
        }
    }
};

commonContentControl.processPlaceholder = function(controlid, placeholderKey) {
  if (commonContentControl.hasSavedOriginalContent(controlid) == false) {
    commonContentControl.saveOriginalContent(controlid);
  }
  var newContent = commonContentControl.getOriginalContent(controlid);

  var regexPlaceholderMap = new RegExp("\{\{[^\}]*\}\}");

  // Process the map
  var placeholderValue = "";
  var map = newContent.match(regexPlaceholderMap);
  if (map != null) {
    map = map[0];
    map = map.replace("{{", "{").replace("}}", "}");
    var mapObj;
    try {
      mapObj = JSON.parse(map);
    } catch (ex) {
      alert("Error parsing common content placeholder map: " + map);
      mapObj = null;
    }
    if (mapObj != null) {
      placeholderValue = mapObj[placeholderKey];
      if (placeholderValue == null) {
        placeholderValue = "";
      }
    }

    // Remove the map from the output
    newContent = newContent.replace(regexPlaceholderMap, "");
  }

  // Use the found value from the map or blank if not found
  newContent = newContent.replace(commonContentControl.regexPlaceholder, placeholderValue);

  var contentBody = $("#" + controlid + " div.commoncontent")[0];
  contentBody.innerHTML = newContent;
};

// Service call to retrive updated content
commonContentControl.requestContent = function(options, callback) {
  var defaults = {};
  var settings = $.extend(defaults, options);

  var filterStorage = $("#" + settings.controlid + " .ContentFilterStorage");
  var filter = JSON.parse(filterStorage.val());
  var params = {
    block: settings.block,
    contentFilter: filter
  };
  var paramsString = JSON.stringify(params);

  try {
    $.ajax({
      type: "POST",
      controlid: settings.controlid,
      url: "/ols/CommonContentService.asmx/GetCommonContent",
      data: paramsString,
      contentType: "application/json; charset=utf-8",
      dataType: "json",
      dataFilter: function(response) {
        var jsonObject = JSON.parse(response);
        if (jsonObject.d) {
          jsonObject = jsonObject.d;
        }
        return JSON.stringify(jsonObject);
      },
      success: function(data) {
        var newContent = JSON.parse(data);
        if (newContent == null) {
          alert("Cannot retrieve common content.");
        } else {
          commonContentControl.processNewContent(this.controlid, newContent, settings.block, callback);
        }
        return false;
      },
      error: function(xhr, ajaxOptions, errorThrown) {
        // AJAX call failed
        alert("Cannot retrieve common content (" + (errorThrown ? errorThrown : xhr.Status) + ").");
      },
      async: true
    });
  } catch (err) {
    alert(err.description);
  }
};

// Process the response from the requestContent call
commonContentControl.processNewContent = function(controlid, newContent, block, callback) {
  var contentBody = $("#" + controlid + " div.commoncontent");
  contentBody.removeClass();
  contentBody.addClass("stellent commoncontent block_" + block);
  contentBody.html(newContent);
  commonContentControl.clearOriginalContent(controlid);
  commonContentControl.processData(controlid);
  $("#" + controlid).slideDown('fast', callback);
};

commonContentControl.getOriginalContent = function(controlid) {
  var origContentBody = $("#" + controlid + " div.originalcontent")[0];
  return origContentBody.innerHTML;
};

commonContentControl.getContent = function(controlid) {
  var contentBody = $("#" + controlid + " div.commoncontent")[0];
  return contentBody.innerHTML;
};

commonContentControl.hasSavedOriginalContent = function(controlid) {
  return (commonContentControl.getOriginalContent(controlid) != "");
};

commonContentControl.saveOriginalContent = function(controlid) {
  var origContentBody = $("#" + controlid + " div.originalcontent")[0];
  var contentBody = $("#" + controlid + " div.commoncontent")[0];
  origContentBody.innerHTML = contentBody.innerHTML;
};

commonContentControl.clearOriginalContent = function(controlid) {
  var origContentBody = $("#" + controlid + " div.originalcontent")[0];
  origContentBody.innerHTML = "";
};

// Init the control
commonContentControl.Init = function() {
  if (commonContentControl.isInitialized == false) {
    commonContentControl.isInitialized = true;
    pageobserver.subscribe(commonContentControl.handleObserverNotification, commonContentControl.acceptedMessagesTypes, commonContentControl.controlIdentifier);
    commonContentControl.processDataAll();
  }
};

// Call ProccessData for each to process data set on the server
commonContentControl.processDataAll = function() {
  $(".CommonContentControl").each(function() {
    var control = $(this);
    commonContentControl.processData(control.attr('id'));
  });
};

(function($) {
  // Handles the event that is raised when the page is loaded
  $(document).ready(function() {
    if ($(".CommonContentControl").length) {
      commonContentControl.Init();
    }
  });

})(jQuery);    // End of CommonContentControl


/*****************
BreadCrumb control
******************/
(function($) {

  var breadCrumbControl = {
    // Declares the message types that this control will accept
    // This variable is used to setup the control with the 
    // observer
    acceptedmessagestypes: 'refreshbreadcrumb;refreshfindcovereddrugsbreadcrumb;fixbreadcrumblinks',
    initialized: false
  };

  /****************************************************
  Callback method for handling published notifications.
  The method parses the JSON message and makes an AJAX
  call to retrieve the persisted state from the model.
  *****************************************************/
  breadCrumbControl.handleObserverNotification = function(message) {
    var m = JSON.parse(message);

    // decide which message we need to handle
    switch (m.messagetype) {
      case 'fixbreadcrumblinks':
        breadCrumbControl.FixBreadcrumbLinks();
        break;
      case 'refreshbreadcrumb':
        CallWCFModel('POST', m.servicePoint + '/UpdateBreadCrumbInformation', '{ "index" : ' + m.breadCrumbIndex + ' }', breadCrumbControl.BreadCrumbCallSuccess);
        break;
      case 'refreshfindcovereddrugsbreadcrumb':
        CallWCFModel('POST', m.servicePoint + '/UpdateFindCoveredDrugsBreadCrumbInformation', '{ "index" : ' + m.breadCrumbIndex + ' }', breadCrumbControl.BreadCrumbCallSuccess);
        break;
      default:
        if (bDebug) {
          trace('Message type recieved in breadcrumb (' + m.messagetype + ') but there is no event handler for this message type!.');
        }
        break;
    }
  };

  /*********************************************************
  Called on the successful return of an
  Ajax call. It parses the response and sets up the carousel
  to indicate the new state as stored in the JSON object.
  **********************************************************/
  breadCrumbControl.BreadCrumbCallSuccess = function(response) {
    if (response !== null) {
      var htmlContent = '';
      for (var i = 0; i < response.BreadCrumbs.length; i++) {
        htmlContent = htmlContent + '<div class="stepContainer">';

        // check to see if we have a placeholder url
        if (response.BreadCrumbs[i].CDSPage == '#') {
          htmlContent = htmlContent + '<a class="breadcrumbLink" id="breadcrumbLink_' + i + '" href="#">';
        }
        else {
          var brandName = getBrandName();
          // if the brand is unicare then we link to the wizard page, also for standlone formulary in these brands we do not want to link to CostAndBenefits, we want to link to CDS page in response
          if ((brandName == "unicare" || brandName == "bcbsks" || brandName == "bcbskc") && i === 0 && response.BreadCrumbs[i].CDSPage.indexOf('StandAlone') == -1) {
            htmlContent = htmlContent + '<a class="breadcrumbLink" id="breadcrumbLink_' + i + '" href="/Shop/CostAndBenefits">';
          }
          else {
            htmlContent = htmlContent + '<a class="breadcrumbLink" id="breadcrumbLink_' + i + '" href="/Shop/' + response.BreadCrumbs[i].CDSPage + '">';
          }

        }
        if (response.BreadCrumbs[i].CurrentSection) {
          htmlContent = htmlContent + '<img src="' + response.BreadCrumbs[i].URLImageOn + '" alt="' + response.BreadCrumbs[i].Text + '"/>';
        }
        else {
          htmlContent = htmlContent + '<img src="' + response.BreadCrumbs[i].URLImageOff + '" alt="' + response.BreadCrumbs[i].Text + '"/>';
        }
        htmlContent = htmlContent + '</a>';
        htmlContent = htmlContent + '</div>&nbsp;';
      }
      $('#BreadCrumbContent').html(htmlContent);

      // Disable breadcrumbs that are beyond the current breadcrumb.
      breadCrumbControl.DisableLaterBreadCrumbs(response);
    }
    else {
      alert('null response');
    }
  };

  /*************************************************
  This method will disable breadcrumbs that are in
  later in sequence than the current breadcrumb link
  **************************************************/
  breadCrumbControl.DisableLaterBreadCrumbs = function(response) {
    for (var i = response.BreadCrumbs.length - 1; i >= 0; i--) {
      if (response.BreadCrumbs[i].CurrentSection || response.BreadCrumbs[i].CDSPage == 'ShoppingCart' || response.BreadCrumbs[i].CDSPage == 'Enroll') {
        break;
      }

      // Replace the image the disabled image and disable the link.
      var disabledImage = response.BreadCrumbs[i].URLImageDisabled ? response.BreadCrumbs[i].URLImageDisabled : response.BreadCrumbs[i].URLImageOff;
      $('#breadcrumbLink_' + i + ' img').attr('src', disabledImage);
      $('#breadcrumbLink_' + i + ' img').css('cursor', 'default');
      $('#breadcrumbLink_' + i).live("click", function(e) {
        e.preventDefault();
      });
    }
  };

  /************************************************************
  Ensures the first bread crumb redirects back to the home page
  *************************************************************/
  breadCrumbControl.FixBreadcrumbLinks = function() {
    $("#breadcrumbLink_0").attr("href", "/Shop");
  };

  /*****************************************
  Sets up the BreadCrumb control when loaded
  ******************************************/
  $(document).ready(function() {
    if ($('#BreadCrumbContent').length) {
      if (breadCrumbControl.initialized == false) {
        breadCrumbControl.initialized = true;
        pageobserver.subscribe(breadCrumbControl.handleObserverNotification, breadCrumbControl.acceptedmessagestypes, 'BreadCrumb');
      }
    }
  });

})(jQuery);       // End of BreadCrumbControl


// -----------------------
// <summary>
//   Social Media Links
// </summary>
// -----------------------
(function($) {

  var socialMediaLinks = {
    acceptedmessagestypes: 'SocialMediaLinksUpdate',
    media: ["http://www.delicious.com/save?v=5&noui&jump=close&url={URL}&title={TITLE}",
            "http://www.facebook.com/sharer.php?u={URL}&t={TITLE}",
            "http://www.stumbleupon.com/submit?url={URL}&title={TITLE}",
            "http://twitter.com/home?status=Currently reading {URL}&title={TITLE}",
            "http://www.myspace.com/Modules/PostTo/Pages/?u={URL}&title={TITLE}",
            "http://digg.com/submit?url={URL}&title={TITLE}"
            ],
    URL: "",
    Title: "",
    MediaConst: {
      delicious: 0,
      facebook: 1,
      stumbleUpon: 2,
      twitter: 3,
      mySpace: 4,
      digg: 5
    },
    MediaWindowConst: {
      width: 500,
      height: 600,
      menubar: 'yes',
      toolbar: 'no',
      scrollbars: 'yes',
      location: 'yes',
      resizable: 'yes'
    }
  };

  /***********************************************
  Sets up page parameter of each social media link
  ************************************************/
  socialMediaLinks.UpdateSocialMediaPageLink = function(url, title) {
    socialMediaLinks.URL = url;
    socialMediaLinks.Title = title;
  };

  /************************************
  Opens the social media url in a popup
  *************************************/
  socialMediaLinks.openSocialMediaWindow = function(mediaId) {
    var options = 'menubar=' + socialMediaLinks.MediaWindowConst.menubar +
      ',toolbar=' + socialMediaLinks.MediaWindowConst.toolbar +
      ',scrollbars=' + socialMediaLinks.MediaWindowConst.scrollbars +
      ',location=' + socialMediaLinks.MediaWindowConst.location +
      ',status=' + socialMediaLinks.MediaWindowConst.status +
      ',resizable=' + socialMediaLinks.MediaWindowConst.resizable +
      ',width=' + socialMediaLinks.MediaWindowConst.width +
      ',height=' + socialMediaLinks.MediaWindowConst.height;
    var url = socialMediaLinks.buildMediaURL(mediaId);
    window.open(url, '', options);
  };

  /*******************************************
  Relace the media url place holders for url and title wit appropriate values
  ********************************************/
  socialMediaLinks.buildMediaURL = function(mediaId) {
    var url = socialMediaLinks.media[mediaId];
    url = url.replace("{URL}", socialMediaLinks.URL);
    url = url.replace("{TITLE}", socialMediaLinks.Title);
    return url;
  };

  /************************************
  Handle an observer event
  *************************************/
  socialMediaLinks.handleObserverNotification = function(message) {
    var m = JSON.parse(message);

    // decide which message we need to handle
    switch (m.messagetype) {
      case 'SocialMediaLinksUpdate':
        socialMediaLinks.UpdateSocialMediaPageLink(m.url, m.title);
        break;
      default:
        if (bDebug) {
          trace('Message type recieved in socialMediaLinks (' + m.messagetype + ') but there is no event handler for this message type!.');
        }
        break;
    }
  };

  /*******************************************
  Setup social media links when page is loaded
  ********************************************/
  $(document).ready(function() {
    if ($("#socialmedialinks").length) {
      $("#socialmedialinks .socialmedia_Delicious").bind('click', function(event) { event.preventDefault(); socialMediaLinks.openSocialMediaWindow(socialMediaLinks.MediaConst.delicious); });
      $("#socialmedialinks .socialmedia_Facebook").bind('click', function(event) { event.preventDefault(); socialMediaLinks.openSocialMediaWindow(socialMediaLinks.MediaConst.facebook); });
      $("#socialmedialinks .socialmedia_StumbleUpon").bind('click', function(event) { event.preventDefault(); socialMediaLinks.openSocialMediaWindow(socialMediaLinks.MediaConst.stumbleUpon); });
      $("#socialmedialinks .socialmedia_Twitter").bind('click', function(event) { event.preventDefault(); socialMediaLinks.openSocialMediaWindow(socialMediaLinks.MediaConst.twitter); });
      $("#socialmedialinks .socialmedia_MySpace").bind('click', function(event) { event.preventDefault(); socialMediaLinks.openSocialMediaWindow(socialMediaLinks.MediaConst.mySpace); });
      $("#socialmedialinks .socialmedia_Digg").bind('click', function(event) { event.preventDefault(); socialMediaLinks.openSocialMediaWindow(socialMediaLinks.MediaConst.digg); });
      pageobserver.subscribe(socialMediaLinks.handleObserverNotification, socialMediaLinks.acceptedmessagestypes, 'SocialMediaLinks');
    }
  });

})(jQuery);     // End of SocialMediaLinks


// -----------------------
// <summary>
//   FaqControl
// </summary>
// -----------------------
(function($) {

  var faqControl = {
    // Declares the message types that this control will accept
    // This variable is used to setup the control with the 
    // observer
    acceptedMessagesTypes: 'SetFaqTopics;SetFaqFilters',
    controlIdentifier: 'faqcontrol',
    reloadNeeded: false,
    initialized: false
  };

  // Handle messages from other controls
  faqControl.handleObserverNotification = function(message) {
    var messagedata = JSON.parse(message);
    switch (messagedata.messagetype) {
      case 'SetFaqTopics':
        faqControl.setTopics(messagedata.topics, messagedata.options);
        break;
      case 'SetFaqFilters':
        faqControl.setFilters(messagedata.filters, messagedata.options);
        break;
    }
  };

  // Setup the more/less button click events
  faqControl.setupMoreLessButtons = function() {
    $("#FaqMoreButton").click(function() {
      $("#FaqMoreButton").addClass("hide");
      $("#FaqLessButton").removeClass("hide");
      $("#FaqControlContainer .FaqQuestionsMore").slideDown('fast');
      return false;
    });

    $("#FaqLessButton").click(function() {
      $("#FaqLessButton").addClass("hide");
      $("#FaqMoreButton").removeClass("hide");
      $("#FaqControlContainer .FaqQuestionsMore").slideUp('fast');
      return false;
    });
  };

  // Update the more/less buttons when a new list is recieved
  faqControl.updateMoreLessButtons = function() {
    if ($("#FaqControlContainer .FaqQuestionsMore").children().size() > 0) {
      $("#FaqMoreButton").removeClass("hide");
      $("#FaqLessButton").addClass("hide");
    } else {
      $("#FaqMoreButton").addClass("hide");
      $("#FaqLessButton").addClass("hide");
    }
  };

  // Save the current topics to the hidden input and update the list
  faqControl.setTopics = function(topics, options) {
    if (!topics) {
      topics = "";
    }

    var defaults = { reload: true };
    var settings = $.extend(defaults, options);

    var topicsChanged = (topics != $("#FaqTopicStorage").val());
    $("#FaqTopicStorage").val(topics);
    faqControl.setHeaderToolTip();

    if (topicsChanged == true) {
      faqControl.reloadNeeded = true;
    }
    if ((faqControl.reloadNeeded == true) && (settings.reload == true)) {
      $("#FaqControlContainer .FaqQuestionsMore").slideUp('fast');
      $("#FaqControlContainer .FaqQuestionsFirst").slideUp('fast', function() {
        faqControl.reloadNeeded = false;
        faqControl.requestFaqs({ topics: topics });
      });
    }
  };

  // Save the current filters to the hidden input and update the list
  faqControl.setFilters = function(filters, options) {
    if (!filters) {
      return;
    }

    var defaults = { reload: true };
    var settings = $.extend(defaults, options);

    var faqFilter = JSON.parse($("#FaqFilterStorage").val());
    var newFilter = $.extend(faqFilter, filters);
    $("#FaqFilterStorage").val(JSON.stringify(newFilter));

    if (settings.reload == true) {
      $("#FaqControlContainer .FaqQuestionsMore").slideUp('fast');
      $("#FaqControlContainer .FaqQuestionsFirst").slideUp('fast', function() {
        faqControl.reloadNeeded = false;
        faqControl.requestFaqs({ topics: faqControl.getTopics() });
      });
    } else {
      faqControl.reloadNeeded = true;
    }
  };

  // Get the current topics from the hidden input
  faqControl.getTopics = function() {
    return $("#FaqTopicStorage").val();
  };

  // Set the tool tip on the header element to the current topics
  faqControl.setHeaderToolTip = function() {
    $("#FaqControlContainer h2").attr("title", "Topics: " + faqControl.getTopics());
  };

  // Collapse the answers in both lists
  faqControl.collapseAllAnswers = function() {
    $("#FaqControlContainer .FaqQuestions dt").removeClass("open");
    $("#FaqControlContainer .FaqQuestions dt").addClass("closed");
    $("#FaqControlContainer .FaqQuestions dd").slideUp('fast');
  };

  // A Faq question has been clicked
  faqControl.setupAnswerExpandClick = function() {
    $("#FaqControlContainer .FaqQuestions").find('dt').each(function() {
      $this = $(this);

      // Move the text into an inner <a>
      $this.wrapInner("<a />");

      // Add a click funtion to the inner a to open the answer
      jQuery("a", this).click(function() {
        var question = $(this).parent();
        var answer = question.next('dd');
        var wasOpen = answer.is(':visible');
        faqControl.collapseAllAnswers();
        if (wasOpen == false) {
          question.removeClass("closed");
          question.addClass("open");
          answer.slideDown('fast');
        }
      });
    });
  };

  faqControl.setupHideAnswer = function() {
    $("#FaqControlContainer").find('.FaqHideAnswer').each(function() {
      $(this).removeClass("hide");
      $(this).click(function() {
        faqControl.collapseAllAnswers();
      });
    });
  };

  // Service call to retrive updated list of faqs
  faqControl.requestFaqs = function(options) {
    var defaults = {};
    var settings = $.extend(defaults, options);

    var faqLists = null;

    var faqFilterStorage = $("#FaqFilterStorage");
    if (faqFilterStorage.length == 0) {
      // FAQ control is missing from the page
      return;
    }
    $("#FaqErrorStorage").val('');
    var faqFilter = JSON.parse(faqFilterStorage.val());
    var params = {
      topics: settings.topics,
      contentFilter: faqFilter
    };

    var paramsString = JSON.stringify(params);

    // The following conversions are necessary for GET instead of POST
    paramsString = paramsString.replace('{"topics":', 'topics=');
    paramsString = paramsString.replace(',"contentFilter":', '&contentFilter=');
    paramsString = paramsString.replace('}}', '}');

    try {
      $.ajax({
        type: "GET",
        cache: true,
        url: $("#FaqBaseUrlStorage").val() + "FaqService.asmx/GetFaqs",
        data: paramsString,
        traditional: false,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        dataFilter: function(response) {
          if (response == null) {
            return null;
          }
          // should also check for an empty response
          if (response.length == 0) {
            return null;
          }
          try {
            var jsonObject = JSON.parse(response);
            if (jsonObject.d) {
              jsonObject = jsonObject.d;
            }
          } catch (ex) {
            $("#FaqErrorStorage").val("FAQ response problem (" + JSON.stringify(params) + ") [" + response + "]");
            return null;
          }
          return JSON.stringify(jsonObject);
        },
        success: function(data) {
          if (data != null) {
            try {
              faqLists = JSON.parse(data);
              faqControl.processNewFaqLists(faqLists);
            } catch (ex) {
              $("#FaqErrorStorage").val("Error parsing FAQ information (" + JSON.stringify(params) + ") [" + JSON.stringify(data) + "]");
            }
          }
          return false;
        },
        error: AjaxError,
        async: true
      });
    } catch (err) {
      alert(err.description);
    }
  };

  // Process the response from the getFaqs call
  faqControl.processNewFaqLists = function(faqlists) {
    var firstFaqs = faqlists.FirstFaqs;
    var moreFaqs = faqlists.MoreFaqs;
    var totalCount = faqlists.TotalCount;

    if (totalCount == 0) {
      $("#FaqControlContainer").slideUp('fast', function() {
        $("#FaqControlContainer").addClass("FaqControlHidden");
      });
    } else {
      $("#FaqControlContainer").removeClass("FaqControlHidden");
    }
    faqControl.formatFaqList(".FaqQuestionsFirst", firstFaqs);
    $("#FaqControlContainer .FaqQuestionsFirst").slideDown('fast');
    faqControl.formatFaqList(".FaqQuestionsMore", moreFaqs);
    faqControl.updateMoreLessButtons();
    faqControl.setupAnswerExpandClick();
    faqControl.setupHideAnswer();
    faqControl.collapseAllAnswers();
    var wasOpen = $("#FaqControlContainer").is(':visible');
    if (wasOpen == false) {
      $("#FaqControlContainer").slideDown('fast');
    }
  };

  // Format a single list of faqs (there are two)
  faqControl.formatFaqList = function(dlclass, faqlist) {

    var dl = $("#FaqControlContainer " + dlclass);

    // Remove existing items
    dl.children().remove();

    // Add new items
    if (faqlist.length > 0) {
      $.each(faqlist, function(index, value) {
        dl.append('<dt>' + value.Question + '</dt>');
        dl.append('<dd style="display:none">' + value.Answer + '<br /><a class="FaqHideAnswer" href="#hide">Hide Answer</a></dd>');
      });
    }
  };

  // Init the control
  faqControl.init = function() {
    $("#FaqControlContainer .FaqQuestions dd").hide();
    $("#FaqControlContainer .FaqQuestionsMore").hide();
    faqControl.collapseAllAnswers();
    faqControl.setupAnswerExpandClick();
    faqControl.setupHideAnswer();
    pageobserver.subscribe(faqControl.handleObserverNotification, faqControl.acceptedMessagesTypes, faqControl.controlIdentifier);
    faqControl.setupMoreLessButtons();
    faqControl.updateMoreLessButtons();
  };

  // Handles the event that is raised when the page is loaded
  $(document).ready(function() {
    if ($("#FaqControlContainer").length) {
      if (faqControl.initialized == false) {
        faqControl.initialized = true;
        faqControl.init();
      }
    }
  });

})(jQuery);                     /// End of FAQControl



// -----------------------
// <summary>
//   EmailControl
// </summary>
// -----------------------
(function($) {

  var emailControl = {
    // Declares the message types that this control will accept
    // This variable is used to setup the control with the observer
    acceptedMessagesTypes: 'EmailShowDialog',
    controlIdentifier: 'EmailControl',
    initialized: false
  };

  // Handle messages from other controls
  emailControl.handleEmailObserverNotification = function(message) {
    var messagedata = JSON.parse(message);
    switch (messagedata.messagetype) {
      case 'EmailShowDialog':
        emailControl.showEmailDialog(messagedata);
        break;
    }
  };

  emailControl.showEmailDialog = function(messagedata) {
    var defaults = {
      dialogTitle: "Send an Email",
      dialogMessage: $("#EmailControlContainer .EmailDialogMessage").val(),
      toAddresses: $("#EmailControlContainer .EmailToAddresses").val(),
      emailSubject: $("#EmailControlContainer .EmailSubjectEdit").val(),
      emailBody: $("#EmailControlContainer .EmailBodyEdit").val()
    };
    var settings = $.extend(defaults, messagedata);

    $("#EmailControlContainer .EmailDialogMessage").val(settings.dialogMessage);

    $("#EmailControlContainer .EmailToAddresses").val(settings.toAddresses);
    $("#EmailControlContainer .EmailSubjectEdit").val(settings.emailSubject);
    $("#EmailControlContainer .EmailBodyEdit").val(settings.emailBody);

    $("#EmailControlContainer").dialog({
      modal: true,
      position: 'center',
      autoOpen: false,
      width: 650,
      draggable: false,
      title: settings.dialogTitle,
      dialogClass: 'olsmodal',
      open: function() {
      }
    });

    $("#EmailControlContainer").dialog('open');
  };

  // Pass this to the email sending service
  emailControl.sendEmail = function() {

    var emailParams = JSON.parse($("#EmailParamStore").val());

    if ($("#EmailControlContainer .EmailFrom").is(':visible')) {
      emailParams.FromName = "";
      emailParams.FromAddress = $("#EmailControlContainer .EmailFrom").val();
    }

    emailParams.ToAddresses = $("#EmailControlContainer .EmailToAddresses").val();
    emailParams.CcAddresses = $("#EmailControlContainer .EmailCcAddresses").val();
    emailParams.EmailSubject = $("#EmailControlContainer .EmailSubjectEdit").val();
    emailParams.EmailBody = $("#EmailControlContainer .EmailBodyEdit").val();

    var params = {
      emailParams: emailParams,
      captchaRequest: getCaptchaRequest()
    };
    var emailParamString = JSON.stringify(params);
    try {
      var errorList = null;

      AjaxWorkingStart($(".EmailButtons"), '', { absolute: true });
      $.ajax({
        type: "POST",
        url: siteBaseURL + "EmailWebService.asmx/SendEmail",
        data: emailParamString,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        dataFilter: function(response) {
          var jsonObject = JSON.parse(response);
          if (jsonObject.d) {
            jsonObject = jsonObject.d;
          }
          return JSON.stringify(jsonObject);
        },
        success: function(data) {
          errorList = JSON.parse(data);
          if (errorList == null) {
            alert("Cannot send email information.");
          } else {
            emailControl.processSendEmailResponse(errorList);
          }
          return false;
        },
        error: AjaxError,
        complete: function() {
          AjaxWorkingDone($(".EmailButtons"), '', { absolute: true });
          reloadCaptcha();
        },
        async: true
      });
    } catch (err) {
      alert(err.description);
    }
  };

  // Process email service response
  emailControl.processSendEmailResponse = function(errorList) {
    if (errorList.length > 0) {
      alert(errorList);
    } else {
      alert("Email Sent");
      $('#EmailControlContainer').dialog('close');
    }
  };

  $.InitEmailControl = function() {
    if (emailControl.initialized == false) {
      emailControl.initialized = true;
      pageobserver.subscribe(emailControl.handleEmailObserverNotification, emailControl.acceptedMessagesTypes, emailControl.controlIdentifier);

      $("#EmailCancelButton").click(function() {
        $('#EmailControlContainer').dialog('close');
        return false;
      });

      $("#EmailSendButton").click(function() {
        emailControl.sendEmail();
        return false;
      });
    }
  };

  // Init Email Control
  $(document).ready(function() {

    if ($("#EmailControlContainer").length) {
      $.InitEmailControl();
    }

  });

})(jQuery);          // END of Email Control


// -----------------------
// <summary>
//   HelpControl
// </summary>
// -----------------------
(function($) {
  var HelpControl = {
    siteName: RetrieveCurrentCDSSite(),
    defaultCategory: "shop"
  };

  $.InitHelpControls = function(target) {
    //For each help icon create the dialog box
    $(target).each(function() {
      var helpLink = $(this);
      var width = 300;
      var height = 300;
      //find the associated DIV for the help icon. Need to set the associatedid property in the HTML markup
      var helpdiv = helpLink.next('#HelpDlg' + helpLink.attr('BlockId'));
      var helpConfigHidden = $('#HelpConfig' + helpLink.attr('BlockId'));
      if (helpConfigHidden.length) {
        var helpConfigText = helpConfigHidden.val();
        var helpConfig = JSON.parse(helpConfigText);
        width = helpConfig.Width;
        height = helpConfig.Height;
      }

      //Click handler to show dialog on help icon. Using the jQuery One event handler to execute the init of the dialog box.
      var link = helpLink.bind('click', function(e) {
        e.preventDefault();
        helpdiv.dialog({
          showPrint: false,
          bgiframe: false,
          autoOpen: true,
          dialogClass: 'olsmodal olsHelpModal',
          width: width,
          height: height,
          position: 'center',
          open: function(event, ui) {
          },
          buttons: {
            Close: function() {
              helpdiv.dialog('close');

              // remove the class to hide the aspnet form for printing modals
              $("body").removeClass('ModalVisible');
            }
          },
          close: function(event, ui) {

            // remove the class to hide the aspnet form for printing modals
            $("body").removeClass('ModalVisible');
          }
        });

        // add the class to hide the aspnet form for printing modals
        $("body").addClass('ModalVisible');

        return false;
      });


    });
  };

  $(document).ready(function() {
    $.InitHelpControls('.helpbutton');
  });

})(jQuery);             // END of Help Control


/******************
Footer Disclaimers
*******************/
(function($) {

  $.footerDisclaimersControl = {
    // Declares the message types that this control will accept
    // This variable is used to setup the control with the 
    // observer
    acceptedMessagesTypes: 'SetFooterDisclaimersBlocks',
    controlIdentifier: 'footerdisclaimerscontrol',
    initialized: false
  };

  // Handle messages from other controls
  $.footerDisclaimersControl.handleObserverNotification = function(message) {
    var messagedata = JSON.parse(message);
    switch (messagedata.messagetype) {
      case 'SetFooterDisclaimersBlocks':
        $(".FooterDisclaimersBlockStorage").val(messagedata.blocks);
        $.footerDisclaimersControl.init();
        break;
    }
  };

  $.footerDisclaimersControl.displayFooterDisclaimerContent = function(control, newContent) {
    var container = $(".FooterDisclaimersContent", control);
    container.empty();
    $.each(newContent, function() {
      var disclaimerHtml = "<h2><a name='" + this.BlockName + "'>" + this.Title + "</a></h2><div>" + this.Content + "</div>";
      container.append(disclaimerHtml);
    });
  };

  $.footerDisclaimersControl.loadBlocks = function(control) {
    var filterStorage = $(".FooterDisclaimersFilterStorage", control);
    var errorStorage = $(".FooterDisclaimersErrorStorage", control);
    var filter = JSON.parse(filterStorage.val());
    var blocks = $(".FooterDisclaimersBlockStorage", control).val();

    var params = {
      blocks: blocks,
      contentFilter: filter
    };
    var paramsString = JSON.stringify(params);

    // The following conversions are necessary for GET instead of POST
    paramsString = paramsString.replace('{"blocks":', 'blocks=');
    paramsString = paramsString.replace(',"contentFilter":', '&contentFilter=');
    paramsString = paramsString.replace('}}', '}');

    try {
      $.ajax({
        type: "GET",
        cache: true,
        url: "/ols/DisclaimerService.asmx/GetDisclaimers",
        data: paramsString,
        traditional: false,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        dataFilter: function(response) {
          var jsonObject = JSON.parse(response);
          if (jsonObject.d) {
            jsonObject = jsonObject.d;
          }
          return JSON.stringify(jsonObject);
        },
        success: function(data) {
          try {
            var newContent = JSON.parse(data);
            if (newContent == null) {
              errorStorage.val("Cannot retrieve disclaimers {" + paramsString + "}");
            } else {
              var loadedBlocks = $(".FooterDisclaimersBlockStorage", control).val();

              // Work Item 11042 PROD00493175 The following line WAS corrupting the value of #SessoinTimeoutStorage
              $(".FooterDisclaimersLoaded", control).val(loadedBlocks);

              $.footerDisclaimersControl.displayFooterDisclaimerContent(control, newContent);
            }
          } catch (errorThrown) {
            errorStorage.val("Cannot parse disclaimers {" + paramsString + "} Error:(" + (errorThrown ? errorThrown : xhr.Status) + ") Data:" + data);
          }
          return false;
        },
        error: function(xhr, ajaxOptions, errorThrown) {
          errorStorage.val("Disclaimers response error {" + paramsString + "} Error:(" + (errorThrown ? errorThrown : xhr.Status) + ") Response:" + xhr.responseText);
        },
        async: true
      });
    } catch (err) {
      alert(err.description);
    }
  };

  $.footerDisclaimersControl.init = function() {
    $(".FooterDisclaimersControl").each(function() {
      var control = this;
      var loadedStorage = $(".FooterDisclaimersLoaded", control);
      var loaded = loadedStorage.val();
      var blocks = $(".FooterDisclaimersBlockStorage", control).val();
      if (loaded != blocks || $(".FooterDisclaimersContent", control).is(':empty')) {
        $.footerDisclaimersControl.loadBlocks(control);
      }
  });
  pageobserver.subscribe($.footerDisclaimersControl.handleObserverNotification, $.footerDisclaimersControl.acceptedMessagesTypes, $.footerDisclaimersControl.controlIdentifier);
  };

  $(document).ready(function() {
    if ($(".FooterDisclaimersControl").length) {
      if ($.footerDisclaimersControl.initialized != true) {
        $.footerDisclaimersControl.init();
        $.footerDisclaimersControl.initialized = true;
      }
    }
  });

})(jQuery);


/******************
WindowOpenLink
*******************/
(function($) {

    $(document).ready(function() {
        if ($(".WindowOpenLink").length) {
            $(".WindowOpenLink").click(function() {
                try {
                    var url = $(this).attr('href');
                    var settings = $(this).attr('openwindowsettings');
                    if (settings) {
                        window.open(url, '', settings);
                        return false;
                    }
                } catch (e) {
                    // Just let the href do it's thing
                }
            });
        }
    });

})(jQuery);


/****************
Page Footer Links
*****************/
(function($) {

  $.PageFooterLinksControl = {
    feedbackPopupWidth: 500,
    feedbackPopupHeight: 525,
    initialized: false
  };

  $.PageFooterLinksControl.init = function() {
    $("#PopupFeedback").click(function(event) {
      event.preventDefault();
      var url = $(this).attr("href");
      if (url != "#") {
        var options = "menubar=no,toolbar=no,scrollbars=yes,location=yes,status=yes,resizable=yes" +
          ",width=" + $.PageFooterLinksControl.feedbackPopupWidth +
          ",height=" + $.PageFooterLinksControl.feedbackPopupHeight;
        window.open(url, "", options);
      }
    });
  };

  $(document).ready(function() {
    if ($("#PageFooterLinks").length) {
      if ($.PageFooterLinksControl.initialized != true) {
        $.PageFooterLinksControl.init();
        $.PageFooterLinksControl.initialized = true;
      }
    }
  });

})(jQuery);


/***************
ZIP Code Control
****************/
(function($) {

  /*****************************
  Initialise zip control if used
  ******************************/
  $(document).ready(function() {
    if ($("#zipCodeContent").length) {
      var zipCodeControl = {
        zipCodeServiceEndPoint: "/ols/UtilityService.asmx/ValidateZipCodeGet",
        previousZipCode: ""
      };

      /***********************************************************
      Triggered by a timer top check for zip code text box changes
      this is needed to accomodate drop-down list selection of
      previously entered zip codes
      ***********************************************************/
      zipCodeControl.zipCodeChangeCheck = function() {
        zipCodeControl.zipCodeChange($("#txtZipCode").val());

        // Restart the timer after check complete
        setTimeout(zipCodeControl.zipCodeChangeCheck, 500);
      };

      /****************************************************
      Calls the WCF web service to get the zip code details
      *****************************************************/
      zipCodeControl.getZipCodeDetails = function(zipCode) {
        AjaxWorkingStart($("#zipCodeContent"), '', { absolute: true });
        var zip = {};
        zip.zipCode = zipCode;

        $.ajax({
          type: "GET",
          //cache: true,
          url: zipCodeControl.zipCodeServiceEndPoint,
          data: 'zipCode="' + zipCode + '"',
          //data: JSON.stringify(zip),
          traditional: false,
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          dataFilter: function(response) {
            var jsonObject = JSON.parse(response);
            if (jsonObject.d) {
              jsonObject = jsonObject.d;
            }
            return JSON.stringify(jsonObject);
          },
          success: function(data) {
            zipCodeControl.zipCodeServiceSucceeded(JSON.parse(data));
          },
          error: function(e) {
          },
          complete: function() {
            AjaxWorkingDone($("#zipCodeContent"));
          },
          async: true
        });
      };

      function parseJsonDateWithGMTOff(jsonDate, gmtOffSet) {
        var offset = new Date().getTimezoneOffset() * 60000;
        var parts = /\/Date\((-?\d+)([+-]\d{2})?(\d{2})?.*/.exec(jsonDate);

        if (parts[2] == undefined)
          parts[2] = 0;

        if (parts[3] == undefined)
          parts[3] = 0;

        //return new Date(+parts[1] + offset + parts[2] * 3600000 + parts[3] * 60000);
        return new Date(parseInt(jsonDate.substr(6)));
      };

      /******************************************************
      Handles a successful callback from a zip code AJAX call
      *******************************************************/
      zipCodeControl.zipCodeServiceSucceeded = function(response) {
        var zipCodeResultList;

        if (response.ZipCodeResponse !== null) {
          // Store the zip code results
          zipCodeResultList = [];
          $.each(response.ZipCodeResponse.ZipCode.CountyList.County, function(key, value) {
            var result = {};
            result.countyName = value.countyName;
            result.city = response.ZipCodeResponse.ZipCode.CityList.City[0].cityName;
            result.stateCode = value.stateCode;
            result.gmtOffsetSpecified = response.ZipCodeResponse.ZipCode.GMTOffsetSpecified;
            result.gmtOffset = response.ZipCodeResponse.ZipCode.GMTOffset;
            result.currentDateTimeinZone = parseJsonDateWithGMTOff(response.ZipCodeResponse.ZipCode.currentDateTimeInZone, response.ZipCodeResponse.ZipCode.GMTOffset);
            result.currentDateTimeinZoneSpecified = response.ZipCodeResponse.ZipCode.currentDateTimeInZoneSpecified;
            result.timeZone = response.ZipCodeResponse.ZipCode.timeZone;

            zipCodeResultList.push(result);

            //                        zipCodeResultList.push(JSON.parse('{"countyName": "' + value.countyName + '" ,' +
            //          '"city": "' + response.ZipCodeResponse.ZipCode.CityList.City[0].cityName + '" ,' +
            //          '"stateCode": "' + value.stateCode + '" }'));
          });

          // Populate drop down with counties (for a multi-county zip code). Requires only one hit to DOM.
          var counties = [];
          $.each(zipCodeResultList, function(key, value) {
            counties.push('<option value="' + value.countyName + '">' + value.countyName + ", " + value.stateCode + '</option>');
          });
          $('#cboCounty').html(counties.join(''));
          if (counties.length >= 1) {
            $('#lblSingleCountyName').text(zipCodeResultList[0].countyName);
            $('#lblSingleCountyState').text(zipCodeResultList[0].stateCode);
          }

          // Trigger a custom event that can be picked up by subscribers and pass it the zip results.
          $('body').trigger('zipCodeServiceCompleted', JSON.stringify(zipCodeResultList));

          // Show whether the zip code search was invalid, had one result or more than one result.
          switch (true) {
            case zipCodeResultList.length == 1:
              $("#divCountyDropDown").hide();
              $("#divSingleCountyResult").show();
              break;
            case zipCodeResultList.length > 1:
              $("#divCountyDropDown").show();
              break;
            default:
              break;
          }
        }
        else {
          zipCodeResultList = null;

          // Trigger a custom event that can be picked up by subscribers and pass it the zip results.
          $('body').trigger('zipCodeServiceCompleted', JSON.stringify(zipCodeResultList));
        }

        return true;
      };

      /****************************************************************************************
      Handle zip code changes. If there are less than 5 digits
      then the county control is hidden. If there are 5 digits and the zip code is different
      than before then a call is made to the service to get the zip code details. External
      clients of the zip code control can call this method to fetch the zip code details.
      *****************************************************************************************/
      zipCodeControl.zipCodeChange = function(zipCode) {
        if (zipCode !== null && zipCode != undefined) {
          // Search for a zip code once 5 digits have been entered.
          switch (true) {
            case zipCode.length < 5:
              {
                $("#divCountyDropDown").hide();
                $("#divSingleCountyResult").hide();
                zipCodeControl.previousZipCode = "";
                break;
              }
            case (zipCode.length == 5 && zipCode != zipCodeControl.previousZipCode):
              {
                // Use of previousZipCode prevents repetitive querying of the web service.
                $("#divCountyDropDown").hide();
                $("#divSingleCountyResult").hide();
                zipCodeControl.previousZipCode = zipCode;
                zipCodeControl.getZipCodeDetails(zipCode);
                break;
              }
            default:
              break;
          }
        }
      };

      /*** Initialize the control ***/
      $("#divCountyDropDown").hide();
      $("#divSingleCountyResult").hide();

      $("#txtZipCode").keydown(function(event) {
        AllowNumericOnly(event, 'zipCodeKeyPressed');
      });
      setTimeout(zipCodeControl.zipCodeChangeCheck, 500);
      $("#cboCounty").change(function(event) {
        $('body').trigger('selectedCountyChanged', event);
      });
    }
  });

})(jQuery);


/***************
Enrollment Popup
****************/
$.displayEnrollmentPopup = function(triggerLink, enrollmentUrl, planId, showPartD, enrollmentMessage) {

  if (enrollmentMessage != null && enrollmentMessage != "") {
    // Display a simple enrollment message
    DisplayGenericModal(enrollmentMessage, "Enroll", null, 400,
      options = {
        buttons: { "Close": function() {
          $(this).dialog("close");
          // remove the class to hide the aspnet form for printing modals
          $("body").removeClass('ModalVisible');
        }
        }
      });
  } else {
    // set up the enrollment popup modal settings
    var modalSettings =
      {
        IsModal: true,
        Position: 'top',
        AutoOpen: true,
        Width: 500,
        Height: 300,
        Draggable: false,
        Title: 'Legal &amp Benefit Summary',
        Class: 'olsmodal EnrollmentPopupModal',
        ShowPrint: false,
        CloseText: "Close",
        buttons: {}
      };

    var divModalHostContainer = $("#EnrollmentModalContainer");
    if (!divModalHostContainer.length) {
      divModalHostContainer = $('<div id="EnrollmentModalContainer"></div>');
      $(triggerLink).after(divModalHostContainer);
    }

    var uiModalFieldControls =
      {
        divModalHostContainer: divModalHostContainer,
        hdnObserverMessage: [], // todo
        hdnOnCloseObserverMessage: [],
        hdnShowDisclaimer: null,
        hdnQueryStringParams: jQuery.format('%26productcode={0}%26planid={0}%26showpartd={1}%26enrollurl={2}', planId, showPartD, encodeURIComponent(enrollmentUrl))
      };

    // show the modal using jquery plugin
    $.displayModalFromHostCtrl(uiModalFieldControls, modalSettings, '~/controls/quote/EnrollmentPopup.ascx');
  }
};


/*** Update the MedSupFormNumber CommonContentControl ***/
$.SetMedSupFormNumberPage = function(pageid) {
  if ($("#MedSupFormNumber").length) {
    pageobserver.fire(JSON.stringify({
      messagetype: "SetCommonContentData",
      controlid: "MedSupFormNumber",
      key: "PlaceholderKey",
      value: pageid
    }));
  }

  if ($("#cmsnumber").length) {
    pageobserver.fire(JSON.stringify({
      messagetype: "SetCommonContentData",
      controlid: "cmsnumber",
      key: "PlaceholderKey",
      value: pageid
    }));
  }
};

/*** Set MedSup Form Number Page Modal ***/
$.SetMedSupFormNumberPageModal = function(pageid) {
  if ($("#MedSupFormNumberModal").length) {
    pageobserver.fire(JSON.stringify({
      messagetype: "SetCommonContentData",
      controlid: "MedSupFormNumberModal",
      key: "PlaceholderKey",
      value: pageid
    }));
  }

  if ($("#CmsNumberModal").length) {
    pageobserver.fire(JSON.stringify({
      messagetype: "SetCommonContentData",
      controlid: "CmsNumberModal",
      key: "PlaceholderKey",
      value: pageid
    }));
  }
};

/*** Reload the captcha image and clear out the input box ***/
function reloadCaptcha() {
  var captchaId = $("#CaptchaId").val();
  eval(captchaId).ReloadImage();
  $("#CaptchaInput").val("");
}

