/*************************************************************************
 JSONCookie 1.0
 Canwest Digital Media
 Built: November 6, 2009
 
 DESCRIPTION:
	JSONCookie.js is a javascript library that creates, reads, updates and deletes cookies. 
	Cookie values are stored as collection of JSON objects, which allows for easy storage and retrieval of complex data objects
	
	NOTE: JSON can get verbose pretty quickly, particularly if you are 'cookie-ing' more complex js objects. 
		  If your JSON value is too long, the cookie will fail to write.
				- keep the data objects to be cookied as simple as possible (ie: only cookie the data required )
				- keep the 'Key' names as short as possible 
 
 DEPENDENCIES:
	Requires the following javascript libraries:
		jquery-1.2.6.min.js  (the jQuery library)
		json2.js  (JSON parser and stringfier)

 FUNCTIONS:

	JSONCookie.Init('[CookieName]',[Options]);
			Description:  Initializes the cookie object. (Creates empty cookie if it doesn't exist OR initializes the existing cookie)
			Parameters:
				CookieName STRING	- the name of the cookie
				Options OBJECT		- an optional list of cookie options (see below)

				Options Object
				
				The options object has four properties:
					* domain
						  - STRING
						  - specifies the cookie domain 
					* path
						  - STRING
						  - specifies the cookie path 
					* daysToLive
						  - NUMBER
						  - Number of days before the cookie will expire
							Passing 0 means to delete the cookie at the end of the browser session--this is default. 
							Negative values will delete the cookie, but you should use the Delete() method instead.
					* secure
						  - BOOL
						  - specifies whether the cookie should be sent to server via HTTPS only

				The structure of the object is as follows:

				  var newOptions = {
					domain: '*.mydomain.com',
					path: '/somedir',
					daysToLive: 24,
					secure: true
				  }

				You need only set those options which you desire to override.

				The default options when not overridden are:

					* domain
						  - no value - will cause current domain of current page to be used 
					* path
						  - / 
					* daysToLive
						  - no value--causes cookie to be deleted at end of browser session 
					* secure (send over HTTPS only)
						  - false 
			
	JSONCookie.Delete('[CookieName]');
		Description:  Deletes the specified cookie 
		Parameters:
			CookieName STRING	- the name of the cookie
		Note:	deleting the cookie means it is no longer available to work with
				Re-initiate the cookie object, using JSONCookie.Init(), before calling any subsequent JSONCookie functions.						
						
	JSONCookie.AddValue('[CookieName]','[Key]','[Value]',[maxValues],'[uniqId]');
		Description:  Adds a name-value pair to the cookie
		Parameters:
			CookieName STRING	- the name of the cookie
			Key STRING			- the variable name
			Value MIXED VALUE	- the value to add.  If the value is an object it will be stored as a JSON array
			maxValues NUMBER	- the maximum number of values to add to the key.  If maxValues > 1 the value will be stored as a JSON array
			uniqId				- if the value is an object, specify the object property to use as the unique identifier to prevent duplicate values 

	JSONCookie.RemoveValue('[CookieName]','[Key]');
		Description:  Removes a name-value pair from the cookie, does not delete the cookie
		Parameters:
			CookieName STRING	- the name of the cookie
			Key		   STRING	- the varialbe name to remove
	
	JSONCookie.GetValue('[CookieName]','[Key]');
		Description:  Retrieves the Value for the specified Key
		Parameters:
			CookieName STRING	- the name of the cookie
			Key STRING			- the variable name to retrieve
	
	JSONCookie.Debug('[CookieName]');
		Description:  display a javascript alert() box with the cookie's contents and some information about it
		Parameters:
			CookieName STRING	- the name of the cookie

		
****************************************************************************************************************************/

(function(jQuery) {

    JSONCookie = {

		Data: {},
		
		Debug:  function(cookieName) {
			var regex = /\+/g;
			var val = unescape(String(parseValues(cookieName)).replace(regex, " "));
			alert("Name: " + cookieName + "\n" +
				  "Options: " + unescape(JSON.stringify(JSONCookie.Data[cookieName].Options)) + "\n" +
				val);
		},

		Delete: function(cookieName) {
			delete JSONCookie.Data[cookieName];
			var expires = new Date();
			expires.setTime(expires.getTime() - 24*60*60*1000);
			document.cookie = (cookieName + "=; expires=" + expires.toGMTString() + "; path=/");
		},

		Init: function(cookieName, options) {
			if (typeof JSONCookie.Data[cookieName] == "undefined") {
				var cookieValues = {};
				
				if( typeof options !== 'object' || options === null)
				{
					options = {};
					options.daysToLive = -1;
				}

				var cookieOptions = getOptions(options);

				//get cookie value
				var v = parseValues(cookieName);
				if (v !== null) {
					cookieValues = JSON.parse( unescape(String(v).replace(/\+/g, " ")) );
				}

				// add cookie details to object
				JSONCookie.Data[cookieName] = { Options: cookieOptions, Values  : cookieValues };
				save(cookieName);
			}
		},

		AddValue: function(cookieName, key, value, maxValues, uniqId) {
			if((typeof maxValues !== 'number' || maxValues === 1) && (typeof value !== 'object' && value !== null))
			{
				JSONCookie.Data[cookieName].Values[key] = value;
			} else {
				if(typeof JSONCookie.Data[cookieName].Values[key] == 'undefined')
					JSONCookie.Data[cookieName].Values[key] = new Array();

				JSONCookie.Data[cookieName].Values[key] = addCollection(JSONCookie.Data[cookieName].Values[key], value, maxValues, uniqId);
			}
			
			save(cookieName);
		},

		RemoveValue: function(cookieName, key) {
			delete JSONCookie.Data[cookieName].Values[key];
			save(cookieName);
		},

		GetValue: function(cookieName, key) {
			        return JSONCookie.Data[cookieName].Values[key];
		}
    }
	
	var	defaultOptions = {				
		daysToLive: null,
		path: '/',
		domain:  null,
		secure: false
	};

	function addCollection(collection, value, maxNumber, uniqId)
	{
		var exists = false;
		for(i=0;i<collection.length;i++)
		{
			if(typeof value !== 'object') {
				if(collection[i] == value)
					exists = true;
			}
			else if (collection[i][uniqId] == value[uniqId])
				exists = true;
		}
		
		if(!exists)
			collection.unshift(value);

		return collection.splice(0,maxNumber);
	}

	function getOptions( options )
	{
		var optVal = {};

		if(typeof options !== 'object' || options === null)
		{
			optVal = defaultOptions;
		}
	    else
		{
			optVal = {
				daysToLive: ( typeof options.daysToLive === 'number' && options.daysToLive !== 0 ? options.daysToLive : defaultOptions.daysToLive ),
				path: ( typeof options.path === 'string' && options.path !== '' ? options.path : defaultOptions.path ),
				domain: ( typeof options.domain === 'string' && options.domain !== '' ? options.domain : defaultOptions.domain ),
				secure: ( typeof options.secure === 'boolean' && options.secure ? options.secure : defaultOptions.secure )
			};
		}
		
		return optVal;
	}

	function getOptionString( options )
	{
		options = getOptions( options );

		return (
			( typeof options.daysToLive === 'number' ? '; expires=' + expiresGMTString( options.daysToLive ) : '' ) +
			'; path=' + options.path +
			( typeof options.domain === 'string' ? '; domain=' + options.domain : '' ) +
			( options.secure === true ? '; secure' : '' )
		);
	}

	function expiresGMTString( daysToLive )
	{
		var dateObject = new Date();
		dateObject.setTime( dateObject.getTime() + ( daysToLive * 24 * 60 * 60 * 1000 ) );

		return dateObject.toGMTString();
	}

    function parseValues(cookieName) {
        
        var contents = document.cookie.split(';');
        cookieName += "=";
        
		var v = null;

        for (var i=0;i<contents.length;i++) {
            var s = contents[i];
            while (s.charAt(0) == " ") {
                s = s.substring(1, s.length);
            }
            if (s.indexOf(cookieName) == 0) {
                v = s.substring(cookieName.length, s.length);
                break;
            }
        }

        return v;
    }

    function save(cookieName) {
        document.cookie = (cookieName + "=" +
                           escape(JSON.stringify(JSONCookie.Data[cookieName].Values)) +
                           getOptionString(JSONCookie.Data[cookieName].Options));
    }
})(jQuery);




