/**
 * uk.co.mfbaker.Cookie class.
 * This Cookie class is taken from:
<cite>
JavaScript<br />
The Definitive Guide<br />
5<sup>th</sup> Edition<br />
by David Flanagon<br />
page 462<br />
</cite>
 * <br />
 * An instance of this class is written to and read from a single cookie, the 
 * cookie-name is passed into the constructor; and stored in this._cookieName property.
 * The name/value pairs, held as properties by an instance of this class,
 * are parsed into a single string value, and stored as the cookie-value; in this
 * way multiple name/value pairs can be assosiated with one cookie. 
 * <br />
 *
 * When the name/value pairs are passed they are encoded using iether encodeURIComponent()
 * or escape(), they both encode '&' and ':' which are used as separation characters.<b> 
 *
 * <br />
 *
 * string:		this._cookieName
 * function:	this._cookieRead
 * function:	this._cookieWrite
 * function:	this._cookieRemove
 * function:	this._cookieEncode
 * function:	this._cookieDecode
 *
 */
 
/**
 * This constructor stores the cookie-name, then calls the method to read in
 * the name/value pairs from the named cookie, this method places those name/vlaue 
 * pairs into properties of this object; the names must not begin with a dollar($) or
 * an underscore (_) and must be a primative type, i.e. string, number or boolean.
 *
 * @author Mark Franklyn Baker
 * @version 0.1 Apr 07 2009
 * @param name - name of the Cookie.
 * @type constructor
 */
uk.co.mfbaker.Cookie = function (name) {
	this._cookieName = name;
	this._cookieRead();
}

if (encodeURIComponent) {
	uk.co.mfbaker.Cookie.prototype._cookieEncode = encodeURIComponent;
	uk.co.mfbaker.Cookie.prototype._cookieDecode = decodeURIComponent;
//alert('uk.co.mfbaker._cookieDecode URI');
}
else if (escape) {
	uk.co.mfbaker.Cookie.prototype._cookieEncode = escape;
	uk.co.mfbaker.Cookie.prototype._cookieDecode = unescape;
//alert('uk.co.mfbaker._cookieDecode ESC')
}
else {
alert('uk.co.mfbaker.Cookie._cookieEncode'
+'\none of encodeURIComponent or escape function is required '
+'');
}


/**
 * This method looks for a single cookie with the specified name
 * for the current document. If one exists, it parses its value into a set of 
 * name/value pairs and stores thoes values as properties of
 * this newly create object.
 * <br />
 * _cookie
 * cookie name/value pairs
 *    - string, number or boolean
 *    - name literal must bebin with a letter
 *      i.e. any name must not begin with $ or _


 * @author Mark Franklyn Baker
 * @version 0.1 Apr 07 2009
 * @param name - name of the Cookie.
 * @type instance-method
 */
uk.co.mfbaker.Cookie.prototype._cookieRead = function () {

	var allcookies;
	var cookies;
	var cookie;
	var index;
	var cookieValue;
 	var nameValuePairs;
 	var nameValuePair;

	// document.cookie contains a list of all the cookies
	// that pertain to this current document (i.e. this web page). 
	allcookies = document.cookie;
	if (allcookies==='') return;
	
	cookies = allcookies.split(';');
	
	// the cookie value
	cookieValue = null;
	
	for (index=0; index<cookies.length&&cookieValue===null; index++) {
	
		cookie = cookies[index];
		
		// remove the leading space, if it exists.
		if (cookie.charAt(0)===' ') cookie = cookie.substring(1);
		
		// check for the required cookie name
		if (cookie.substring(0, this._cookieName.length+1)===(this._cookieName+'=')) {
			cookieValue = cookie.substring(this._cookieName.length+1);
		}
	
	}
	
 	if (cookieValue!==null) {
 	
 		// parse the cookie value:
 		// build an array of name:value strings (separated by the andpersand &)
 		// from the cookie-value.
 		nameValuePairs = cookieValue.split('&');
 
 		// create properties on this Cookie object from the names:value strings
 		// and assign the values to the properties.
 		for (index=0; index<nameValuePairs.length; index++) {
 		
 			// 
 			nameValuePair = nameValuePairs[index].split(':');
 			
 			// expecting one or two colons
 			// therefor 2 or 3 elements
 			if (nameValuePair.length===2) {
 			
 				// string
 				this[nameValuePair[0]] = this._cookieDecode(nameValuePair[1]);
 			}
 			else if (nameValuePair.length===3) {
 			
 				if (nameValuePair[1]==="number") {
 				
 					// number - converted by subtracting zero
 					this[nameValuePair[0]] = this._cookieDecode(nameValuePair[2]) - 0;
 				}
 				else if (nameValuePair[1]==="boolean") {
 				
 					// boolean 
 					this[nameValuePair[0]] = this._cookieDecode(nameValuePair[2])==='true';
 				}
 				else {
 				
 					// string
 					this[nameValuePair[0]] = this._cookieDecode(nameValuePair[2]);
 				}
 			
 			} 			
 			
 		} 		
 
 	}

}

/**
 * Method to store the cookie.
 * This method will store any primitive string, boolean or number 
 * properties of this object, that does NOT begin with a '$' or an '_',
 * into a cookie. The cookie name is held in this._cookieName property.
 *
 * @author Mark Franklyn Baker
 * @version 0.1 Apr 07 2009
 * @param daysToLive 	- number of days this Cookie is set to Live.
 		- if zero: 			The cookie will be deleted.
 		- null (or omited)	The cookie will be a "session" cookie.
 		  and is only held by the browser until the browser is closed by the user.
 * @param path - .	
 * @param domain - .
 * @param secure - .
 * @type instance-method
 */
uk.co.mfbaker.Cookie.prototype._cookieWrite = function (daysToLive, path, domain, secure) {

	var cookieValue;
	var cookie;
	var nameValueType;
	var propertyName;
	var propertyValue;
	
	cookieValue = '';
	
	// for all properties on this object
	for (propertyName in this) {
	
		// if the property does NOT begin with a dollar "$" or underscore "_"
		// 
		if ( !((propertyName.charAt(0)==='$')||(propertyName.charAt(0)==='_')) ) {
	
			propertyValue = this[propertyName];
	
			nameValueType = typeof propertyValue;
		
			// if the property is a primative type
			if (nameValueType === 'string' || 
				nameValueType === 'number' ||
				nameValueType === 'boolean') {
			
				if (cookieValue!=='') cookieValue += '&';
		
				if (nameValueType === 'string') {
					cookieValue += propertyName
						+ ':'
						+ this._cookieEncode(propertyValue);
				}
				else {
					cookieValue += propertyName
						+ ':'
						+ nameValueType
						+ ':'
						+ this._cookieEncode(propertyValue+'');
				}
			
			}
			
		}
		
	}

	cookie = this._cookieName + '=' + cookieValue;

	if (daysToLive || daysToLive===0) {
		cookie += '; max-age=' + (daysToLive*86400);
	}	
	
	if (path) cookie += '; path=' + path;
	if (domain) cookie += '; domain=' + domain;
	if (secure) cookie += '; secure=' + secure;


//alert('uk.co.mfbaker.Cookie._cookieWrite'
//+'\ncookie: '+cookie
//+'');
	
	document.cookie = cookie;

}

/**
 * Method to remove all the name value pairs held in this cookie object.
 * @author Mark Franklyn Baker
 * @version 0.1 Apr 07 2009
 * @type instance-method
 */
uk.co.mfbaker.Cookie.prototype._cookieRemove = function () {

	var propertyName;

	// for all properties on this object
	for (propertyName in this) {

		if ( !((prop.charAt(0)==='$')||(prop.charAt(0)==='_')) ) {
	
			nameValueType = typeof this[propertyName];
		
			// if the property is a primative type
			if (nameValueType === 'string' || 
				nameValueType === 'number' ||
				nameValueType === 'boolean') {
				delete this[prop];
			}
		
		}
		
	}

}

/**
 * Convinience Method to remove all the name value pairs held in this cookie object.
 * and remove the the cookie from the browser.
 * @author Mark Franklyn Baker
 * @version 0.1 Apr 07 2009
 * @param path - .	
 * @param domain - .
 * @param secure - .
 * @type instance-method
 */
uk.co.mfbaker.Cookie.prototype._cookieRemoveWrite = function (path, domain, secure) {

	this._cookieRemove();
	this._cookieWrite(0, path, domain, secure);
	
}