// Add stand-alone functions to the jQuery root object.  
// Note that these functions are not applied to the jQuery
// object returned by selectors, rather they must be accessed via:
//
// $.someMethod();
 
(function($, undefined)
{
  //   ================================
  //  |  Extension Method Definitions  | 
  //   ================================

  /**
    * Determines if a variable is defined and non-null.
    *
    * @param {object} target    The object to consider.
  */
  this.isDefined = function GeekRead$jQuery$Extensions$isDefined(target)
  {
    return ((target !== undefined) && (target !== null));

  }; // End method isDefined

  /**
    * Determines if text is null or is empty.
    *
    * @param {string} text    The text to consider.
  */
  this.isNullOrEmpty = function GeekRead$jQuery$Extensions$isNullOrEmpty(text)
  {
    if (!isDefined(text))
    { 
      return true;
    }

    // Force string conversion for numbres by appending an empty string, and test
    // to ensure that it is not empty.

    text += '';
    return ((!isDefined(text)) || (typeof(text) !== 'string') || (!isDefined(text.length)) || (text.length == 0));

  }; // End method isNullOrEmpty

  /**
    * Determines if a service result has failures.
    *
    * @param {object} serviceResult    The service result object to consider.
  */
  this.serviceResultHasFailures = function GeekRead$jQuery$Extensions$serviceResultHasFailures(serviceResult)
  {
    if (!isDefined(serviceResult))
    {
      return false;
    }
        
    if (((isDefined(serviceResult.Exceptions)) && (serviceResult.Exceptions.length > 0)) || 
        ((isDefined(serviceResult.ValidationFailures)) && (serviceResult.ValidationFailures.length > 0)))
    {
      return true;
    }
    
    return false;

  }; // End method serviceResultHasFailures

  /**
    * Loads and caches elements from the dom on demand.
    *
    * @param {object} elementCache     The object to use as the cache for selected elements.
    * @param {string} selector         The selector of the element to retrieve.
    * @param {object} parentElement    The parent element of the element to retrieve.
  */
  this.selectAndCacheElement = function GeekRead$jQuery$Extensions$selectAndCacheElement(elementCache,
                                                                                       selector, 
                                                                                       parentElement) 
  { 
    if (!isDefined(selector)) 
    { 
      return null; 
    } 

    // Attempt to retrieve the element from the cache, if one was passed.
   
    if ((isDefined(elementCache)) && (selector in elementCache) && (isDefined(elementCache[selector])))
    {
      return elementCache[selector]; 
    } 
   
    // If the element was not in the cache, attempt to locate and cache it.

    var element = $(selector, parentElement); 
   
    if (element.length <= 0) 
    { 
      return null; 
    } 
    
    if (isDefined(elementCache))
    {
      elementCache[selector] = element; 
    }

    return element;
     
  }; // End method selectAndCacheElement

  /**
    * Performs a test to verify that cookies are enabled in the browser, using
    * the jQuery cookies plug-in.
    *
    * @param {bool}  persistent    A flag indicating if persistent cookies should be tested.  If not set, session cookies are tested.
  */
  this.testCookies = function GeekRead$jQuery$Extensions$testCookies(persistent)
  {
    if (!isDefined($.cookie))
    {
      return false;
    }

    var expirationValue = 1;

    if ((isDefined(persistent)) && (persistent === false))
    {
      expirationValue = 0;
    }

    // Test cookies by attempting to set, read, then delete a cookie.

    var name = 'GeekReadCookieTest';
    
    $.cookie(name, null, { expires : -1 });
    $.cookie(name, name, { expires : expirationValue });

    var value = $.cookie(name);

    $.cookie(name, null, { expires : -1});

    return ((isDefined(value)) && (value == name));

  }; // End method testCookies

  this.disableEnterKey = function GeekRead$jQuery$Extensions$disableEnterKey(event)
  {
      var key; 
      if ($.isDefined(window.event)) 
      { 
        key = window.event.keyCode; 
      }
      else 
      {
        key = event.which; 
      }

      return key == 13 ? false : true;

  }; // End method disableEnterKey

  /**
    * Prevents an event object from performing its default action.
    *
    * @param {object}  event    OPTIONAL.  The jQuery event object.  If not present, no action will be taken.
  */
  this.preventEventDefault = function MainMaster$preventEventDefault(event)
  {
    if ($.isDefined(event))
    {
      event.preventDefault();
    }

    return false;

  }; // End method preventEventDefault

  this.readCookie = function GeekRead$jQuery$Extensions$readCookie(name)
  {
    var nameEQ = name + '=';
    var ca = document.cookie.split(';');
    var length = ca.length;
    for (var i = 0; i < length; i++ )
    {
      var c = ca[i];
    	while (c.charAt(0)==' ')
      {
        c = c.substring(1,c.length);
      }
		  if (c.indexOf(nameEQ) == 0)
      {
        return c.substring(nameEQ.length,c.length);
      }
    }
    return null;

  }; // End method readCookie

  this.historyMatchesCurrentPage = function GeekRead$jQuery$Extensions$historyMatchesCurrentPage(currentPage)
  {   
    var data = $.readCookie('history');
    if ($.isDefined(data) === false)
    {
      return false;
    }
    return (data.toLowerCase() == currentPage.toLowerCase());

  }; // End method historyMatchesCurrentPage

  /**
    * Prevents default action when enter key is pressed then executes a callback
    *
    * @param {object} event       The jQuery event object.  If not present, no action will be taken.
    * @param {object} callback    Callback executes case-defined function provided by caller.
  */
  this.fireOnEnter = function GeekRead$jQuery$Extensions$fireOnEnter(event, callback) 
  {
    if ($.isDefined(event)) 
    {
      if (event.which === 13) 
      {
        if ($.isDefined(callback)) 
        {
          $.preventEventDefault(event);
          callback();

          return false;
        }
      }
    }
  };  // End method fireOnEnter

  //   ================================
  //  |         Extend jQuery          | 
  //   ================================

  var methods = this;

  $.extend(
  { 
    isDefined                : methods.isDefined,
    isNullOrEmpty            : methods.isNullOrEmpty,
    serviceResultHasFailures : methods.serviceResultHasFailures,
    selectAndCacheElement    : methods.selectAndCacheElement,
    testCookies              : methods.testCookies,
    disableEnterKey          : methods.disableEnterKey,
    preventEventDefault      : methods.preventEventDefault,
    fireOnEnter              : methods.fireOnEnter, 
    readCookie               : methods.readCookie,
    historyMatchesCurrentPage : methods.historyMatchesCurrentPage
  });

})(jQuery);
