/* $Id: fo.js,v 1.3 2005/07/05 08:44:40 haihee Exp $ */

var fo = {
	magic: {
		fold: "fold",
		collect: "collect",
		cover: "cover",
		split: "sub"
	},
	shift: {
		x: 0,
		y: 0,
		custom: []
	}
};

/* show([id])
Shows all layers with a value for id starting with fo.magic.fold + id, and
their ancestors.  Ancestors are recognized by the "foldfoosubbarsubbaz" naming
convention.  When id is undefined, hides all affected layers. The div_id is the
identifyer of the containing div.
*/

function show(lid, relative_to, div_id, ox, oy) {
	
	// IE4 bugfix: IE4 cannot handle an argument named "id" in a function
	var id = lid;

	if (dom.finished) {

		// Position the layer to show relative to some object (usually caller):
		if (typeof id != 'undefined' && typeof relative_to != 'undefined') {

			offset = _get_offset(relative_to);
			var id = fo.magic.fold + id;
			var div_id = fo.magic.fold + div_id;
			if (typeof dom.handles[div_id] != 'undefined' && typeof document.layers != 'undefined') {
				offset['x'] += dom.handles[div_id].style.left;
				offset['y'] += dom.handles[div_id].style.top;
			}

			// Shift the layer:
			offset['x'] += (typeof ox != 'undefined') ? ox : fo.shift.x;
			offset['y'] += (typeof oy != 'undefined') ? oy : fo.shift.y;
			//alert(navigator.userAgent);
			for (var i = 0; i < fo.shift.custom.length; i++) {
				if (fo.shift.custom[i].ua.test(navigator.userAgent) ) {
					offset['x'] += fo.shift.custom[i].x;
					offset['y'] += fo.shift.custom[i].y;
					break;
				}
			}

			// Position the layer:
			dom.handles[id].style.left = offset['x'];
			dom.handles[id].style.top = offset['y'];
		}

		// Determine for every layer if it should show or not:
		// fos:
		for (p in dom.handles) {
			if (typeof id != 'undefined') {
				if (id.indexOf(fo.magic.fold) != 0) {
					id = fo.magic.fold + id;
				}
			}
			if (typeof dom.handles[p].id != 'undefined') {
				if (dom.handles[p].id.indexOf(fo.magic.fold) == 0) {
					if (_is_ancestor(id, dom.handles[p].id, fo.magic.split) ) {
						dom.handles[p].style.visibility = "visible";
						dom.handles[p].style.zIndex = 1000;
					}
					else {
						dom.handles[p].style.visibility = "hidden";
						dom.handles[p].style.zIndex = 1;
					}
				}
			}
		}

		// Collectors:
		if (typeof id != 'undefined') {
			for (p in dom.handles) {
				if (typeof dom.handles[p].id != 'undefined') {
					if (dom.handles[p].id.indexOf(fo.magic.collect) == 0) {
						dom.handles[p].style.visibility = "visible";
						dom.handles[p].style.zIndex = 35;
					}
				}
			}
		}
		else {
			for (p in dom.handles) {
				if (typeof dom.handles[p].id != 'undefined') {
					if (dom.handles[p].id.indexOf(fo.magic.collect) == 0) {
						dom.handles[p].style.visibility = "hidden";
						dom.handles[p].style.zIndex = 1;
					}
				}
			}
		}
		if (typeof id != 'undefined' && typeof relative_to != 'undefined') {
			var line = id.split(fo.magic.split);
			var cover_id = line[0] + fo.magic.cover;
			if (typeof dom.handles[cover_id] != 'undefined') {
				var offset = _get_offset(relative_to);
				dom.handles[cover_id].style.left = offset['x'];
				dom.handles[cover_id].style.top = offset['y'];
				dom.handles[cover_id].style.visibility = "visible";
				dom.handles[cover_id].style.zIndex = 100;
			}
		}
	}
}

/* _is_ancestor([child id], [potential ancestor id])
To find out if we need to show a div we have to compare the id of this div with
the id of the main div to show.  Besides the main div there can be helper-divs
to create a multiple div fo, which must be shown together with the main
div, and a line of ancestor main-divs and their helpers which must also be
shown.
*/

function _is_ancestor(showid, id) {
	
	if (typeof showid == 'undefined') return false;
	var showid_line = showid.split(fo.magic.split);
	var id_line = id.split(fo.magic.split);
	for (var i = 0; i < id_line.length; i++) {
		if (id_line[i].indexOf(showid_line[i]) != 0) {
			return false;
		}
	}
	return true;
}

/* _get_offset(object)
Returns a coordinate based on the object passed to it:
*/

function _get_offset(obj) {
	// Does not get the offset if the object is in an unfinished element (table for instance)
	var passed_obj = obj;
	var offset;
	if (typeof obj.x != 'undefined') {
		offset = {x: obj.x, y: obj.y};
	}
	else {
		var offset = {x: obj.offsetLeft, y: obj.offsetTop};
		while (obj.offsetParent != null) {
			obj = obj.offsetParent;
			offset['x'] += obj.offsetLeft;
			offset['y'] += obj.offsetTop;
		}
	}
	//if (typeof obj.document != 'undefined') {
	//	var div_offset = _get_offset(obj.document);
	//	offset['x'] += div_offset['x'];
	//	offset['y'] += div_offset['y'];
	//}
	return offset;
}
