
/*
##############################################################################################
#   $Source: /home/cvs/clientside/cvsroot/jstools/lib/lib.jst_string.js,v $
#   $Author: stephenc $
#   $Revision: 1.5 $
#   $Date: 2004/08/24 11:25:12 $
##############################################################################################
*/

bbcjs.lib.string = {};

/**
 * Takes a uniform object and converts this to a name-value paired string, using the delimiters passed as args 2,3
 *
 * @param {object} o The object to be referenced when building the string.
 * @param {string} pd The pair delimiter, default is "&"
 * @param {string} vd The value delimiter, default is "="
 *
 * @returns A string in the format of (for example): name1=val1&name2=val2&...&nameN=valN
 *
 * @author Stephen Calcott
 */
bbcjs.lib.string.obj2string = function (o, pd, vd)
{
	//Have name1=val1&name2=val2 as defaults
	if (typeof(pd)=="undefined") pd = "&";
	if (typeof(vd)=="undefined") vd = "=";

	var str = "", i, t="", cnt = 0;
	if (typeof(o)=="object")
	{
		for (i in o)
		{
			cnt++;
			if (typeof(o[i])=="object" && ((o[i].constructor==Object) || (o[i].constructor==Array) ))
			{
				t += i + vd + escape(bbcjs.lib.string.obj2string(o[i], pd, vd)) + pd;
			}
			else if (typeof(o[i])!="object")
			{
				t += i + vd + o[i] + pd;
			}
		}
		str = t.substring(0, t.length-1);
	}
	else bbcjs.trace("obj2string expected typeof object, not "+typeof(o),1);

	if (cnt==0) str = "_{}";

	return str;
}

/**
 * Takes a name-value paired string, returns an object that is built from this by splitting on args 2,3
 *
 * @param {object} str The string to be analysed and split.
 * @param {string} pd The pair delimiter, default is "&"
 * @param {string} vd The value delimiter, default is "="
 *
 * @returns A single-level nested object with the values found in the name-val pairs.
 *
 * @author Stephen Calcott
 */
bbcjs.lib.string.string2obj = function (str, pd, vd)
{
	//Have name1=val1&name2=val2 as defaults
	if (typeof(pd)=="undefined") pd = "&";
	if (typeof(vd)=="undefined") vd = "=";

	var pairs = str.split(pd);
	var i, j, o={}, pair=[], t;

	for (i=0; i<pairs.length; i++)
	{
		pair = pairs[i].split(vd);
		if (i==0 && (parseInt(pair[0])==0)) o = [];
		if (pair.length==2)
		{
			t = unescape(pair[1]);
			if (t.indexOf(vd)!=-1)
			{
				o[pair[0]] = bbcjs.lib.string.string2obj(t, pd, vd);
			}
			else
			{
				if (!isNaN(parseInt(pair[0]))) pair[0] = parseInt(pair[0]);
				if (unescape(pair[1])!="_{}") o[pair[0]] = pair[1];
				else o[pair[0]] = {};
			}
		}
		else bbcjs.trace("WARNING: string2obj:: '"+pairs[i]+"' is not a proper name-val pair (using '"+pd+"' and '"+vd+"')",5);
	}
	return o;
}
/*
##############################################################################################
#   $Source: /home/cvs/clientside/cvsroot/jstools/lib/lib.jst_cookies.js,v $
#   $Author: stephenc $
#   $Revision: 1.6 $
#   $Date: 2004/08/24 11:25:12 $
##############################################################################################
*/

//Create cookies object...
bbcjs.cookies =
{
	version		: 0.1,
	cvs_version	: "$Revision: 1.6 $",
	build_date	: "$Date: 2004/08/24 11:25:12 $",
	cookieData	: {},
	cookieRaw	: {},
	loadOnSet	: true
}

//Gets all cookies available from the browser, then creates an object called cookieData containing
// all cookies we can access, with a split for name=value pairs.
bbcjs.cookies.loadCookies = function()
{
	bbcjs.trace("<b>loadCookies called...</b>",3);

	//Use reference shortcuts...
	var cookieData = bbcjs.cookies.cookieData = {};
	var cookieRaw  = bbcjs.cookies.cookieRaw = {};
	var tmpCookname, tmpArray, i, c, value;
	
	//Split cookie contents on the ; seperator, store in allCookies
	var allCookies = document.cookie.split("; ");

	//Loop through all of our cookies found...
	for (i=0; i<allCookies.length; i++)
	{
		//Split on the '=' seperator, which splits "cookieName=content"
		tmpCookname = unescape(allCookies[i].split("=")[0]);
		cookieRaw[tmpCookname] = allCookies[i].split("=")[1];
		value = cookieRaw[tmpCookname];

		bbcjs.trace("&nbsp;&nbsp;&nbsp;Found cookie: <b>"+tmpCookname+"</b>, calling string2obj...",4);

		//Ignore leading space if we had a space after the last ';'
		if (tmpCookname.charAt(0)==" ") tmpCookname = tmpCookname.substring(1,tmpCookname.length);

		cookieData[tmpCookname] = bbcjs.lib.string.string2obj(unescape(value)); //create a new object within cookieData
	}
	bbcjs.trace("<b>loadCookies found "+i+" cookie(s)...</b>",3);
	return true;
}

//Given any string, store it under a name, with expiry, path and domain extras
bbcjs.cookies.setCookie = function(cn, str, exp, pth, dmn)
{
	var t = "";

	//if we pass the cookiedata type info, munge name=vals into a string.
	if (typeof(str)=="object")
	{
		str = bbcjs.lib.string.obj2string(str);
	}
	
	//If we have a string, do our parsing with dateFromNow
	if (typeof(exp)=="string") exp = bbcjs.cookies.dateFromNow(exp);
	if ((typeof(exp)=='undefined')||(exp=='')) exp = "";
	else exp = ("; expires="+exp.toGMTString());

	bbcjs.trace("setCookie: setting '"+cn+"' to:<br />&nbsp;&nbsp;"+str, 3);
	bbcjs.cookies.checkCookieLimits(cn+"="+ escape(str));
	
	pth  = ((typeof(pth)   =='undefined')||(pth==''))   ? "; path=/":("; path="+pth);
	dmn  = ((typeof(dmn) =='undefined')|| (dmn==''))? "; domain=bbc.co.uk":("; domain="+dmn);
	document.cookie = cn+"="+ escape(str) + exp + pth + dmn;

	if (bbcjs.cookies.loadOnSet) bbcjs.cookies.loadCookies(); //reload our cookieData array
	return true;
}

//Delete data from all available (BBC) cookies:
bbcjs.cookies.removeCookies = function()
{
	bbcjs.trace("removeCookies called: deleting ALL cookies...",3);
	var str = "", arr = [];

	//loop through all cookies loaded from loadCookies, and set to expire in past
	if (document.cookie != "") {
		for (var i in bbcjs.cookies.cookieRaw)
		{
			bbcjs.cookies.deleteCookie(i);
			arr[arr.length] = i;
		}
	}
	return arr;
}

//Delete a specific cookie:
bbcjs.cookies.deleteCookie = function (cn)
{
	bbcjs.trace("deleteCookie: deleting '"+cn+"'", 4);
	return bbcjs.cookies.setCookie(cn, "delete", "-1y");
}

//Converts a format of "+/-n[smhdy]" to a date (gmtstring). e.g +1d or +3y
bbcjs.cookies.dateFromNow = function (s)
{
	bbcjs.trace("dateFromNow: pattern: '"+s+"'", 5);
	var today = new Date();
	var expdate = new Date();
	var multi = 1;

	var md = s.match(/([\+\-]{1})(\d+)([smhdwMy]{1})/i);
	if (md[1] == "-") multi = -1;

	if ( (md.length) && (md.length==4))
	{
		diff = multi*(parseInt(md[2]));

		//Ammend the expdate to reflect the information given...
		if (md[3]!="M") md[3] = md[3].toLowerCase();
		switch (md[3])
		{
			case "s" : expdate.setSeconds(today.getSeconds() + diff ); break;
			case "m" : expdate.setMinutes(today.getMinutes() + diff ); break;
			case "h" : expdate.setHours(today.getHours() + diff ); break;
			case "d" : expdate.setDate(today.getDate() + diff ); break;
			case "w" : expdate.setDate(today.getDate() + (diff*7) ); break;
			case "M" : expdate.setMonth(today.getMonth() + diff ); break;
			case "y" : expdate.setFullYear(today.getFullYear() + diff ); break;
			default : expdate = today; break;
		}
		bbcjs.trace("dateFromNow: new date is: "+expdate, 5);
	}
	else bbcjs.trace("bbcjs.cookies.dateFromNow:: ERROR - pattern does not match required.",1);
	return expdate;
}

//Checks if the string is too long...
bbcjs.cookies.checkCookieLimits = function (str)
{
	var kB = (str.length/1024);
	if (kB>=4) bbcjs.trace("WARNING: the cookie length may be too long for the browser ("+kB+"KB)",1);
	else bbcjs.trace("checkCookieLimits: cookie length OK: ("+kB+"KB)",4);
	return false;
}

//Load cookies straight away...
bbcjs.cookies.loadCookies();

/*
##############################################################################################
#   $Source: /home/cvs/clientside/cvsroot/jstools/mod/mod.jst_cookies.js,v $
#   $Author: stephenc $
#   $Revision: 1.1 $
#   $Date: 2004/02/25 15:41:46 $
##############################################################################################
*/

bbcjs.trace('<b><font color="green">jst_cookies.js</font> was included.</b>',2);

