/**
 * @fileoverview (GENERIC) Provides cookie functionality.
 */

/** 
 * @class (GENERIC) Provides cookie functionality.
 * <p>
 * <b>Component:</b> Generic<br>
 * <b>Type:</b> Object
 * <p>
 * <b>Functionality:</b>
 * <p>
 * Provides simple and (direct) keyed cookie set, get and del functionality.
 */ 
var cookie = {

	// ******************************************************************
	// Properties.
	// ******************************************************************

	/**
	 * Whether to call debug functionality.
	 *
	 * @private
	 * @type	{boolean}
	 * @see		#debug_message
	 */
	debug_enabled: false,

	// ******************************************************************
	// Methods.
	// ******************************************************************

	/**
	 * Gets the value of a cookie.
	 * 
	 * @param	{string}	name			The name of the cookie to get.
	 * @param	{string}	default_value	The (optional) default value to return if the cookie is not found - default null.
	 * @return	{string}					The string value of the cookie.
	 */
	get: function(name, default_value) {
		
		// Check the default value parameter.
		if (!default_value && default_value != '') var default_value = null;
		
		// Set up the value string to search for.
		var search = name+'=';

		// Search the cookie for an existing value.
		for (var start = 0; start < document.cookie.length && document.cookie.substring(start, start + search.length) != search; ) {
			
			// Find the next space.
			start = document.cookie.indexOf(' ', start) + 1;
			
			// Completely not found.
			if (start == 0) break;
		}

		// Was it found?
		if (document.cookie.substring(start, start + search.length) == search) {
			
			// Yes - get the end position of the value.
			var end = document.cookie.indexOf (';', start + search.length);
			
			// Or the end of the string if last in the list.
			if (end == -1) end = document.cookie.length;
			
			// The value.
			var value = document.cookie.substring(start + search.length, end);

			// Debug.
			this.debug_message('get', 'returning cookie['+name+'] value of '+value);
			
			// Return the value.
			return unescape(value);
		}
		
		// Not found - Return the default.
		return default_value;
	},

	/**
	 * Sets the value of a cookie.
	 * 
	 * @param	{string}	name		The name of the cookie to set.
	 * @param	{string}	value		The value to set the cookie to.
	 * @param	{integer}	expires		The (optional) time after which the cookie shoud expire (in hours) - default 0.
	 * @param	{string}	path		The (optional) path key to set the cookie against.
	 * @param	{string}	domain		The (optional) domain key to set the cookie against.
	 * @param	{string}	secure		The (optional) secure flag for the cookie.
	 */
	set: function (name, value, expires, path, domain, secure) {

		// Debug.
		this.debug_message('set', 'setting cookie['+name+'] to '+escape(value)+'('+expires+':'+path+':'+domain+':'+secure+')');
		
		// Set the expires information.
		if (expires != null) {
			
			// Parameter exists - create a date object, set its value and swap into the parameter.
			var exp = new Date();
			exp.setTime(exp.getTime() + (expires*1000*60*60));
			expires = exp;
		}

		// Create a cookie value.
		var cookie = name+'='+escape(value)+
			( (expires) ? '; expires='+expires.toGMTString() : '') +
			( (path)    ? '; path='+path : '') +
			( (domain)  ? '; domain='+domain : '') +
			( (secure)  ? '; secure' : '');

		// Set the cookie.
		document.cookie = cookie;
	},

	/**
	 * Deletes a cookie.
	 * 
	 * @param	{string}	name	The name of the cookie to delete.
	 */
	del: function (name) {
		
		// Debug.
		this.debug_message('del', 'deleting cookie['+name+']');

		// Simply blank the value and set the expiry to a minus number. 	
		this.set(name, null, -1000);
	},

	/**
	 * Gets a keyed data item directly from a cookie.
	 * 
	 * @param	{string}	cookie			The name of the cookie to use.
	 * @param	{string}	key				The name of the keyed item.
	 * @param	{string}	default_value	The (optional) default value to return if the keyed item is not found - default null.
	 * @param	{string}	delimeter		The (optional) delimeter to use when searching the source string - default ;;.
	 */
	kd_get: function (cookie, key, default_value, delimeter) {
		
		// Get the value.
		var value = _kd.get(key, this.get(cookie, ''), default_value, delimeter)

		// Debug.
		this.debug_message('kd_get', 'returning key['+key+'] from cookie['+cookie+'] value of '+value);

		// Get the keyed data value using the cookie as the source.
		return value;
	},

	/**
	 * Sets a keyed data item directly into a cookie.
	 *	
	 * @param	{string}	cookie		The name of the cookie to use.
	 * @param	{string}	key			The name of the keyed item.
	 * @param	{string}	value		The value to set the keyed item to.
	 * @param	{integer}	expires		The (optional) time after which the cookie shoud expire (in hours) - default 0.
	 * @param	{string}	delimeter	The (optional) delimeter to use when searching the source string - default ;;.
	 * @param	{string}	path		The (optional) path key to set the cookie against.
	 * @param	{string}	domain		The (optional) domain key to set the cookie against.
	 * @param	{string}	secure		The (optional) secure flag for the cookie.
	 */
	kd_set: function (cookie, key, value, expires, delimeter, path, domain, secure) {
	
		// Debug.
		this.debug_message('kd_set', 'setting key['+key+'] in cookie['+cookie+'] to '+value);

		// Get the cookie value, set the keyed item in it and re-save.
		this.set(cookie, _kd.set(key, value, this.get(cookie, ''), delimeter), expires, path, domain, secure);
	},

	/**
	 * Deletes a keyed data item directly from a cookie.
	 * 
	 * @param	{string}	cookie		The name of the cookie to use.
	 * @param	{string}	key			The name of the keyed item.
	 * @param	{integer}	expires		The (optional) time after which the cookie shoud expire (in hours) - default 0.
	 * @param	{string}	delimeter	The (optional) delimeter to use when searching the source string - default ;;.
	 * @param	{string}	path		The (optional) path key to set the cookie against.
	 * @param	{string}	domain		The (optional) domain key to set the cookie against.
	 * @param	{string}	secure		The (optional) secure flag for the cookie.
	 */
	kd_del: function (cookie, key, expires, delimeter, path, domain, secure) {

		// Debug.
		this.debug_message('kd_del', 'deleting key['+key+'] from cookie['+cookie+']');

		// Get the cookie value, delete the keyed item in it and re-save.
		this.set(cookie, _kd.del(key, this.get(cookie, ''), delimeter), expires, path, domain, secure);
	},

	/**
	 * Simple setter function for debug_enabled.
	 * 
	 * @param	{boolean}	value	The value to set for debug_enabled.
	 * @see #debug_enabled
	 */
	set_debug_enabled: function (value) { this.debug_enabled = value; },

	/**
	 * Simple debug reporting function.  Designed to be overridden if
	 * library is being used in a larger system.
	 * 
	 * @param	{string}	fn		The (optional) name of the function raising the error.
	 * @param	{string}	message	The (optional) description of the error.
	 */
	debug_message: function (fn, message) {
		
		// Check the parameters.
		if (fn == null || fn == '') var fn = 'unknown';
		if (message == null || message == '') var message = 'unknown debug';

		// Check the debug setting and alert if necessary.
		if (this.debug_enabled) alert(fn+'() : '+message);
	}
}

