/**
 * k4 Bulletin Board, k4lib JavaScript object
 * Copyright (c) 2005, Peter Goodman
 * Licensed under the LGPL license
 * http://www.gnu.org/copyleft/lesser.html
 * @author Peter Goodman
 * @version $Id$
 * @package k4bb
 */

var FA = {
	
	//
	// Get an object by its id
	//
	"getObj": function(obj_id) {
		var ret_obj = false;
		if (document.getElementById) {
			ret_obj =  document.getElementById(obj_id);
		} else if (document.all) {
			ret_obj =  document.all[obj_id];
		} else if (document.layers) {
			ret_obj =  document.layers[obj_id];
		} else if (document.frames) {
			ret_obj =  document.frames[obj_id];
		}
		return ret_obj;
	},

	//
	// Get elements by their tag names
	//
	"tagsByName": function(obj, tag_name) {
		var elements = new Array();
		if (typeof(obj.getElementsByTagName) != 'undefined') {
			elements = obj.getElementsByTagName(tag_name);
		} else if(obj.all && obj.all.tags) {
			elements = obj.all.tags(tag_name);
		}
		return elements;
	},

	//
	// Prepend child_obj to obj
	//
	"prependChild": function(obj, child_obj) {
		if(typeof(obj.firstChild) != 'undefined' && obj.firstChild) {
			obj.insertBefore(child_obj, obj.firstChild);
		} else {
			obj.appendChild(child_obj);
		}
		return true;
	},
	
	//
	// Get the top position of an element
	//
	"posTop": function(obj) {
		var postop	= 0;
		while(obj && obj != null) {
			postop += obj.offsetTop; // - obj.scrollTop
			obj = obj.offsetParent;
		}
		return postop;
	},
	
	//
	// Get the left position of an object
	//
	"posLeft": function(obj) {
		var posleft = 0;
		if(obj) {
			posleft = obj.offsetLeft;
			while((obj = obj.offsetParent) != null) {
				posleft += obj.offsetLeft;
			}
		}
		return posleft;
	},
	
	//
	// Get the right position of an object
	//
	"posRight": function(obj) {
		return parseInt(this.posLeft(obj) + obj.offsetWidth);
	},
	
	//
	// Get the bottom position of an object
	//
	"posBottom": function(obj) {
		return parseInt(this.posTop(obj) + obj.offsetHeight);	
	},
	
	
	//
	// Show an element
	//
	"show": function(obj) {
		if(typeof(obj.style) != 'undefined') {
			if(obj.style.display == '' || obj.style.display == 'none') {
				obj.style.display = 'block';
			}
		}
	},
	
	//
	// Hide an element
	//
	"hide": function(obj) {
		if(typeof(obj.style) != 'undefined') {
			obj.style.display = 'none';
		}
	},
	
	//
	// Put a cursor as a link
	//
	"linkCursor": function(obj) {
		try {
			obj.style.cursor = 'pointer';
		} catch(e) {
			obj.style.cursor = 'hand';
		}
	},
	
	//
	// Attach an event to an object
	// this is an adaptation of the AttachEvent function by Gavin Kirstner
	//
	"attachEvent": function(obj, evt, fnc) {
		
		var ret = true;

		if (obj.addEventListener){
			obj.addEventListener(evt, fnc, false);
		} else if (obj.attachEvent) {
			ret = obj.attachEvent("on" + evt, fnc);
		} else{
			
			if (!obj.myEvents) {
				obj.myEvents = {};
			}
			if (!obj.myEvents[evt]) {
				obj.myEvents[evt] = [];
			}
			
			var evts = obj.myEvents[evt];
			
			evts[evts.length] = fnc;
			
			obj['on' + evt] = function() { 
				if (!obj || !obj.myEvents || !obj.myEvents[evt]) {
					return;
				}
				var evts = obj.myEvents[evt];
				for (var i = 0, len = evts.length; i < len;i++) {
					evts[i]();
				}
			}
		}

		return ret;
	},
	
	//
	// Get an event
	//
	"getEvent": function(e) {
		if (!e) { e = window.event; }
		if (typeof(e.layerX) == 'undefined') { e.layerX = e.offsetX; }
		if (typeof(e.layerY) == 'undefined') { e.layerY = e.offsetY; }
		return e;
	},

	//
	// Get the target of an event
	//
	"eventTarget": function(ev) {
		
		var e		= this.getEvent(ev);
		var targ	= false;

		if(typeof(e.target) != 'undefined' && e.target) {
			targ = e.target;
		} else if(typeof(e.srcElement) != 'undefined' && e.srcElement) {
			targ = e.srcElement;
		}
		if(targ.nodeType == 3) { // defeat Safari bug
			targ = targ.parentNode;
		}
		return targ;
	},
	
	//
	// Stop an event
	//
	"stopEvent": function(e) {
		this.stopPropagation(e);
		this.preventDefault(e);
	},

	//
	// Stop event propogation and bubbling
	//
	"stopPropagation": function(e) {
		if (e.stopPropagation) {
			e.stopPropagation();
		} else {
			e.cancelBubble = true;
		}
	},

	//
	// Prevent the default behavior of an event if any
	//
	"preventDefault": function(e) {
		if (e.preventDefault) {
			e.preventDefault();
		}
	},
	
	//
	// Enable an element
	//
	"enableElm": function(obj) {
		if(typeof(obj) != 'undefined' && typeof(obj.disabled) != 'undefined') {
			obj.disabled = false;
		}
	},
	
	//
	// Disable an element
	//
	"disableElm": function(obj) {
		if(typeof(obj) != 'undefined') {
			obj.disabled = true;
		}
	},
	
	//
	// Array sizeof function
	//
	"sizeOf": function(thearray) {
		array_length		= 0;
		if(thearray != null && typeof(thearray) != 'undefined') {
			
			if(typeof(thearray.length) != 'undefined') {
				array_length	= thearray.length;
			} else {
				
				var i = 0;
				for (key in thearray) {
					if ((typeof(thearray[i]) == 'undefined') || (thearray[i] == '') || (thearray[i] == null)) {
						return i;
					}
					i++;
				}
			}
		}
		return array_length;
	},
	
	//
	// Array search function
	//
	"search": function(thearray, needle) {
		var pos = 0;
		for(var i = 0; i < this.sizeOf(thearray); i++) {
			if(thearray[i].value == needle) {
				pos = i;
			}
		}
		return pos;
	},
	
	//
	// Get the DOM object for an iframe
	//
	"getDocument": function(iframe_obj) {
		var dom_object		= false;
		var frame_object	= false;

		if(this.iframe_obj) {
			if(document.all) {
				try { frame_object = frames[iframe_obj.id]; } catch(ex) { }
			} else {
				try { frame_object = iframe_obj.contentWindow; } catch(e) { }
			}
			if(frame_object) {

				dom_object	= frame_object.document;

				if(!dom_object && document.all && iframe_obj.contentWindow) {
					dom_object = iframe_obj.contentWindow.document;
				}
			}
		}
		return dom_object;
	}
};

function k4lib() {
	
	//
	// Get browser information
	//
	this.userAgent = navigator.userAgent.toLowerCase();
	this.is_opera  = (this.userAgent.indexOf('opera') != -1);
	this.is_saf    = ((this.userAgent.indexOf('applewebkit') != -1) || (navigator.vendor == 'Apple Computer, Inc.'));
	this.is_webtv  = (this.userAgent.indexOf('webtv') != -1);
	this.is_ie     = ((this.userAgent.indexOf('msie') != -1) && (!this.is_opera) && (!this.is_saf) && (!this.is_webtv));
	this.is_ie4    = ((this.is_ie) && (this.userAgent.indexOf('msie 4.') != -1));
	this.is_ie5    = ((this.is_ie) && (this.userAgent.indexOf('msie 5') != -1));
	this.is_moz    = ((navigator.product == 'Gecko') && (!this.is_saf));
	this.is_kon    = (this.userAgent.indexOf('konqueror') != -1);
	this.is_ns     = ((this.userAgent.indexOf('compatible') == -1) && (this.userAgent.indexOf('mozilla') != -1) && (!this.is_opera) && (!this.is_webtv) && (!this.is_saf));
	this.is_ns6    = ((this.is_ns) && (parseInt(navigator.appVersion) == 6));
	this.is_mac    = (this.userAgent.indexOf('mac') != -1);
}	

//
// Prepend an object (obj) to its parent object
//
Object.prototype.prependChild = function(obj) {
	var ret = false;
	if(typeof(this.firstChild) != 'undefined') {
		this.insertBefore(obj, this.firstChild);
		ret = true;
	}
	return ret;
};

//
// Boolean true or false if a value is in an array
//
Array.prototype.find = Object.prototype.find = function(needle) {
	var bool				= false;
	for(key in this) {
		if(bool) {
			break;
		}
		if(this[key] == needle) {
			bool = true;
		}
	}
	return bool;
};
k4lib.prototype.in_array = function(thearray, needle) {
	return thearray.find(needle);
};

//
// Return the array key of a value
//
Array.prototype.key = function(needle) {
	var the_key				= false;
	for(key in this) {
		if(the_key) {
			break;
		}
		if(key == needle) {
			the_key = key;
		}
	}
	return the_key;
};
k4lib.prototype.array_key = function(thearray, needle) {
	thearray.key(needle);
};

//
// Array unset function for a given value 
//
Array.prototype.kill = function(value) {
	for(var i = 0; i < FA.sizeOf(this); i++) {
		if(this[i] == value) {
			delete this[i];
		}
	}
	return true;
};
k4lib.prototype.unset = function(thearray, value) {
	thearray.kill(value);	
};

//
// Array Push function 
//
Array.prototype.push = function(value) {
	this[FA.sizeOf(this)] = value;
};
k4lib.prototype.array_push = function(thearray, value) {
	thearray.push(value);
};

//
// Get the positiong of an element in an array
//
Array.prototype.search = function(needle) {
	return FA.search(this, needle);
};
Object.prototype.search = function(needle) {
	return FA.search(this, needle);
}