/* initially set up for use with backroads.com's promotracker

the primary purposes of these functions are to:
1. extract search parameters passed to an url for later use
2. ..by a cookie file (for a given site) that we create here

the end result is that the cookie file of a given site for a given browser
is updated with certain name-value pairs of data passed in via the url.

note:
a cookie file for a given site in the list of sites tracked in a browser's
privacy preferences contains 1 or more name-value variable names.  these
variable names are sometimes each considered a separate cookie.  in this
file's context, we consider a 'cookie file' the cookie, and each name-value
pair a 'crumb'.

--put together by elle 2007-12-05
*/



// --------------- helper functions definitions start here ---------------

/* get the names of the search parameters appended to an url;
parameters: none;
return value: array of parameter names */
function getUrlParamNames() {
	var params = new Array();
	var regex = /[\?&]([^=]+)=/g;	// matches ? or &, then 1 or more of anything that's not an '=', an '='; perform match globally
	while ((results = regex.exec(window.location.href)) != null)	// exec matches and matching substrings of matches
		params.push(results[1]);	// results[0] has form ?varname= or &varname=; results[1] is just varname
	return params;
}


/* get the value of a particular search parameter appended to an url;
parameters: name of parameter to look up;
return value: string of parameter's value */
function getUrlParamVal(name) {
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";	// 1 of (0 or more '\', '&'), plus name, '=', then 0 or more of anything but '&', '#'
  var regex = new RegExp(regexS);
  var results = regex.exec(window.location.href);
  if (results == null)
    return "";
  else
    return results[1];
}


/* make list of just the pre-existing cookie crumbs' names;
parameters: string of all cookies' name-value pairs for given site;
return value: array of existing cookie crumbs' names */
function makeInitCrumbNamesList(initCookie) {
	var crumbNames = new Array();
	
	if (initCookie.length != 0) {	// not empty
		for (var i = 0; i < initCookie.length; i++) {
			var cookieCrumbs = initCookie[i].split("=");
			crumbNames.push(cookieCrumbs[0].split(' ').join(''));	// need to strip off any whitespace(s)!
		}
	}
	else	// no initial cookie values
		crumbNames.push("");
	return crumbNames;
}


/* check if string is in list;
aka, can use to check if new cookie crumb name-value passed in url is already in the page's cookie information;
parameters: a string to search, an array to search the string in;
return value: boolean */
function isInList(someStr, someList) {
	var found = false;

	for (i = 0; i < someList.length; i++) {
		if (someStr.split(' ').join('') == someList[i].split(' ').join('')) {	// remove whitespaces just in case
			var found = true;
			break;
		}
	}
	return found;
}


/* get existing cookie crumbs' name-value pairs;
paramters: crumb name to look up, string of all existing crumbs' names and values for given site;
return value: boolean */
function getInitCrumbVal(searchName, initCookie) {
	for (var k=0; k < initCookie.length; k++) {
		var cookieCrumbs = initCookie[k].split("=");

		var crumbName = cookieCrumbs[0].split(' ').join('');	// making sure to remove whitespaces just in case!
		var crumbVal = cookieCrumbs[1].split(' ').join('');
		
		if (crumbName == searchName)
			return crumbVal;
	}
	return false; // otherwise
}


/* make a dictionary or associative array;
if array1.length < array2.length, the extra end elements of array2.length will not be assigned to a 'key';
if array1.length > array2.length, the extra end elements of array1.length will be 'undefined';
parameters: two arrays of preferably equal length;
return value: associative array
*/
function makeDict(array1, array2) {
	var dictArray = new Array();
	
	for (var i=0; i < array1.length; i++) {
		dictArray[array1[i].split(' ').join('')] = array2[i].split(' ').join('');
	}
	return dictArray;
}


/* set the cookies to expire at some point in the future
parameters: number of years from today;
return value: string of expiration date
*/
function setExpirationDate(numYears) {
	var expireTime = new Date();	// today's date

	expireTime.setFullYear(expireTime.getFullYear() + numYears);
	var expirationDate = expireTime.toGMTString();

	return expirationDate;	// eg. "Tue, 05 Dec 2017 21:51:03 GMT"
}


/* testing pre-existing test cookie file information.  change these values to suit your needs;
paramters: none;
return value: none */
function setTestInitCrumbs() {
}


/* set up any initial data here that is required before making changes to the document.cookie property;
paramters: none;
return value: array packed with 6 arrays,
	[expectedParamNames, expectedCrumbNames, unchangingCrumbs, expectedNamesDict, initCrumbs, initCrumbNames, paramNames] */
/* srcIDinit and/or srcIDrcnt are set only if srcID shows up in url's search parameters */
function setInitData() {
	var initDataArray = new Array();

	// allowed/expected url search parameters' names
	var expectedParamNames = new Array("p", "c", "se", "st", "pt1", "pt2", "pt3", "pt4", "pt5");

	// allowed/expected crumb names
	var expectedCrumbNamesAll = new Array("firstVisitSource", "mostRecentSource", "customer_id", "search_engine", "search_term", "pt1", "pt2", "pt3", "pt4", "pt5");
	var expectedCrumbNames = new Array("mostRecentSource", "customer_id", "search_engine", "search_term", "pt1", "pt2", "pt3", "pt4", "pt5");

	// crumb values that we don't want changed once set
	var unchangingCrumbs = new Array("firstVisitSource");

	// make a 'dictionary' of parameter and crumb names 
	var expectedNamesDict = makeDict(expectedParamNames, expectedCrumbNames);

	// insert test/pre-existing document.cookie values here if desired
	//setTestInitCrumbs();

	// first, check if document.cookie contains existing information and if exist, retain that information for later use
	var initCrumbs = document.cookie.split(";");

	var initCrumbNames = makeInitCrumbNamesList(initCrumbs);

	// now grab the url search parameters' name-value pairs from url
	paramNames = getUrlParamNames();

	var expirationDate = setExpirationDate(10);

	initDataArray.push(expectedParamNames, expectedCrumbNames, unchangingCrumbs, expectedNamesDict, initCrumbs, initCrumbNames, paramNames, expirationDate);

	if (isInList("p", paramNames) == true) {
		if (isInList("firstVisitSource", initCrumbNames) == false) {	// firstVisitSource has never been set/found in cookie file
			document.cookie = "firstVisitSource" + "=" + getUrlParamVal("p") + ";expires=" + expirationDate + ";path=/";
		}
		document.cookie = "mostRecentSource" + "=" + getUrlParamVal("p") + ";expires=" + expirationDate + ";path=/";
	}

	return initDataArray; // [expectedParamNames, expectedCrumbNames, unchangingCrumbs, expectedNamesDict, initCrumbs, initCrumbNames, paramNames, expirationDate]
}


/* the main function that sets the final expected set of cookie variables for the browser's cookie file;
expected parameters: none;
return value: none */
function makeCookieWithUrlParams() {

	// set all desired initial data here
	var initDataArray = setInitData();

	var expectedParamNames = initDataArray[0];
	var expectedCrumbNames = initDataArray[1];
	var unchangingCrumbs = initDataArray[2];
	var expectedNamesDict = initDataArray[3];
	var initCrumbs = initDataArray[4];
	var initCrumbNames = initDataArray[5];
	var paramNames = initDataArray[6];
	var expirationDate = initDataArray[7];

	/* add each new url param-value pair into the document object's cookie property (a string)
	while checking if each already exists in document.cookie or not, and handle accordingly */
	for (var j = 0; j < paramNames.length; j++) {
		var paramName = paramNames[j];	// handle each potentially new crumb (url name-value pair)

		// 1. check if parameter name's corresponding cookie crumb name is already in cookie file or not
		if (initCrumbNames.length == 0)
			var exists = false;
		else if (typeof expectedNamesDict[paramName] != 'undefined')
	 		var exists = isInList(expectedNamesDict[paramName], initCrumbNames);
		else
			var exists = false;

		var isExpectedParamName = isInList(paramName, expectedParamNames);

		var noChange = isInList(paramName, unchangingCrumbs);
	
		// 2. handle new url name-value params and existing name-value pairs in document.cookie
		if (exists == true) {
			if (noChange == true)
				break;
			else 
				document.cookie = expectedNamesDict[paramName] + "=" + getUrlParamVal(paramName) + ";expires=" + expirationDate + ";path=/";	// overwrite previously assigned value
		}

		else if (exists == false && isExpectedParamName == true)
			document.cookie = expectedNamesDict[paramName] + "=" + getUrlParamVal(paramName) + ";expires=" + expirationDate + ";path=/";	// append expected search param's value to existing cookie info
	}
	// don't need to 'return document.cookie;' since final set of cookie variables are available in browser cookie file as needed
}



// --------------- final function call(s) here --------------------

// calling main function
makeCookieWithUrlParams();

