//domcompatiblity.js Copyright DAS Software (c) 2005
// $Id: domcompatibility.js,v 1.3 2008/05/08 18:48:11 gregorynacu Exp $

/** @file
		javascript library comprised of functions
		specifically intended to abstract incompatibilities between the 
		Document Object Models of IE, FireFox and Safari. 
*/

// *** Node Types: ***
var ELEMENT_NODE 								= 1;
var ATTRIBUTE_NODE 							= 2;
var TEXT_NODE 									= 3;
var CDATA_SECTION_NODE 					= 4;
var ENTITY_REFERENCE_NODE 			= 5;
var ENTITY_NODE 								= 6;
var PROCESSING_INSTRUCTION_NODE = 7;
var COMMENT_NODE 								= 8;
var DOCUMENT_NODE 							= 9;
var DOCUMENT_TYPE_NODE 					= 10;
var DOCUMENT_FRAGMENT_NODE 			= 11;
var NOTATION_NODE 							= 12;

function addLoadEvent(newfunc,append) {
	var func = window.onload;
	window.onload = function() {
		if(typeof append == 'boolean' && append) {
			if(typeof func == "function")
				func();
			newfunc();
		} else {
			newfunc();
			if(typeof func == "function")
				func();
		}
	};
}

//This is a function that does essentially the same thing as 
//Simply setting the innerHTML of a node like this:
//
//	document.getElementById('SomeNode').innerHTML='new content';
//
//However, because this is a function that abstracts the 
//innerHTML setting process, this function can be overridden
//by other code.  For instance, the Virtual Keyboard wedges
//itself into this function, so that it can scan the new 
//HTML content whenever new content is added to the page, and
//if it finds text inputs in the new content, it can automatically
//add focus and blur event listeners to them. --Greg2007

//setInnerHTML('blah'); should be used instead of just innerHTML='blah';
function setInnerHTML(content) {
	if(this.nodeType != ELEMENT_NODE)
		return(false);

	this.innerHTML = content;
	return(true);
}

Object.prototype.setInnerHTML = setInnerHTML;

//For subclassing one object from another
document.applyInherit = function(original,subclass) {
	for(item in subclass)
		original[item] = subclass[item];
	return(original);
};

//Allows for the dynamic creation of functions
function makefunc(str) { 
	return(eval(str)); 
}

function getElementsByTagNameWithClassName(tagname,classname) {
	var children = this.getElementsByTagName(tagname);
	var elements = new Array();
	var i = 0;
	var child;
	var classNames;
	var j = 0;
	
	for(i=0;i<children.length;i++) {
		child = children[i];
		classNames = child.className.split(' ');
		
		for(var j = 0; j < classNames.length; j++) {
			if(classNames[j] == classname) {
				elements.push(child);
				break;
			}
		}
	}
	return elements;
}

Object.prototype.getElementsByTagNameWithClassName = getElementsByTagNameWithClassName;

///	@brief	returns absolute X position of an object on the page
///	@param	obj		Element reference to object
///	@returns	Absolute X offset
/// deprecated, should use object method .bexPosX()
function findPosX(obj){
	var curleft = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	} else if (obj.x)
		curleft += obj.x;
	return curleft;
}

function bexPosX(e) {
	var left = 0;
	var obj  = this;

	if(obj.offsetParent) {
		while(obj.offsetParent) {
			left += obj.offsetLeft
			obj = obj.offsetParent;
		}
	} else if(obj.x)
		left += obj.x;

	return(left);
}

Object.prototype.bexPosX = bexPosX;

///	@brief	returns absolute Y position of an object on the page
///	@param	obj		Element reference to object
///	@returns	Absolute Y offset
/// deprecated, should use object method .bexPosY()
function findPosY(obj) {
	var curtop = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	} else if (obj.y)
		curtop += obj.y;
	return curtop;
}

function bexPosY(e) {
	var top = 0;
	var obj = this;
	
	if(obj.offsetParent) {
		while(obj.offsetParent) {
			top += obj.offsetTop
			obj = obj.offsetParent;
		}
	} else if (obj.y)
		top += obj.y;
		
	return top;
}

Object.prototype.bexPosY = bexPosY;

//Add the method inArray() to the Array object.

// Returns true if the passed value is found in the
// array.  Returns false if it is not.

Array.prototype.inArray = function (value) {
	for (var i=0; i < this.length; i++) {
		// Matches identical (===), not just similar (==).
		if(this[i] === value) {
			return true;
		}
	}
	return false;
};

Array.prototype.lastItem = function() {
	return(this[this.length-1]);
}

function setSelectboxByValue(sbox,value) {
	var found = false;
	for(var i=0;i<sbox.length;i++) {
		if(sbox.options[i].value == value) {
			sbox.selectedIndex = i;
			found = true;
			break;
		}
	}
	if(!found)
		sbox.selectedIndex = 0;	

	if(typeof sbox.onchange == 'function')
		sbox.onchange();
}

//Clone an object.  If deep is true, all nested objects will be 
//recursively cloned as well.  If deep is false, nested objects 
//are converted just to a blank object string.
function Object_Clone(deep) {
	var objectClone = new this.constructor();
	for (var property in this)
		if (!deep)
			objectClone[property] = this[property];
		else if (typeof this[property] == 'object')
			objectClone[property] = this[property].clone(deep);
		else
			objectClone[property] = this[property];
	return objectClone;
}
Object.prototype.clone = Object_Clone;			


//CONTROL PAGE TEXT SELECTION FUNCTIONS
/**	@brief	En/disable text selection on the current page
	@param	enable	TRUE to re-enable text selection

	call this function to disable or enable the
	ability to select text on the current page. This is very useful in
	preventing content from being selected while an element is being
	dragged.
*/
function pagetextselectable(enable) {
	if(enable) {
	
		//if the browser is IE4+
		document.onselectstart	= new Function ('return true');
	
		//if the browser is NS6
		if(window.sidebar) {
			document.onmousedown	= new Function ('return true');
			document.onclick			= new Function ('return true');
		}
	} else {
		//alert(document.onselectstart);


		//if the browser is IE4+
		document.onselectstart = new Function ('return false');
	
		//if the browser is NS6
		if(window.sidebar) {
			document.onmousedown = pagetextselectable_ns6disable;
			document.onclick		 = pagetextselectable_ns6enable;
		}
	}

	try {
		if(enable)
			document.body.setAttribute('pagetextselectable',1);
		else
			document.body.setAttribute('pagetextselectable',0);
	} catch(e) {
		var attrnode = document.createAttribute('pagetextselectable');
		if(enable)
			attrnode.nodeValue = 1;
		else
			attrnode.nodeValue = 0;
		document.body.setAttributeNode(attrnode);
	}
}

function pagetextselectable_ns6disable(e){
	try {
		if(e.target.type == 'text')
			return true
		else
			return false
	}
	catch(e) {
		return false
	}
}

function pagetextselectable_ns6enable(){
	return true
}
			
function duplicatenodestyle(src,dest) {
	for(var styleindex=0;styleindex<JSStyleProperties.length;styleindex++) {
		styleproperty = '';
		element = src;
		while(styleproperty == '' && element.tagName != 'BODY') {
			styleproperty = eval('element.style.'+JSStyleProperties[styleindex]);
			element = element.parentNode;
		}

		eval('dest.style.'+JSStyleProperties[styleindex]+' = "'+styleproperty+'"');
	}
}

var JSStyleProperties = new Array(
	'background',
	'backgroundAttachment',
	'backgroundColor',
	'backgroundImage',
	'backgroundPosition',
	'backgroundRepeat',
	'border',
	'borderBottom',
	'borderBottomColor',
	'borderBottomStyle',
	'borderBottomWidth',
	'borderColor',
	'borderLeft',
	'borderLeftColor',
	'borderLeftStyle',
	'borderLeftWidth',
	'borderRight',
	'borderRightColor',
	'borderRightStyle',
	'borderRightWidth',
	'borderSpacing',
	'borderStyle',
	'borderTop',
	'borderTopColor',
	'borderTopStyle',
	'borderTopWidth',
	'borderWidth',
	//'clear',
	//'clip',
	'color',
	//'cursor',
	//'display',
	//'filter',
	'font',
	'fontFamily',
	'fontSize',
	'fontVariant',
	'fontWeight',
	//'height',
	//'left',
	'letterSpacing',
	'lineHeight',
	'listStyle',
	'listStyleImage',
	'listStylePosition',
	'listStyleType',
	'margin',
	'marginBottom',
	'marginLeft',
	'marginRight',
	'marginTop',
	'overflow',
	'padding',
	'paddingBottom',
	'paddingLeft',
	'paddingRight',
	'paddingTop',
	'pageBreakAfter',
	'pageBreakBefore',
	//'position',
	//'styleFloat',
	'textAlign',
	'textDecoration',
	//'textDecorationBlink',
	//'textDecorationLineThrough',
	//'textDecorationNone',
	//'textDecorationOverline',
	//'textDecorationUnderline',
	//'textIndent',
	'textTransform',
	//'top',
	//'visibility',
	//'width',
	//'zIndex',
	'verticalAlign'
	);

