function dispatch(element, event) {

	if (typeof(event)=="undefined") event = window.event;
	if (typeof(event.target)=="undefined") event.target = event.srcElement;
/*
	if (typeof(event.relatedTarget)=="undefined") {
		if (event.type=="mouseout") { event.relatedTarget = event.toElement; }
		else if (event.type=="mouseover") { event.relatedTarget = event.fromElement; }
	}
*/
// get mouse position
	if (event.pageX || event.pageY) { event.mouseX = event.pageX; event.mouseY = event.pageY; }
	else if (event.clientX || event.clientY) { event.mouseX = event.clientX + document.body.scrollLeft; event.mouseY = event.clientY + document.body.scrollTop; }

	var m = element.id.match(/^([^:]+):?([^:]*):?(.*)$/);
	if (!m) { alert(element.id); return }
	var doc = element.ownerDocument;
	var win = doc.defaultView ? doc.defaultView : doc.parentWindow;
	
	var id = element.id.split(':');
	var data = m[3].split('.');
	eval('var result='+m[1]+'_'+m[2]+'_'+event.type+'({element:element, event:event, document:doc, window:win, id:id, data:data})');
	return result;
}

function $_(s) {
	if (typeof s=='string') return document.getElementById(s);
//	if (typeof s=='array') for (var i=0; i<s.length; i++);
	return s;
}

function _getElementsByTagName(a) {
	var elems = [], arr, tags = a.tags.split(','), i, j;

	for (i=0; i<tags.length; i++) {
		arr = a.root.getElementsByTagName(tags[i]);
		for (j=0; j<arr.length; j++) elems[elems.length] = arr[j];
	}

	return elems;
}

function getFormFields(a) {
	return _getElementsByTagName({root:a.root, tags:'INPUT,SELECT,TEXTAREA'});
}

function validateForm(a) {
	var root = a.form?a.form:document;
	var labels = root.getElementsByTagName('LABEL');
	var elems = getFormFields({root:root}), i, j, m, e, c1, c=[], ok, l, errors='';

	for (i=0; i<elems.length; i++) {
		e = elems[i];
		if (!(l=$_('label:'+e.id))) { for (j=0; j<labels.length; j++) if (labels[j].htmlFor==e.id) { l = labels[j]; break; } }

		if ((m = e.className.match(/(^|\s)(required|optional):([^:]*):\'([^\']*)\'($|\s)/))) {
			ok = true;

			if (!e.disabled && (m[2]=='required' || e.value!='')) {
				c = m[3].split('|'); 

				ok = !((c[0]=='nz'  && e.value=="")
				|| (c[0]=='length'  && e.value.length<1*c[1])
				|| (c[0]=='int'     && (e.value=="" || Math.floor(e.value)!=e.value || c[1]!='' && 1*e.value<1*c[1] || c[2]!='' && 1*e.value>1*c[2]))
				|| (c[0]=='decimal' && (e.value=="" || e.value*1!=e.value || c[1]!='' && 1*e.value<1*c[1] || c[2]!='' && 1*e.value>1*c[2]))
				|| (c[0]=='email'   && !e.value.match(/^[0-9a-z._-]+@[0-9a-z._-]+\.[a-z]{1,6}$/i))
				|| (c[0]=='re'      && !RegExp(c[1]).test(e.value)));
			}

			if (!ok) {
				errors += (m[4].charAt(0)=='*'?('Please enter a valid '+(l?l.innerHTML:(e.title?e.title:e.name))+m[4].substring(1,m[4].length)):m[4])+"\n";
				if (!e.className.match(/\berror\b/)) {
					e.className += ' error';
					if (l) l.className += ' error';
				}
			} else {
				if (e.className.match(/\berror\b/)) {
					e.className = e.className.replace(/\berror\b/, '');
					if (l) l.className = l.className.replace(/\berror\b/, '');
				}
			}

		}
	}

	if (errors) { alert(errors); return false; }

	return true;
}

function grid_pager_set(name, value) {
	var f = document.forms.pager;

	if (validateForm({form:f})) {
		f['pager['+name+']'].value = value;
		f.submit();
	} else {
		f['pager[pageNum_top]'].value = '';
		f['pager[pageNum_bottom]'].value = '';
	}
}

function copyToClipboard(meintext)
{

 if (window.clipboardData) 
   {
   
   // the IE-way
   window.clipboardData.setData("Text", meintext);
   
   // Probabely not the best way to detect netscape/mozilla.
   // I am unsure from what version this is supported
   }
   else if (window.netscape) 
   { 
   
   // This is importent but it's not noted anywhere
   netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   
   // create interface to the clipboard
   var clip = Components.classes['@mozilla.org/widget/clipboard;[[[[1]]]]'].createInstance(Components.interfaces.nsIClipboard);
   if (!clip) return;
   
   // create a transferable
   var trans = Components.classes['@mozilla.org/widget/transferable;[[[[1]]]]'].createInstance(Components.interfaces.nsITransferable);
   if (!trans) return;
   
   // specify the data we wish to handle. Plaintext in this case.
   trans.addDataFlavor('text/unicode');
   
   // To get the data from the transferable we need two new objects
   var str = new Object();
   var len = new Object();
   
   var str = Components.classes["@mozilla.org/supports-string;[[[[1]]]]"].createInstance(Components.interfaces.nsISupportsString);
   
   var copytext=meintext;
   
   str.data=copytext;
   
   trans.setTransferData("text/unicode",str,copytext.length*[[[[2]]]]);
   
   var clipid=Components.interfaces.nsIClipboard;
   
   if (!clip) return false;
   
   clip.setData(trans,null,clipid.kGlobalClipboard);
   
   }
   alert("Following info was copied to your clipboard:\n\n" + meintext);
   return false;
}