/**
 * jQuery Cookie Plugin
 * 
 * Copyright (c) 2010 Timothy Leverett
 * http://zzzzbov.com/
 * Licenses:
 *  GPL - http://www.gnu.org/licenses/gpl.html
 *  Creative Commons - http://creativecommons.org/licenses/by-sa/3.0/
 * 
 */
(function($){
  $.cookie = function (name, value, options){
    // defaults to encodeURIComponent and decodeURIComponent
    var settings = $.extend({
      'decode':decodeURIComponent,
      'domain':null,
      'encode':encodeURIComponent,
      'expires':null,
      'path':null,
      'secure':false
    }, value, options),
    val;
    if ( name && name.length )
    {
      // if an encoding function is provided, encode the name
      if ( settings.encode ) name = settings.encode( name );
      
      // remember to regex escape the name (addslashes?)
      // \^$*+?.()|{}[]/
      var rName = name.replace('\\', '\\\\')
        .replace('^', '\\^')
        .replace('$', '\\$')
        .replace('*', '\\*')
        .replace('+', '\\+')
        .replace('?', '\\?')
        .replace('.', '\\.')
        .replace('(', '\\(')
        .replace(')', '\\)')
        .replace('{', '\\{')
        .replace('}', '\\}')
        .replace('[', '\\[')
        .replace(']', '\\]')
        .replace('|', '\\|')
        .replace('/', '\\/');
      
      // get the previous value of the cookie if it existed
      /**
       * RegExp Breakdown:
       * search from the beginning or last semicolon: (^|;)
       * skip variable number of spaces (escape backslash in string): \\s*
       * find the name of the cookie: name
       * skip spaces around equals sign: \\s*=\\s*
       * select all non-semicolon characters: ([^;]*)
       * select next semicolon or end of string: (;|$)
       */
      var regex = new RegExp( '(^|;)\\s*'+rName+'\\s*=\\s*([^;]*)(;|$)' );
      match = document.cookie.match( regex );
      // if there was a match, match[2] is the value
      // otherwise the cookie is null ?undefined?
      val =  match ? match[2] : null;
      
      // if a decoding function is provided, decode the value
      if ( settings.decode ) val = settings.decode( val );
      
      // set the cookie if the value is defined and not an object (string, number)
      if ( value !== undefined && typeof value != 'object' )
      {
        // if the value is set, the cookie will be set
        if ( settings.encode ) value = settings.encode( value );
        
        // mix the dough
        var cookie = name + '=' + value;
        
        // check the expire settings
        switch ( typeof settings.expires )
        {
          case 'object':
          {
            // null values will also be objects
            // check if expires is set and has toUTCString method
            if ( settings.expires && settings.expires.toUTCString )
            {
              cookie += '; expires='+settings.expires.toUTCString();
            }
          } break;
          case 'number':
          {
            // offset the current timestamp by # days
            var d = new Date();
            // 24h * 60m * 60s * 1000ms
            d.setTime( d.getTime() + ( settings.expires * 86400000 ) );
            cookie += '; expires='+d.toUTCString();
          } break;
          case 'string':
          {
            // set the expiry string to whatever was provided
            cookie += '; expires='+settings.expires;
          } break;
          default:
          { } break;
        }
        
        // if path, domain, or secure are set, add them to the cookie
        if ( settings.path ) cookie += '; path='+settings.path;
        if ( settings.domain ) cookie += '; domain='+settings.domain;
        if ( settings.secure ) cookie += '; secure';
        
        // bake the cookie
        document.cookie = cookie;
      }
      else if ( value === null )
      {
        // remove the cookie if the value is null
        // beginning of time
        var d = new Date(0);
        // mix the dough
        var cookie = name+'=; expires='+d.toUTCString();
        // if path, domain, or secure are set, add them to the cookie
        if ( settings.path ) cookie += '; path='+settings.path;
        if ( settings.domain ) cookie += '; domain='+settings.domain;
        if ( settings.secure ) cookie += '; secure';
        
        // bake the cookie
        document.cookie = cookie;
      }
    }
    
    // return the prior value of the cookie if it was set
    return val;
  };
})(jQuery);
