﻿/*-- Required Scripts:
js / JQueryPlugins / jquery.address - 1.2.js
--*/

var bDebug = false;

/*****************************************************
The base URL for the site and is used with ajax calls
******************************************************/
var siteBaseURL = "/ols/";

/*******************************************************
Defines the base URL for the the usercontrol rendering
service. this allows for loading ascx controls with .net
elements via ajax.
********************************************************/
var userControlServiceURL = siteBaseURL + 'LoadView.svc/LoadUserControl?path=';

/**************************************************************
Extends the function for string to include an ends with method
***************************************************************/
String.prototype.endsWith = function(str) {
  return (this.match(str + "$") == str);
};

/**************************************************************
Extends the function for string to include a contains method
***************************************************************/
String.prototype.contains = function(str) {
  return (this.indexOf(str) > -1);
};

/************************************************
Determines if a string ends with a another string
*************************************************/
String.prototype.endsWith = function(endsWithString, isCaseSensitive) {
  if (isCaseSensitive === undefined || !isCaseSensitive) {
    return (endsWithString.toLowerCase() == this.substring(this.length - endsWithString.length).toLowerCase());
  } else {
    return (endsWithString == this.substring(this.length - endsWithString.length));
  }
};

/****************************************************************************************
Wraps calls to a WCF service via ajax. The paramters are defined as follows;

calltype      - The HTTP method for the call e.g. POST, GET
endpoint      - The [svc file]/[method name] syntax of where you
want to call
jsondata      - The data you want to send to the service in JSOn format. If no data
pass in '{}'
successmethod - The method you want to return to after a successfull ajax
call
asyncValue    - Whether you want the call to be synchronous or not. 
The value can be boolean true or false. true is an
asynchronous ajax call and false indicates a synchronous
ajax call. defaults to true;
failuremethod    - Provides a mean to provide an overidden AjaxError behaviour for a particular control
completemethod   - Called for both success and error
*****************************************************************************************/
function CallWCFModel(calltype, endpoint, jsondata, successmethod, asyncValue, failuremethod, completemethod, timeout) {

  // check for null async value
  asyncValue = asyncValue === undefined ? true : asyncValue;

  // check for null failure method - use AjaxError
  failuremethod = (failuremethod === undefined) ? AjaxError : failuremethod;

  timeout = (timeout === undefined) ? (120 * 1000) : timeout;

  // create the wcf service url
  var wcfServiceUrl = siteBaseURL + endpoint;

  $.ajax({
    type: calltype,
    url: wcfServiceUrl,
    data: jsondata,
    timeout: timeout,
    dataFilter: function(response) {
      var jsonObject = JSON.parse(response);
      if (jsonObject.d || (typeof jsonObject.d === 'boolean')) {
        jsonObject = jsonObject.d;
      }

      return JSON.stringify(jsonObject);
    },
    dataType: 'json',
    contentType: 'application/json;',
    async: asyncValue,
    success: successmethod,
    error: failuremethod,
    complete: completemethod
  });
}

/****************************************************************************************
Wraps calls to load an external ascx control via ajax.
The paramters are defined as follows;

Note: "cat" and "page" are also appended as querystring parameters by default. These
are read from the hidden field rendered from the master page

Note: Any error in the Ajax call is handled the same for all instances. The fct AjaxError is used.

ascx            - The user control view to load.
querystring     - The querystring parameters to append onto the user control.
cache           - Specifies whether to use the cache for the loaded control.
successmethod   - Provides the callback function following a successful ajax call.
completemethod  - Provides the callback function following completion (success or error) ajax call.
*****************************************************************************************/
function LoadASCXViaAjax(
          ascx,
          querystring,
          cache,
          successmethod,
          completemethod) {

  var site = GetQueryStringParam("cdssite", "#ctl00_hdnCDSSite");
  var cat = GetQueryStringParam("cat", "#ctl00_hdnCDSCategory");
  var page = GetQueryStringParam("page", "#ctl00_hdnCDSPage");

  //hack to fix issues in my account page
  if (cat == '%26cat=user' && page == '%26page=myaccount') {
    if (ascx.contains('DrugsListView.ascx')) {
      cat = '%26cat=shop';
      page = '%26page=costandbenefits';
      site = '%26cdssite=olspublic';
    }

    //PlanDetailSavings.ascx PlanDetailDocuments
    if (ascx.contains('PlanDetailOverview.ascx') ||
        ascx.contains('PlanDetailAdditionalPD.ascx') ||
        ascx.contains('PlanDetailOSB.ascx') ||
        ascx.contains('PlanDetailPrescriptionDrug.ascx') ||
        ascx.contains('PlanDetailSavings.ascx') ||
        ascx.contains('PlanDetailDocuments.ascx')) {
      site = '%26cdssite=olspublic';
    }
  }

  // get the querystring params for the "cat" and "page" fields
  if (querystring.indexOf("cat=") == -1) {
    querystring += cat;
  }
  if (querystring.indexOf("page=") == -1) {
    querystring += page;
  }
  if (querystring.indexOf("cdssite=") == -1) {
    querystring += site;
  }

  // load the control via ajax from the loadview svc url
  $.ajax({
    url: userControlServiceURL + ascx + querystring,
    dataType: 'html',
    cache: cache,
    success: successmethod,
    complete: function(xhtml, status) {

      if (xhtml.status == 302) {
        $("#SessionTimeoutMessage").html('Your session has been disconnected');
        $.displayTimeout(false);
      }

      if (completemethod != null) {
        completemethod();
      }
      // Check if footer disclaimers need to be updated to a different block set
      $.footerDisclaimersControl.init();
    },
    error: AjaxError
  });

}

/************************************************************
Provides a mechanism to check for the cat, page hidden field,
And return a querystring parameter if available
*************************************************************/
function GetQueryStringParam(key, fieldSelector) {
  return $(fieldSelector).length > 0 ? jQuery.format('%26{0}={1}', key, $(fieldSelector).val()) : "";
}

// Get a querystring parameter
function queryparameter(name, querystring) {
  name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
  var regexS = "[\\?&]" + name + "=([^&#]*)";
  var regex = new RegExp(regexS);
  var results = regex.exec(querystring);
  if (results === null) {
    return "";
  }
  return results[1];
}


/*****************************************************************************
Wraps calls to load an external ascx control via ajax. 
The paramters are defined as follows;

page          - The page to load
successmethod - The method you want to return to after a successfull ajax call
errormethod   - The method you want to return to after a failed ajax call
******************************************************************************/
function LoadHtmlViaAjax(page, successmethod) {
  $.ajax({
    url: page,
    dataType: 'html',
    success: successmethod,
    error: AjaxError
  });
}

/**************************************************************
Returns a boolean value indicating whether this is adebug build
***************************************************************/
function IsDebugBuild() {
  // get the hidden field
  var debugField = $("#ctl00_hdnIsDebugBuild").length > 0 ? $("#ctl00_hdnIsDebugBuild") : ($("#hdnIsDebugBuild").length > 0 ? $("#hdnIsDebugBuild") : null);

  // check if the field is null
  if (debugField === null) {
    // return false
    return false;
  }

  // return a boolean based on the hidden field value (output on all master pages)
  return debugField.val() == "True" ? true : false;
}

/**************************************************************
Handles errors returned from WCF services
Displays a user friendly error dialog if in Release mode and
a dialog with the stack trace and other exception info in debug
mode
***************************************************************/
function AjaxError(response) {
/*
  // if it's debug build
  if (IsDebugBuild() === true) {
    // display the debug error dialog
    DisplayDebugErrorDialog(response);
  }
  else {
*/
    // display the user friendly error dialog
    DisplayUserFriendlyErrorDialog();
//  }

  // make sure all elements on the form have been enabled if an error has occurred so that the user can proceed
  EnableInputForm($("#aspnetForm").find('input, button'));
}

/*****************************************************
Displays the user friendly error dialog
This loads the ErrorView control into the jQuery modal
******************************************************/
function DisplayUserFriendlyErrorDialog() {
  // load the prescription i.e. drugs modal control via ajax
  LoadASCXViaAjax(
    '~/controls/Error/ErrorView.ascx',
    '',
    false,
    // success method
    function(response) {
      // display a modal
      if (response.length > 10) {
        DisplayGenericModal(response, "", null, 700);
      } else {
        // Didn't get error text - redirect
        NavigateWithReferrer("http://" + $("#publicHostname").val() + "/ols/error.aspx");
      }
    }
  );
}

/******************************
Displays the debug error dialog
*******************************/
function DisplayDebugErrorDialog(response) {
  // create the formatter for the error message
  var formatter = "<h1>An error has occurred.</h1><p>Check the logs for full details.</p><strong>Error Message:</strong>&nbsp;{0}<br /><br /><strong>Stack Trace:</strong>&nbsp;{1}";

  // a variable for the header for the modal error detail
  var header = "An error occurred...";

  // create a full error message detail object
  var detailedErrorMessage;
  // parse the json response
  if (response != null && response.responseText != undefined) {
    try {
      var jsonResponse = JSON.parse(response.responseText);
      detailedErrorMessage = jQuery.validator.format(formatter, jsonResponse.Message, jsonResponse.StackTrace);
    } catch (e) {
      detailedErrorMessage = jQuery.validator.format(formatter, response.responseText, "");
    }
  } else {
    detailedErrorMessage = jQuery.validator.format(formatter, response, "");
    debugger;
  }

  // display a modal
  DisplayGenericModal(detailedErrorMessage, header);
}


/**************************************************************
Handles displaying errors from the validation control
in the scenario where we are placing the error messages at the top
of the page. It assumes the errors will be placed in a div on the page
with and ID of "pageErrors". The method also adds the error symbol beside
each field label that is in error. The for attribute, as per 508, must be
set on the label for this to work.
***************************************************************/
function DisplayErrorsPageTop(error, element) {
  $('#pageErrors').append(error);
  var tooltip = 'Error message not available.';
  if (error.length > 0 && error[0]) {
    tooltip = error[0].innerHTML;
  }
  $(element).parent().prepend('<div id="errorsymbol" title="' + tooltip + '" class="error_symbol">&nbsp;&nbsp;&nbsp;&nbsp;</div>');
}

/*Seperate version for Appcapture*/
function DisplayErrorsPageTopAppCapture(error, element) {
  var tooltip = 'Error message not available.';
  if (error.length > 0 && error[0]) {
    tooltip = error[0].innerHTML;
  }
  var title = $(tooltip).html();
  // if the title is not null then display it
  if (title != null) {
      // display error on top of page
      if (!($("#pageErrors").html().indexOf(tooltip) >= 0)) {
      
      // WARNING: hack to stop displaying multiple errors on group validation
      var controlName = error.attr('htmlFor');
      var controlNameLastChar = controlName.substring(controlName.length-1);
      var controlGroupName = controlName.substring(0, controlName.length-1);
      
      var $existingError = $("#pageErrors").find('div[htmlFor*="' + controlGroupName + '"]');
      
      // if last char is not a number we disregard the logic above, not a group validation scenario
      if($existingError.length === 0 || isNaN(controlNameLastChar)){
        $('#pageErrors').show().append(error);
      }
    }
    // martin fenton: don't want to show multiple errors for the fields - if there is no error symbol visible already for this error
    if ($(element).parent(":visible").length > 0) {
      if ($(element).parent().find('#errorsymbol').length == 0) {
        // prepend the icon
        $(element).parent().prepend('<div id="errorsymbol"  element="' + element.id + '" title="' + title + '" class="error_symbol">&nbsp;&nbsp;&nbsp;&nbsp;</div>');
      }
    } else {
      // If a radio button list is validated and the first item is hidden we need to go up the dom to get a place to show the error
      if ($(element).parents("div.input:visible").parent().find('#errorsymbol').length == 0) {
        // prepend the icon
        $(element).parents("div.input:visible").prepend('<div element="' + $(element).attr('name') + '" id="errorsymbol" title="' + title + '" class="error_symbol">&nbsp;&nbsp;&nbsp;&nbsp;</div>');
      }
    }
  }

  //  $('#pageErrors a').unbind();
  //  $('#pageErrors a').click(function(event) {
  //        event.preventDefault();
  //        window.location = '#lbl' + $(this).attr('href');
  //        $('#' + $(this).attr('href')).focus();
  //      });
}

/***********************************************************
Displays an info message to the user. The method
is passed in a div selector to hold the message
(e.g. a div on the page - '#mydiv') and the message to show
***********************************************************/
function DisplayInfoMessage(errorDiv, message) {
  $(errorDiv).html('<div class="info"><strong>' + message + '</strong></div>');
  $(errorDiv).show();
}

/***********************************************************
Returns the difference between two dates/times.
The method is passed in the two dates and also the interval.
This result will be returned in units of the interval.
************************************************************/
function dateDifference(date1, date2, interval) {
  var second = 1000, minute = second * 60, hour = minute * 60, day = hour * 24, week = day * 7;
  date1 = new Date(date1);
  date2 = new Date(date2);
  var timediff = date2 - date1;
  if (isNaN(timediff)) return NaN;
  switch (interval) {
    case "years": return date2.getFullYear() - date1.getFullYear();
    case "months": return ((date2.getFullYear() * 12 + date2.getMonth()) - (date1.getFullYear() * 12 + date1.getMonth()));
    case "weeks": return Math.floor(timediff / week);
    case "days": return Math.floor(timediff / day);
    case "hours": return Math.floor(timediff / hour);
    case "minutes": return Math.floor(timediff / minute);
    case "seconds": return Math.floor(timediff / second);
    default: return undefined;
  }
}

/************************************************
Clears an info message that has been shown in a
container. It is passed in the selector for the
container (e.g. a div on the page - '#mydiv') and
clears the container
*************************************************/
function ClearInfoMessage(container) {
  $(container).html("");
  $(container).hide();
}

// *** Change the display css on the labels and validation fields
function HasValue(objInputField) {
  return jQuery.trim(objInputField.val()).length > 0;
}

/************************************************
Displays an error message to the user. The method
is passed in a div selector to hold the message
(e.g. a div on the page - '#mydiv') and the message to show
***********************************************************/
function DisplayErrorMessage(errorDivSelector, message) {
  // set the html of the element
  $(errorDivSelector).html('<div id="summary" class="warning">' + message + '</div>');
  $(errorDivSelector).show();
}

/***********************************************************
Clears an error message. The method
is passed in a div selector to hold the message
(e.g. a div on the page - '#mydiv') and the message to show
************************************************************/
function ClearErrorMessage(errorDivSelector) {
  // clear the contents of the div
  $(errorDivSelector).html('');
  $(errorDivSelector).hide();
}

/**************************************************************
Enables input fields based on the passed jQuery selectors on the page.
This is used to ensure that user cannot click on any element during a JQuery operation
***************************************************************/
function DisableInputForm(selector, datePickerSelector) {

  // disable all input fields
  $(selector).attr("disabled", true);
  // disable all datepicker controls
  if (datePickerSelector !== '') {
    $(datePickerSelector).datepicker('disable');
  }
}

/**************************************************************
Enables input fields based on the passed jQuery selectors on the page.
This is used to ensure that user cannot click on any element during a JQuery operation
***************************************************************/
function EnableInputForm(selector, datePickerSelector) {
  // enable all input fields
  $(selector).removeAttr("disabled");
  // enable all datepicker controls
  if (datePickerSelector !== '') {
    $(datePickerSelector).datepicker('enable');
  }
}

/****************************************************************************
This function provides a mechanism to display a modal dialog for a disclaimer
When user clicks on a link that opens an external site
*****************************************************************************/
function LeavingSiteModal(url, openWindow) {
  var brandName = GetSiteName();
  var brandSite = brandName + '.com';

  var $dialog = $('<div></div>').html("You are leaving " + brandSite + " <br /> <br /> By clicking on the “Continue” button below, you will be leaving <Anthem’s> site and linking to a site created and/or maintained by another entity (“External Site”) and you acknowledge that " + brandName + " does not control, guarantee, endorse or approve the information, products or services available at the External Site or the security of transmissions between you and the External Site. <br /> <br /> Upon linking you are subject to the terms of use, privacy, copyright and security policies of the External Site. " + brandName + " provides these links solely for your information and convenience. Members: Your health plan may not cover all services or products described on the External Site; please refer to your benefit booklet. The information contained on the External Site should not be interpreted as medical advice or treatment.");
  $dialog.dialog({
    width: 550,
    height: 330,
    draggable: false,
    modal: true,
    dialogClass: 'olsmodal',
    position: 'center',
    autoOpen: false,
    title: 'Disclaimer',
    buttons: { "Continue": function() {
      $(this).dialog("close");
      if (openWindow == 'True') {
        window.open(url);
      }
      else {
        window.location.href = url;
      }
    }, "Return": function() {
      $(this).dialog("close");
    }
    }
  });

  $dialog.dialog('open');
}

/*******************************************************************
Provides a mechanism to display a modal dialog for a generic message
********************************************************************/
function DisplayGenericModal(message, header, onContinueFunc, modalWidth, options) {

  //perform cleanup first
  var modalDivs = $('.olsmodal');

  for (var i = 0; i < modalDivs.length; i++) {
    $(modalDivs[i]).remove();
  }

  var width = screen.width;
  width = Math.round(width / 2);
  if (modalWidth !== undefined && modalWidth !== null) {
    width = modalWidth;
  }

  // Set the default options for the geernic modal.
  var defaultOptions = {
    width: width,
    draggable: false,
    modal: true,
    dialogClass: 'olsmodal',
    position: 'center',
    autoOpen: false,
    title: header,
    buttons: { "Continue": function() {
      $(this).dialog("close");
      if (onContinueFunc !== undefined && onContinueFunc !== null) {
        onContinueFunc();
      }
      // 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');
    }
  };

  // Override the default options with any that are supplied by the options parameter.
  $.extend(defaultOptions, options);

  var $dialog = $('<div></div>').html(message).dialog(defaultOptions);
  $dialog.dialog('open');

  // resize the modal
  $.ui.dialog.overlay.resize();

  // add the class to hide the aspnet form for printing modals
  $("body").addClass('ModalVisible');
}


/**********************
Close all modal dialogs
***********************/
function CloseAllModalDialogs() {
  $(":ui-dialog").each(function() {
    var $this = $(this);
    if ($this.dialog("isOpen")) {
      $this.dialog("close");
    }
  });
}

/***************************************************************************************
Gets  a querystring value
Possibly temporary will need to adopt a different mechanism when url re-writing in place
****************************************************************************************/
function GetQueryStringParameter(ji) {
  var hu = window.location.search.substring(1);
  var gy = hu.split("&");
  for (var i = 0; i < gy.length; i++) {
    var ft = gy[i].split("=");
    if (ft[0].toLowerCase() == ji.toLowerCase()) {
      return ft[1];
    }
  }
  return "";
}

/************************************************************************
Navigates to a URL and makes sure the referring url property is populated
*************************************************************************/
function NavigateWithReferrer(url) {
  // Bug Fix DL.24.06.2011 - This function was checking if fakeLink.click() returned 'undefined' as apparently IE was the only browser to do so.
  // FF5 now returns a function for fakeLink.click() so this was causing FF5 into the IE specific hack.
  // Changed to use $ browser detection.
  // A possible future improvement would be to change the widget buttons to anchors, change the href and let the links be links.
  // Similar change made in function openBrowserWithRedirect(url) in WelcomeWidget.js
  if ($.browser.msie){
    var $modal = $('#aspnetForm').siblings('.ui-dialog:visible');
    var fakeLink = document.createElement("a");
    // Check to see if a modal is displayed and append the Href to the modal instead of the body
    if ($modal.length > 0) {
      fakeLink.href = url;
      $modal.append(fakeLink);
      fakeLink.click();   // click() method defined in IE only - not true as of FF5
    }
    else {
      fakeLink.href = url;
      document.forms[0].appendChild(fakeLink);
      fakeLink.click();   // click() method defined in IE only - not true as of FF5
    }
  }else{
  location.href = url;
  }
}

/*********************************************************
Gets the brand name from the 'ols' cookie
This is only reliable if the cookie exists and is readable
**********************************************************/
function getBrandName() {
  // Get the brand from the ols cookie.
  // Anthem (abcbs) is the default brand.
  var brand = 'abcbs';
  // NOTE ols cookie should have been httpOnly and not accessible client side.
//  var olsCookie = $.cookie('ols');
//  if (olsCookie !== null) {
//    var attrib = olsCookie.split('&');
//    $.each(attrib, function(index, value) {
//      var attribName = value.split('=')[0];
//      var attribValue = value.split('=')[1];
//      if (attribName.toLowerCase() == 'brand') {
//        brand = attribValue.toLowerCase();
//      }
//    });
//  }

  return $('#hdnBrand').val() || brand;
}

/**************************************************************
Gets the brand state name from the 'ols' cookie
This is only reliable if the cookie exists and is readable.
***************************************************************/
// NOTE Commenting this out as it is not used anywhere.
// NOTE Also, it shouldn't access the ols cookie, this is HttpOnly
//function getBrandStateName() {
//  // Get the brand state from the ols cookie.
//  var brandState;
//  var olsCookie = $.cookie('ols');
//  if (olsCookie !== null) {
//    var attrib = olsCookie.split('&');
//    $.each(attrib, function(index, value) {
//      var attribName = value.split('=')[0];
//      var attribValue = value.split('=')[1];
//      if (attribName.toLowerCase() == 'state') {
//        brandState = attribValue.toLowerCase();
//      }
//    });
//  }
//  
//  return brandState;
//}

/****************************************************************************************
Allows only numeric values to be entered. Bind the keydown event to this
method to ensure that only numbers can be entered. The eventToRaise parameter specifies
an event to call if the current keypress is numeric. Set this to null if no error is
to be raised.
*****************************************************************************************/
function AllowNumericOnly(event, eventToRaise) {
  // Allow only backspace, delete and navigation keys (left, right, up, down, home)
  // Allow ctrl key operations also.
  var isValidKey = true;
  if (event.ctrlKey === false) {
    if (!(event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 ||
      (event.keyCode >= 35 && event.keyCode <= 40) || (event.keyCode >= 48 && event.keyCode <= 57) ||
      (event.keyCode >= 96 && event.keyCode <= 105))) {
      event.preventDefault();
      isValidKey = false;
    }
    else {
      if (eventToRaise !== null) {
        $('body').trigger(eventToRaise);
      }
    }
  }

  // Prevent shift & alt operations.
  if (event.shiftKey || event.altKey) {
    // But allow shift + tab.
    if (!(event.shiftKey && event.keyCode == 9)) {
      event.preventDefault();
      isValidKey = false;
    }
  }
  return isValidKey;
}

/*****************************************************************
Only allows alphabetic keys to be entered (with some
exceptions like hyphen and apostrophee). This is used mainly when
entering a persons name (first name or surname).
******************************************************************/
$.allowOnlyPersonNameText = function(event) {
  // Allow only delete, backspace and tab.
  // Allow space, apostrophee and hyphen.
  // Allow navigation keys (left, right, up, down).
  // Allow alphabetic keys (A-Z, a-z).
  var isValidKey = true;
  if (!event.ctrlKey && !event.shiftKey) {
    if (!(event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9
          || event.keyCode == 32 || event.keyCode == 189 || event.keyCode == 192
          || (event.keyCode >= 37 && event.keyCode <= 40)
          || (event.keyCode >= 65 && event.keyCode <= 90))) {
      event.preventDefault();
      isValidKey = false;
    }
  }

  // Prevent shift & alt operations except for alphabetic keys.
  if (event.shiftKey || event.altKey) {
    // But allow shift + tab, shift + alphabetic key.
    if (!(event.shiftKey && event.keyCode == 9
        || (event.keyCode >= 37 && event.keyCode <= 40)
        || (event.keyCode >= 65 && event.keyCode <= 90))) {
      event.preventDefault();
      isValidKey = false;
    }
  }

  return isValidKey;
};


/*****************************************************************
Do not allow the following characters ~`!@#$%^&*()-+={}[];:¿?/<>
******************************************************************/
$.disableSpecialCharacters = function(event) {
  // Allow only delete, backspace and tab.
  // Allow space.
  // Allow navigation keys (left, right, up, down).
  // Allow alphabetic keys (A-Z, a-z).
  // Allow numeric keys (0-9).
  var isValidKey = true;
  if (!event.ctrlKey && !event.shiftKey) {
    if (!(event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9
          || event.keyCode == 32
          || (event.keyCode >= 37 && event.keyCode <= 40)
          || (event.keyCode >= 65 && event.keyCode <= 90)
          || (event.keyCode >= 48 && event.keyCode <= 57))) {
      event.preventDefault();
      isValidKey = false;
    }
  }

  // Prevent shift & alt operations except for alphabetic keys.
  if (event.shiftKey || event.altKey) {
    // But allow shift + tab, shift + alphabetic key.
    if (!(event.shiftKey && event.keyCode == 9
        || (event.keyCode >= 37 && event.keyCode <= 40)
        || (event.keyCode >= 65 && event.keyCode <= 90))) {
      event.preventDefault();
      isValidKey = false;
    }
  }

  return isValidKey;
};

/***********************************************************
Gets the name of the site based on the brand from the cookie
************************************************************/
function GetSiteName() {
  var brand = getBrandName();
  var returnvalue;

  switch (brand) {
    case 'abcbs':
      returnvalue = 'Anthem';
      break;
    case 'unicare':
      returnvalue = 'Unicare';
      break;
    case 'eblue':
      returnvalue = 'EmpireBlue';
      break;
    case 'bcbsga':
      returnvalue = 'BCBSGA';
      break;
    case 'bcbsks':
      returnvalue = 'BCBSKS';
      break;
    case 'bcbskc':
      returnvalue = 'BCBSKC';
      break;
    default:
      returnvalue = 'Anthem';
      break;
  }

  return returnvalue;
}

/****************************************
Gets the current CDS site from the cookie
*****************************************/
function RetrieveCurrentCDSSite() {
  // NOTE ols cookie should have been HttpOnly and not accessible client side
//  var siteValue;
//  var olsCookie = $.cookie('ols');
//  if (olsCookie !== null) {
//    var attrib = olsCookie.split('&');
//    $.each(attrib, function(index, value) {
//      var attribName = value.split('=')[0];
//      var attribValue = value.split('=')[1];
//      if (attribName.toLowerCase() == 'site') {
//        siteValue = attribValue.toLowerCase();
//      }
//    });
//  }
//  return siteValue;
  return $('#hdnSite').val();
}

// function to ovveride the backspace key and prevent issue with ajax
var trapfunction = function(event) {
  var keynum;

  // get the src element object
  var srcElementObject = null;

  if (window.event) // eg. IE
  {
    keynum = window.event.keyCode;
    srcElementObject = window.event.srcElement;
  }
  else if (event.which) // eg. Firefox
  {
    keynum = event.which;
    srcElementObject = event.target;
  }

  if (keynum == 8) // backspace has code 8
  {
    // if it's not an array
    if (isArray(srcElementObject) === false) {
      // if we are on an input field and it is text editable return true
      if (srcElementObject.nodeName == "INPUT" && srcElementObject.getAttribute('type') == 'text') {
        return true;
      }
    }
    return false;
    // nullifies the backspace
  }
  return true;
};

//chk if an object is an array or not.
function isArray(obj) {
  return (obj.constructor.toString().indexOf("Array") != -1);
}

//document.onkeydown = trapfunction; // IE, Firefox, Safari
//document.onkeypress = trapfunction; // only Opera needs the backspace nullifying in onkeypress

function escapeHTML(str) {
  var div = document.createElement('div');
  var text = document.createTextNode(str);
  div.appendChild(text);
  return div.innerHTML;
}

var selectedCoverageType = -1;

// *** This function reuses the glossary functionality to provide a mechanism to display tooltips for long names
function DisplayToolTip(term, acceptedLength) {

  if (term === null || term === "") {
    return "";
  }

  // check if the term length is less than acceptedLength, if so return term
  if (term.length < acceptedLength) {

    return term;

  }

  // get a substring of the term from the start to the end length
  var termToDisplay = term.substring(0, acceptedLength - 1);

  // format the glossary term and return
  return jQuery.validator.format("{0}<dfn class=\"longNameTerm\" title=\"{1}\"> ...</dfn>", termToDisplay, term);
}

// Safely retrieve the value of a button control working around an IE7 bug
// param "control": the button control object
// returns: the value on the button
function GetButtonValue(control) {
  if ($.browser.msie && ($.browser.version.substr(0, 1) == 7 || $.browser.version.substr(0, 1) == 6)) {
    // Text has to be temporarily removed in order to see the value in IE6 & IE7
    var buttonText = control.innerHTML;
    control.innerHTML = '';
    var buttonValue = control.value;
    control.innerHTML = buttonText;
    return buttonValue;
  } else {
    return control.value;
  }
}

/*****************************************************************
Refreshes the current page

loadfromserver - A variable indicating whether the browser should
go back to the server or not when reloading. If true then it goes
back to the server and if false it only goes to the cache. The
default is true
******************************************************************/
function RefreshPage(loadfromserver) {
  // check for null loadfromserver value
  loadfromserver = loadfromserver === undefined ? true : loadfromserver;
  window.location.reload(loadfromserver);
}

/*****************************************
Refreshes the current selected tab

tabID - The id of the tabs to be refreshed
******************************************/
function RefreshTab(tabId) {
  // get the tabs element
  var selector = $('#' + tabId);
  // get the selected tab index
  var selectedTab = selector.tabs("option", "selected");

  // get the actual tab <li> tags
  var liTabsSelector = $('#' + tabId + ' ul li');

  // make the tabs collapsible just for the refresh
  liTabsSelector.removeClass('ui-tabs-selected');
  liTabsSelector.removeClass('ui-state-active');

  // set the selected tab - collapse's the tab
  selector.tabs('select', selectedTab);
  // set the selected tab - opens the collapsed tab back up again
  selector.tabs('select', selectedTab);
}

/**************************************
Global jQuery validation reset function
options - provides jQuery options
***************************************/
function GlobalResetValidation(options) {

  // unbind to the aspnet form
  $('#aspnetForm').unbind('invalid-form.validate');

  // reset the validation - i.e. pass true into the validate method, undefined ensures thatr those parameters are not used
  var validator = $('#aspnetForm').validate(options, undefined, undefined, true);

  // clear the rules
  validator.settings.rules = {};

  // clear the messages
  validator.settings.messages = {};
}

/*****************************************************************
Global jQuery validation reset function for the error
symbol icon alongside fields that have been invalid
(i.e. an icon with tooltip).

Should not be used in most cases - only needed 
where the jQuery validation is used in 
conjunction with the jQuery dialog

options -                 Provides jQuery options
formContainerSelector -   Provides a jQuery selector for the
containing div or other control
that contains the input elements to reset
******************************************************************/
function GlobalResetValidationTooltips(options, formContainerSelector) {

  // reset the validation
  GlobalResetValidation(options);

  // get the input elements
  var inputElements = $(formContainerSelector + " :input");

  // for each elements find and remove the div
  $.each(inputElements, function(index, element) {

    // clear out the error label
    $(formContainerSelector + " div[htmlfor=" + element.id + "]").remove();

  });
}

/*****************************************************************
Global jQuery validation reset function for the error
symbol icon alongside fields that have been invalid 
(i.e. an icon with tooltip).

Should not be used in most cases - only needed 
where the jQuery validation is used in 
conjunction with the jQuery dialog

options -                 Provides jQuery options
formContainerSelector -   Provides a jQuery selector for the 
containing div or other control
that contains the input elements to reset
******************************************************************/
function GlobalResetValidationMsgs(options, formContainerSelector) {

  // reset the validation
  GlobalResetValidation(options);

  // empty the container
  $(formContainerSelector).empty();
}

/*** When doing an ajax callback, call this to replace the contents
*** of some div with a spinning cirlce animation
***/
function AjaxWorkingStart(divToHide, message, options) {
  try {
    var optionDefaults = {
      absolute: false
    };

    var opts = $.extend({}, optionDefaults, options);

    var position = divToHide.position();
    var width = Math.max(divToHide.outerWidth(false), 16);
    var height = Math.max(divToHide.outerHeight(false), 16);

    var overflowValue = "auto";
    var maxHeightValue = 0;

    if (opts.overflowCss) {
      overflowValue = opts.overflowCss;
    }

    if (opts.maxHeight) {
      maxHeightValue = opts.maxHeight;
    }

    if (opts.minHeight) {
      if (height < opts.minHeight) {
        height = opts.minHeight;
      }
    }

    // If the overlay is clipped, then adjust the animation to be vertically centered in the visible area
    var viewportMinY = $(window).scrollTop();
    var viewportMaxY = viewportMinY + $(window).height();
    var clippedTop = Math.max(position.top, viewportMinY);
    var clippedBottom = Math.min(position.top + height, viewportMaxY);
    var animationTopMargin = Math.round(Math.max((clippedBottom - clippedTop - 16) / 2, 0));
    if (animationTopMargin > 10) {
      animationTopMargin -= 10;
    }

    var overlay = $("<div class='contentLoading'></div>");
    if (opts.absolute == true) {
      overlay.addClass("contentLoadingAbsolute");
      overlay.css(
      {
        left: position.left + "px",
        top: position.top + "px"
      });
    }
    overlay.css(
    {
      "width": width + "px",
      "min-height": height - animationTopMargin + "px",
      "overflow": overflowValue,
      "padding-top": animationTopMargin + "px"
    });

    if (maxHeightValue !== 0) {
      overlay.css({ "max-height": maxHeightValue + "px" });
    }

    var animation = $("<div class='contentLoadingSpinner'></div>");
    overlay.append(animation);
    if (message != "" && message != null) {
      var messageSpan = $("<span>" + message + "</span>");
      overlay.append(messageSpan);
    }
    divToHide.attr("styleprev", divToHide.attr("style"));
    if (opts.absolute == true) {
      divToHide.css({ "visibility": "hidden" });
      divToHide.parent().append(overlay);
    } else {
      divToHide.css({ "display": "none" });
      divToHide.before(overlay);
    }
  } catch (err) {
    // Cosmetic only
  }
}

/*** Ajax call completed - make the div visible again, and remove the animation ***/
function AjaxWorkingDone(divToRestore) {
  var go = true;
  if (go == false) {
    return;
  }
  var parentElement;
  try {
    parentElement = divToRestore.parent();
  } catch (e) {
    throw ("AjaxWorkingDone can't find parent " + divToRestore);
  }
  var animation = $(".contentLoading", parentElement);
  animation.remove();
  var prevStyle = divToRestore.attr("styleprev");
  if (prevStyle == null) {
    divToRestore.removeAttr("style");
  } else {
    divToRestore.attr("style", prevStyle);
  }
  divToRestore.removeAttr("styleprev");
}

// *** This is a prototype function to replace all of one char occurrences with another char
String.prototype.ReplaceAll = function(stringToFind, stringToReplace) {
  var temp = this;
  var index = temp.indexOf(stringToFind);
  while (index != -1) {
    temp = temp.replace(stringToFind, stringToReplace);
    index = temp.indexOf(stringToFind);
  }
  return temp;
};

/*** Provides a global cross browser mechanism to disable a hyperlink  ***/
function DisableAnchor(obj, disable) {
  if (disable) {
    var href = obj.attr("href");
    if (href && href != "" && href != null) {
      obj.attr('href_bak', href);
    }
    obj.removeAttr('href');
    obj.css("color", "gray");
  }
  else {
    obj.attr('href', obj.attr['href_bak']);
    obj.css("color", "blue");
  }
}

/*** Returns true if the user is logged on and false if they are not  ***/
function IsUserLoggedOn() {
  var hidField = $('#logonFormControl_logonstatus').val();

  if (hidField == 1) {
    return true;
  }
  else {
    // Check for standalone flow
    hidField = $('#navigatehomeplaceholder_logonstatus').val();

    if (hidField == 1) {
      return true;
    }
    else {
      // Check for ade flow
      hidField = $('#uiLogOnWidgetUc_logonstatus').val();

      if (hidField == 1) {
        return true;
      }
      else {
        return false;
      }
    }
  }
}

/*** Returns true if the user is has previously selected continue as guest  ***/
function IsContinueAsGuestSet() {
  var hidField = $('#logonFormControl_continueAsGuestStatus').val();

  if (hidField == 1) {
    return true;
  }
  else {
    // Check for standalone flow
    hidField = $('#navigatehomeplaceholder_continueAsGuestStatus').val();

    if (hidField == 1) {
      return true;
    }
    else {
      // Check for ade flow
      hidField = $('#uiLogOnWidgetUc_continueAsGuestStatus').val();

      if (hidField == 1) {
        return true;
      }
      else {
        return false;
      }
    }
  }
}


/*****************************************************************
Custom Validation: Contains only alpha numeric characters, space, . / -
******************************************************************/
function IsAlphaNumeric(value) {
  return (/^[a-zA-Z0-9% .\-\/]*$/.test(value));
}

/*** Makes textarea inputs support maxlength like textbox does ***/
$.fn.textareaMaxLength = function() {
  $("textarea[maxlength]").keypress(function(event) {
    var key = event.which;
    //all keys including return.
    if (key >= 32 || key == 13) {
      var maxLength = $(this).attr("maxlength");
      var length = this.value.length;
      if (length >= maxLength) {
        this.val = this.value.substring(0, maxLength);
        event.preventDefault();
      }
    }
  }).bind('paste', function(e) {
    var el = $(this);
    setTimeout(function() {
      var text = el.val();
      var maxLength = el.attr("maxlength");
      if (text.length > maxLength) {
        $(el).val(text.substring(0, maxLength));
        alert("Text truncated to " + maxLength + " characters.");
      }
    }, 100);
  })
  ;
};


/*****************************************************************
Fires when a URL change has been detected having
being caused by an external source (e.g. the browser back button).
The addressChange event is fired here and subscribers can then
handle it as they please.
Note: this requires the jquery.address plug in order to fire.
******************************************************************/
$.address.externalChange(function(event) {
  // split the event value into a prefix and bookmark
  var prefix = event.value.replace("/", "");
  var bookmark = "";
  var dash = prefix.indexOf('-');
  if (dash > -1) {
    bookmark = prefix.substr(dash + 1, prefix.length - dash - 1);
    prefix = prefix.substring(0, dash);
  }
  var message = {
    messagetype: "BrowserNav",
    prefix: prefix,
    bookmark: bookmark
  };
  pageobserver.fire(JSON.stringify(message));
});

/*****************************************************************
Adds the current bookmark to the browsers back button history.
The prefix uniquely identifies the control which is requesting the
bookmark. This is used to determine if the message is intended for
your control in the externalChange message above.
******************************************************************/
$.browserNavigationAddBookmark = function(prefix, bookmark) {
  // Clean up bookmark (if it is a string)
  if (bookmark.replace) {
    bookmark = bookmark.replace("#", "");
  }
  // Save in browser history
  $.address.value(prefix + "-" + bookmark);

  // Reset the session timeout (requires SessionTimeout control)
  pageobserver.fire(JSON.stringify({ messagetype: "ResetSessionTimeoutServer" }));
};

/**********************
Leaving Site Hyperlinks
***********************/
function HandleStellentLeavingSiteLinkClick(e) {
  e.preventDefault();
  var anchor = $(e.target).closest('a'); // Click could be from element inside anchor
  var link = anchor.attr('href');
  var openWindow;
  if (anchor.attr('target') == "_blank") {
    openWindow = 'True';
  } else {
    openWindow = 'False';
  }
  LeavingSiteModal(link, openWindow);
}

$('a.leavingsiteclass').die();
$('a.leavingsiteclass').live('click', HandleStellentLeavingSiteLinkClick);


/*** Print the contents of an element with the given id ***/
function printContent(id) {
  var newwin = window.open('', 'printwin', 'left=100,top=100,width=200,height=50');
  newwin.document.write('<html>\n<head>\n');
  newwin.document.write('<title>Print Page</title>\n');
  newwin.document.write('<style type="text/css">\n');
  newwin.document.write('@media screen { .printcontent {display: none; } }');
  newwin.document.write('@media print { .screencontent {display: none; } }');
  newwin.document.write('</style>\n');
  newwin.document.write('<script type="text/javascript">\n');
  newwin.document.write('function chkstate(){\n');
  newwin.document.write('if(document.readyState=="complete"){\n');
  newwin.document.write('window.close()\n');
  newwin.document.write('}\n');
  newwin.document.write('else{\n');
  newwin.document.write('setTimeout("chkstate()",2000)\n');
  newwin.document.write('}\n');
  newwin.document.write('}\n');
  newwin.document.write('function print_win(){\n');
  newwin.document.write('window.print();\n');
  newwin.document.write('chkstate();\n');
  newwin.document.write('}\n');
  newwin.document.write('<\/script>\n');
  newwin.document.write('</head>\n');
  newwin.document.write('<body onload="print_win()">\n');
  newwin.document.write('  <div class="screencontent">Printing...</div>\n');
  newwin.document.write('  <div class="printcontent">\n');
  newwin.document.write(document.getElementById(id).innerHTML);
  newwin.document.write('  </div>\n');
  newwin.document.write('</body>\n');
  newwin.document.write('</html>\n');
  newwin.document.close();
}

/*** Display browser warning ***/
$(document).ready(function() {
  if ($(".BrowserWarningContent").length) {
    var warningDialog = $(".BrowserWarningContent");
    warningDialog.dialog({
      showPrint: false,
      title: "Browser Recomendation",
      modal: true,
      autoOpen: false,
      dialogClass: 'olsmodal',
      position: 'center',
      width: 660,
      buttons: {
        Close: function() {
          warningDialog.dialog('close');
        }
      }
    });
    warningDialog.dialog('open');
  }
});

/*** Dynamically load a css file onto a page. Safe to call multiple times ***/
var loadedCssFiles = [];
function loadCssFile(pathToFile) {
  if ($.inArray(pathToFile, loadedCssFiles) == -1) {
    loadedCssFiles.push(pathToFile);
    if (document.createStyleSheet != null) {
      document.createStyleSheet(pathToFile);
    } else {
      var link = jQuery("<link>");
      link.attr({
        rel: "stylesheet",
        type: "text/css",
        href: pathToFile
      });
      $("head").append(link);
    }
  }
}

/*** Dynamically load a js file onto a page. Safe to call multiple times ***/
var loadedJsFiles = [];
function loadJsFile(pathToFile, callback) {
  if ($.inArray(pathToFile, loadedJsFiles) == -1) {
    loadedJsFiles.push(pathToFile);

    jQuery.ajax({
      async: false,
      type: "GET",
      url: pathToFile,
      data: null,
      success: callback,
      dataType: 'script'
    });

    /*
    $.getScript(pathToFile, function() {
      if (callback != null) {
        callback();
      }
    });
    */

  } else {
    if (callback != null) {
      callback();
    }
  }
}

/********************************
Add jquery date validation method
*********************************/
function AddDateValidationMethod(methodName, validationMessage)
{
  $.validator.addMethod(
      methodName,
      function(value, element) {
        return this.optional(element) || IsValidDate(value);
      },
       validationMessage
    );
}

/*********************************
Validate date
Allowed format: mm/dd/1900 onwards
**********************************/
function IsValidDate(value) {
  return /(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d/.test(value);
}

/********************************
Add jquery date validation method
*********************************/
function AddDateInFutureValidationMethod(methodName, validationMessage)
{
  $.validator.addMethod(
      methodName,
      function(value, element) {
        var adata = value.split('/');
        var mm = parseInt(adata[0], 10);
        var dd = parseInt(adata[1], 10);
        var yyyy = parseInt(adata[2], 10);
        var dateOfBirth = new Date(yyyy, mm - 1, dd);
        var check = true;
        var timeNow = new Date();
        if (dateOfBirth.getTime() > timeNow.getTime()) {
          //todo: should we really be comparing time on these and not date?
          check = false;
        }
        return this.optional(element) || check;
      },
      validationMessage
    );
}

// Hide the CMS Number in the footer if a Med Supp Form Number is present in the footer
function HideCmsNumberIfMedSuppFormNumberPresent()
{
  if ($("#MedSupFormNumber .stellent").length > 0) {
    if ($("#MedSupFormNumber .stellent").text().length > 0) {
      HideCmsNumber();
    } else {
      ShowCmsNumber();
    }
  }
}

// Hide the CMS Number in the footer if user has selected MedSupp
function HideCmsNumberIfMedSuppInSession()
{
  if ($("#cmsnumber .ContentFilterStorage").length > 0) {
    var filterStorage = $("#cmsnumber .ContentFilterStorage");
    var filter = JSON.parse(filterStorage.val());
    if (filter.MedicarePlan == "medsupp") {
      HideCmsNumber();
    }
  }
}

// Hide the CMS number
function HideCmsNumber()
{
  //$("#cmsnumber").hide();
}

// Show the CMS number
function ShowCmsNumber()
{
  $("#cmsnumber").show();
}

