function padNumber( num, len ) {
	ret = String(num);
	while(ret.length < len) ret = "0" + ret;
	return ret;
}


function typeOf( v ) {
	var t = typeof v;

	if(t === "object") {
		if(v) {
			if(v instanceof Array)
				t = "array";
			/* else t = "object" is correct */
		}
		else
			t = "null";
	}
	else if(t === "number") {
		if(String("" + v).indexOf(".") === -1)
			t = "integer";
		/* else t = "number" means floating-point value */
	}

	return t;
}


function getBasename( path ) {
	var extPos = path.lastIndexOf(".");
	if(extPos > -1) return path.substring(0, extPos);
	return "";
}


function getExtension( path ) {
	var extPos = path.lastIndexOf(".");
	if(extPos > -1) return path.substring(extPos + 1);
	return "";
}


function isValidNumber( n ) {
	var validChars = String("0123456789-.");
	//alert("checking validity of (" + (typeof n) + ") " + n + " as a real number");

	switch(typeof n) {
		case "number":
			return true;

		case "string":
			var haveDecimal = false;
			var c;

			for(var i = 0; i < n.length; i++) {
				c = n.charAt(i);
				if(validChars.indexOf(c) == -1) return false;
				if(c == "-" && i > 0) return false;

				if(c == ".") {
					if(haveDecimal) return false;
					haveDecimal = true;
				}
			}

			return true;
			break;

		default:
			return false;
	}
}


function isValidInteger( n ) {
	var validChars = String("0123456789-");
	//alert("checking validity of (" + (typeof n) + ") " + n + " as an integer");

	switch(typeof n) {
		case "number":
			return String(n).indexOf(".") == -1;

		case "string":
			n = n.trimmed();
			var c;

			for(var i = 0; i < n.length; i++) {
				c = n.charAt(i);
				if(validChars.indexOf(c) == -1) return false;
				if(c == "-" && i > 0) return false;
			}

			return true;
			break;

		default:
			return false;
	}
}


function isLeapYear( year ) {
	if(isValidInteger(year)) year = parseInt(year);
	return (year > 8) && (((year % 400) == 0) || (((year % 4) == 0) && ((year % 100) != 0)));
}


function maxDaysForMonth( month, year ) {
	if(isValidInteger(year)) year = parseInt(year);
	else year = 1981;	/* 1981 is just a random year with 28 days in feb */
	if(month < 1 || month > 12) return -1;

	switch(month) {
		case 2:
			if(isLeapYear(year)) return 29;
			return 28;

		case 4:
		case 6:
		case 9:
		case 11:
			return 30;
			break;

		default:
			return 31;
	}
}


function isValidDate( day, month, year ) {
	if(typeOf(day) != "integer" || typeOf(month) != "integer" || typeOf(year) != "integer") return false;
	if(day < 1 || year < 1) return false;
	return day <= maxDaysForMonth(month, year);
}


function idOrObjectToObject( idOrObject ) {
	switch(typeOf(idOrObject)) {
		case "object": return idOrObject;
		case "string": return document.getElementById(idOrObject);
	}

	return null;
}


function cancelEvent( e ) {
	if(e.preventDefault) e.preventDefault();
	e.returnValue = false;
}


function bpCopyElementContent( sourceElement, destElement ) {
	sourceElement = idOrObjectToObject(sourceElement);
	destElement = idOrObjectToObject(destElement);
	if(sourceElement && sourceElement.innerHTML && destElement && destElement.innerHTML) destElement.innerHTML = sourceElement.innerHTML;
}


function bpUpdateElementByUrl( idOrObject, url ) {
	idOrObject = idOrObjectToObject(idOrObject);
	var id = $(idOrObject.id);
	new Ajax.Request(url, {method: "get", xTargetContainerId: id, onSuccess: function(r){$(r.request.options.xTargetContainerId).update(r.responseText);}, onFailure: function(r){$(r.request.options.xTargetContainerId).update("<p>Failed to retrieve content.</p>");}, onCreate: function(r){$(r.request.options.xTargetContainerId).update("<p><img src=\"images/library/bpAjaxLoading.gif\" alt=\"\" />&nbsp;Loading...</p>");}});
}


function bpToggleElementVisibility( idOrObject ) {
	var object = idOrObjectToObject(idOrObject);
	object = $(object.id);	/* make sure object has prototype extensions */

	if(typeof object.xbpLibraryToggleState == "undefined") object.xbpLibraryToggleState = "visible";

	if(object.xbpLibraryToggleState == "visible") {
		object.fade({duration: 0.5, transition: Effect.Transitions.sinoidal});
		object.xbpLibraryToggleState = "invisible"
	}
	else {
		object.appear({scaleTo: 2, scaleContent: false, duration: 0.5, transition: Effect.Transitions.sinoidal});
		object.xbpLibraryToggleState = "visible"
	}
}


function bpRollImage( idOrObject ) {
	var object = idOrObjectToObject(idOrObject);

	if(object && object.src) {
		/* on first call extend the image attributes to store the rollover state */
		/* used to cache rolled and notrolled images but sometimes the image changes
		 * elsewhere due to other events (e.g. click on twistie in tree node) so
		 * can't cache without upsetting image "logic" */
		if(typeof object.xbpLibraryRollState == "undefined")
			object.xbpLibraryRollState = "notrolled";

		if(object.xbpLibraryRollState == "rolled") {
			object.xbpLibraryRollState = "notrolled";
			object.src = object.src.replace(/_roll/, "");
		}
		else {
			object.xbpLibraryRollState = "rolled";
			var parts = /(.*)\.(.*)$/.exec(object.src);	/* regex is greedy by default */
			object.src = parts[1] + "_roll" + (parts.length > 2 ? "." + parts[2] : "");;
		}
	}
}
