/*
JavaScript Object JSURL (JS State Management through URL Anchors) v1.0.0
Requires: Nothing
Author: Nico Westerdale
http://www.iconico.com
*/

Boolean.prototype.jsurlSmallDelimiter	= '=';
Date.prototype.jsurlSmallDelimiter		= '=';
Number.prototype.jsurlSmallDelimiter	= '=';
String.prototype.jsurlSmallDelimiter	= '=';

Boolean.prototype.jsurlLargeDelimiter	= '_';
Date.prototype.jsurlLargeDelimiter		= '_';
Number.prototype.jsurlLargeDelimiter	= '_';
String.prototype.jsurlLargeDelimiter	= '_';

Boolean.prototype.jsurlSave		= jsurlSave;
Boolean.prototype.jsurlRead		= jsurlRead;
Boolean.prototype.jsurlRemove	= jsurlRemove;
Boolean.prototype.jsurlTest		= jsurlTest;

Date.prototype.jsurlSave		= jsurlSave;
Date.prototype.jsurlRead		= jsurlRead;
Date.prototype.jsurlRemove		= jsurlRemove;
Date.prototype.jsurlTest		= jsurlTest;

Number.prototype.jsurlSave		= jsurlSave;
Number.prototype.jsurlRead		= jsurlRead;
Number.prototype.jsurlRemove	= jsurlRemove;
Number.prototype.jsurlTest		= jsurlTest;

String.prototype.jsurlSave		= jsurlSave;
String.prototype.jsurlRead		= jsurlRead;
String.prototype.jsurlRemove	= jsurlRemove;
String.prototype.jsurlTest		= jsurlTest;


//Saves value to URL
function jsurlSave(token) {
	var url = document.location.href;
	var urlToken = this.jsurlLargeDelimiter + escape(token) + this.jsurlSmallDelimiter;
	var urlValue = escape(this);
	if (url.indexOf('#') > -1) {
		//has hash mark
		if (this.jsurlTest(token)) {
			//has token
			document.location.href = url.substring(0, url.indexOf(urlToken, url.indexOf('#')) + urlToken.length) + urlValue + url.substring(url.indexOf(urlToken, url.indexOf('#')) + urlToken.length + escape(this.jsurlRead(token, true)).length);
		} else {
			//does not have token
			document.location.href += urlToken + urlValue;
		}
	} else {
		//no hash at all
		document.location.href += '#' + urlToken + urlValue;
	}
}

//Reads token value from URL
// returnAsString is optional, and by default = false
function jsurlRead(token, returnAsString) {

	//Returns the type of an object from the constructor as a string, e.g. Number
	function GetExactType(obj) {
		try {
			if (obj.constructor)
				return obj.constructor.toString().match(/function (\w*)/)[1];
			else
				return 'n/a';
		} catch(e) {
			return 'n/a';
		}
	}

	var url = document.location.href;
	var urlToken = this.jsurlLargeDelimiter + escape(token) + this.jsurlSmallDelimiter;
	if (this.jsurlTest(token)) {
		var urlValue = url.substring(url.indexOf(urlToken, url.indexOf('#')) + urlToken.length);
		if (urlValue.indexOf(this.jsurlLargeDelimiter) > -1) {
			urlValue = urlValue.substring(0, urlValue.indexOf(this.jsurlLargeDelimiter));
		}
		urlValue = unescape(urlValue);
		if (! returnAsString) {
			//return as the object type, this preserves the type of the object used
			switch(GetExactType(this)) {
				case 'Boolean':
					urlValue = (urlValue == 'true' ? true : false);
					break;    
				case 'Date':
					urlValue =  new Date(Date.parse(urlValue));
					break;
				case 'Number':
					urlValue = parseFloat(urlValue);
					break;
				//We ignore String
			}
		}
	} else {
		urlValue = this;
	}
	return urlValue;
}

//Removes token and value from URL
function jsurlRemove(token) {
	var url = document.location.href;
	var urlToken = this.jsurlLargeDelimiter + escape(token) + this.jsurlSmallDelimiter;
	if (this.jsurlTest(token)) {
		document.location.href = url.substring(0, url.indexOf(urlToken, url.indexOf('#'))) + url.substring(url.indexOf(urlToken, url.indexOf('#')) + urlToken.length + escape(this.jsurlRead(token, true)).length);
	}
}

//Retruns boolen if token is present in URL
function jsurlTest(token) {
	var url = document.location.href;
	var urlToken = this.jsurlLargeDelimiter + escape(token) + this.jsurlSmallDelimiter;
	if (url.indexOf('#') > -1) {
		if (url.indexOf(urlToken, url.indexOf('#')) > -1) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}