/* 
	Basic object handling javascripts 
	Called and linked with globalbehaviors.js.xsl 
	
	Some DOM object properties and method:
	P R O P E R T Y					D E S C R I P T I O N
	nodeName						name of the node
	nodeValue						value of node (only applicable to text nodes)
	nodeType						type of node - see below
	parentNode						parent, if one exists
	childNodes						list (array) of child nodes
	firstChild						first child
	lastChild						last child
	previousSibling					previous sibling
	nextSibling						next sibling
	attributes						list of attributes of an element
	ownerDocument					document containing the element
	
	M E T H O D S					D E S C R I P T I O N
	appendChild()					append a node to node's list of child nodes.
	createElement					create new HTML element, but doesn't "attach" it to the DOM hierarchy.
	createTextNode()				create new text node, but doesn't "attach" it to the DOM hierarchy.
	geElementById()					get a node from the hierarchy
	insertBefore(child1,child2)		inserts the node child1 as a new child node before node child2 
	removeChild()					remove child node
	replaceChild(child1,child2)		replace node child2 by node child1
	
	
	$Log$
	Revision 1.10  2005/07/12 11:06:56  torben
	Add allformscheckallonoff() to check/uncheck checkboxes of all forms on a page

	Revision 1.9  2005/07/07 10:25:54  torben
	Add more formhandling scripts: submitform(), formcheckallonoff() and formcheckallshift()
	
	Revision 1.8  2005/05/04 15:10:31  torben
	Add function updatefieldvalues(). Comment is within the function
	
	Revision 1.7  2005/05/01 14:28:14  torben
	Add a list of useful properties and methods for manipulation with javascript. Fix objectXpos() and objectYpos(). Add some checkbox functions: checkonoff(), checkallonoff(), checkallshift()
	
	Revision 1.6  2005/04/10 14:18:16  torben
	Make findobject() handle objects. Add objectXpos() and objectYpos() to get an objects position
	
	Revision 1.5  2004/05/05 13:35:21  torben
	Change scripting a little showhideobject. Add showhidemultiple for better handling in templates
	
	Revision 1.4  2004/05/04 21:44:26  torben
	Add functionality to showhideobject() - see javascripts/globalbehaviors.js.xsl
	
	Revision 1.3  2004/04/24 14:27:14  torben
	Add javascript function getproperty
	
	Revision 1.2  2004/04/13 15:48:56  torben
	Fix bug in showhideobject()
	
	Revision 1.1  2004/04/06 07:45:08  torben
	Start globalbehaviors that can be linked to a document
	
*/

function px(v) { return v+'px'; }
function findobject(n, d) {
	if (typeof(n)=='object') return n;
	var p,i,x;  
	if(!d) { d=document; }
	if((p=n.indexOf("?"))>0&&parent.frames.length) { d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p); }
	if(!(x=d[n])&&d.all) { x=d.all[n]; } 
	for (i=0;!x&&i<d.forms.length;i++) { x=d.forms[i][n];}
	for(i=0;!x&&d.layers&&i<d.layers.length;i++) { x=findobject(n,d.layers[i].document); }
	if(!x && d.getElementById) { x=d.getElementById(n); }
	return x;
	}

function changeproperty(objname,x,objprop,objpropval) { 
	var obj = findobject(objname);
	if (obj && (objprop.indexOf("style.")==-1 || obj.style)){
		if (objpropval == '') { eval("obj."+objprop+"=''"); }
		else if (objpropval == true || objpropval == false) { eval("obj."+objprop+"="+objpropval); }
		else { eval("obj."+objprop+"='"+objpropval+"'"); }
		}
	}

function getproperty(objname,objprop) { 
	var obj = findobject(objname);
	if (obj && (objprop.indexOf("style.")==-1 || obj.style)){
		return eval("obj."+objprop); 
		}
	}

function relationdisplay(element, relation, id) {
	elements = document.getElementsByTagName(element);
	for (i=0;i<elements.length;i++) {
		if (elements[i].getAttribute('relation') == relation) {
			elements[i].style.display = 'none';
			if (elements[i].id == id) {
				switch (element) {
					case 'div':
						elements[i].style.display = 'block';
						break;
					case 'tr':
						elements[i].style.display = 'tr-row';
						break;
					default:
					}
				}
			}
		}
	}

function showhide() { 
	args=showhide.arguments;
	if ((obj=findobject(args[0]))!=null) {
		v = _get_style_visibility(obj);
		if (obj.style.visibility) {
			v=(v=='show')?'visible':(v=='hide')?'hidden':v;
			obj.style.visibility=v;
			}
		else {
			v=(v=='show')?'block':(v=='hide')?'none':v;
			obj.style.display=v;
			}
		return v;
		}
	return null;
	}

function showhideobject() { 
	var i,p,v,obj,args=showhideobject.arguments;
	for (i=0; i<args.length-1; i+=3) if ((obj=findobject(args[i]))!=null) { 
		v = (args[i+2] == '')?_get_style_visibility(args[i]):args[i+2];
		if (obj.style) { 
			obj=obj.style; 
			if (obj.visibility) {
				v=(v=='show')?'visible':(v=='hide')?'hidden':v;
				obj.visibility=v;
				}
			else {
				v=(v=='show')?'block':(v=='hide')?'none':v;
				obj.display=v;
				}
			}
		}
	}

function showhidemultiple() { 
	a = showhidemultiple.arguments;
	for (i=0; i<a.length; i+=2) showhideobject(a[i],'',a[i+1]);
	}

function objectPos(o) {
	var curleft = curtop = 0;
	if ((obj=findobject(o))!=null) {
		if (obj.offsetParent) {
			do {
				curleft += obj.offsetLeft;
				curtop += obj.offsetTop;
				} while (obj = obj.offsetParent);
			return [curleft,curtop];
			}
		}
	}
function objectXpos(o) {
	if ((obj=findobject(o))!=null) {
		var cx = (obj.offsetParent)?0:(obj.x)?obj.x:0;
		/*while ((obj = obj.offsetParent)!=null) cx += obj.offsetLeft;*/
		if (obj.offsetParent) { while (obj.offsetParent) {cx += obj.offsetLeft;obj = obj.offsetParent;}}
		return cx;
		}
	}

function objectYpos(o) {
	if ((obj=findobject(o))!=null) {
		var cy = (obj.offsetParent)?0:(obj.y)?obj.y:0;
		/*while ((obj = obj.offsetParent)!=null) cy += obj.offsetTop;*/
		if (obj.offsetParent) { while (obj.offsetParent) {cy += obj.offsetTop;obj = obj.offsetParent;}}
		return cy;
		}
	}

/* F O R M  H A N D L I N G */

function submitform(f){
	fobj = findobject(f);
	fobj.submit();
	return true;
	}
function confirmcheckednamed(){
	/* 
	Raises a confirm alert if a chexkbox (checkbox name or object) is been ckecked.
	Eg. confirmcheckednamed(this,'If this checkbox is checked, user will only be able to set local passwordroles','pwlocalpasswdrolesonly')
	*/
	args = confirmcheckednamed.arguments;
	chbx = findobject(args[0]);
	name = args[2];
	mess = args[1];
	if (chbx.name == name) {
		if (chbx.checked) {
			if (!confirm(mess)) chbx.checked=false;
			}
		}
	}
function checkRelOnOff(){
	
	args = checkRelOnOff.arguments;
	cb = args[0];
	popstr = '_cb'
	if (args.length>1) popstr = args[1]
	na = cb.name.split(popstr);
	garbage = na.pop()
	dstfield = cb.form[na.join(popstr)]
	dstfield.value=(cb.checked==true)?1:0;
	}
function checkonoff(){
	args = checkonoff.arguments;
	o = args[0];i = 0;
	if (args.length>1) i = args[1];
	cobj = findobject(o);
	if (cobj.length>i) cobj[i].checked = !cobj[i].checked;
	else cobj.checked = !cobj.checked;
	}
function checkallonoff(){
	args = checkallonoff.arguments;
	if (args.length) {
		o = args[0];cobj = findobject(o);
		a=0;b=0;
		for (i=0;i<cobj.length;i++) {
			if (cobj[i].checked == true) a++;
			else b++;
			}
		ch = (a<b);
		for (i=0;i<cobj.length;i++) cobj[i].checked = ch;
		}
	}
function checkallshift(){
	args = checkallshift.arguments;
	o = args[0];cobj = findobject(o);
	if (args.length) for (i=0;i<cobj.length;i++) cobj[i].checked = !cobj[i].checked;
	}

function formcheckallonoff(){
	/* 
	Argument is formname or form object, like: formcheckallonoff('formname) or formcheckallonoff(this.form) 
	Checks all checkboxes in the form on or off - depending on how many are checked or not.
	More arguments can be names of checkboxes that should not be changed.
	Eg. formcheckallonoff(this.form,'nottobechanged') will not touch the checkbox named 'nottobechanged'.
	*/
	args = formcheckallonoff.arguments;
	skip = '';
	if (args.length>1) for (i=1;i<args.length;i++) skip = skip +'('+args[i]+')';
	f = args[0];fobj = findobject(f);a=0;b=0;
	for (i=0;i<fobj.length;i++) if (fobj[i].type == 'checkbox') if (fobj[i].checked == true) a++; else b++;
	for (i=0;i<fobj.length;i++) {
		if (fobj[i].type == 'checkbox') {
			if (skip.indexOf('('+fobj[i].name+')')==-1) fobj[i].checked = (a<b);
			}
		}
	}

function formcheckallshift(){
	/* 
	Argument is formname or form object, like: formcheckallshift('formname) or formcheckallshift(this.form) 
	Shifts all checkboxes in the form on or off.
	*/
	args = formcheckallshift.arguments;
	f = args[0];fobj = findobject(f);
	for (i=0;i<fobj.length;i++) if (fobj[i].type == 'checkbox') fobj[i].checked = !fobj[i].checked
	}

function allformscheckallonoff(){
	/* 
	Argument is formname or form object, like: formcheckallonoff('formname) or formcheckallonoff(this.form) 
	Checks all checkboxes in the form on or off - depending on how many are checked or not.
	*/
	nobj = new Array()
	args = allformscheckallonoff.arguments;a=0;b=0;
	if (args.length) {
		for (n=0;n<document.forms.length;n++) {
			fobj = document.forms[n][args[0]];
			if (fobj) {
				if (fobj.length) {
					for (i=0;i<fobj.length;i++) { if (fobj[i].type == 'checkbox') { if (fobj[i].checked == true) a++; else b++; nobj.push(fobj[i]); } }
					}
				else { if (fobj.type == 'checkbox') { if (fobj.checked == true) a++; else b++;nobj.push(fobj); } }
				}
			}
		for (i=0;i<nobj.length;i++) nobj[i].checked = (a<b)
		}
	}

function updatefieldvaluefromfield() {
	args = updatefieldvaluefromfield.arguments;
	f = findobject(args[0]);
	updatefieldvalues(args[0],args[1],f[args[2]].value);
	}

function updatefieldvalues() {
	/* 
	E.g. updatefieldvalues(this.form,'cmd','save','command','formsave','templatepath','/kost20052/_manage/netnyt/')
	will update the value of the fields 'cmd', 'command', 'templatepath' in this.form with the values next to the field names.
	this.form is the parent object of an <input>. The form may also be defined by the name, such as:
	updatefieldvalues('formname','cmd','save','command','formsave','templatepath','/kost20052/_manage/netnyt/')
	if it is called from a non form element (like a <a href>.
	Note: this javascript call example may be build in xsl with e.javascriptcall(), like this
	e.javascriptcall('updatefieldvalues',(
											'this.form',
											repr('cmd'),repr('save'),
											repr('command'),repr('formsave'),
											repr('templatepath'),repr(e['path'])
											))
	*/
	args = updatefieldvalues.arguments;
	f = findobject(args[0]);
	for (i=1;i<args.length;i+=2) {
		if (f[args[i]])  f[args[i]].value = args[i+1];
		else {
			newinput = document.createElement('input');
			//What is this doing, probably an error
			//newinput.setAttribute(args[i],args[i+1]);
			newinput.setAttribute('name',args[i]);
			newinput.setAttribute('value',args[i+1]);
			newinput.setAttribute('type','hidden');
			f.appendChild(newinput);
			}
		}
	}
function buildDatePopupValue(path, doSubmit){
	/*
	Added by Petr. Comes from XierpaBuilder.datepopup(). 
	It's better to have it here permatent, because ajax does not always load the script when inside the form.
	This function builds the combined date from the datepopup parts on change of on of the values.
	If the parameter doSubmit is set, then pass it on, so the calling form knows when to submit on the change.
	*/
	y = getElement(path+'_year');
	m = getElement(path+'_month');
	d = getElement(path+'_day');
	log(m, y);
	//log(d, m, y);
	root = getElement(path+'_span');
	oldResult = getElement(path);
	if (y && y.value != '-' && y.value != '0' && m && m.value != '-' && m.value != '0' && d && d.value != '-' && d.value != '0') {
		// There is a valid date value because all three popups are set.
		//log(y.value, m.value, d.value, path);
		result = INPUT({'id': path, 'type': 'hidden', 'name': path, 'value': y.value + '-' + m.value + '-' + d.value});					
		swapDOM(oldResult, result);
		if (doSubmit)
			return 1
	}
	else if (y && m && d && (y.value == m.value && m.value == d.value)) {
		// There is a vaid value because all tree popups are cleared. This will clear the date
		//log(y.value, m.value, d.value, path);
		result = INPUT({'id': path, 'type': 'hidden', 'name': path, 'value': ''});					
		swapDOM(oldResult, result);
		if (doSubmit)
			return 1
	}
	return 0
}
	
/* I N I T I A L  S E T T I N G   &  S U B R O U T I N E S */

var sh = new Array();
sh['hidden'] = 'show';
sh['visible'] = 'hide';
sh['block'] = 'hide';
sh['none'] = 'show';

function _get_style_visibility(obj) {
	styleDisplay = getproperty(obj,'style.display');
	styleVisibility = getproperty(obj,'style.visibility');
	if (styleVisibility) return sh[styleVisibility];
	else return sh[(styleDisplay)?styleDisplay:'block'];
	}
function windowinner() {
	bw = window.innerWidth - 20;
	bh = window.innerHeight - 10;
	}
function documentclient() {
	bw = document.clientWidth;
	bh = document.clientHeight;
	}
function documentbody() {
	bw = document.body.clientWidth - 20;
	bh = document.body.clientHeight - 10;
	}
function documentelement() {
	bw = document.documentElement.offsetWidth - 26;
	bh = document.documentElement.offsetHeight - 10;
	}
function BrowserCheck() {
	var b = navigator.appName;
	if (b=="Netscape") this.b = "ns";
	else if (b=="Microsoft Internet Explorer") this.b = "ie";
	else this.b = b;
	this.version = navigator.appVersion;
	this.v = parseInt(this.version);
	this.ns = (this.b=="ns" && 4<=this.v);
	this.ns4 = (this.b=="ns" && this.v==4);
	this.ns5 = (this.b=="ns" && this.v==5);
	this.ie = (this.b=="ie" && 4<=this.v);
	this.ie4 = (this.version.indexOf('MSIE 4')>0);
	this.ie5 = (this.version.indexOf('MSIE 5')>0);
	this.ie6 = (this.version.indexOf('MSIE 6')>0);
	this.ie7 = (this.version.indexOf('MSIE 7')>0);
	this.min = (this.ns||this.ie);
	if (this.ns4 || this.ns5) browserwh = windowinner;
	else if (this.ie4 || this.ie5) browserwh = documentbody;
	else if (this.ie6 || this.ie7) browserwh = documentelement;
	}
is = new BrowserCheck()

/* Parameterized addEventListener function*/ 
function addObjectEventListener(event, f, object) {
	if(!object) { object=window; }
	if (navigator.platform == "Win32" && navigator.appName == "Microsoft Internet Explorer" && object.attachEvent) object.attachEvent("on"+event, f);
	else object.addEventListener(event,f,false);
	}
