// <dtml-call set_base_path>

// library of common javascript functions

var d = document; // speeds things up a bit
var is_ie = (d.all)? true: false; // detect the evil IE

// return a reference to an object
getObj = function(id) {
	if (d.getElementById) { // class 'A' browsers
		return d.getElementById(id);
	} else if (d.all) {
		return d.all['id']; // IE 4, class 'B' browser
	} else if (d.layers) {
		// Netscape 4, class 'C' browsers
	} else {
		// Unknown class 'C' browsers
	}
}

// add functions to fire on page load
function addLoadEvent (func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload=function() {
			if (oldonload) {
				oldonload();
			}
			func ();
		}
	}
}

// add functions to fire on page unload
function addUnloadEvent (func) {
	var oldonunload = window.onunload;
	if (typeof window.onunload != 'function') {
		window.onunload = func;
	} else {
		window.onunload=function() {
			if (oldonunload) {
				oldonunload();
			}
			func ();
		}
	}
}

/*

The following function colors every other row in the data tables for easy reading.
Technique borrowed from: http://davious.org/onepagers/anewstripe.html
With tweaks borrowed from: http://validweb.nl/artikelen/javascript/better-zebra-tables/

Your CSS should include styles for the selected table's TR tags and for the same TR
tags with the "even" class applied to them.  For example, assuming your table had the
id "striped" you might have these two declarations in your CSS:

table#striped tr {
	background: white;
	color: black;
}

table#striped tr.even {
	background: black;
	color: white;
}

*/
// stripe them rows!
// id = id of the container object, tag = tag name of objects to stripe
stripe = function (id, tag) {
	var obj = document.getElementById(id);
	if (!obj) return;
	var subObjs = obj.getElementsByTagName(tag);
	for (var i = 0; i < subObjs.length; i += 2) subObjs[i].className += " even";
}

// add emulation of :hover behaviors to arbitrary elements in IE
// id = id of the container object, tag = tag name of objects to which to add hover behaviors
addHovers = function (id, tag) {
	var obj = document.getElementById(id);
	if (!obj) return;
	var subObjs = obj.getElementsByTagName(tag);
	// for IE, add the hover behaviors using JavaScript
	if (navigator.userAgent.indexOf('MSIE') > 0) {
		for (var i = 0; i < subObjs.length; i++) {
			subObjs[i].onmouseover = function() {
				this.className += ' hovered';
			}
			subObjs[i].onmouseout = function() {
				this.className = this.className.replace('hovered', '');
			}
		}
	}
}

// set the desired element to selected, while deselecting its peers
// id = id of the container object, tag = tag name of objects to deselect, el = id of object to select
selectElement = function (id, tag, el) {
	var obj = document.getElementById(id);
	if (!obj) return;
	var subObjs = obj.getElementsByTagName(tag);
	// deselect sub objects
	for (var i = subObjs.length-1; i > -1; i--) {
		subObjs[i].className = subObjs[i].className.replace('selected', '');
	}
	// select the one object
	obj = document.getElementById(el);
	obj.className += ' selected';
}

// select a radio button, nm = name of the radio button collection, val = value to match
selectRadio = function (nm, val) {
	if (d.getElementsByTagName) {
		var inputs = d.getElementsByTagName('INPUT');
		for (var i = inputs.length-1; i > -1; i--) {
			if (inputs[i].name == nm && inputs[i].value == val) {
				inputs[i].checked = true;
				return;
			}
		}
	}
}

// toggle an element's display style, id = id of the element
toggleDisplay = function (id) {
	var obj = getObj(id);
	var img = getObj(id + '_arrow');
	obj.style.display = (obj.style.display == 'block')? 'none': 'block';
	img.src = (img.src.indexOf('_closed') > -1)? '<dtml-var base_path>images/system/disclosure_open.gif': '<dtml-var base_path>images/system/disclosure_closed.gif';
}

// set an element's display style to 'none', id = id of the element
setDisplayNone = function (id) {
	var obj = getObj(id);
	var img = getObj(id + '_arrow');
	obj.style.display = 'none';
	img.src = '<dtml-var base_path>images/system/disclosure_closed.gif';
}

// set an element's display style to 'block', id = id of the element
setDisplayBlock = function (id) {
	var obj = getObj(id);
	var img = getObj(id + '_arrow');
	obj.style.display = 'block';
	img.src = '<dtml-var base_path>images/system/disclosure_open.gif';
}

// set all items in a list to display='none'
setListDisplayNone = function (list) {
	if (typeof list == 'object' && list.constructor == Array) {
		for (var i = list.length-1; i > -1; i--) {
			setDisplayNone(list[i]);
		}
	}
}

// set all items in a list to display='block'
setListDisplayBlock = function (list) {
	if (typeof list == 'object' && list.constructor == Array) {
		for (var i = list.length-1; i > -1; i--) {
			setDisplayBlock(list[i]);
		}
	}
}

// parse query string (e.g., name1=value1&name2=value2) and return an associative array of name/value pairs
parseQueryString = function (qs) {
	var qsArray = new Array();
	var qsItems = qs.substring(1).split('&');
	for (var i = qsItems.length-1; i > -1; i--) {
		var qsItem = qsItems[i].split('=');
		qsArray[qsItem[0]] = qsItem[1];
	}
	return qsArray;
}

// trim trailing character (c) from the string (s)
trimTrailingChar = function (s, c) {
	if (s.charAt(s.length-1) == c) s = s.substring(0, s.length-1);
	return s;
}

// update textarea counter, cid = counter id, val = current textarea value, max = maximum number of characters
updateCounter = function (cid, val, max) {
	var count = max - val.length;
	var counter = getObj(cid)
	counter.value = count;
	if (count < 0) { // sound the alarms! (red)
		counter.style.background = 'rgb(153,0,0)';
		counter.style.color = 'rgb(255,255,255)';
	} else if (count < (max/20)) { // 5% left (orange)
		counter.style.background = 'rgb(255,153,0)';
		counter.style.color = 'rgb(255,255,255)';
	} else if (count < (max/10)) { // 10% left (yellow)
		counter.style.background = 'rgb(255,255,0)';
		counter.style.color = 'rgb(0,0,0)';
	} else { // all good
		counter.style.background = 'rgb(255,255,255)';
		counter.style.color = 'rgb(0,0,0)';
	}
}

// delete a photo from a given directory, dir = directory within MVP/images, uid = user's ID
deletePhoto = function (dir, id) {
	if (j.canDoRequests) {
		// compose query
		var query = 'dir=' + dir + '&id=' + id;
		// make the request
		j.makeRequest(requestUri, query, true);
	} else {
		objects['photo_html_error'].innerHTML = requestErrorHTML;
	}
}

// emulation of PHP's in_array function, returns the key or false
Array.prototype.in_array = function (search_term) {
	var i = this.length;
	if (i > 0) {
		do {
			if (this[i] === search_term) return i;
		} while (i--);
	}
	return false;
}

// in_array function, but for associative arrays, returns the key or false
Array.prototype.in_array_assoc = function (search_term) {
	for (p in this) {
		if (search_term === this[p]) return p;
	}
	return false;
}

// rough emulation of PHP's sprintf function
// rough because there's no padding, no alignment ... just straight string substitution
// strings_array = array of strings to be substituted, in order, for occurrences of %s
// will not change the string if there are not the same number of replacement strings and occurrences of %s
// will not change the string if the strings array is empty
String.prototype.sprintf = function (strings_array) {
	if (strings_array.length > 0) {
		var idx;
		var string_pieces = this.split('%s');
		var string_new = '';
		if (string_pieces.length == strings_array.length+1) { // split seems to return a value at position [0] whether there is anything there or not
			for (var s = 0; s < string_pieces.length; s++) {
				string_new += string_pieces[s];
				if (s < string_pieces.length-1) string_new += strings_array[s];
			}
			return string_new;
		} else {
			return this;
		}
	} else {
		return this;
	}
}

/******************************/
/* begin: debugging functions */
writeDebug = function (s) {
	document.getElementById('debug').innerHTML += s + '<br \/>';
}

revealObject = function (o) {
	writeDebug('<hr \/>revealObj: '+o);
	for (p in o) {
		writeDebug(p+': '+o[p]);
	}
	writeDebug('revealObj: '+o+'<hr \/>');
}
/* end: debugging functions */
/****************************/
