/***************************/
/** DOM OBJECT MANAGEMENT **/
/***************************/

/**
 * @fileoverview
 * This API as been made to facilitate web creators job by
 * giving them tools to include AJAX and DOM power in their
 * pages <br />
 * It has been tested under many browsers and platforms :
 * <ul>
 * <li>Firefox 0.8, 1.0, 1.5</li>
 * <li>Internet Explorer 6.0</li>
 * <li>Mozilla Suite</li>
 * <li>Konqueror</li>
 * <li>Opera 8.0</li>
 * <li>Safari</li>
 * </ul>
 */

/********************/
/** CORE FUNCTIONS **/
/********************/

/**
 * Get the DOM object from its ID, and return it.
 * This method is valid for all browsers tested
 * @param id the id string of the element
 * @return the DOM object or false
 */
function object_get(id) {
	var object = false;
	if (document.getElementById) { object = document.getElementById(id); }
	else if (document.all) { object = document.all[id]; }
	else if (document.layers) { object = document.layers[id]; }
	if (object) { return object; }
	return false;
}

/**
 * Check the type of the object string/object etc
 * @param obj the object to be tested
 * @return the type of the object
 */
function object_type(obj) { return (typeof obj); }

/**
 * This function has a really particular purpose, it allows
 * the user of the API to call the object_* functions either
 * with an id or a DOM object.
 * If the given parameter is a string, then the function go
 * get the DOM object from this id, if the given parameter is
 * already a DOM object, it returns it, cos its job is
 * already done.
 * @param obj the object/id of the element
 * @return the DOM object
 */
function object_get_object(obj) {
	var type = object_type(obj);
	if (type == "string") { return object_get(obj); }
	return obj;
}

/*********************/
/** STYLE FUNCTIONS **/
/*********************/

/**
 * Set the visibility of an object to "visible"
 * @param id the id of an object/an object
 */
function object_show(id) {
	var object = object_get_object(id);
	if (object) { object.style.visibility = 'visible'; }
}

/**
 * Set the visibility of an object to "hidden"
 * @param id the id of an object/an object
 */
function object_hide(id) {
	var object = object_get_object(id);
	if (object) { object.style.visibility = 'hidden'; }
}

/**
 * Change the visibility of an object
 * @param id the id of an object/an object
 */
function object_swap_visibility(id) {
	var object = object_get_object(id);
	if (object) {
		if (object.style.visibility == 'hidden') {
			object_show(object);
		} else { object_hide(object); }
	}
}

/**
 * Set the display of an object to "none"
 * @param id the id of an object/an object
 */
function object_hide_block(id) {
	var object = object_get_object(id);
	if (object) { object.style.display = 'none'; }
}

/**
 * Set the display of an object to "block"
 * @param id the id of an object/an object
 */
function object_show_block(id) {
	var object = object_get_object(id);
	if (object) { object.style.display = 'block'; }
}

/**
 * Set the display of an object to "inline"
 * @param id the id of an object/an object
 */
function object_show_inline(id) {
	var object = object_get_object(id);
	if (object) { object.style.display = 'inline'; }
}

/**
 * Change the display of an object
 * @param the id of an object/an object
 */
function object_swap_display(id) {
	var o = object_get_object(id);
	if (o) {
		if (o.style.display == 'block') { object_hide_block(o); }
		else { object_show_block(o); }
	}
}

/**
 * Set the opacity of an object
 * @param obj the id of an object/an object
 * @param num the value of the opacity in percentage
 */
function object_set_opacity(obj,num) {
	var o = object_get_object(obj);
	if (o) {
		if (! isNaN(num)) {
			o.style.opacity=num/100;
			o.style.filter="alpha(opacity="+num+")";
		}
	}
}

/**
 * Set the width of the object
 * @param obj the id of an object/an object
 * @param w the width in % or px
 * (e.g. "90%", 45, "30px")
 */
function object_set_width(obj,w) {
	var o = object_get_object(obj);
	if (o) {
		if (! isNaN(w)) {
			w = ""+w;
			if (w.substr(-1,1) == "%") { o.style.width = w; }
			else if (w.substr(-2,2) == "px") { o.style.width = w; }
			else { o.style.width = ""+w+"px"; }
		}
	}
}

/**
 * Set the width of an object
 * @param obj the id of an object/an object
 * @param h the height in % or px
 * (e.g. "90%", 45, "30px")
 */
function object_set_height(obj,h) {
	var o = object_get_object(obj);
	if (o) {
		if (! isNaN(h)) {
			h = ""+h;
			if (h.substr(-1,1) == "%") { o.style.height = h; }
			else if (h.substr(-2,2) == "px") { o.style.height = h; }
			else { o.style.height = ""+h+"px"; }
		}
	}
}

/**
 * Get the css class of an object
 * @param obj the id of an object/an object
 */
function object_get_class(obj) {
	var o = object_get_object(obj);
	if (o) { return o.className; }
	return false;
}

/**
 * Set the css class of an object
 * @param obj the id of an object/an object
 * @param classe the class name
 */
function object_set_class(obj,classe) {
	var o = object_get_object(obj);
	if (o) {
		o.setAttribute('class',classe);
		o.setAttribute('className',classe);
	}
}

/**
 * Set the text color of an object
 * @param obj the id of an object/an object
 * @param c the color to set to the text
 */
function object_set_color(obj,c) {
	var o = object_get_object(obj);
	if (o) {
		if (o.style) { o.style.color = c; }
	}
}

/**************************/
/** READ/WRITE FUNCTIONS **/
/**************************/

/**
 * Set the innerHTML content of the DOM object
 * (Elements like div,p,span)
 * @param id the id of an object/an object
 * @param data the text the user want to be set as the
 * innerHTML
 */
function object_write(id,data) {
	var object = object_get_object(id);
	if (object) { object.innerHTML = data; }
}

/**
 * Append data to the innerHTML content of the DOM object
 * (Elements like div,p,span)
 * @param id the id of an object/an object
 * @param data the text the user want to be added to the
 * innerHTML
 */
function object_append(id,data) {
	var object = object_get_object(id);
	if (object) { object.innerHTML = object.innerHTML + data; }
}

/**
 * Retrieve the innerHTML of an element
 * @param id the id of an object/an object
 * @return the content or false
 */
function object_get_content(id) {
		var object = object_get_object(id);
		if (object) { return object.innerHTML; }
		return false; 
}

/****************************/
/** POSITIONNING FUNCTIONS **/
/****************************/

/**
 * Get the mouse x-position in the document (with scrolling support)
 * @param e the event object
 */
function mouse_get_X(e) {
	var x = 0;
	/* Firefox */
	if (navigator.appName.substring(0,3) == "Net") { x=e.pageX; }
	/* IE, Opera, Konqueror */
	else {
		/** 
		 * BEWARE: we use document.documentElement.scroll* instead of
		 * document.body.scrollLeft* to be in the standard mode ...
		 * We also check for the document.body.scroll* in case it's a IE5.
		 */
		var left_scroll = document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft;
		x = event.x + left_scroll;
	}
	return x;
}

/**
 * Get the mouse y-position in the document (with scrolling support)
 * @param e the event object
 */
function mouse_get_Y(e) {
	var y = 0;
	/* Firefox */
	if (navigator.appName.substring(0,3) == "Net") { y=e.pageY; }
	/* IE, Opera, Konqueror */
	else {
		/** 
		 * BEWARE: we use document.documentElement.scroll* instead of
		 * document.body.scrollLeft* to be in the standard mode ...
		 * We also check for the document.body.scroll* in case it's a IE5.
		 */
		var top_scroll = document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
		y = event.y + top_scroll;
	}
	return y;
}

/**
 * Set the position of the object according to the mouse
 * cursor position
 * This method can be used like this:
 * function move_my_object(e) {
 *  object_follow_mouse_position(e,"div_id",20,20);
 * }
 * window.onmousemove=move_my_object;
 * @param e the event listened (here it is the onmousemove
 * event)
 * @param obj the id of an object/an object
 * @param dleft the distance you want to leave between your
 * mouse and the left of the element
 * @param dtop the distance you want to leave between your
 * mouse and the top of the element
 */
function object_follow_mouse_position(e,obj,dleft,dtop) {
	var x; var y;
	x = mouse_get_X(e);
	y = mouse_get_Y(e);
	object_set_static_position(obj,x+dleft,y+dtop);
}

/**
 * Set the position of the object to the given coords
 * This method can be used like this:
 * object_set_static_position("div_id",20,20);
 * @param obj the id of an object/an object
 * @param x the x position you want to place the element to
 * @param y the y position you want to place the element to
 */
function object_set_static_position(obj,x,y) {
	var o = object_get_object(obj);
	object_set_left(o,x);
	object_set_top(o,y);
}

/**
 * Get the top gap between the object and the top border of
 * the window
 * @param obj the id of an object/an object
 */
function object_get_top(obj) {
	var o = object_get_object(obj);
	if (o) {
		var ot=o.offsetTop;
		while((o=o.offsetParent) != null) { ot += o.offsetTop; }
		return ot;
	}
	return 0;
}

/**
 * Set the top gap between the object and the top border of
 * the window
 * @param obj the id of an object/an object
 * @param dtop the length in % or px
 * (e.g. "90%", 45, "30px")
 */
function object_set_top(obj,dtop) {
	var o = object_get_object(obj);
	if (o) {
		if (! isNaN(parseInt(dtop))) {
			dtop = ""+dtop;
			if (dtop.substr(-1,1) == "%") { o.style.top = dtop; }
			else if (dtop.substr(-2,2) == "px") { o.style.top = dtop; }
			else { o.style.top = ""+dtop+"px"; }
		}
	}
}

/**
 * Get the left gap between the object and the left border of
 * the window
 * @param obj the id of an object/an object
 */
function object_get_left(obj) {
	var o = object_get_object(obj);
	if (o) {
		var ot=o.offsetLeft;
		while((o=o.offsetParent) != null) { ot += o.offsetLeft; }
		return ot;
	}
	return 0;
}

/**
 * Set the left gap between the object and the left border of
 * the window
 * @param obj the id of an object/an object
 * @param dleft the length in % or px
 * (e.g. "90%", 45, "30px")
 */
function object_set_left(obj,dleft) {
	var o = object_get_object(obj);
	if (o) {
		if (! isNaN(parseInt(dleft))) {
			dleft = ""+dleft;
			if (dleft.substr(-1,1) == "%") { o.style.left = dleft; }
			else if (dleft.substr(-2,2) == "px") { o.style.left = dleft; }
			else { o.style.left = ""+dleft+"px"; }
		}
	}
}

/** 
 * Set the object position as absolute
 * @param obj the id of an object/an object
 */
function object_set_absolute(obj) {
	var o = object_get_object(obj);
	if (o) { o.style.position="absolute"; }
}

/**
 * Return the position of the mouse inside the object
 * @param mouse_x the x position in the window
 * @param mouse_y the y position in the window
 * @param id the id of the object/object
 * @return an array with x and y position of the mouse in the object
 */
function object_get_inside_position(mouse_x,mouse_y,id) {
	var doc_x = mouse_x;
	var doc_y = mouse_y;
	var obj_x = object_get_left(id);
	var obj_y = object_get_top(id);
	var x = doc_x - obj_x;
	var y = doc_y - obj_y;
	return [x,y];
}

/***********************/
/** NEW DOM FUNCTIONS **/
/***********************/

/**
 * Place the given object as the first child of the body tag
 * @param o the object
 * @return the DOM object if everything goes right, false otherwise
 */
function object_place_first(o) {
	var body = document.getElementsByTagName('body');
	if (body.toString() == "[object HTMLCollection]") { body=body[0]; }
	try {
		if (body) {
			if (body.firstChild) {
				body.insertBefore(o,body.firstChild);
			} else {
				body.appendChild(o);
			}
			return o;
		}
	} catch(e) { return false; }
	return false;
}

/**
 * Create or get the element with the given id and tag
 * If an object with the given id and tag exists, then we return it, otherwise
 * we create a new one with the given data
 * @param tag the tag the new object should have
 * @param id the id the new object should have
 * @return the object created/retrieved
 */
function object_create_element(tag,id) {
	var o = object_get(id);
	if (o && o.tagName.toLowerCase() == tag.toLowerCase()) { return o;  }
	o = document.createElement(tag);
	o.id=id;
	return o;
}

/**
 * Create a new child to the body element, with the given tag name and id
 * @param tag the tag name of the element
 * @param id the id of the element
 * @return the new DOM object if everything goes right, false otherwise
 */
function object_create_first_element(tag,id) {
	var o = object_create_element(tag,id);
	return object_place_first(o);
}

/**
 * Duplicate tag,innerhtml,class object
 * @param from the id/object you want to duplicate
 * @return the duplicated object if everything goes right, false otherwise
 */
function object_duplicate(from) {
	var f = object_get_object(from);
	if (f) {
		var o = object_create_first_element(f.tagName,f.id+"_dupe");
		o.innerHTML = f.innerHTML;
		o.className = f.className;
		return o;
	}
	return false;
}

/*********************/
/** DEBUG FUNCTIONS **/
/*********************/

/**
 * Create a div element with id=debug to allow debug print
 * The div element is placed as the first child of the body
 * tag element
 * @return true if the element was created, false otherwise
 */
function object_debug_create() {
	var o = object_create_first_element("DIV","debug");
	if (o) {
		o.style.backgroundColor="#dddddd";
		return true;
	}
	return false;
}

/**
 * Display a debug message on the top of the page
 * @param msg the message the user wants to display
 */
function object_debug_write(msg) {
	if (object_debug_create()) { object_write('debug',msg); }
}

/**
 * Dump all the properties of the given object into a debug element placed at
 * the top of the page
 */
function object_dump(obj) {
	var o = object_get_object(obj);
	if (o && object_debug_create()) {
		for(var i in o) {
			try {
				object_append('debug',i + " = " + o[i]+"<br>");
			} catch(e) {}
		}
	}
}

