/*
	Class to wrap all functionality concerning cookies
	A single cookie is written for all app name/value pairs
	Cookie data is stored as JSON
	Each sub-item (or crumb) can have its own expiry date
	A separate cookie is used for crumbs that require a session expiry 
	Each crumb has the following structure:
	{
		"name" 		:	"crumb_name",
		"value"		:	[any value, object, array etc],
		"expires"	:	[expiry date - formatted GMT-javascript style] || "session"
	}
*/
tfoCookie = function(v_cookie_name, v_is_session_cookie){

	try {
	
		// Check that THEFOOT namespace is created
		if (!THEFOOT){throw('THEFOOT global namespace is not yet initialised.');}
	
		/*********************************************************************
			Member Properties
		*********************************************************************/
		this.cookie_name = v_cookie_name;
		this.is_session_cookie = v_is_session_cookie;
		if (this.is_session_cookie){this.cookie_name += '_sess';}
		this.crumbs = {}
	
		/*********************************************************************
			Public methods
		*********************************************************************/
		
		/*********************************************************************/
		// Get a crumb item (value node) from the app cookie
		this.get = function(v_name){
			_readCookie();
			if (this.crumbs[v_name]){
				return this.crumbs[v_name].value;
			} else {
				return null;	
			}
		} // this.get
		
		/*********************************************************************/
		// Add a sub-item (crumb) to the app cookie
		// If a crumb by this name exists, it will be overwritten
		// If v_expire_minutes == null then use the default timeout
		this.set = function(v_name, v_value, v_expire_minutes){
			
			// Validate
			if (v_name.length == 0){
				throw('Cookie name must be specified.');	
			}
			
			// Retrieve current cookie
			_readCookie();
			
			// Calculate the expiry 
			if (this.is_session_cookie){
				// Add crumb to cookie
				var o_crumb = {
					"name"		:	v_name,
					"value"		:	v_value
				}
			} else {
				var d_expires = new Date();
				if (v_expire_minutes == null){
					var v_milliseconds = THEFOOT.DEFAULT_COOKIE_TIMEOUT * 60 * 1000;
				} else {
					var v_milliseconds = v_expire_minutes * 60 * 1000;
				}
				d_expires.setTime(d_expires.getTime() + v_milliseconds);
				
				// Add crumb to cookie
				var o_crumb = {
					"name"		:	v_name,
					"value"		:	v_value,
					"expires"	:	d_expires.toUTCString()
				}
			}
			this.crumbs[v_name] = o_crumb;
			
			// Write out the cookie
			_writeCookie();
			
			return this.crumbs[v_name];
			
		} // this.set
		
		/*********************************************************************/
		// Remove an item from the app cookie
		this.remove = function(v_name){
			_readCookie();
			var o_crumb = this.crumbs[v_name];
			delete this.crumbs[v_name];
			_writeCookie();
			return o_crumb;
		} // this.remove
		
		/*********************************************************************/
		// Return true if cookies are enabled
		this.enabled = function(){
			
			var v_testval = Math.floor(1000*Math.random());
			var v_enabled = false;
			try {
				this.set('cookieTest', v_testval, 1);
				v_enabled = (this.get('cookieTest') == v_testval);
				this.remove('cookieTest');
			} catch(e){}
			return v_enabled;
			
		} // this.enabled
		
		/*********************************************************************/
		// Return crumbs as JSON object
		this.toJson = function(){
			_readCookie();
			return this.crumbs;
		} // this.toJson
		
		/*********************************************************************/
		// Return crumbs as string
		this.toString = function(){
			_readCookie();
			return JSON.stringify(this.crumbs);
		} // this.toString
		
		/*********************************************************************/
		// Return crumbs as numerically-indexed array
		this.toArray = function(){
			_readCookie();
			var a_crumbs = [];
			for (var i in this.crumbs){
				a_crumbs.push(this.crumbs[i]);	
			}
			return a_crumbs;
		} // this.toArray

		/*********************************************************************
			Private methods
		*********************************************************************/
		
		/*********************************************************************/
		// Write the app cookie
		var _writeCookie = function(){
			try {
				
				// First get crumbs string
				var v_data = JSON.stringify(this.crumbs);
			
				if (this.is_session_cookie){
					var v_cookie_string = this.cookie_name + "=" + escape(v_data) +
						'; path=/'; // + THEFOOT.SITE_ROOT;
				} else {
					// Set global cookie date
					var v_cookie_date = new Date();
					v_cookie_date.setFullYear(v_cookie_date.getFullYear() + 10);
					
					// Write cookie
					var v_cookie_string = this.cookie_name + "=" + escape(v_data) +
						'; expires=' + v_cookie_date.toUTCString() + 
						'; path=/'; // + THEFOOT.SITE_ROOT;
				}
				document.cookie = v_cookie_string;
				
			} catch(e) {
				throw ('Error writing app cookie: ' + e);	
			}
		}.bind(this) // _writeCookie
		
		/*********************************************************************/
		// Get the app cookie
		var _readCookie = function(){
			try {
				
				// Split document.cookie into array and search for our app cookie
				var a_raw = document.cookie.split(';');
				var v_rawcookie = null;
				for (var i = 0; i < a_raw.length; i++){
					a_raw[i] = a_raw[i].trim();
					var v_name = a_raw[i].split('=')[0].trim();
					if (v_name == this.cookie_name){
						v_rawcookie = unescape(a_raw[i].split('=')[1].trim());
					}
				}

				// Into JSON
				this.crumbs = (!v_rawcookie) ? {} : JSON.parse(v_rawcookie);
				
			} catch(e) {
				throw ('Error getting app cookie: ' + e);	
			}
		}.bind(this) // _readCookie
	
		/*********************************************************************/
		// Create our expiration check timer
		if (!this.is_session_cookie){
			var _timerExpiration = setInterval(function(){
			
				// Get cookie
				_readCookie();
				
				// Check each crumb for expiration and delete expired ones
				var v_changed = false; var v_date = new Date();
				for (var v_key in this.crumbs){
					var v_expires_date = new Date(this.crumbs[v_key].expires.replace(/\+/g, ' '));
					if (v_expires_date < v_date){
						delete this.crumbs[v_key];
						v_changed = true;
					}
				}
				
				// Write out updated cookie if changed
				if (v_changed){_writeCookie();}
			
			}.bind(this), 5000);
		}
	
		// On completion of constructor, initialise cookie and return ref
		_readCookie(); _writeCookie();
		return this;
	
	} catch(e) {
		alert('Error creating application cookie object: ' + e);	
		return false;
	}

} // tfoCookie


