/******************************************************* 
*	2007 ballyhoos.com.au
*	contact scott@ballyhoos.com.au
*
*	DOM 
*
****************************************************** */

var dom = {
	
	/* get the obj that fired the event */
	getEventElement : function(e)
	{
		var obj = false;
		
		if(window.event && window.event.srcElement){
			obj = window.event.srcElement;
		}
		else if(e && e.target){
			obj = e.target;
		}
		if(!obj){
			return false;
		}else{
			return obj;
		}
	},
	
	/* add event listners to certin elements*/
	addEvent : function( obj, evType, fn, useCapture )
	{
		if( obj ){
			if( obj.addEventListener ){ // FF
				obj.addEventListener( evType,fn,useCapture );
			}
			else if(obj.attachEvent){ // IE
				return obj.attachEvent("on" + evType, fn);
			}
			else{
				obj['on' + evType] = fn;
			}
		}else{
			alert( "dom.addEvent() :: "+obj + " doesn't exist");	
		}
	},
	
	
	/*******************************
	get an element by ID 
	***************************** */
	byId : function(id, obj)
	{
		if(!obj){
			obj = document;
		}
		return obj.getElementById(id);
	},
	
	
	/********************************************
	convert passed values to objs, if they exist
	****************************************** */
	setObjects : function(array)
	{
		var objArray = [];
		for (var i = 0; i < array.length; i ++) {
			var obj = dom.byId(array[i]);
			if( obj ){
				objArray.push(obj);
			}
		}
		return objArray;
	},
	
	
	/* **************************************
	test if anthing is an object
	************************************** */
	isObject : function(value)
	{
		if( value instanceof Object ){
			return true;
		}
		return false;
	},
	
	
	/* **************************************
	set passed values as an object if exists
	************************************** */
	mkObject : function(value)
	{
		if( typeof(value) == "string" ){
			return dom.byId(value);
		}else if(typeof(value) == "object"){
			return value;
		}
		
		return false;
	},


	byTag : function(tag, obj)
	{
		if(!obj) obj = document;
		
		return obj.getElementsByTagName(tag);
	},

	/* ************************************
	return all tags with this class, SINGLE VALUES ONLY CHANGE
	************************************* */
	byClass : function(classname, obj)
	{
		//	store found class objects
		var classObjs = [];
		
		if(!obj){
			var obj = document;
		}
		// get all elements under passed obj
		var elm = dom.byTag("*", obj);
				
		for (var e = 0; e < elm.length; e ++) {
			if(dom.hasClass(elm[e], classname)){
				classObjs.push(elm[e]);
			}
		}
		return classObjs;
	},
	
	
	/* ************************************
	get all values or class attribute
	************************************* */
	getClass : function(obj)
	{
		// tests for IE naming covention that differs from FF
		var classes = dom.hasAttr(obj, ((document.all) ? "className" : "class"), true);
		if( classes ){
			return classes.split(" ");
		}
		return false;
	},
	
	
	/* ************************************
	tests to see if class exists
	************************************* */
	hasClass : function(obj, classname)
	{
		var classes = dom.getClass(obj);
		if( dom.inArray( classname, classes ) ){
			return true;
		}
		return false;
	},


	/* ************************************
	swap a class with another valued class
	************************************* */
	swapClass : function(array, value, to)
	{
		for(var i = 0; i < array.length; i ++) {
			var obj =  dom.mkObject(array[i]);
			if( obj ){
				// get class values of element
				var classes = dom.getClass(obj); 
				//alert(classes);
				if( classes ){
					for(var c = 0; c < classes.length; c ++) {
						// replace if makes passed value
						if(classes[c] == value ) classes[c] = to;
					}
					obj.className = classes.join(" ");
				}
			}
		}
	},
	
	/* ************************************
	addes like this ["sss", "xxx"] as array
	************************************* */
	addClass : function(array, newClassName)
	{
		for(var i = 0; i < array.length; i ++) {
			var obj =  dom.mkObject(array[i]);
			if( obj ){
				if( !dom.hasClass(obj, newClassName) ){
					if(dom.hasAttr(obj, "class", true )){
						
						newClassName = dom.hasAttr(obj, "class", true) + " " + newClassName;		
					}
					obj.className = newClassName; 
				} 
			}
		}
	},
	
	
	/* ************************************
	this gets the elements computerized styles
	eg the styles within a class of CSS
	************************************* */
	getClassStyle : function(obj, property, debug)
	{
		var objStyle;
		
		// IE
		if( obj.currentStyle ){
			objStyle = obj.currentStyle[property];
		}
		// FF and Co.
		else{
			try{
				objStyle = document.defaultView.getComputedStyle( obj, null ).getPropertyValue( property );
		 	}
			catch(e){
				return false; 
			}
		}
		return (( !debug ) ? objStyle : alert( objStyle ) );
	},


	hasAttr : function(obj, type, ret)
	{
		// typical MS IE bug, "for" will return NULL
		// this bug extends IE5 - IE 7, when will this end? 
		if( type == "for" && document.all ){
			return ( !obj.attributes["for"].nodeValue ? false : ((!ret) ? true : obj.attributes["for"].nodeValue)) ;
		}
		return ( !obj.getAttribute(type) ? false : ((!ret) ? true : obj.getAttribute(type))) ;
	},

	/* *********************************
	Create a Element within the DOM
	************************************/
	create : function( tag, objId )
	{	
		el = document.createElement(tag);
		if( objId != false ){
			el.id = objId;
		}
		return el;
	},


	/* **************************************
	sets display of objects, as well as auto
	**************************************** */
	setDisplay : function(objs, mode)
	{
		for(var i = 0; i < objs.length; i++) {
			// ensure objects are passed
			var obj = dom.mkObject(objs[i]);	
			
			if( obj ){
				if( mode || mode == "" ){
					obj.style.display = mode;
				}else{
					var sd = obj.style.display;
					if( sd == "" || sd == "block" ){
						 d = "none";
					}else{
						 d = ""
					}
					obj.style.display = d;
				}
			}
		}
	},
	
	/* *********************************
	insert a node  ..
	************************************/	
	addNode : function( obj_id, node, option )
	{
		// { mode:"after/before" , child: "first"  }
		var obj = dom.mkObject(obj_id);

		if( obj ){
			if( option && option.add ){
				if( option.add == "before"){
					obj.insertBefore( node, ((!option.child) ? obj.firstChild : obj.childNodes[option.child] ) );
				}else{
					//obj.childNodes[opt.add].appendChild(node);
				}
			}
			// append to end of elements in obj
			else{
				obj.appendChild( node );
			}
		}
	},

	
	/* ************************************
	array = specifying the ones to remove
			otherwise it will remove all
	************************************ */
	delNodes : function( obj, targeted )
	{
		if( obj && obj.hasChildNodes ){
			
			nodes = obj.childNodes;
			/* removed required only */
			if( targeted ){
				for(var n = 0; n < nodes.length; n++) {
					
					/* make sure that the id is set within the tag to test againist */
					/* removes the #text nodes also with tagName check */
					if(nodes[n].tagName && dom.hasAttr(nodes[n], "id" )){

						/* do they exist in the removal array */
						if( dom.inArray(nodes[n].id, targeted ) ){
							obj.removeChild( nodes[n] );   
						}
					}
				}
			}
			/* remove all */
			else{
				while ( nodes.length >= 1 )
				{
					obj.removeChild( obj.firstChild );       
				} 
			}
		}
	},
	
	/* **********************************************
	*	deletes obj and childern ndes within
	********************************************** */
	delElement : function( obj )
	{
		if(obj){
			dom.delNodes( obj );
			obj.parentNode.removeChild( obj );
		}
	},
	
	
	/* **********************************************
	*	custom -find a parent by classname, 
	*	function will only return 'undefined' otherwise 
	*	due to cllections array not object array returned
	********************************************** */
	delParentByClass : function(obj, classname){
		
		if( dom.hasClass(obj, classname) ){
			dom.delElement(obj);
		}else{
			dom.delParentByClass(obj.parentNode, classname);
		};
		
	},

	getKey : function(e)
	{
		return e.keyCode;
	},
	
	
	/* **********************************************
	not really a dom event, but a very handy function
	********************************************** */
	inArray : function( value, array, retKeys )
	{
		var keys = [];
		
		for(var i = 0; i < array.length; i++) {
			if(array[i] == value){
				/* return the found keys, if set */
				if(retKeys){
					keys.push(i);
				}else{
					return true;
				}
			}
		}
		return (retKeys) ? keys : false;
	},
	
	
	/* **********************************************
	collections and arrays are different, 
	does not handle HTML Collections
	alternatively use arraddto.concat(array)
	********************************************** */
	joinArrays : function( arrayAddTo, array )
	{
		if(array.length){
			for(var i = 0; i < array.length; i++) {
				arr.push(array[i]);
			}
		}
		return arrayAddTo;
	},

	
	/* **********************************************
	not really a dom event, but a very handy function
	********************************************** */
	getMargin : function(obj)
	{
		return (isNaN(parseInt(obj.style.marginLeft))) ? 0 : parseInt(obj.style.marginLeft);
	},
	
	
	debug : function(value)
	{
		var debug = dom.byId("debug");
		if( debug ){
			debug.innerHTML = debug.innerHTML + value + "<br />";
			
		}else{
				alert("no debug container");
		}
	},
	
	stopProp : function(e)
	{
		if(window.event && !window.event.cancelBubble){
			window.event.cancelBubble = true;
		}
		else if(e && e.stopPropagation){
			e.stopPropagation();
		}
		
	},
	
	cancel : function(e)
	{
		if(window.event && !window.event.returnValue){
			window.event.returnValue = false;
		}
		else if(e && e.preventDefault){
			e.preventDefault();
			return false;
		}
	},
	
	/* **********************************************
	get the dimensions of the body width, height
	********************************************** */
	bodyWidth : function()
	{
		return dom.bodyDimension("Width");
	},
	
	bodyHeight : function()
	{
		return dom.bodyDimension("Height");
	},
	
	bodyDimension : function( value )
	{
		var bod = document.body;
		
		if( bod.scrollHeight > bod.offsetHeight ) {// all but Explorer Mac
			return eval("bod.scroll" + value );
		}else{
			// Explorer Mac;
			//would also work in Explorer 6 Strict, Mozilla and Safari
			return eval("bod.offset" + value );
		}
	},
	
	
	/* **********************************************
	get the dimensions of the browser width, height
	********************************************** */
	browserWidth : function()
	{
		return dom.browserDimension("Width");
	},
	
	browserHeight : function()
	{
		return dom.browserDimension("Height");
	},
	
	browserDimension : function( value )
	{
		// all except Explorer
		if(self.innerHeight){
			return eval("self.inner" + value );
		}
		else if( document.documentElement && document.documentElement.clientHeight ){
			// Explorer 6 Strict Mode
			return eval("document.documentElement.client" + value );
		}
		else if( document.body ){
			// other Explorers
			return eval("document.body.client" + value );
		}
	},
	
	/* **********************************************
	get object sizes
	********************************************** */
	getHeight : function( obj_id, retCharPx )
	{
		return dom.mkObject(obj_id).offsetHeight + ((retCharPx) ? "px" : "");
	},
	
	getWidth : function( obj_id, retCharPx )
	{
		return dom.mkObject(obj_id).offsetWidth + ((retCharPx) ? "px" : "");
	},
	
	

	/* **********************************************
	get the actual viewing display of the browser
	********************************************** */
	getPageHeight : function( returnPxChar )
	{
		if( dom.bodyHeight() <  dom.browserHeight() ) {
			
			var h = dom.browserHeight();
			
		}else{
			var h = dom.bodyHeight();
		}
		
		return ( !returnPxChar ) ? h : "" + h + "px";
	}
}
