if(typeof miwt == 'undefined') miwt={};
if(typeof miwtutil == 'undefined') {
var miwtutil = {};
/** Symbolic names are much more readable than magic numbers. */
if(typeof Node == 'undefined') {
Node = {ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,
		ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,
		DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12};
}
if(!Array.prototype.each){Array.prototype.each=function(f){for(var h = 0, hb = this.length; h < hb; h++)f(h, this[h]);};}
if(!Array.prototype.filter){
	Array.prototype.filter=function(f,thisObj){
		var h=0,hb=this.length,r=[];
		for(;h++<hb;) if(f.call(thisObj, this[h], h, this)) r.push(this[h]);
		return r;
	};
};
if(!Array.prototype.without){Array.prototype.without=function(w){return this.filter(function(v){return w!=v;})};}
if(!Array.prototype.indexOf){
	Array.prototype.indexOf=function(e){
		for(var h = 0, hb = this.length; h < hb; h++)if(this[h]==e)return h;
		return -1;
	};
}
if(!String.prototype.trim) {String.prototype.trim = function() {return this.replace(/^\s+|\s+$/g, "");};}
miwt.B=(function(){
    var ua = navigator.userAgent, isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
	return {
      IE:             !!window.attachEvent && !isOpera,
      Opera:          isOpera,
      WebKit:         ua.indexOf('AppleWebKit/') > -1,
      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1
	};
})();
miwt.children=function(el){
	if(typeof el.children != 'undefined') return miwt.array(el.children);
	else { // firefox<3.5, ie<9 (comment nodes)
		var l=[], n = el.firstChild;
	    while (n) {
	      if(n.nodeType == 1) l.push(n);
	      n = n.nextSibling;
	    }
	    return l;
	}
};
miwt.childElementCount=function(el){
	if(typeof el.childElementCount != 'undefined') return el.childElementCount;
	else { // firefox<3.5, ie<9 (comment nodes)
		var c=0, n = el.firstChild;
	    while (n) {
	      if(n.nodeType == 1) c++;
	      n = n.nextSibling;
	    }
	    return c;
	}
};
//(c) Steven Levithan <stevenlevithan.com>
//MIT License
miwt.parseUri = function(url) {
	var p=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
		u={},i=p.length,
		m=/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(url);
	while (i--) u[p[i]] = m[i] || "";
	return u;
};

/**
 * Gets the computed style of the element.
 * @see http://www.quirksmode.org/dom/getstyles.html
 * @param element the DOM element.
 * @param style the name of the CSS style.
 * @return the value, will be the empty string if not able to compute.
 */
miwt.getComputedStyle = function (el, style) {
	if (document.defaultView && document.defaultView.getComputedStyle)
		return document.defaultView.getComputedStyle(el, "").getPropertyValue(style);
	else if (el.currentStyle) return el.currentStyle[style];
	else return "";
};
/*miwt.scrollbarOffset={x:25,y:25};
miwt.recalcScrollbarOffset = function() { 
    var x,y,w1,w2,h1,h2,c,div = document.createElement('div');
    div.innerHTML = '<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"/></div>';
    div = div.firstChild;
    c = div.firstChild;
    document.body.appendChild(div); 
    w1 = c.scrollWidth;
    h1 = c.scrollHeight;
    c.style.overflow = 'scroll';
    w2 = c.scrollWidth;
    h2 = c.scrollHeight;
    x = (w1 - w2);
    y = (h1 - h2);
    document.body.removeChild(div);
    return (miwt.scrollbarOffset={x:x,y:y});
   
};*/
miwt.height = function(el){
	var h,s=el.style,p={},sl={position:'absolute',visibility:'hidden',display:'block',top:'auto',bottom:'auto'},k;
	for(k in sl){p[k]=s[k];s[k]=sl[k];}
	h = el.offsetHeight;
	for(k in sl){s[k]=p[k];}
	return h;
};
miwt.hasCSSRule = function(el, style, excludeValue) {
	if(!!el.style[style] && (excludeValue == null || el.style[style] != excludeValue))
		return true;
	var ss, r, i=0,j,v;
	el = [el];
	try{
		for(;i < document.styleSheets.length/*ie*/ && (ss=document.styleSheets[i++]);){
			ss = ss.cssRules || ss.rules;
			if(!ss) continue;
			for(j=0;r=ss[j++];){
				try {
					v = r.style[style];
					if(v && (excludeValue == null || v != excludeValue)
							&& miwt.$$.matches(r.selectorText, el).length == 1){
						return true;
					}
				}catch(e) {
					//miwt.debug('Unable to test selector: '+e, e);
				}
			}
		}
	}catch(e2){miwt.debug('Unable to check stylesheets: '+e2, e2);}
	return false;
};
/**
 * Close all CKEditors at or below the specified element.
 * @param el the DOM element.
 */
miwt.closeCKEditors = function (el) {
	if(typeof CKEDITOR == 'undefined') return;
	var i, ta, list = el.getElementsByTagName('textarea');
	for(i=0; i<list.length; i++) {
		ta = list[i];
		var editor = CKEDITOR.instances[ta.id];
		if (editor) {
		  try {
		    //editor.focus(); // Workaround http://dev.fckeditor.net/ticket/4241
		  } finally {
		    if (editor)
		      editor.destroy();
		  }
	  }
	}
};
miwt.pointer=function(evt){
	var de = document.documentElement, body = document.body,
	x = evt.pageX || (evt.clientX + (de.scrollLeft || body.scrollLeft) - (de.clientLeft || 0)),
	y = evt.pageY || (evt.clientY + (de.scrollTop || body.scrollTop) - (de.clientTop || 0));
	return {0:x,1:y,x:x,y:y,left:x,top:y};
};
miwt.$ = function element(el){return (typeof el == 'string') ? document.getElementById(el) : el;};
/** Select elements given an optional context.
 * miwt.$$('div.window > input', formElement);
 */
miwt.$$ = Sizzle_i2rd; // function(selector, context)
miwt.addClassName=function(el,cn){
	cn = cn.trim();
	if (!miwt.hasClassName(el,cn))el.className = ((el.className || '') + ' ' + cn).trim();
};
miwt.removeClassName=function(el,cn){
	if (!miwt.hasClassName(el,cn)) return;
	el.className = (el.className || '').replace(RegExp("(^|\\s+)" + cn.trim() + "(\\s+|$)",'g'), ' ').trim();
};
miwt.hasClassName=function(el,cn){
	var cur = (el.className || '');
	return (RegExp('\\b'+cn+'\\b').test(cur));
};
miwt.element = function element(evt){
	if(typeof evt == 'string') return miwt.$(evt);
	evt = evt || window.event;
	evt = evt.target || evt.srcElement;
	if(evt && evt.nodeType == Node.TEXT_NODE) evt = evt.parentNode;
	return evt;
};
miwt.scrollTo=function(el){
	el=miwt.$(el);
	var p = miwt.cumulativeOffset(el);
	window.scrollTo(p.x,p.y);
};
/**
 * Find an element iteratively searching parents.
 * @param start the element or event to start.
 * @param expression the expression.
 * @returns the first element that matches the expression "closest" to the starting element.
 */
miwt.findElement = function findElement(start, expression){
	start = miwt.element(start) || start;
	while(start){
		var m=miwt.$$(expression, start);
		if(m[0])return m[0];
		start = start.parentNode;
	}
	return null;
};
miwt.siblings=function(el){
	var i,l=[],n=miwt.$(el).parentNode.childNodes;
	for(i=0;i<n.length;i++) if(n[i] != el) l.push(n[i]);
	return l;
};
// Useful for copying nodelist and arguments.
miwt.array=function(nl){
	var i,l = [];
	for(i=0; i < nl.length; i++) l.push(nl[i]);
	return l;
};
miwt.wrap=function(el, tag){
	var w = document.createElement(tag);
	w.addChild(el);
	return w;
};
miwt.remove=function(el){
	el=miwt.$(el);
	if(el.parentNode)el.parentNode.removeChild(el);
	return el;
};
miwt.getDimensions=function(el){
	el=miwt.$(el);
	return {width:el.offsetWidth, height:el.offsetHeight};
};
/**
 * Find the first ancestor element that matches the specified expression.
 * @param el the element to start.
 * @param the expression.
 * @return the first matching ancestor.
 */
miwt.up=function(el, expression){
	el = miwt.element(el) || el;
	while(el){
		var m=miwt.$$.matches(expression, [el]);
		if(m[0])return m[0];
		el = el.parentNode;
	}
	return null;
};
miwt.words=function(s){return s ? s.split(/\s+/) : [];};
miwt.stop = function(evt){
	evt = evt || window.event;
	if(evt.preventDefault)evt.preventDefault();
	if(evt.stopPropagation)evt.stopPropagation();
	evt.cancelBubble=true;
	evt.returnValue=false;
};
miwt.extend = function(dest, src){
	for (var p in src) 
		dest[p] = src[p];
	return dest;
};
miwt.cumulativeOffset = function(el, scroll){
	el = miwt.$(el);
	scroll = !!scroll;
	var y = 0, x = 0, t = scroll ? 'scroll' : 'offset', wk = miwt.B.WebKit, b = document.body;
	if (el.parentNode) {
	  do {
	    y += el[t + 'Top']  || 0;
	    x += el[t + 'Left'] || 0;
	    el = scroll ? el.parentNode : el.offsetParent;
        if (!scroll && wk && el == b && miwt.getComputedStyle(el, 'position') == 'absolute')
        	break;
	  } while (el);
	}
	return {0:x,1:y,x:x,y:y,left:x,top:y};
};
miwt.observe = function(el, name, observer, cap) {
    el = miwt.$(el);
    if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || el.attachEvent))
    	name = 'keydown';

    if (el.addEventListener) {
    	el.addEventListener(name, observer, (cap||false));
    } else if (el.attachEvent) {
    	el.attachEvent('on' + name, observer);
    }
};

miwt.stopObserving = function(el, name, observer, cap) {
    el = miwt.$(el);
    if (name == 'keypress' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || el.detachEvent))
    	name = 'keydown';
    if (el.removeEventListener) {
    	el.removeEventListener(name, observer, (cap||false));
    } else if (el.detachEvent) {
    	try {
    		el.detachEvent('on' + name, observer);
    	} catch (e) {}
    }
};
/**
 * Serialize a form.
 */
miwt.serialize=function(form,sv){
	var t,e,i,s=[];
	sv = sv || miwt.serializeValue;
	for(i=0; e=form.elements[i]; i++){
		t=e.type;
		if(e.serializeValue) e.serializeValue(form,s,e.name,e.value);
		else if(e.name && !e.disabled && t != 'submit' && t != 'file') {
			switch(e.nodeName.toLowerCase()){
				case 'input':
					switch(t){
						case 'checkbox':
						case 'radio':
							if(e.checked)sv(form,s, e.name, e.value); 
							break;
						case 'button':break;
						default: sv(form,s, e.name, e.value); break;
					}
					break;
				case 'select':
					for(var o,j=0; o=e.options[j];j++) if(o.selected) sv(form,s, e.name, o.value);
					break;
				case 'button':break;
				default:sv(form,s, e.name, e.value); break;
			}
		}
	}
	return s.join('&');
};
miwt.disabled=function(el){el.disabled || el.getAttribute("disabled") != null;};
/**
 * Serialize a form element.
 * @param f form.
 * @param s serialized value "$name=$value" list.
 * @param n the form element name.
 * @param v the form element value.
 */
miwt.serializeValue=function(f, s, n,v){
	if(n && v != null){s.push(encodeURIComponent(n) + '=' + encodeURIComponent(v));}
};

miwt.viewResource = function (url, newWindow) {
	//miwt.info("Viewing resource "+url);
	var f = miwt.$$("form.viewresource").pop(),
	 pleaseNo = document.all && !window.opera;
	if (f) {
		f.action = url;
		if (newWindow)
			f.target = "_blank";
		else
			f.target = "_self";
		f.submit();
	} else {
		// MSIE: The behavior of opening a file depends on the file type mapping. For example, the default mapping of .css
		// is to Notepad. IE will open a browser window and then close immediately without further action.
		// Firefox 3: This works as intended.
		url = url + (miwt.parseUri(url).query ? '&' : '?') + "disposition=inline";
		if (newWindow) {
			var nw = pleaseNo ? window.open() : window.open(url, '_blank');
			if (!nw) {
				if(confirm(miwt.$$("dfn.miwt_popup_blocked").pop().firstChild.data))
					window.location.href = url;
			} else if(pleaseNo) {
				var mesg = miwt.$$("dfn.miwt_loading_file").pop().firstChild.data;
				nw.document.write('<p>' + mesg.replace(/\${url}/, url) + '</p>');
				nw.location = url;
			}
		} else {
			window.location.href = url; 
		}
	}
};

miwt.saveResource = function (url) {
	//miwt.info("Saving resource "+url);
	var f = miwt.$$("form.saveresource").pop();
	if (f) {
		// MSIE: When a blocked file download is requested to be downloaded by the user ("Download file...") the page is
		// reloaded. It is unclear if this is due to the form.
		// Firefox 3: Using the form works great, the file is downloaded without warning from the pop-up blocker
		f.action = url;
		f.submit();
	} else {
		// MSIE: window.open ignores the content disposition and thus opens instead of saves
		var nw = window.open(url + (miwt.parseUri(url).query ? '&' : '?') + "disposition=attachment");
		if (!nw) {
            if (confirm(miwt.$$("dfn.miwt_popup_blocked").pop().firstChild.data))
                window.location.href = url;
        }
	}
};
miwt._log=function logger(t, args){
	var l=window.console,t=arguments[0],f;
	if(typeof log4js != 'undefined')l=log4js.logger;
	if(l && typeof (f=l[t]) == 'function')f.apply(l, args);
};
miwt.error=function(){miwt._log("error",arguments);};
miwt.warn=function(){miwt._log("warn",arguments);};
miwt.info=function(){miwt._log("info",arguments);};
miwt.debug=function(){miwt._log("debug",arguments);};

}// End conditional eval
if(typeof miwt.Form == 'undefined') {

/**
 * MIWT form extension.
 */
miwt.prv_FormOnSubmitHandler = function(evt) {
	var form = miwt.element(evt);
	if (!form || !form.MIWTOnSubmit)
		return true;
	return form.MIWTOnSubmit.apply(form);
};

miwt.TransientFieldNames = [ "btnhit", "dnd_source", "dnd_target", "dnd_location", "dnd_option" ];

miwt.Form = function(){this.initialize();};
miwt.Form.prototype = {
	initialize: function(){
		// list of element IDs that have form submission handlers
		this.submitters = [];
		this.submitter_functions = []; // maps element.id to function
		this.onsubmit = miwt.prv_FormOnSubmitHandler;	
	}, 
	/**
	 * Called to process before form submission.
	 * @return true if the form can be submitted, false if not.
	 */
	MIWTOnSubmit: function (){
		if (typeof(window.miwtReady) != 'undefined' && window.miwtReady == 2) // we are already in the process of submitting the form
			return false;
			
		// Handle form specific onSubmit script
		var submitter, el, i=0;
		for(; submitter = this.submitters[i++];) {
			el = miwt.$(submitter);
			if (el) {
				var f = this.submitter_functions[el.id];
				if (f && !f(this))
				{
						//miwt.debug("submit handler for element "+(el.name||el.id)+" failed");
						return false;
				}
			}
		}
					
		// Indicate we are in the process of submitting the form	
		window.miwtReady=2;
	
		return true;
	},
	
	/**
	 * Submit the form. Calls the MIWTOnSubmit function.
	 * @param opts options. See readme.txt in miwt-lib.js directory. If this is not 
	 * specified and the form has a property called submit_options, then that is used.
	 * @return true if submitted, false if not submitted.
	 */
	MIWTSubmit: function (opts){
		//miwt.debug("MIWTSubmit called for "+(this.id || this.name));
		if(typeof opts == 'function'){
			// backward compat.
			opts = {postUpdate:opts};
		} else opts=opts||this.submit_options||{};
		// ignore submits too close together, either double-click or default behavior not prevented
		if (this.lastSubmit) {
			var now = new Date().getTime(), then = this.lastSubmit.getTime();
			if ((now - then) < 250){
				// Clear this for the next form submit
				this.ResetTransient();
				return false; 
			}
		}
			
		if (!this.MIWTOnSubmit())
			return false;
		if(opts.onSubmit && !opts.onSubmit.call(this)){
			window.miwtReady = 1;
			return false;
		}
		if(opts.hasOwnProperty('btnhit')){
			this.elements.btnhit.value=opts.btnhit;
		}
		var ajax = !miwt.$(this.elements.btnhit.value+"_noajax");
		if(opts.hasOwnProperty('ajax')){ajax=opts.ajax;}
		if (!ajax) {
			var progress = miwtajax.showFormPostWait();
			if(opts.preUpdate){opts.preUpdate.call(this, progress);}
			this.submit();
			return true;
		}
		var ajax = new miwtajax.InputProcessor(this, opts);
		this.lastSubmit = new Date();
		if (!ajax.isRequestSubmitted()) {
			// AJAX not supported or failed
			var progress = miwtajax.showFormPostWait();
			if(opts.preUpdate){opts.preUpdate.call(this, progress);}
			this.submit();
		}
		else {
			// Don't disable the form for AJAX requests
			// commented out to prevent multiple AJAX requests from processing
			//window.miwtReady = 1;
		}
		return true;
	},
	
	/** 
	 * Register a function to be called before the form is submitted. The handler will be called with the form object as
	 * the only argument. It should return true to continue processing or false to abort.
	 */
	RegisterOnSubmitHandler: function(el, handler){
		if (el == null)
			return;

 		// set the handler on the element so it will get removed when the element is removed
 		this.submitter_functions[el.id] = handler;
 		
 		if (this.submitters.indexOf(el.id) == -1)
	 		this.submitters.push(el.id);
	},
	
	/**
	 * Clean up handlers whose object has been removed from the DOM.
	 */
	CleanOnSubmitHandlers: function(){
		var list = [], el, elId, i=0;
		for(; elId = this.submitters[i++];) {
			el = miwt.$(elId);
			if (el)
				list.push(elId);
			else
				this.submitter_functions[elId] = null;
		};
		this.submitters=list;
	},
	
	/**
	 * Reset the transient form elements, intended to be called after a form submit.
	 * Elements such as the last drag and drop operation are cleared.
	 */
	ResetTransient: function(){
		for(var name, i = 0; name = miwt.TransientFieldNames[i++]; ) {
			if (this.elements[name])
				this.elements[name].value='';
		}
	}
};

} // End conditional eval.
if(typeof miwtsetup == 'undefined') {
var miwtsetup = {};

/**
 * Setup handlers are called for each node to setup listeners, etc. in order for the component to work. Each entry is
 * a function with the signature:
 * function f(tag, Node, ClassNames) where:
 * 	tag is the lower case Node.tagNode or null if there is no tagName
 * 	Node is the DOM node
 *		ClassNames is the prototype ClassNames object for the Node
 */
miwt.setupHandlers = [];
for(var i=0,l=["any", "a", "button", "div", "img", "input", "select", "dfn", "table", "textarea"];i<l.length;i++)
	miwt.setupHandlers[l[i]]=[];

/**
 * Register a setup handler.
 * @param tags array of tags that are used
 * @param f the function to call.
 */
miwt.AddSetupHandler = function (tags, f){
	if (tags == null)
		tags = [ "any" ];
	var i, tag;
	for(i = 0; tag = tags[i]; i++) {
		if (!miwt.setupHandlers[tag]) miwt.setupHandlers[tag] = [];
		miwt.setupHandlers[tag].push(f);
	}
};

// Setup the document tree rooted at node.
miwt.setup = function (node){
	var nodes = node.getElementsByTagName('*');
	var f, a, j, i = 0;
	var any = miwt.setupHandlers["any"];
	while (node) {
		var tag = node.tagName.toLowerCase();
		if (node.className) {	
			// ensure a combo box does not have focus, causes unexpected behavior when used with a wheel mouse		
			if (tag == 'select' 
				&& node.type && node.type == 'select-one'
				&& !/\bmiwt_focus\b/.exec(node.className))
			{
				if (miwt.lastFocusId == null)
					node.blur();
			}
		}

		for(j = 0; f = any[j]; j++) {
			f(tag, node);
		}

		a = miwt.setupHandlers[tag];
		if (a) {
			for(j = 0; f = a[j]; j++) {
				f(tag, node);
			}
		}
		node = nodes.item(i++);
	}
};

// components that submit on change
miwt.scheduleUpdateKeydownHandler = function (evt) { 
	miwttimer.scheduleUpdate(miwt.element(evt).form.id); 
};
miwt.observerFormSubmit = function (el) { 
	miwt.element(el).form.MIWTSubmit(); 
};
miwt.AddSetupHandler([ 'input', 'select', 'textarea' ], function (tag, node){
	if (node.form && miwt.hasClassName(node,'miwt_watch')) {
		//miwt.debug("Found watcher "+node.id);
		var nt = (node.type||'').toLowerCase();
		if ((tag=='input' && nt == 'text') || tag=='textarea')
			miwt.observe(node, 'keydown', miwt.scheduleUpdateKeydownHandler);
		else if(tag == 'input' && (nt=='checkbox' || nt =='radio'))
			miwt.observe(node, 'click', miwt.observerFormSubmit);
		else
			miwt.observe(node, 'change', miwt.observerFormSubmit);
	}
	
});

// initial focus
miwt.AddSetupHandler([ 'button', 'input', 'select', 'textarea' ], function (tag, node){
	if (node.focus && miwt.hasClassName(node,'miwt_focus')) 
		window.setTimeout(function(){node.focus()}, 200);
});

/**
 * Setup an MIWT form element.
 */  
miwt.setupForm = function(form){
	if(form.miwt_init)return;
	form.miwt_init=true;
	//miwt.debug("Configuring MIWT form "+(form.id || form.name));
	miwt.extend(form, miwt.Form.prototype);
	try{
		form.initialize();
		miwt.setup(form);
	}
	catch (e) { miwt.error("Error configuring MIWT form "+(form.id || form.name), e); }
};

/**
* Set the top window to be visible in the viewport.
* This is intended to only be called on page load.
*/
miwt.setViewportPosition = function(){
    var wz, w, windows = miwt.$$("div.window");
    while( (w=windows.pop()) ) {
        if(!wz || (parseInt(wz.style.zIndex) < parseInt(w.style.zIndex)))
          wz = w;
    }
    if(!!wz) {
    	var pos = miwt.cumulativeOffset(wz);
    	window.scrollTo(pos[0], pos[1] - 20);
    }
};
miwt.initDoc = function(){
	// setup the components in each form
	var i=0, form;
	for(;form=document.forms[i++];) {
		if(form.miwt_init)continue;
		if (miwt.hasClassName(form, 'miwt_form')) {
			miwt.setupForm(form);
            miwt.setViewportPosition();
		} else if (miwt.hasClassName(form, 'miwt_external_action')) {
			var form2 = form;
			setTimeout(function(){form2.submit();}, 1);
		}
	}
};
miwt.onLoad = function(evt){
	//miwt.recalcScrollbarOffset();
	miwt.initDoc();
	if(!miwt.domupdate_check){
		if(window.i2rd)
			i2rd.addEvent(document, 'dom:update', miwt.initDoc);
		if(document.addEventListener)
			document.addEventListener('DOMNodeInsertedIntoDocument', miwt.initDoc, false);
	}
	miwt.domupdate_check=true;
}

} // End conditional eval
if(typeof miwtbutton == 'undefined') {
miwtbutton = {};

miwt.ButtonClicked = function(event){
	miwt.stop(event);
	var form = miwt.findElement(event, 'form'), el = miwt.element(event), btnId, ct;
	while (el && el.parentNode && !(el.name || el.id))
		el = el.parentNode;
	if (miwt.disabled(el))
		return;
	btnId = el.name || el.id;
	ct = miwt.$(btnId+'_confirm');
	if (ct && !confirm(ct.firstChild.data))
		return;
	form.elements['btnhit'].value=btnId;
	//miwt.debug("Button '"+form.elements['btnhit'].value+"' clicked");
	form.MIWTSubmit();
};

miwt.resetEventHandler = function (event){
	miwt.findElement(event, 'form').reset();
};

miwt.AddSetupHandler(null, function BtnSetup(tag, node){
	if(miwt.hasClassName(node, 'miwt_reset'))
		miwt.observe(node, "click", miwt.resetEventHandler);
	if(miwt.hasClassName(node, 'miwt_submit')) {
		if ((tag=='input' && (node.type == 'text' || node.type == 'password')) || tag=='textarea')
			miwt.observe(node, "keydown", miwt.FieldAction);
		else
			miwt.observe(node, "click", miwt.ButtonClicked);
	}
});

miwt.imagebutton = {};
miwt.imagebutton.groups = [];

miwt.imagebutton.imageButtonEnabled = function (btn){return !miwt.disabled(btn);};

miwt.imagebutton.imageButtonMouseOver = function (evt){
	var t=miwt.element(evt);
	if (t==null)
		return;

	miwt.stop(evt);
	
	if (miwt.imagebutton.imageButtonEnabled(t))
		miwt.imagebutton.imageButtonSetState(t, null, null, "rollover");
};

miwt.imagebutton.imageButtonMouseOut = function (evt){
	var t=miwt.element(evt);
	if (t==null)
		return;

	miwt.stop(evt);	
	
	if (miwt.imagebutton.imageButtonEnabled(t))
		miwt.imagebutton.imageButtonSetState(t, null, null, "normal");
};

miwt.imagebutton.imageButtonMouseDown = function (evt){
	var t=miwt.element(evt);
	if (t==null)
		return;

	miwt.stop(evt);	
	
	if (miwt.imagebutton.imageButtonEnabled(t)){
		if (t.focus)
			t.focus();
		miwt.imagebutton.imageButtonSetState(t, null, null, "pressed");
	}
};

miwt.imagebutton.imageButtonMouseUp = function (evt){
	var t=miwt.element(evt);
	if (t==null)
		return;
	
	miwt.stop(evt);
	
	if (miwt.imagebutton.imageButtonEnabled(t))
		miwt.imagebutton.imageButtonSetState(t, null, null, "normal");
};

miwt.imagebutton.imageButtonMouseClick = function (evt){
	var t=miwt.element(evt);
	if (t==null)
		return;

	miwt.stop(evt);
	
	if (miwt.imagebutton.imageButtonEnabled(t)){
		var selected=t.miwt_isSelected;
		if (t.miwt_selectedvalue!=null){
			// toggle the selection value like a native element does
			selected= (t.miwt_isSelected == false);
		}

		if (t.miwt_buttonGroup==null || selected)
			miwt.imagebutton.imageButtonSetState(t, null, selected, "normal");
		
		if (t.miwt_watch)
			miwt.findElement(evt, 'form').MIWTSubmit();
	}
};

/**
 * Set the image button state. This will set the appropriate image.
 *
 * @param img The image object.
 * @param isActive The active state, true or false.
 * @param isSelected The selected state, true or false, false if the button
 * has no selection state.
 * @param state The state: "normal", "rollover", "pressed".
 * @return true if something was changed, false if no change.
 */
miwt.imagebutton.imageButtonSetState = function (img, isActive, isSelected, state){
	isActive=isActive||img.miwt_isActive;
	isSelected=isSelected||img.miwt_isSelected;
		
	if (img.miwt_isActive==isActive 
		&& img.miwt_isSelected==isSelected
		&& img.miwt_state==state){
		return false;
	}

	var newimgsrc;	
	if (isActive){
		if (state=="normal"){
			if (isSelected && img.miwt_activeselected!=null)
				newimgsrc=img.miwt_activeselected;
			else
				newimgsrc=img.miwt_active;
		}
		else if (state=="rollover"){
			newimgsrc=img.miwt_activerollover;
		}else if (state=="pressed"){
			newimgsrc=img.miwt_activepressed;
		}else{
			alert("Invalid button state "+state);
		}
	}else{
		if (state=="normal"){
			if (isSelected && img.miwt_inactiveselected!=null){
				newimgsrc=img.miwt_inactiveselected;
			}else{
				newimgsrc=img.miwt_inactive;
			}
		}else if (state=="rollover"){
			newimgsrc=img.miwt_inactiverollover;
		}else if (state=="pressed"){
			newimgsrc=img.miwt_inactivepressed;
		}else{
			alert("Invalid button state "+state);
		}
	}
	
	img.miwt_isActive=isActive;
	img.miwt_state=state;
	
	if (img.miwt_isActive && img.miwt_isSelected!=isSelected){
		var wasSelected=img.miwt_isSelected,btn;
		img.miwt_isSelected=isSelected;
		
		if (isSelected){
			var group = null;
			if (img.miwt_buttonGroup
				&& (group = miwt.imagebutton.groups[img.miwt_buttonGroup])){
				// unselect others
				group.each(function (btnId) {
					if (btnId != img.id) {
						if (btn = miwt.$(btnId))
							miwt.imagebutton.imageButtonSetState(btn, null, false, "normal");
					}
				});
			}

			img.miwt_valuenode.value=img.miwt_selectedvalue;
		}else{
			img.miwt_valuenode.value="";
		}
	}
	
	if(newimgsrc && typeof(newimgsrc) != 'undefined' && newimgsrc != 'undefined' && newimgsrc!='null'){
		img.src=newimgsrc.src;
		return true;
	}else{
		return false;
	}	
};

miwt.AddSetupHandler([ 'img' ], function ImgBtnSetup(tag, node) {
	if (tag!='img' || !node.className.match(/miwt_image\S*_button/))
		return;
	
	var id = node.id;
	var buttonGroupId = null;
	var match = /miwt_button_group_(\S+)/.exec(node.className);
	if (match)
		buttonGroupId = match[1];
	var valueid = null;
	var selectedvalue = null;
	if (id.match(/_img$/))
	{
		valueid = id.replace(/(_r\d+)*_img$/, "");
		var valuenode = miwt.$(id+"_value");
		if (valuenode)
			selectedvalue = valuenode.firstChild.data;
	}
	
	var img=miwt.$(id);
	if (img==null)
	{
		miwt.warn("There is an error with the generated page, cannot find image button with id '"+id+"'");
		return;
	}
	
	/* Set the variables */
	img.miwt_active=miwt.$(id+"_unselected");
	img.miwt_activeselected=miwt.$(id+"_selected");
	img.miwt_activepressed=miwt.$(id+"_pressed");
	img.miwt_activerollover=miwt.$(id+"_rollover");
	img.miwt_inactive=miwt.$(id+"_unselected_inactive");
	img.miwt_inactiveselected=miwt.$(id+"_selected_inactive");
	img.miwt_inactivepressed=miwt.$(id+"_pressed_inactive");
	img.miwt_inactiverollover=miwt.$(id+"_rollover_inactive");
	img.miwt_valueid=valueid;
	img.miwt_valuenode=miwt.$(valueid);
	img.miwt_selectedvalue=selectedvalue;
	if (img.miwt_code==null)
		img.miwt_code='null';
	img.miwt_isSelected=(img.miwt_valuenode!=null) && (img.miwt_valuenode.value==selectedvalue);
	img.miwt_watch = node.className.match(/miwt_watch/);

	var isActive = (img.miwt_active && img.src == img.miwt_active.src) 
		|| (img.miwt_activeselected && img.src == img.miwt_activeselected.src);
	
	if (buttonGroupId!=null)
	{
		img.miwt_buttonGroup = buttonGroupId;
		var group = miwt.imagebutton.groups[buttonGroupId];
		if (!group)
		{
			group = [];
			miwt.imagebutton.groups[buttonGroupId] = group;
		}
		else
		{
			// clean up
			var bid = null;
			var newa = null;
			for(var i = 0; bid = group[i]; i++) {
				var bobj = miwt.$(bid);
				if (!bobj) {
					if (!newa) {
						newa = [];
						for(var j = 0; j < i; j++)
							newa.push(group[j]);
					}
				}
				else if (newa) {
					newa.push(bobj);
				}
			}
			if (newa) {
				group = newa;
				miwt.imagebutton.groups[buttonGroupId] = group;
			}
		}
		group.push(node.id);
	}
	
	/* Setup the events */
	miwt.observe(img, "mouseover", miwt.imagebutton.imageButtonMouseOver, false);
	miwt.observe(img, "mouseout", miwt.imagebutton.imageButtonMouseOut, false);
	miwt.observe(img, "mousedown", miwt.imagebutton.imageButtonMouseDown, false);
	miwt.observe(img, "mouseup", miwt.imagebutton.imageButtonMouseUp, false);
	miwt.observe(img, "click", miwt.imagebutton.imageButtonMouseClick, false);

	/* Set the initial state */	
	miwt.imagebutton.imageButtonSetState(img, isActive, img.miwt_isSelected, "normal");
});

/**
 * Make an image button active.
 *
 * @param id The ID of the image object.
 */
miwt.imagebutton.imageButtonActivate = function (id){
	var img=miwt.$(id);
	if (img==null){
		//alert("There is an error with the generated page, cannot find image button with id '"+id+"'");
		return;
	}
	
	miwt.imagebutton.imageButtonSetState(img, true, null, img.miwt_state);
};

/**
 * Make an image button inactive.
 *
 * @param id The ID of the image object.
 */
miwt.imagebutton.imageButtonDeactivate = function (id){
	var img=miwt.$(id);
	if (img==null){
		//alert("There is an error with the generated page, cannot find image button with id '"+id+"'");
		return;
	}
	
	miwt.imagebutton.imageButtonSetState(img, false, null, img.miwt_state);
};

} // End conditional eval
if(typeof miwtfield == 'undefined') {
miwtfield = {};

miwt.FieldAction = function(event){
	var element = miwt.element(event);
	var keycode = event.keyCode || event.which;
	if (keycode==10 || keycode==13)
		miwt.ButtonClicked(event);
};

miwt.FieldKeyDownHandler = function (evt){
	miwttimer.rescheduleTimer();
	return true;
};

miwt.FieldKeyUpHandler = function (evt){
	var field=miwt.element(evt);
	if (field.maxlength 
		&& field.maxlength > 0 
		&& field.value.length >= field.maxlength) {
			field.value = field.value.substring(0, field.maxlength);
	}
	return true;
};

miwt.FieldFocusHandler = function (evt) {
	var field=miwt.element(evt);
	miwt.lastFocusId = field.id;

	if (field.hinttexton) {
		field.value = '';
		field.hinttexton = false;
		field.style.color = null;
	}

	return true;
};

miwt.FieldBlurHandler = function (evt){
	var field = (evt.tagName == 'input') ? evt : miwt.element(evt);
	miwt.lastFocusId = null;

	if (field && field.hinttext && field.value == '') {
		field.value = field.hinttext;
		field.hinttexton = true;
		field.style.color = 'gray';
	}

	return true;
};

miwt.prv_FieldSubmitHandler = function (nodeId) {
	var node = miwt.$(nodeId);
	if (node.hinttexton) {
		node.value = '';
		node.hinttexton = false;
		node.style.color = null;
	}
	window.setTimeout("miwt.FieldBlurHandler(miwt.$('"+node.id+"'))", 10, "JavaScript");
	return true;
}

miwt.AddSetupHandler([ 'a', 'input', 'textarea' ], function (tag, node) {
	if ((tag=='input' && node.type=='text') || tag=='textarea')
	{
		miwt.observe(node, "keydown", miwt.FieldKeyDownHandler, true);
		miwt.observe(node, "focus", miwt.FieldFocusHandler, true);
		miwt.observe(node, "blur", miwt.FieldBlurHandler, true);
		var hint = miwt.$(node.id+"_hint");
		if (hint) {
			var hinttext = hint.firstChild.data;
			node.hinttext = hinttext;
			if (node.value == '') {
				node.value = hinttext;
				node.hinttexton = true;
				node.style.color = 'gray';
			}
			var nodeId = node.id;
			node.form.RegisterOnSubmitHandler(node, function(){return miwt.prv_FieldSubmitHandler(nodeId);});
		}
		var maxlength = miwt.$(node.id+"_maxlength");
		if (maxlength) {
			var i = parseInt(maxlength.firstChild.data, 10);
			if (!isNaN(i)) {
				node.maxlength = i;
				miwt.observe(node, "keyup", miwt.FieldKeyUpHandler, true);
			}
		}
		
		if (/\bfckeditor\b/.exec(node.className)) {
			CKeditorHelper.fckactivate(node);
			node.serializeValue=function(f,s,n,v){
				s.push(encodeURIComponent(n) + '=' + encodeURIComponent(CKEDITOR.instances[this.id].getData()));
			};
		}
	}
});

} // End conditional eval
if(typeof miwtsearchablecombo == 'undefined') {
var miwtsearchablecombo = {};

/**
 * Searchable combo box class.
 */
 
miwt.SearchableComboButtonClick = function (event) { 
	miwt.stop(event); 
	miwt.element(event).combo.doSearch(); 
};

miwt.SetupSearchableCombo = function (tag, element){
	if (tag != 'select' || !/\bmiwt_searchable\b/.exec(element.className))
		return;
		
	try
	{
		var field = miwt.$(element.id+"_field");
		field.combo = element;
		miwt.extend(element, miwt.SearchBox.prototype);
		element.initialize(field);
		miwt.observe(field, 'keydown', miwt.SearchableComboKeydownHandler);
		var button = miwt.$(element.id+"_search");
		if (button && !/\bmiwt_submit\b/.exec(button.className))
		{
			// client side search
			button.combo = element;
			miwt.observe(button, 'click', miwt.SearchableComboButtonClick);
			if (field.value && element.mode == element.MODE_FILTER)
				element.doSearch();
		}
	}
	catch (e) { miwt.error("Setup searchable combo "+element.id, e); }
};

miwt.AddSetupHandler([ 'select' ], miwt.SetupSearchableCombo);

miwt.SearchableComboKeydownHandler = function (event) {
	 if (event.keyCode == 13) { 
	 	miwt.stop(event); 
	 	miwt.element(event).combo.doSearch();
	 }
};

miwt.SearchBox = function(){};

miwt.SearchBox.prototype = {
	MODE_ITERATE: 0,
	MODE_FILTER: 1,
	
	initialize: function (field)
	{
		this.field = field;
		this.selectOptions = [];
		var opt,i ;
		for(i = 0; opt = this.options[i]; i++)
			this.selectOptions[i] = opt;
		this.mode = this.MODE_ITERATE;
		var me = this, cns = miwt.words(this.className),i,c;
		for(i=0; i < cns.length; i++) {
			c=cns[i];
			if (/.*_flags_(\w+)/.exec(c)) {
				me.flags = RegExp.$1.toLowerCase();
			} else if (/.*_mode_filter/.test(c)) {
				me.mode = me.MODE_FILTER;
			}
		}
		//miwt.debug("Searchable Combo "+this.id+" inited, flags = "+this.flags+", mode = "+this.mode);
	},
			
	addAvailableOption: function (val, txt) {
		var opt = new Option();
		opt.value = val;
		opt.text = txt;
		this.selectOptions.push(opt);
	},
	getAvailableOptions:  function () {
		return this.selectOptions;
	},
      
	setVisibleOptions: function (visibleOptions) {
		this.options.length = 0;
		var opt;
		for(var i = 0; opt = visibleOptions[i]; i++)
			this.options[i] = opt;
	},
  
	setSelectedIndex: function (index){
		// Doesn't work?
		if(index >= 0 && index < this.options.length)
			this.options[index].selected = true;
	},
        
    doSearch: function(){
    	if (this.mode == this.MODE_ITERATE)
			this.searchSelectIterative(false);
		else
			this.searchSelectFilter(false);
    },
    
	/**
	 * Perform a search on a select element.
	 * @param onlyIfNoMatch If true only change the selection if the current selection doesn't match.
	 */
	searchSelectFilter: function (onlyIfNoMatch){
	        var searchString = this.field.value;
	        var searchTextLength = searchString.length;
	        var allOptions = this.getAvailableOptions();
	        var selectedIndex=0;
	        var matches = [];
	        var matcher = new RegExp(searchString, this.flags);
	
			/*
	        if (onlyIfNoMatch && matcher.test(selectObject.options[selectObject.selectedIndex].text))
	        {
	        	return;
	        }
	        */
	        
	        for (j=0; j <  allOptions.length; j++)
	        {
	                var optionText = allOptions[j].text;
	                if(searchTextLength==0 || matcher.test(optionText))
	                {
	                        matches[matches.length] = allOptions[j];
	                        if (allOptions[j].selected)
	                        {
	                        	selectedIndex=matches.length-1;
	                        }
	                }
	        }
	        this.setVisibleOptions(matches);
	        this.setSelectedIndex(selectedIndex);
	},

	/**
	 * Perform an iterative search on a select element.
	 * @param onlyIfNoMatch If true only change the selection if the current selection doesn't match.
	 */
	searchSelectIterative: function (onlyIfNoMatch){
	       var searchString = this.field.value;
	       var searchTextLength = searchString.length;
	       if(searchTextLength == 0)
	                return;
	       var start = this.selectedIndex + 1;
	       if(start >= this.options.length)
	               start = 0;
	       var end = this.selectedIndex - 1;
	       if(end <= 0)
	               end = this.options.length;
	       var matcher = new RegExp(searchString, this.flags);
	       
	       if (onlyIfNoMatch && matcher.test(this.options[this.selectedIndex].text))
	       {
		       	return;
	       }
	       
	       var forEnd = (start < end ? end : this.options.length);
	       for (j=start; j <  forEnd; j++)
	       {
	               var optionText = this.options[j].text;
	               if(matcher.test(optionText))
	               {
	                       this.selectedIndex = j;
	                       return;
	               }
	       }
	       if(start > end)
	       {
	               for (j=0; j <=  end; j++)
	               {
	                       var optionText = this.options[j].text;
	                       if(matcher.test(optionText))
	                       {
	                               this.selectedIndex = j;
	                               return;
	                       }
	               }
	       }
	}
};

} // End conditional eval
if (typeof miwt.menu == 'undefined') {
(function(){
	var PAT_MENU = /(^|\s)menu(\s|$)/;
	var PAT_MENU_ITEM = /(^|\s)menu_item(\s|$)/;
	var PAT_MENU_COMPONENT = /(^|\s)menu_component(\s|$)/;

	miwt.menu = {};
	miwt.menu.ActiveMenuList = [];
	miwt.menu.ActivateMenu = function(evt) {
		var menu = miwt.up(miwt.element(evt), "div.menu_component");
		if (!menu || miwt.hasClassName(menu, 'active')) return null;

		miwt.addClassName(menu, "active");
		while (miwt.menu.ActiveMenuList.length > 0)
			miwt.menu.DeactivateLastActiveMenu();
		miwt.siblings(menu).each(function(idx, el) {
			if (miwt.up(el, "div.menu_bar") && PAT_MENU_COMPONENT.test(el.className))
				miwt.observe(el, "mouseover", miwt.menu.ShowMenu);
		});
		miwt.menu.ActiveMenuList.push(menu);
		return menu;
	};
	miwt.menu.DeactivateLastActiveMenu = function() {
		var menu = miwt.menu.ActiveMenuList.pop();
		if (!menu) return;
		miwt.removeClassName(menu, "active");
		if (miwt.up(menu, "div.menu_bar")) {
			miwt.stopObserving(menu, "mouseover", miwt.menu.ShowMenu);
			miwt.siblings(menu).each( function(idx, el) {
				miwt.stopObserving(el, "mouseover", miwt.menu.ShowMenu);
			});
		}
	};
	miwt.menu.MenuItemHit = function(evt) {
		miwt.stop(evt);
		var mi = miwt.up(evt, '.menu_item'), li = miwt.up(mi, 'li.menu'),
		 hasSubmenu = miwt.$$('.menu_items', li).length>0;
		if (mi && !hasSubmenu) {
			while (miwt.menu.ActiveMenuList.length > 0) 
				miwt.menu.HideMenu(evt);
			var form = miwt.findElement(evt, 'form');
			form.elements['btnhit'].value = mi.id;
			form.MIWTSubmit();
		}
	};
	miwt.menu.HideMenu = function(evt) {
		if ((evt.keyCode && evt.keyCode != 27/*escape*/) || evt.which == 3 /*right button*/)
			return;
		miwt.stop(evt);
		miwt.menu.DeactivateLastActiveMenu();
		if (miwt.menu.ActiveMenuList.length == 0) {
			miwt.stopObserving(document, "click", miwt.menu.HideMenu);
			miwt.stopObserving(document, "keydown", miwt.menu.HideMenu);
		}
	};
	miwt.menu.ShowMenu = function(evt) {
		var target = miwt.findElement(evt, 'a')
		if (miwt.menu.ActivateMenu(evt)){
			miwt.stop(evt);
			window.setTimeout( function() {
				miwt.observe(document, "click", miwt.menu.HideMenu);
				miwt.observe(document, "keydown", miwt.menu.HideMenu);
			}, 5);
		}
	};
	miwt.AddSetupHandler( [ 'a' ], function(tag, node) {
		if (PAT_MENU_ITEM.test(node.className) && PAT_MENU_COMPONENT.test(node.parentNode.className))
			miwt.observe(node, "click", miwt.menu.ShowMenu);
	});
	miwt.AddSetupHandler( [ 'li' ], function(tag, node) {
		if (PAT_MENU.test(node.className)) {
			miwt.observe(node, 'click', miwt.menu.MenuItemHit);
			if (navigator.userAgent.match(/MSIE 6/)) {
				miwt.observe(node, "mouseenter", function(evt) {miwt.addClassName(miwt.element(evt), 'active');});
				miwt.observe(node, "mouseleave", function(evt) {miwt.removeClassName(miwt.element(evt), 'active');});
			}
		}
	});
})();
} // End conditional eval
if(typeof miwtselectall == 'undefined') {
var miwtselectall = {};

/**
 * Setup a check box will a "select all" check box.
 * @param checkbox the check box.
 */
miwt.setupSelectAllCheckbox = function (checkbox){
	var selectall = miwt.$(checkbox.name+"_all");
	if (!selectall)
		return;
	if (!selectall.checkboxes)
	{
		selectall.checkboxes = [];
		miwt.observe(selectall, "click", miwt.selectAllChanged, false);
	}	
	checkbox.selectall = selectall;
	selectall.checkboxes.push(checkbox);
	miwt.observe(checkbox, "click", miwt.selectAllChildChanged, false);
};

miwt.selectAllChanged = function (event){
	var selectall = miwt.element(event), box,i;
	for(i = 0; box = selectall.checkboxes[i]; i++) {
		box.checked = selectall.checked;
	}
};

miwt.selectAllChildChanged = function (event){
	var box = miwt.element(event);
	if (!box.checked)
		box.selectall.checked=false;
};

miwt.AddSetupHandler([ 'input' ], function (tag, node){
	// table / tree selections
	if (tag=='input' && node.type == 'checkbox' && /\bmiwt_row_select\b/.exec(node.className))
		miwt.setupSelectAllCheckbox(node);
});

} // End conditional eval
/**
 * Functions needed for AJAX support.
 * @author Pat Double <double@i2rd.com>
 */
if(typeof miwtajax == 'undefined') {
var miwtajax={READY_STATE_UNINITIALIZED:0,READY_STATE_LOADING:1,READY_STATE_LOADED:2,
		READY_STATE_INTERACTIVE:3,READY_STATE_COMPLETE:4,
		serial:{},
		ajax_failed_update_callback:[],
		ajax_request_complete_callback:[]};

/**
 * Get the document content type.
 */
miwtajax.getDocContentType=function(){
	var d = document, de = d.documentElement, ct = d.contentType, m, el;
	try{
	if(!ct) {
		m = miwt.array(document.getElementsByTagName('head')[0].getElementsByTagName('meta'));
		while( (el = m.pop()) ) {
			if((el.getAttribute('http-equiv')+'').toLowerCase() == 'content-type'){
				ct = el.getAttribute('content').replace(/;.+/,'');
				break;
			}
		}
		if(!ct) 
			ct = de.getAttribute('xmlns') == 'http://www.w3.org/1999/xhtml' ? 'application/xhtml+xml' : 'text/html';
		// TODO should only treat XMLNS as XHTML if doctype is not HTML (html5).
	  return ct;
	}
	}catch(e){
		return 'text/html';
	}
};
miwtajax.currentSerial = function(form){
	var key=form['wm'].value, val = miwtajax.serial[key];
	if(!val) val = parseInt(form['ajax_serial'].value, 10);
	return val;
};
miwtajax.nextSerial = function(form){
	var key=form['wm'].value, val = miwtajax.serial[key];
	if(!val) val = parseInt(form['ajax_serial'].value, 10);
	miwtajax.serial[key]=(++val);
	return val;
};
/**
 * Presents a progress dialog while waiting for AJAX content to load.
 */
miwtajax.Progress=function() {
	// Create content if not already available
	this.dialog = document.createElement("div");
	this.dialog.innerHTML = '<div class="miwt_ajax_progress" style="position: absolute; top: 100px; left: 100px;">'
		+miwt.$$("dfn.miwt_loading_message").pop().firstChild.data
        + "<div id=\"miwt_loading_message_503\" style=\"display: none;\">" + miwt.$$("dfn.miwt_loading_message503").pop().firstChild.data + "</div>" 
		+'<br /><br />'
		+'<span class="miwt_ajax_progress">'
		+'<span id="miwt_ajax_progress_0">&#x00a0;&#x00a0;&#x00a0;&#x00a0;&#x00a0;</span>'
		+'<span id="miwt_ajax_progress_1">&#x00a0;&#x00a0;&#x00a0;&#x00a0;&#x00a0;</span>'
		+'<span id="miwt_ajax_progress_2">&#x00a0;&#x00a0;&#x00a0;&#x00a0;&#x00a0;</span>'
		+'<span id="miwt_ajax_progress_3">&#x00a0;&#x00a0;&#x00a0;&#x00a0;&#x00a0;</span>'
		+'<span id="miwt_ajax_progress_4">&#x00a0;&#x00a0;&#x00a0;&#x00a0;&#x00a0;</span>'
		+'</span>'
		+'</div>';
	this.dialog.firstChild.style.visibility = 'hidden';
	document.getElementsByTagName("body").item(0).appendChild(this.dialog);
	this.useCount = 0;
};

miwtajax.Progress.prototype={
	start:function(){
		this.useCount++;
		if (this.useCount > 1)
			return; // already running

		var progress = this;
		this.timeout_callback = function() {
			progress.callback.call(progress);
		}
		
		for(var i = miwtajax.READY_STATE_UNINITIALIZED; i <= miwtajax.READY_STATE_COMPLETE; i++)
		{
			var progressNode = miwt.$("miwt_ajax_progress_"+i);
			if (progressNode != null)
				progressNode.style.backgroundColor = 'white';
		}
		if (this.indeterminate)
			this.mark = miwtajax.READY_STATE_UNINITIALIZED;
		
		this.timeout=setTimeout(this.timeout_callback, 500);
	},

	callback:function(){
		if (document.all)
			this.dialog.firstChild.style.position = 'absolute';

		this.dialog.firstChild.style.visibility = 'visible';
		var w=miwt.getWindowWidth();
		var h=miwt.getWindowHeight();
		var scroll = miwt.getScrollOffset();
		this.dialog.firstChild.style.top=(scroll.y+((parseInt(h)/2)-17))+"px";
		this.dialog.firstChild.style.left=(scroll.x+((parseInt(w)/2)-100))+"px";

		if (this.indeterminate) {
			this.mark++;
			if (this.mark > miwtajax.READY_STATE_COMPLETE)
				this.mark = miwtajax.READY_STATE_UNINITIALIZED;
			for(var i = miwtajax.READY_STATE_UNINITIALIZED; i <= miwtajax.READY_STATE_COMPLETE; i++)
			{
				var progressNode = miwt.$("miwt_ajax_progress_"+i);
				if (progressNode != null) {
					if (this.mark == i)
						progressNode.style.backgroundColor = 'lightsteelblue';
					else
						progressNode.style.backgroundColor = 'white';
				}
			}
		}
		
		this.timeout=setTimeout(this.timeout_callback, 300, "JavaScript");
	},
		
	stop:function(){
		if (this.useCount <= 0)
			return; // extraneous stop
			
		this.useCount--;
		if (this.useCount > 0)
			return; // something is still using this
			
		if (this.timeout!=null)
		{
			window.clearTimeout(this.timeout);
			this.timeout = null;
			this.timeout_callback = null;
		}

		this.dialog.firstChild.style.visibility = 'hidden';
	}
};

miwtajax.showFormPostWait = function() {
  	if (miwt.ajaxprogress == null) miwt.ajaxprogress = new miwtajax.Progress();
	miwt.ajaxprogress.indeterminate = true;
	miwt.ajaxprogress.start();
	return miwt.ajaxprogress;
};

/**
 * Create an InputProcessor object to process the miwt form.
 *  @param form the form object.
  * @param opts options. See readme.txt in this directory for more information.
 */
miwtajax.InputProcessor=function(form, opts){
	this.req = null;
	this.opts = opts;
	// multipart implies file upload
	if (form.encoding && form.encoding.match(/multipart/))
	{
		var el, i=0;
		for(; el = form.elements[i++];) {
			if (el.type=='file' && el.value != null && el.value.length > 0)
				return;
		}
	}

	this.form = form;
	this.failsafe = false;

  	if (miwt.ajaxprogress == null) miwt.ajaxprogress = new miwtajax.Progress();

	this.initXMLHttpRequest();
	if (this.req == null) // No XMLHttpRequest object available
	{
	  		// AJAX cannot be used
	  		return;
	}
	
	var sv = opts.serializeValue || miwt.serializeValue, params = opts.serialize 
		? opts.serialize.call(this.form, this.form, sv)
		: miwt.serialize(this.form, sv);
	params += "&ajax="+miwtajax.nextSerial(form);

	// Clear this for the next form submit
	this.form.ResetTransient();

	// setup callback to reload the page if AJAX request times out
	var dotimeout = deploymentcontext ? deploymentcontext.doAjaxTimeout : true;
	if (dotimeout && !miwtajax.debug){
		var ajax = this, to = opts.ajax_to || 15;
		this.timeout_callback = function() {ajax.doFailsafe.call(ajax);}
		this.timeout=setTimeout(this.timeout_callback, (to*1000));
	}

	miwt.ajaxprogress.start();
	if(opts.preUpdate)opts.preUpdate.call(this.form, miwt.ajaxprogress);
		
	// Initiate the asynchronous call
	//miwt.debug("Sending query string to "+this.uri+": "+params);
	this.req.send(params);
};

miwtajax.InputProcessor.prototype={  

	  /**
	   * Create the XMLHttpRequest object. Puts the object into the
	   * 'req' field. The 'req' field will be null if AJAX is not supported.
	   */
	  initXMLHttpRequest:function(){
        var uriEl = miwt.$$("dfn.ajax_uri", this.form).pop();
	  	if (!uriEl || !uriEl.firstChild) // No AJAX URI available
			return;
		this.uri = uriEl.firstChild.data;
		
	  	if (window.XMLHttpRequest){
	  		this.req = new XMLHttpRequest();
	  	}else if (window.ActiveXObject){
	  		this.req = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
	  	if (this.req){
	  		var processor = this;
	  		this.req.onreadystatechange = function() {
	  			processor.handleReadyStateForComponentUpdate.call(processor);
	  		};
	  		this.req.open("POST", this.uri, true);
	  		this.req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	  		this.req.setRequestHeader("X-MIWT-Ajax", "true");
	  		this.req.setRequestHeader("X-DocumentContentType", miwtajax.getDocContentType());
		}
	  },

	  /**
	   * Decompose a node value. If made of "part" nodes, the value
	   * is composed of the parts. Otherwise the node's value is used.
	   */
	  decomposeParts:function(node){
		  	var content="", partNodesFound=false, partnode, j=0,i;
		  	for(; partnode = node.childNodes[j++];){
		  		if (partnode.nodeName=='part') {
		  		    // This will actually be a single text node most of the time, but sometimes firefox splits text nodes in a seemingly arbitrary way. (ken)
					for(i=0; i < partnode.childNodes.length; i++) {
			  			content += partnode.childNodes.item(i).nodeValue;
			  		}		  		
		  			partNodesFound=true;
	  			}
	  		}
		  						
	  		if (!partNodesFound) {
		  		content = node.firstChild.nodeValue;
	  		}
	  						
	  		return content;
	  },
	  	  
	  /**
	   * Handles ready state updates for component content updates.
	   */
	  handleReadyStateForComponentUpdate:function(){
		for(var i = miwtajax.READY_STATE_UNINITIALIZED; i <= this.req.readyState; i++){
			var progressNode = miwt.$("miwt_ajax_progress_"+i);
			if (progressNode != null && progressNode.style.backgroundColor != 'lightsteelblue')
				progressNode.style.backgroundColor = 'lightsteelblue';
		}

		if (this.failsafe) // failsafe was called, do no processing
			return;
					
	  	if (this.req.readyState==miwtajax.READY_STATE_COMPLETE){
		  	delete this.req.onreadystatechange;
		  	this.req.onreadystatechange=function(){}; // IE hack
		  	
	  		if (this.timeout) {
		  		window.clearTimeout(this.timeout);
		  		this.timeout = null;
		  	}
		  		
	  		var failsafe = false, failsafeSkipParam = false, updatedNodes=[], action='failsafe';
	  		processXML:
            if(this.req.status == 503){
            	// server busy
                miwt.ajaxprogress.indeterminate = true;
                miwt.ajaxprogress.mark = miwtajax.READY_STATE_UNINITIALIZED;
                var retryTime = this.req.getResponseHeader("Retry-After") || '30', mesgElement = miwt.$("miwt_loading_message_503");
                mesgElement.style.display = "block";
                mesgElement.innerHTML = mesgElement.innerHTML.replace("$(seconds)", retryTime); 
                var retryTimeMillis = parseInt(retryTime) * 1000, form = this.form, retryFunc = function() {
                	mesgElement.style.display = "none";
                	form.submit();
                };
                window.setTimeout(retryFunc, retryTimeMillis);
                return;
            }else if (this.req.status==301 || this.req.status==302){
	  			// perform redirect
	  			//miwt.debug("Redirect HTTP response: "+this.req.status+" => "+this.req.getResponseHeader("Location"));
		  		miwt.ajaxprogress.stop();
		  		var loc = this.req.getResponseHeader("Location"), data = {
			  			status:this.req.status,
			  			action:'redirect',
			  			location:loc,
			  			success:true,
			  			nodesUpdated:[],
			  			source:this.form
			  		};
		  		if(this.opts.postUpdate) this.opts.postUpdate.call(this.form, data);
	  			this.req=null;
	  			window.location.href=loc;
	  			return;
	  		}else if (this.req.status!=200){
	  			miwt.debug("Unsuccessful HTTP response: "+this.req.status);
	  			failsafe = true;
	  		}else if (/html/.test(this.req.getResponseHeader("Content-Type"))){
	  			// we got HTML for some reason, probably a redirect was not handled during AJAX processing
	  			miwt.debug("Received HTML response: "+this.req.responseText);
	  			failsafe = true;
	  		}else if(this.req.responseXML != null){
	  			//miwt.debug("Received AJAX XML: "+this.req.responseText);
	  			var actionNodes = this.req.responseXML.getElementsByTagName("action"), redirectURL;
	  			action = "reload";
	  			if (actionNodes.length > 0){
	  				var actionNode = actionNodes.item(0); 
	  				action = actionNode.firstChild.nodeValue;
	  				redirectURL = actionNode.getAttribute('url');
	  			}else{
	  				miwt.debug("Received HTML response: "+this.req.responseText);
		  			miwt.error("No action specified");
	  			}
	  			var firstChild = this.req.responseXML.firstChild;
	  			if ( firstChild == null || firstChild.nodeName.toLowerCase() == "html"){
	  				// parsing error
	  				if (miwtajax.debug){
		  				if (firstChild != null){
		  					// output parsing error
			  				var stack = [];
			  				stack.push(firstChild);
			  				while (stack.length > 0){
			  					var node = stack.pop();
			  					if (node.nodeType == 3){
						  			miwt.error("Parse error: "+node.nodeValue);
			  					}else{
			  						for(var i =0; i < node.childNodes.length; i++)
			  							stack.push(node.childNodes.item(i));
			  					}
			  				}
			  			}
		  				break processXML;
	  				}
		  			miwt.error("Parse error. firstChild is " 
	  					+ (firstChild == null ? "null" : (firstChild.nodeName + " -> " + firstChild.innerHTML)));
	  				failsafe = true;
	  			}else if (action=='reload'){
		  			//miwt.debug("Reload action");
	  				failsafe = true;
	  				failsafeSkipParam = true;
	  			}else if (action=='nochange'){
					break processXML;
	  			}else if (action=='update'){
	  				var lastFocusId = miwt.lastFocusId, 
	  				 closeNodes = this.req.responseXML.getElementsByTagName("closewindow");
	  				for(var i = 0; i < closeNodes.length; i++ ) {
		  					var refid = closeNodes.item(i).attributes.getNamedItem("ref").nodeValue;
		  					var n = miwt.$(refid);
		  					if (n) {
		  						miwt.closeWindow(n);
		  					}
	  				}
	  				
	  				// handle content updates
	  				var contentNodes = this.req.responseXML.getElementsByTagName("component"),
	  					preProcessNode=this.opts.preProcessNode,
	  					postProcessNode=this.opts.postProcessNode;
	  				try {
		  				for(var i=0; i<contentNodes.length; i++) {
		  					var iecase,tmpnode, newcontent, newnode, updatenode = contentNodes.item(i), 
		  						refid = updatenode.attributes.getNamedItem("ref").nodeValue,
		  						docnode = miwt.$(refid);
		  					if (docnode == null) {
					  			miwt.info("Node not found: "+refid+", likely caused by update to component that was not rendered here");
		  						failsafe = true;
		  						break;
		  					}
		  					miwt.closeCKEditors(docnode);
	  						newcontent=this.decomposeParts(updatenode);
	  						tmpnode=document.createElement("div");
	  						try {
	  							iecase = miwt.B.IE && (docnode.tagName||'').toUpperCase() == 'TD' && !newcontent.match(/^</);
	  							if(preProcessNode){
	  								newcontent = preProcessNode.call(this.form, {content:newcontent, refid:refid});
	  								if(newcontent == null) continue;
	  							}
		  						if(iecase)
			  						tmpnode.innerHTML = "<span>"+newcontent+"</span>";
			  					else
			  						tmpnode.innerHTML = newcontent;
	  						}catch (exception){
	  	  						miwt.error("Exception creating DOM node from " + newcontent, exception);
	  			  				failsafe = true;
	  			  				break;
	  	  					}
	  						newnode = tmpnode.firstChild;
	  						if (miwt.childElementCount(tmpnode)==1 
	  							&& newnode.nodeName == docnode.nodeName 
	  							&& newnode.getAttribute("id") == docnode.getAttribute("id"))
	  						{
		  						// replace the existing node
			  					//miwt.debug("Replacing "+docnode.nodeName+" node for "+refid+" with "+newcontent.length+" bytes: "+newcontent);
		  						docnode.parentNode.replaceChild(newnode, docnode);
		  						updatedNodes.push(newnode);
	  						}
	  						else
	  						{
	  							// replace all child nodes
			  					//miwt.debug("Replacing child nodes of "+docnode.nodeName+" node for "+refid+" with "+newcontent.length+" bytes: "+newcontent);
	  							// clear the existing node
	  							while (docnode.firstChild!=null)
	  								docnode.removeChild(docnode.firstChild);
	  							// move the new nodes from the tmpnode to the docnode
	  							while (tmpnode.firstChild!=null){
	  								var node = tmpnode.firstChild;
	  								tmpnode.removeChild(node);
	  								docnode.appendChild(node);
	  							}
	  							updatedNodes.push(docnode);
	  							newnode = docnode;
	  						}
	  						if(postProcessNode)postProcessNode.call(this.form, {node:newnode});
		  				}
					}
  					catch (exception)
  					{
  						miwt.error("Exception updating DOM", exception);
		  				failsafe = true;
  					}
					
	  				// handle new windows
	  				var windowNodes = this.req.responseXML.getElementsByTagName("newwindow");
	  				for(var i = 0; i < windowNodes.length; i++ ) {
  						var tmpnode=document.createElement("div"), tmpcontent = this.decomposeParts(windowNodes.item(i));
						if(preProcessNode){	
							tmpcontent = preProcessNode.call(this.form, {content:tmpcontent, refid:null});
							if(tmpcontent == null) continue;
						}
  						tmpnode.innerHTML = tmpcontent;
  						var newnode = tmpnode.firstChild;
  						var windowcon = miwt.$$("form#"+this.form.id+" > div.miwt").pop();
  						if (windowcon) {
  							var refid = windowNodes.item(i).attributes.getNamedItem("ref").nodeValue;
  							var existing = miwt.$(refid);
  							if (existing) {
  								existing.parentNode.replaceChild(newnode, existing);
  							}
  							else {
	  							windowcon.appendChild(newnode);
	  						}
  							updatedNodes.push(newnode);
  							if(postProcessNode)postProcessNode.call(this.form, {node:newnode});
  						}else{
  							failsafe = true;
  						}
	  				}
	  				
  					try	{
	  					miwt.ajaxprogress.stop();
	  					
		  				// handle JS init
		  				var oldloc = window.location.href; // detect page change on window property
		  				var locref = false; // detect page change on script content
		  				var initNodes = this.req.responseXML.getElementsByTagName("jsinit");
		  				for(var i=0; i<initNodes.length; i++){
		  					var node = initNodes.item(i);
		  					var script = this.decomposeParts(node);
		  					locref = locref || script.match(/window\.location\.href/);
		  					//miwt.debug("Executing JS : "+script);
		  					if (window.execScript)
		  						window.execScript(script);
		  					else
			  					window.eval(script);
		  				}
		  				if (locref || oldloc != window.location.href) { // page location has been changed
		  					/*
		  					if (locref)
			  					miwt.debug("Page location changed in script");
			  				else
			  					miwt.debug("Page location changed from "+oldloc+" to "+window.location.href);
			  				*/
		  					return;
		  				}
		  					
		  				// if error during DOM update we need to reload the page but only after processing "jsinit"
		  				if (failsafe)
	  						break processXML;
		  				
		  				// reactivate top window in case underlying window(s) have been updated
		  				if (window.windowlist)
		  					repairWindowsAfterUpdate();

		  				// move focus back
		  				var focusChanged = false;
		  				if (lastFocusId!=null) {
		  					var node = miwt.$(lastFocusId);
		  					if (node!=null && node.focus) {
		  						//miwt.debug("Setting focus back to "+lastFocusId);
                                try {
		  						    node.focus();
		  						    focusChanged = true;
                                } catch(e) {
                                    miwt.info("Unable to reset focus for ID = "+lastFocusId, e);
                                }
		  					}
		  				}
		  				for(var i = 0; i < updatedNodes.length; i++ ) {
		  					var n = updatedNodes[i], w = miwt.up(n, "div.window");
	  						try{__i2rd_domupdate_fire(n);}catch(e){}
		  					miwt.setup(n);
		  					if(w && w != n && w.auto_size_serial !== miwtajax.currentSerial(this.form)){
		  						w.auto_size_serial=miwtajax.currentSerial(this.form);
		  						miwt.autoSizeWindow(w);
		  					}
		  				}
		  				
		  				// the following is a hack for MSIE, sometimes it will not be able to set focus (even by mouse click) if
		  				// an FCK editor is initialized
		  				if (miwt.B.IE) {
			  				var fcklist = miwt.$$('textarea.fckeditor', this.form);
			  				if (!focusChanged && fcklist.length > 0) {
			  					var el, nodes = miwt.$$('input[type="text"]', this.form);
			  					while ((el = nodes.shift())) {
			  						if (el.type != 'hidden' && el.focus) {
			  							var f = function() {
			  								// add onload listener to set the focus on a regular field
			  								for(var i = 0; i < fcklist.length; i++) {
			  									var fck = fcklist[i];
			  									var iframes = miwt.$$('iframe', fck.parentNode);
			  									if (iframes.length == 0) {
				  									window.setTimeout(f, 100);
				  									return;
			  									}
			  									var iframe;
			  									while (iframe = iframes.shift()) {
			  										miwt.observe(iframe, "load", function() {
			  											if(!el.disabled)el.focus(); 
			  										});
			  										// in case the iframe is already loaded
			  										if(!el.disabled)el.focus();
			  									}
			  								}
			  							};
			  							window.setTimeout(f, 100);
			  							break;
			  						}		  							
			  					}
			  				}
		  				}
		  				
		  				// scroll to the top most update
		  				if (updatedNodes.length > 0){
			  				var docHeight, scroll=miwt.getScrollOffset(), clientHeight, scrollBottom, de = document.documentElement, db = document.body;
			  				if (de){
				  				clientHeight = de.clientHeight;
				  				docHeight = de.scrollHeight;
				  				scrollBottom = scroll.y+clientHeight;
			  				}else{
				  				clientHeight = db.clientHeight;
				  				docHeight = db.scrollHeight;
				  				scrollBottom = scroll.y+clientHeight;
			  				}
			  				if(docHeight > clientHeight){
				  				var scrollNode, miny = -1, node, y;
				  				for(var i = 0; node = updatedNodes[i]; i++){
				  					if (!node.id.match(/c_.*/) || !miwt.isInActiveWindow(node))
				  						continue;
				  					y = miwt.cumulativeOffset(node)[1];
			  						//miwt.debug("Top for "+node.id+" is "+y);
				  					if (miny == -1 || y < miny){
				  						miny = y;
				  						scrollNode = node;
				  					}
				  				}
				  					
				  				if (miny != -1 && (miny < scroll.y || miny > scrollBottom)){
				  					if (miny > scrollBottom){
				  						// only scroll what we need to show the change
				  						var targetHeight = scrollNode.offsetHeight;
				  						if (targetHeight < clientHeight){
					  						miny = miny - (clientHeight - targetHeight);
				  						}
				  					}
			  						//miwt.debug("Scrolling to "+miny+" from "+scroll.y);
					  				window.scrollTo(0, miny);
				  				}
				  			}
		  				}
  					}catch (exception){
  						miwt.error("Exception processing updates", exception);
		  				failsafe = true;
  						break processXML;
  					}
	  				
	  				this.form.CleanOnSubmitHandlers();
	  			}else if (action=="error"){
		  			miwt.error("Error occurred during rendering");

	  				// an error occurred while creating the response
	  				var errormessage = "", errormessageNodes = this.req.responseXML.getElementsByTagName("errormessage");
	  				for(var i =0; i<errormessageNodes.length; i++){
	  					if (i>0) errormessage = errormessage + "\n";
	  					errormessage = errormessage + errormessageNodes.item(i).firstChild.nodeValue;
	  				}

	  				var errordetail = "", errordetailNodes = this.req.responseXML.getElementsByTagName("errordetail");
	  				for(var i =0; i<errordetailNodes.length; i++){
	  					if (i>0) errordetail = errordetail + "\n";
	  					errordetail = errordetail + errordetailNodes.item(i).firstChild.nodeValue;
	  				}
	  				var node = document.createElement("div");
	  				node.innerHTML = '<div style="border: solid red 10px; background-color: white; position: fixed; z-index: 9000; top: 10px; left: 10px; padding: 10px; max-width: 800px; max-height: 600px; overflow: scroll;"><div>'+errormessage+'</div><textarea cols="60" rows="10" wrap="off">'+errordetail+'</textarea></div>';
	  				document.getElementsByTagName("body").item(0).appendChild(node);
	  			}else if (action=='redirect'){
	  				if(!redirectURL)
	  					miwt.error("Missing redirect URL.");
	  				else{
	  					var url = this.opts.processRedirect ? this.opts.processRedirect(redirectURL) : redirectURL;
	  					if(url !== false) {
	  						if((typeof url) == 'string') redirectURL = url;
	  						window.location.href = redirectURL;
	  						return;
	  					}
	  				}
	  			}else{
	  				// unknown action code
		  			miwt.error("Unknown action: "+action);
	  				failsafe = true;
	  			}
	  		}else{
	  			miwt.error("Received no content / invalid content from server. Status = " + this.req.status
	  					+ ", ResponseText: " + this.req.responseText);
	  			failsafe = true;
  			}
	  		
	  		try{
				// stop the progress window
		  		miwt.ajaxprogress.stop();
				// enable form processing
				window.miwtReady = 1;
	
				var postUpdateData = {
					  status:this.req.status,
					  action:action,
					  nodesUpdated:updatedNodes,
					  success:true,
					  source:this.form
					};
		  		// Something went wrong, reload the page
		  		if (failsafe){
		  			this.doFailsafe(failsafeSkipParam);
			  		//miwt.debug("MIWT ajax response performed failsafe");
		  		}else{
					// Clear this for the next form submit
					this.form.ResetTransient();
					if(this.opts.postUpdate)
						this.opts.postUpdate.call(this.form, postUpdateData);
				}
		  		this.doRequestCompleteCallback(postUpdateData);
		  		//miwt.debug("MIWT ajax response processed");
	  		}finally{
		  		// free the request object
				this.req = null;
	  		}
	  	}
	  },

	  doRequestCompleteCallback: function(data) {
			var i=0,f;
			for(;f = miwtajax.ajax_request_complete_callback[i++];)
				f.call(this.form, data);
	  },
	  
      /**
       * Fall back to reloading the page.
       */	  
	  doFailsafe:function(skipParam){
			var i=0,f,data = {
			  status:this.req.status,
			  action:'failsafe',
			  nodesUpdated:[],
			  success:false,
			  source:this.form
			};
			for(;f = miwtajax.ajax_failed_update_callback[i++];) {
				if (!f.call(this.form, data)) return;
	  		}
			if(this.opts.postUpdate) this.opts.postUpdate.call(this.form, data);
	  		//miwt.debug("Failsafe: reloading page");
	  		this.failsafe = true;
	  		if(!!skipParam)
	  			window.location.href=this.form.action;
	  		else
	  			window.location.href=this.form.action + (miwt.parseUri(this.form.action).query ? '&' : '?') + "failsafe=true";
  			//this.form.submit();
	  },
	  
	  /**
	   * Check if the request was successfully submitted.
	   */
	  isRequestSubmitted:function(){
	  	return this.req!=null;
	  }
 };
 
 /**
  * Add a callback function when an AJAX update fails. Normal processing is to reload the page, the callback
  * function may allow this normal processing to continue or replace it. The callback should return true to continue with
  * normal processing, false to abort normal processing. The callback is passed an Object argument which has
  * a property named 'source' that is the form object.
  */
miwtajax.addMIWTAJAXUpdateFailureCallback = function (f){
	miwtajax.ajax_failed_update_callback.push(f);
};
 
 /**
  * Remove a callback for AJAX failures. 
  */
miwtajax.removeMIWTAJAXUpdateFailureCallback = function (f){
	miwtajax.ajax_failed_update_callback = miwtajax.ajax_failed_update_callback.without(f);
};
 
  /**
  * Add a callback function when an AJAX update is complete. The callback is passed an Object argument which has
  * a property named 'source' that is the form object.
  */
miwtajax.addMIWTAJAXRequestCompleteCallback = function (f){
	miwtajax.ajax_request_complete_callback.push(f);
};

/**
  * Remove a callback for AJAX completions. 
  */
miwtajax.removeMIWTAJAXRequestCompleteCallback = function (f){
	miwtajax.ajax_request_complete_callback = miwtajax.ajax_request_complete_callback.without(f);
};

} // End conditional eval
if(typeof miwtcardcontainer == 'undefined') {

miwtcardcontainer = {};

/**
 * Code to active a card container card.
 */

/**
 * Called to change the selected card.
 * @param containerId card container ID.
 * @param cardId card ID.
 */
miwt.CardContainerSelect = function (containerId, cardId){
	var container=miwt.$(containerId);
	var i;
	for(i=0; i<container.childNodes.length; i++)
	{
		var node=container.childNodes.item(i);
		if (node.nodeType==1 && node.nodeName.toLowerCase()=="div")
		{
			if (node.id == cardId)
				node.style.display="block";
			else
				node.style.display="none";
		}
	}
};

/**
 * Event handler for card container selector.
 */
miwt.CardContainerSelectEvent = function (event){
	var element = miwt.element(event);
	miwt.CardContainerSelect(element.cardid, element.cardname);
};

/**
 * Called to setup an element for card container select.
 * @param containerId card container ID.
 * @param cardId card ID.
 */
miwt.CardContainerSelectSetup = function (el, containerId, cardId){
	el.cardid = containerId;
	el.cardname = cardId;

	if(el.type){
		switch (el.type.toLowerCase()) 
		{
			case 'checkbox':
			case 'radio':
				miwt.observe(el, 'click', miwt.CardContainerSelectEvent);
				break;
			case 'password':
			case 'text':
			case 'textarea':
			case 'select-one':
			case 'select-multiple':
				miwt.observe(el, 'change', miwt.CardContainerSelectEvent);
				break;
		}
    }
    else
    {
		miwt.observe(element, 'click', miwt.CardContainerSelectEvent);
    }
};

miwt.AddSetupHandler(null, function (tag, node) {
	var match = /miwt_card_(\S+)___(\S+)/.exec(node.className);
	if (match)
		miwt.CardContainerSelectSetup(node, match[1], match[2]);
});

}// End conditional eval
if(typeof miwt.windowTopZIndex == 'undefined') {

// Window management using the DOM, Supports DOM2, IE 5.5 and IE 6.
// Requires an *ImageButton.js file.

// The window being moved
miwt.windowMoveTarget=null;
// Keeps track of the next z-index to allocate
miwt.windowTopZIndex=1;
// The list of windows
miwt.windowlist=[];

miwt.getWindowWidth = function ()
{
	// clientWidth does not include scrollbars, so this is better - viewport size
	if (document.documentElement 
		&& document.documentElement.clientWidth
		&& document.documentElement.clientWidth > 0)
	{
		return document.documentElement.clientWidth;
	}
	else if (document.body 
		&& document.body.clientWidth
		&& document.body.clientWidth > 0)
	{
		return document.body.clientWidth;
	}
	else if (window.innerWidth)
	{
		return window.innerWidth;
	}
	else
	{
		return null;
	}
};

miwt.getWindowHeight = function (){
	// On some browsers the document.body.clientHeight isn't correct, prefer window.innerHeight - viewport size
	if (window.innerHeight
		&& window.innerHeight > 0)
	{
		return window.innerHeight;
	}
	else if (document.documentElement 
		&& document.documentElement.clientHeight
		&& document.documentElement.clientHeight > 0)
	{
		return document.documentElement.clientHeight;
	}
	else if (document.body 
		&& document.body.clientHeight
		&& document.body.clientHeight > 0)
	{
		return document.body.clientHeight;
	}
	else
	{
		return null;
	}
};
miwt.getScrollOffset = function() {
	var x,y,b = document.body, de = document.documentElement;
	if (self.pageYOffset) {
        x = self.pageXOffset;
        y = self.pageYOffset;
	} else {
		if (de && de.scrollTop) {
	        x = de.scrollLeft;
	        y = de.scrollTop;
		} else if (b) {
	        x = b.scrollLeft;
	        y = b.scrollTop;
		}
	}
	return {x:x,y:y};
};

/**
 * Fixes the window list to remove non-existant windows. Modifies
 * miwt.windowlist.
 */
miwt.fixWindowList = function (){
	var newlist = [];
	for(var i = 0; i<miwt.windowlist.length; i++)
	{
		var w = miwt.$(miwt.windowlist[i]);
		if (w != null)
			newlist.push(w.id);
	}
	miwt.windowlist = newlist;
};

miwt.saveWindowPosition = function (winName,topFormName,leftFormName,widthFormName,heightFormName,zorderFormName){
	var win = miwt.$(winName);
	if (win==null)
		return;
		
	var zorder=miwt.$(zorderFormName);
	if (zorder!=null)
		zorder.value=win.style.zIndex;
		
	var top=miwt.$(topFormName);
	if (top!=null)
		top.value=win.style.top;
		
	var left = miwt.$(leftFormName);
	if (left!=null)
		left.value=win.style.left;
	
	var width = miwt.$(widthFormName);
	if (width!=null)
		width.value=win.style.width;
		
	var height = miwt.$(heightFormName);
	if (height!=null)
		height.value=win.style.height;
};

miwt.getWindowForElement = function (el){
	var oel = el,tn;
    while (el!=null){
    	tn = (el.tagName || "").toLowerCase();
    	if(tn == "div")
    	{
			if(miwt.hasClassName(el, 'window') || miwt.hasClassName(el, 'inlinewindow'))
				return el;
    	}

		if (el.parentNode)
			el=el.parentNode;
		else
			el=el.parentElement;
	}
    miwt.error("miwt.getWindowForElement(" + oel + "): Unable to find element parent that is a window.");
	alert("An unexpected error occurred. Try reloading the page.");
	return null;
};

/**
 * Repairs the window state after a document update.
 */
miwt.repairWindowsAfterUpdate = function (){
	var activewindow = null;
	var newlist = [];
	
	// mark all windows as not having the permeating elements hidden, we might have updated
	// FIXME - this breaks things.
	for(i=0; i<miwt.windowlist.length; i++)
	{
		var w = miwt.$(miwt.windowlist[i]);
	    if (w != null)
		{
	    	newlist.push(miwt.windowlist[i]);
			w.miwt_hide_permiating=false;
			if (miwt.isWindowActive(w))
				activewindow = w;
		}
	}
	miwt.windowlist = newlist;
	
	// hide permeating elements as needed
	if (activewindow != null)
		miwt.checkForPermiatingElements(activewindow);
};

miwt.activateWindow = function (object){
	if (miwt.$(object.id+"_title_div")==null)
		return;

	if (object.style.zIndex != miwt.windowTopZIndex) { 
		miwt.windowTopZIndex++;
		object.style.zIndex=miwt.windowTopZIndex;
	}
	
	var title_td = miwt.$(object.id+"_title_td");
	miwt.removeClassName(title_td, "inactivewindowtitle");
	miwt.addClassName(title_td, "activewindowtitle");
	var title_div = miwt.$(object.id+"_title_div");
	miwt.removeClassName(title_div, "inactivewindowtitle");
	miwt.addClassName(title_div, "activewindowtitle");

    if (miwt.$(object.id+"_menu_btn")!=null)
    	miwt.button.imageButtonActivate(object.id+"_menu_btn");
    
    if (miwt.$(object.id+"_minimize_btn")!=null)
	    miwt.button.imageButtonActivate(object.id+"_minimize_btn");
    
    if (miwt.$(object.id+"_maximize_btn")!=null)
	    miwt.button.imageButtonActivate(object.id+"_maximize_btn");
    
    if (miwt.$(object.id+"_close_btn")!=null)
	    miwt.button.imageButtonActivate(object.id+"_close_btn");

    if (object.focusable)
    	miwt.stopObserving(miwt.getWindowContent(object), "mousedown", miwt.activateWindowPassive, false);
    
	var dialog = !!/\bdialog\b/.exec(object.className);
	for(i=0; i<miwt.windowlist.length; i++)
	{
	    if (miwt.windowlist[i]!=object.id)
		{
			var w = miwt.$(miwt.windowlist[i]);
			if (w !=null && w != object) {
			    miwt.deactivateWindow(w);
				if (dialog)
					miwt.disableChildren(w);
			}
		}
	}
	miwt.enableChildren(object);
	// This shouldn't be here but is due to the repairWindowsAfterUpdate function.
	object.miwt_hide_permiating=true;
	// Show SELECTs for MSIE <=6
	miwt.showPermiatingElements(object);
};

miwt.deactivateWindow = function (object){
	if (miwt.$(object.id+"_title_div")==null)
		return;

	var title_td = miwt.$(object.id+"_title_td");
	miwt.removeClassName(title_td, "activewindowtitle");
	miwt.addClassName(title_td, "inactivewindowtitle");
	var title_div = miwt.$(object.id+"_title_div");
	miwt.removeClassName(title_div, "activewindowtitle");
	miwt.addClassName(title_div, "inactivewindowtitle");

    if (miwt.$(object.id+"_menu_btn")!=null)
    	miwt.button.imageButtonDeactivate(object.id+"_menu_btn");
    
    if (miwt.$(object.id+"_minimize_btn")!=null)
	    miwt.button.imageButtonDeactivate(object.id+"_minimize_btn");
    
    if (miwt.$(object.id+"_maximize_btn")!=null)
	    miwt.button.imageButtonDeactivate(object.id+"_maximize_btn");
    
    if (miwt.$(object.id+"_close_btn")!=null)
	    miwt.button.imageButtonDeactivate(object.id+"_close_btn");
    
    if (object.focusable)
		miwt.observe(miwt.getWindowContent(object), "mousedown", miwt.activateWindowPassive, false);
}

miwt.closeWindow = function (object) {
	var dialog = !!/\bdialog\b/.exec(object.className);
	miwt.closeCKEditors(object);
	object.parentNode.removeChild(object);
	miwt.repairWindowsAfterUpdate();
	if (miwt.windowlist.length > 0) {
		var top = miwt.$(miwt.windowlist[0]);
		if (!top) {
			miwt.error("miwt.closeWindow: Expecting top window at miwt.windowlist[0], got null");
			return;
		}
		if (dialog)
			miwt.enableChildren(top);
		for(i=1; i<miwt.windowlist.length; i++)
		{
			var w = miwt.$(miwt.windowlist[i]);
			if (dialog)
				miwt.enableChildren(w);
			if (w && w.style.zIndex > top.style.zIndex)
				top = w;
		}	
		miwt.activateWindow(top);
	}
};

miwt.isWindowActive = function (object){
	// special check if this is an inline window
	if (object.className.match(/inlinewindow/) && miwt.windowlist.length == 1)
	{
		// if no other windows are active then this one is.
		for(i=0; i<miwt.windowlist.length; i++)
		{
		    if (miwt.windowlist[i]!=object.id)
			{
				var otherwindow=miwt.$(miwt.windowlist[i]);
				if (!otherwindow.className.match(/inlinewindow/))
				{
					var titletd=miwt.$(otherwindow.id+"_title_td");
					if (titletd != null && titletd.className.match(/activewindowtitle/))
						return false;
				}
			}
		}
		return true;
	}
	
	var titletd=miwt.$(object.id+"_title_td");
	if (titletd==null)
	{
		return false;
	}
	
	return !!titletd.className.match(/activewindowtitle/);
};

miwt.getWindowContent = function (object){
	return miwt.$(object.id+"_content_div");
};

/**
 * Returns true if the activewindow overlaps the otherwindow.
 */
miwt.isWindowOverlapped = function (activewindow, otherwindow){
	if (otherwindow.className.match(/inlinewindow/))
		return true;
		
	var activeTop=parseInt(activewindow.style.top);
	var activeLeft=parseInt(activewindow.style.left);
	var activeBottom=activeTop+parseInt(activewindow.offsetHeight);
	var activeRight=activeLeft+parseInt(activewindow.offsetWidth);
	
	var otherTop=parseInt(otherwindow.style.top);
	var otherLeft=parseInt(otherwindow.style.left);
	var otherBottom=otherTop+parseInt(otherwindow.offsetHeight);
	var otherRight=otherLeft+parseInt(otherwindow.offsetWidth);
	
	if (activeTop>otherBottom) return false;
	if (activeBottom<otherTop) return false;
	if (activeLeft>otherRight) return false;
	if (activeRight<otherLeft) return false;
	
	/*alert("Window "+activewindow.id+" ("+activeTop+","+activeLeft+","+activeBottom+","+activeRight+") and window "+otherwindow.id+" ("+otherTop+","+otherLeft+","+otherBottom+","+otherRight+") overlap");*/
	
	return true;
};

/**
 * Shows/hides permitating form elements as necesary.
 * @param activewindow The active window object.
 */
miwt.checkForPermiatingElements = function (activewindow){
	for(i=0; i<miwt.windowlist.length; i++)
	{
	    if (miwt.windowlist[i]!=activewindow.id)
		{
			var otherwindow=miwt.$(miwt.windowlist[i]);
			if (otherwindow!=null)
			{
				if (miwt.isWindowOverlapped(activewindow, otherwindow))
				    miwt.hidePermiatingElements(otherwindow);
				else
				    miwt.showPermiatingElements(otherwindow);
			}
		}
	}

	miwt.showPermiatingElements(activewindow);
};

miwt.beginWindowMove = function (evt){
	miwt.windowMoveTarget=miwt.getWindowForElement(miwt.element(evt));
	if (miwt.windowMoveTarget==null)
	    return;
	miwt.stop(evt);
	var p = miwt.pointer(evt);
	miwt.lastWindowX=p.x;
	miwt.lastWindowY=p.y;
	miwt.observe(document, "mousemove", miwt.doWindowMove, true);
	miwt.observe(document, "mouseup", miwt.endWindowMove, true);
	var td = miwt.$(miwt.windowMoveTarget.id+"_title_td");
	miwt.lastWindowCursor = td.style.cursor;
	td.style.cursor='move';
	miwt.lastDocumentCursor = document.body.style.cursor;
	document.body.style.cursor='move';

	var activate = true,i,mzi=miwt.windowMoveTarget.style.zIndex,w;
	if(mzi != miwt.windowTopZIndex)
	{
		for(i=0; i<miwt.windowlist.length && activate; i++)
		{
			w = miwt.$(miwt.windowlist[i]);
			if (w !=null && w.className.match(/\bdialog\b/) && w.style.zIndex > mzi) {
			    activate = false;
			}
		}
	}

	if(activate) miwt.activateWindow(miwt.windowMoveTarget);
	miwt.$(miwt.windowMoveTarget.id+"_content_div").style.visibility="hidden";
};

miwt.getWindowPositionDelta=function(w, p){
	var dx=p.x-miwt.lastWindowX, dy=p.y-miwt.lastWindowY;
	return {dx:dx,dy:dy,distance:(Math.sqrt(Math.pow(dx,2) + Math.pow(dy,2)))};
};
miwt.updateLastWindowPosition=function(p){
	miwt.lastWindowX=p.x;
	miwt.lastWindowY=p.y;
	miwt.lastWindowTime=new Date().getMilliseconds();
};
miwt.doWindowMove = function (evt, force){
	miwt.stop(evt);
	var w = miwt.windowMoveTarget, p = miwt.pointer(evt), td = new Date().getMilliseconds()-miwt.lastWindowTime, 
		delta=miwt.getWindowPositionDelta(w,p);
	force = force || Math.abs(delta.distance) > 10 || td > 75;
	var f = function windowMove(){
		miwt.moveWindowRelative(w, delta);
		miwt.updateLastWindowPosition(p);
	};
	if(force) 
		f();
};
miwt.moveWindowRelative = function (w,delta){
	var x = parseInt(w.style.left)+delta.dx, y = parseInt(w.style.top)+delta.dy;
	w.style.left=x+"px";
	w.style.top=y+"px";
};
miwt.endWindowMove = function (evt){
	miwt.stopObserving(document, "mousemove", miwt.doWindowMove, true);
	miwt.stopObserving(document, "mouseup", miwt.endWindowMove, true);
	miwt.doWindowMove(evt, true);
	miwt.$(miwt.windowMoveTarget.id+"_title_td").style.cursor=miwt.lastWindowCursor;
	document.body.style.cursor=miwt.lastDocumentCursor;
	miwt.$(miwt.windowMoveTarget.id+"_content_div").style.visibility="visible";
	miwt.stop(evt);
	miwt.checkForPermiatingElements(miwt.windowMoveTarget);
	miwt.windowMoveTarget=null;
};

miwt.beginWindowResize = function (evt){
	var target = miwt.element(evt);
	miwt.windowResizeTarget=miwt.getWindowForElement(target);
	if (miwt.windowResizeTarget==null)
	    return;
	
	miwt.stop(evt);
	miwt.updateLastWindowPosition(miwt.pointer(evt));
	miwt.windowResizeDir=target.resizeDir;
	
	miwt.observe(document, "mousemove", miwt.doWindowResize, true);
	miwt.observe(document, "mouseup", miwt.endWindowResize, true);
	
	miwt.activateWindow(miwt.windowResizeTarget);
};

miwt.doWindowResize = function (evt){
	miwt.$(miwt.windowResizeTarget.id+"_content_div").style.visibility="hidden";

	var p = miwt.pointer(evt);
	var difX=p.x-miwt.lastWindowX;
	var difY=p.y-miwt.lastWindowY;

	var object=miwt.windowResizeTarget;
	var top=parseInt(object.style.top);
	var left=parseInt(object.style.left);
	var width=parseInt(object.style.width);
	var height=parseInt(object.style.height);
	
	var table=miwt.$(miwt.windowResizeTarget.id+"_table");
	var tableWidth=parseInt(table.style.width);
	var tableHeight=parseInt(table.style.height);
	
	var content=miwt.$(miwt.windowResizeTarget.id+"_content_div");
	var contentWidth=parseInt(content.style.width);
	var contentHeight=parseInt(content.style.height);
	
	if (miwt.windowResizeDir=="ne") {
		width=width+difX;
		height=height-difY;
		tableWidth=tableWidth+difX;
		tableHeight=tableHeight-difY;
		contentWidth=contentWidth+difX;
		contentHeight=contentHeight-difY;
		top=top+difY;
	}else if (miwt.windowResizeDir=="nw") {
		width=width-difX;
		height=height-difY;
		tableWidth=tableWidth-difX;
		tableHeight=tableHeight-difY;
		contentWidth=contentWidth-difX;
		contentHeight=contentHeight-difY;
		left=left+difX;
		top=top+difY;
	}else if (miwt.windowResizeDir=="se") {
		width=width+difX;
		height=height+difY;
		tableWidth=tableWidth+difX;
		tableHeight=tableHeight+difY;
		contentWidth=contentWidth+difX;
		contentHeight=contentHeight+difY;
	}else if (miwt.windowResizeDir=="sw") {
		width=width-difX;
		height=height+difY;
		tableWidth=tableWidth-difX;
		tableHeight=tableHeight+difY;
		contentWidth=contentWidth-difX;
		contentHeight=contentHeight+difY;
		left=left+difX;
	}else {
		alert("Internal error in window resize, I don't know which direction you are resizing.");
		miwt.endWindowResize(evt);
	}

	object.style.top=top+"px";
	object.style.left=left+"px";
	object.style.width=width+"px";
	object.style.height=height+"px";
	
	table.style.width=tableWidth+"px";
	table.style.height=tableHeight+"px";
	
	content.style.width=contentWidth+"px";
	content.style.height=contentHeight+"px";
};

miwt.endWindowResize = function (evt){
	miwt.stopObserving(document, "mousemove", miwt.doWindowResize, true);
	miwt.stopObserving(document, "mouseup", miwt.endWindowResize, true);
	miwt.$(miwt.windowResizeTarget.id+"_content_div").style.visibility="visible";
	miwt.stop(evt);
	
	miwt.checkForPermiatingElements(miwt.windowMoveTarget);
	miwt.windowResizeTarget=null;
};

/** Prevents a window from getting focus. */
miwt.disableWindowActivation = function (evt){
	miwt.stop(evt);
};

miwt.enableChildren = function (root) {
	miwt.disableChildren(root, false);
};

miwt.disableChildren = function (root, disable) {
	if (root==null || !root.hasChildNodes() || miwt.IsIterationStopNode(root))
		return;
	
	if (typeof disable == 'undefined')
		disable = true;
	var i;
	for(i=0; i<root.childNodes.length; i++)
	{
		var node=root.childNodes.item(i);
		if (node.nodeType==Node.ELEMENT_NODE)
		{
			if (node.hasAttributes)
			{
				if (node.hasAttributes())
				{
					if (disable) {
						if (!node.hasAttribute("disabled")) {
							node.wedisabled = true; 
							node.setAttribute("disabled", "true");
						}	
					} else {
						if (node.wedisabled) {
							node.wedisabled = false;
							node.removeAttribute("disabled");
						}
					}
				}
			}
			else
			{
				if (disable) {
					if (node.disabled) {
						node.wedisabled = true;
						node.disabled = disable;
					}
				} else {
					if (node.wedisabled) {
						node.wedisabled = false;
						node.disabled = false;
					}
				}
			}
			
			miwt.disableChildren(node, disable);
		}
	}
};

miwt.activateWindowPassive = function (evt){
	var win = miwt.getWindowForElement(miwt.element(evt));
	if (win==null)
	    return;
	
	if (!miwt.isWindowActive(win))
	{
		miwt.activateWindow(win);
		miwt.checkForPermiatingElements(win);
	}
};

miwt.setAbsoluteWidth = function (object){
	var width=parseInt(object.offsetWidth, 10);
	var height=parseInt(object.offsetHeight, 10);
	
	object.style.width=width+"px";
	object.style.height=height+"px";
};

/**
 * Set the initial position of the window if needed.
 * @param windowObject the window object.
 */
miwt.setInitialPosition = function (windowObject){
	if (windowObject.className.match(/inlinewindow/))
		return;
		
	if (!windowObject.style.top || windowObject.style.top=="")
	{
		var scroll = miwt.getScrollOffset();
		var initialTop = scroll.y + 10;

		if (windowObject.className.match(/dialog/)) {
			var height = miwt.getComputedStyle(windowObject, "height");
			if (height.match(/px/)) {
				height = parseInt(height);
				if (height < miwt.getWindowHeight())
					initialTop = scroll.y + (miwt.getWindowHeight() - height)/2;
			}
			else if (height.match(/%/)) {
				height = parseInt(height);
				if (height > 0)
					initialTop = scroll.y + (miwt.getWindowHeight() * (1 - height/100))/2;
			} else {
				height = windowObject.offsetHeight;
				if (height < miwt.getWindowHeight())
					initialTop = scroll.y + (miwt.getWindowHeight() - height)/2;
			}
		}

		// check for overlap
		for(i=0; i<miwt.windowlist.length; i++)
		{
		    if (miwt.windowlist[i]!=windowObject.id)
			{
				var otherwindow=miwt.$(miwt.windowlist[i]);
				if (otherwindow.style.top 
					&& otherwindow.style.top != ''
					&& Math.abs(parseInt(otherwindow.style.top) - initialTop)<30)
				{
					initialTop += 30;
				}
			}
		}
		
		windowObject.style.top = initialTop + "px";
	}

	if (!windowObject.style.left || windowObject.style.left=="")
	{
		var scroll = miwt.getScrollOffset();
		var initialLeft = scroll.x + 10;
			
		if (windowObject.className.match(/dialog/)) {
			var width = miwt.getComputedStyle(windowObject, "width");
			if (width.match(/px/)) {
				width = parseInt(width);
				if (width < miwt.getWindowWidth())
					initialLeft = scroll.x + (miwt.getWindowWidth() - width)/2;
			}
			else if (width.match(/%/)) {
				width = parseInt(width);
				if (width > 0)
					initialLeft = scroll.x + (miwt.getWindowWidth() * (1 - width/100))/2;
			} else {
				width = windowObject.offsetWidth;
				if (width < miwt.getWindowWidth())
					initialLeft = scroll.x + (miwt.getWindowWidth() - width)/2;
			}
		}

		// check for overlap
		for(i=0; i<miwt.windowlist.length; i++)
		{
		    if (miwt.windowlist[i]!=windowObject.id)
			{
				var otherwindow=miwt.$(miwt.windowlist[i]);
				if (otherwindow.style.left 
					&& otherwindow.style.left != ''
					&& Math.abs(parseInt(otherwindow.style.left) - initialLeft)<30)
				{
					initialLeft += 30;
				}
			}
		}
		
		windowObject.style.left = initialLeft + "px";
	}
};

/**
 * Ensure the listener for passive activation is added to the window object.
 * @param windowObject the window object.
 */
miwt.ensurePassiveWindowActivation = function (windowObject){
	var windowContent=miwt.$(windowObject.id+"_content_div");
	miwt.stopObserving(windowContent, "mousedown", miwt.activateWindowPassive, false);
	miwt.observe(windowContent, "mousedown", miwt.activateWindowPassive, false);
}

/**
 * Call this method with the name of each window to setup window management.
 *
 * @param name			The ID of the window.
 * @param resizable		Flag if the window can be resized, true or false.
 * @param zindex		The initial zindex of the window.
 * @param focusable		Set whether this window can get focus, true or false.
 * @param moveable		Set whether this window can move, true or false.
 */
miwt.setupWindow = function (name, resizable, zindex, focusable, moveable){
	miwt.fixWindowList();
	
	var alreadyInList = false;
	for(var i = 0; i<miwt.windowlist.length; i++)
	{
		if (miwt.windowlist[i] == name)
		{
			alreadyInList = true;
			break;
		}
	}
	
	if (!alreadyInList)
	    miwt.windowlist.push(name);
	
	var windowObject=miwt.$(name);
	var windowTitle=miwt.$(name+"_table");
	// TODO: windowTable is now the titlebar - update refs to windowTable
	var windowTable=miwt.$(name+"_table");
	var windowContent=miwt.$(name+"_content_div");
    var title=miwt.$(name+"_title_td");
    var active=miwt.isWindowActive(windowObject);

	//miwt.debug("setupWindow for "+windowObject.id);

	if (zindex > miwt.windowTopZIndex)
	{
		miwt.windowTopZIndex=zindex;
	}

	windowObject.focusable=focusable;
		
	if (focusable)
	{
		if (!active)
		{	
			miwt.ensurePassiveWindowActivation(windowObject);
		}
		else if (!windowObject.className.match(/inlinewindow/))
		{
			// ensure inline windows get the passive activation listener
			for(i=0; i<miwt.windowlist.length; i++)
			{
				var otherwindow=miwt.$(miwt.windowlist[i]);
				if (otherwindow.className.match(/inlinewindow/))
				{
					miwt.ensurePassiveWindowActivation(otherwindow);
				}
			}
		}
		
		if (moveable)
		{
			miwt.observe(title, "mousedown", miwt.beginWindowMove, true);
		}
	
		if (resizable)
		{	
			setAbsoluteWidth(windowContent);
			setAbsoluteWidth(windowTable);
			setAbsoluteWidth(windowObject);
			
			var resize;
			
			resize=miwt.$(name+"_windowresize_nw_div");
			miwt.observe(resize, "mousedown", miwt.beginWindowResize, false);
			resize.resizeDir="nw";
			resize=miwt.$(name+"_windowresize_ne_div");
			miwt.observe(resize, "mousedown", miwt.beginWindowResize, false);
			resize.resizeDir="ne";
			resize=miwt.$(name+"_windowresize_sw_div");
			miwt.observe(resize, "mousedown", miwt.beginWindowResize, false);
			resize.resizeDir="sw";
			resize=miwt.$(name+"_windowresize_se_div");
			miwt.observe(resize, "mousedown", miwt.beginWindowResize, false);
			resize.resizeDir="se";
		}
	}
	else
	{
		miwt.observe(windowObject, "mousedown", miwt.disableWindowActivation, true);
		miwt.disableChildren(windowObject);
	}
	
	// Handle initial visibility of permiating elements
	for(i=0; i<miwt.windowlist.length; i++)
	{
	    if (miwt.windowlist[i]!=windowObject.id)
		{
			var otherwindow=miwt.$(miwt.windowlist[i]);
			if (otherwindow!=null
				&& miwt.isWindowOverlapped(windowObject, otherwindow))
			{
			    if (active)
			    {
					//miwt.debug("Hiding elements for "+otherwindow.id+" (other)");
				    miwt.hidePermiatingElements(otherwindow);
			    }
			    else
			    {
					//miwt.debug("Hiding elements for "+windowObject.id+" (me)");
				    miwt.hidePermiatingElements(windowObject);
				}			    
			}
		}
	}
	
	if (active)
	{
		//miwt.debug("Showing elements for "+windowObject.id);
		miwt.showPermiatingElements(windowObject);
	}

	if (!miwt.hasClassName(windowObject, "inlinewindow"))
	{
		var form = miwt.up(windowObject, 'form');
		var funcArg = name;
		form.RegisterOnSubmitHandler(windowObject, function(){return miwt.prv_saveWindowPosition(funcArg)});
		miwt.autoSizeWindow(windowObject, windowContent, windowTitle);
	}

	// Handle initial position
	miwt.setInitialPosition(windowObject);
	
	if (active || !miwt.hasClassName(windowObject, "dialog"))
		miwt.activateWindow(windowObject);
};

miwt.autoSizeWindow = function(windowObject, windowContent, windowTitle) {
	if(miwt.isResizable(windowObject) || !windowObject)
		return;
	// Set window content height if height isn't specified and content size is greater than window height
	var wos=windowObject.style, hasHeight = miwt.hasCSSRule(windowObject, 'height', 'auto');
	if(!hasHeight || !!windowObject.autosized) // If no height set or it's set by this method.
	{
		//miwt.info("Auto sizing window " + windowObject.id);
		wos.top='0px';
		wos.left='0px';
		windowContent = windowContent || miwt.$(windowObject.id+"_content_div");
		var hb = windowContent.offsetTop,
			contentNode=windowContent.firstChild;
		/* Workaround for min sizing on ie. */
		if(navigator.userAgent.match(/MSIE 7/)) contentNode.style.minHeight="2em";
		
		windowTitle = windowTitle || miwt.$(windowObject.id+"_table");
		var childH=0, hh = false, h = miwt.getWindowHeight() - 40, i, el, list=miwt.children(contentNode),	cnh = 0;
		for(i=0;el=list[i++];) childH += miwt.height(el);
		for(i=0,list=[windowContent, contentNode];el=list[i++];) {
			cnh = Math.max(cnh, miwt.height(el));
			if(miwt.hasCSSRule(el, 'height', '100%')) {
				hh = true;
				break;
			}
		}
		if(!hh)	cnh = Math.max(cnh, childH);
		if(cnh > 0){
			var ih = cnh + hb;
			if(ih > h) ih = h;
			if(ih > windowObject.offsetHeight)
				windowObject.style.height = ih + "px";
			else if(windowObject.autosized && (cnh +  40) < windowObject.offsetHeight)
				windowObject.style.height = (cnh + hb) + "px";
			
			// This, autosized, should get replaced if the whole window is updated due to a Dimension change on Window.java or a content change.
			windowObject.autosized = true;
		}
		wos.top='';
		wos.left='';
		miwt.setInitialPosition(windowObject);
	} 
	/*else {
		miwt.info("Auto sizing window " + windowObject.id + " disabled");
	}*/
};

miwt.prv_saveWindowPosition = function () {
	  miwt.saveWindowPosition(this+'', 
		   this+'_windowTop',
		   this+'_windowLeft',
		   this+'_windowWidth',
		   this+'_windowHeight',
		   this+'_windowZOrder');
	return true;
};

miwt.isWindow = function (node) {
	if (!node || !node.className)
		return false;
	return !!/\bwindow\b/.exec(node.className);
};

miwt.isInlineWindow = function (node) {
	if (!node || !node.className)
		return false;
	return !!/\binlinewindow\b/.exec(node.className);
};

miwt.isInActiveWindow = function (node) {
	var win = miwt.getWindowForElement(node);
	if (!win)
		return false;
	return miwt.isWindowActive(win);
};

miwt.AddSetupHandler([ 'div' ], function (tag, node)
{
	var isWindow = miwt.isWindow(node);
	var isInlineWindow = miwt.isInlineWindow(node);
	if (isWindow || isInlineWindow)
	{
		miwt.setupWindow(node.id,
			miwt.isResizable(node),  // resizable
			miwt.getComputedStyle(node, 'z-index') || 0,  // z-index
			true, // focusable
			!isInlineWindow // moveable
		);
	}
});

miwt.isResizable = function(node) {
	return node && miwt.$(node.id+"_windowresize_nw_div")!=null
};

}// End conditional eval
if(typeof miwtpermiating == 'undefined') {
var miwtpermiating = {};

miwt.elementPermiatingNone = [];
miwt.elementPermiatingIE6 = [ 'select' ];

// this doesn't effect functionality, only visuals so it's OK to not be totally correct
miwt.elementPermiating=miwt.elementPermiatingNone;
if (navigator.userAgent.match(/MSIE [456]/))
	miwt.elementPermiating=miwt.elementPermiatingIE6;

miwt.isElementPermiating = function (node) {
	if (!node.tagName) return false;
	var tag = node.tagName.toLowerCase(), t, i=0;
	for(; t = miwt.elementPermiating[i++];)
		if (tag == t) return true;
	return false;
};

/**
 * Hide the permeating form elements that are children of the given object.
 */
miwt.hidePermiatingElements = function (object){
	if (object.miwt_hide_permiating==true)
		return;

	object.miwt_hide_permiating=true;

	var el, node, i=0, nodes,j;
	for(; el = miwt.elementPermiating[i++];) {
		nodes = object.getElementsByTagName(el);
		for(j = 0; node = nodes[j++];) node.style.visibility="hidden";
	}
};

/**
 * Show the permeating form elements that are children of the given object.
 */
miwt.showPermiatingElements = function (object){
	if (object.miwt_hide_permiating==false)
		return;

	object.miwt_hide_permiating=false;

	var el, node, i=0, j, nodes, p;
	for(; el = miwt.elementPermiating[i++];) {
		nodes = object.getElementsByTagName(el);
		nodeLoop:
		for(j = 0; node = nodes[j++];) {
			// check if parent visibility is set
			p = node.parentNode;
			while (p) {
				if (miwt.isVisibilitySet(p)) {
					try {
						node.style.visibility=null;
						break nodeLoop;
					} catch (e) { }
				}
				p = p.parentNode;
			}
			node.style.visibility="visible";
		}
	}
};

/**
 * Check if the given node has the visibility style set.
 * @param node the node.
 * @return true or false.
 */
miwt.isVisibilitySet = function (node){
	var s = node.style;
	return (s && (s.visibility||'') != '');
};

/**
 * Check if the DOM node is one in which we can stop an iteration as it
 * inherits the properties from the parent that we want to set.
 * @param object A DOM node.
 * @return true if we should stop iteration on this node.
 */
miwt.IsIterationStopNode = function (object){
	return object.nodeName=="SELECT" || object.nodeName=="select";
};

} // End conditional eval
if(typeof miwtcollapsible == 'undefined') {
var miwtcollapsible = {};
/**
 * Provides methods for collapsing and expanding a CollapsableContainer.
 */

miwt.collapsableContainerToggle = function (collapseFormKey,containerDivId,triggerId,anchor,inline) {
	var formElement=miwt.$(collapseFormKey);
	if (formElement==null)
		return;
	
	if (formElement.value=="true") {
		miwt.prv_collapsableContainerShow(containerDivId,triggerId,anchor,inline);
		formElement.value="false";
	}
	else if (formElement.value=="false") {
		miwt.prv_collapsableContainerHide(containerDivId,triggerId,inline);
		formElement.value="true";
	}
};

miwt.prv_collapsableContainerShow = function (containerDivId,triggerId,anchor,inline) {
	var divObject=miwt.$(containerDivId);
	if (divObject==null)
		return;
	
	var triggerObject=miwt.$(triggerId);
	
	if (triggerObject!=null) {
		var pos = miwt.cumulativeOffset(triggerObject);

		/* Set top */
		if (anchor.indexOf("south")>=0) {
			if (anchor=="south") {
				divObject.style.left=pos[0]+"px";
				divObject.style.top=(pos[1]+triggerObject.offsetHeight)+"px";
			}
			else {
				divObject.style.top=pos[1]+"px";
			}	
		}
		
		/* Set left */
		if (anchor.indexOf("east")>=0) {
			divObject.style.left=(pos[0]+triggerObject.offsetWidth)+"px";

			if (anchor=="east")
				divObject.style.top=pos[1]+"px";
		}

		/* Set bottom */
		if (anchor.indexOf("north")>=0) {
			if (anchor=="north") {
				divObject.style.left=pos[0]+"px";
				divObject.style.top=(pos[1]-divObject.offsetHeight)+"px";
			}
			else {
				divObject.style.top=((pos[1]+triggerObject.offsetHeight)-divObject.offsetHeight)+"px";
			}
		}

		/* Set right */
		if (anchor.indexOf("west")>=0) {
			divObject.style.left=(pos[0]-divObject.offsetWidth)+"px";

			if (anchor=="west")
				divObject.style.top=pos[1]+"px";
		}

		miwt.removeClassName(triggerObject, "miwt_collapsable_hidden");
		miwt.removeClassName(triggerObject.parentNode, "miwt_collapsable_hidden");
		miwt.addClassName(triggerObject, "miwt_collapsable_shown");
		miwt.addClassName(triggerObject.parentNode, "miwt_collapsable_shown");
	}
	
	miwt.removeClassName(divObject, "miwt_collapsable_hidden");
	miwt.addClassName(divObject, "miwt_collapsable_shown");

	if (inline)
		divObject.style.display="inline";
	else
		divObject.style.visibility="visible";
		
	// hide all exclusive containers
	if (miwt.hasClassName(triggerObject, "miwt_collapsable_exclusive"))
	{
		var el, list;
		list = miwt.$$('.miwt_collapsable_exclusive');
		while (el = list.pop()) {
			if (el.div && el.div != divObject) {
				miwt.prv_collapsableContainerHide(el.div.id,el.id,el.disposition.toLowerCase()=='inline');
				el.state.value="true";
			}
		}
	}
};

miwt.prv_collapsableContainerHide = function (containerDivId,triggerId,inline){
	var divObject=miwt.$(containerDivId);
	if (divObject==null)
		return;
	
	if (inline)
		divObject.style.display="none";
	else
		divObject.style.visibility="hidden";
		
	miwt.removeClassName(divObject, "miwt_collapsable_shown");
	miwt.addClassName(divObject, "miwt_collapsable_hidden");

	var triggerObject = miwt.$(triggerId);
	if (triggerObject != null) {
		miwt.removeClassName(triggerObject, "miwt_collapsable_shown");
		miwt.removeClassName(triggerObject.parentNode, "miwt_collapsable_shown");
		miwt.addClassName(triggerObject, "miwt_collapsable_hidden");
		miwt.addClassName(triggerObject.parentNode, "miwt_collapsable_hidden");
	}
};

miwt.collapseContainerToggle = function (event) {
	miwt.stop(event);
	var element = miwt.element(event) || event;
	miwt.collapsableContainerToggle(element.state.name,element.div.id,element.id,element.anchor,element.disposition.toLowerCase()=='inline');
};

miwt.AddSetupHandler([ 'button', 'a', 'img' ], function (tag, node) {
	// collapsable container
	var match = /miwt_collapsable_(\w+)_(\w+)/.exec(node.className);
	if (match) {
		node.anchor = match[1];
		node.disposition = match[2];
		node.div = miwt.$(node.id.replace("_collapsable_trigger", "_collapsable"));
		node.state = miwt.$(node.id.replace("_collapsable_trigger", ""));
		miwt.observe(node, "click", miwt.collapseContainerToggle);
		if (node.disposition.toLowerCase()!='inline' && node.state.value=='false') {
			miwt.prv_collapsableContainerShow(node.div.id, node.id, node.anchor, false);
		}
	}
});

} // End conditional eval
if(typeof miwttimer == 'undefined') {
var miwttimer = {};

/**
 * The time in which we give the user to enter input before firing the timer. For example, a timer will
 * be delayed for this many milliseconds after a keystroke.
 */
miwttimer.graceperiod = 3000;

/**
 * Fires a timer. If a reschedule is requested, such as due to user interaction, firing may be delayed up to
 * the grace period.
 * @param formname the form name.
 */
miwttimer.fireTimer = function (formname){
 	var form = miwt.$(formname);
 	if (!form) // sanity check, form removed somehow
 		return;
 	miwttimer.oldTimer = null;	

	if (miwttimer.rescheduleTimerNeeded && (new Date() - miwttimer.rescheduleTimerNeeded) < miwttimer.graceperiod)
	{
		miwttimer.oldTimer = setTimeout('miwttimer.fireTimer("'+formname+'")', miwttimer.graceperiod, 'JavaScript');
	}
	else
	{
		form.MIWTSubmit();
	}
};
 
/**
 * Reschedule the timer to account for user interaction.
 */       
miwttimer.rescheduleTimer = function (){
	if(miwttimer.oldTimer) {
		miwttimer.rescheduleTimerNeeded=new Date();	
	}
};
 
/**
 * Schedule an update. This method is meant to be called:
 * 1) by elements that wish to update the interface based on UI events.
 * 2) to schedule the form to be submitted in the future eg. to support miwt Timer java API
 *
 * Some UI activity (typing in a form) will call rescheduleTimer which will cause an update
 * scheduled by this method to be delayed.
 * 
 * @param formname the name of the form.
 * @param time the number of milliseconds to wait. (optional, defaults to 1000)
 */
miwttimer.scheduleUpdate = function (formname, time){
	var form = miwt.$(formname);

	if(miwttimer.oldTimer) {
		clearTimeout(miwttimer.oldTimer);
		miwttimer.oldTimer = null;
	}
		
	miwttimer.oldTimer = setTimeout('miwttimer.fireTimer("'+formname+'")', time || 1000, 'JavaScript');
};

miwt.AddSetupHandler([ 'dfn' ], function (tag, node) {
	if (tag == 'dfn' && /\bmiwt_timer\b/.exec(node.className))
	{
		var form = node;
	    while (form.parentNode && (!form.tagName ||  (form.tagName.toLowerCase() != "form")))
	      form = form.parentNode;
	    miwttimer.scheduleUpdate(form.id || form.name, parseInt(node.firstChild.data));
	}
});

}// End conditional eval.
if(typeof validation == 'undefined') {

/**
 * Provides validation of form elements.
 * @author Yong Jia Ni (yni@i2rd.com)
 * @author Pat Double (double@i2rd.com)
 */

var validation = {};
validation.integerpattern = new RegExp( "[ ]*([-]?[ ]*[0-9]+)[ ]*$" );
validation.realpattern = new RegExp( "([ ]*[-]?[ ]*[0-9]*[\.][0-9]+[ ]*$)|([ ]*[-]?[ ]*[0-9]+[\.][0-9]*[ ]*$)" );
validation.emailpattern = new RegExp( "^.+@.+\..{2,3}$" );
/** We MUST use slash notation when escaped forward slash is included, for IE 4.0 */
validation.date_mmddyyyy_slash = /([0-9][0-9])\x2F([0-9][0-9])\x2F([0-9][0-9][0-9][0-9])/;
validation.date_mmddyyyy_dash = new RegExp("([0-9][0-9])-([0-9][0-9])-([0-9][0-9][0-9][0-9])");
/** We MUST use slash notation when escaped forward slash is included, for IE 4.0 */
validation.date_mmddyy_slash = /([0-9][0-9])\x2F([0-9][0-9])\x2F([0-9][0-9])/;
validation.date_mmddyy_dash = new RegExp("([0-9][0-9])-([0-9][0-9])-([0-9][0-9])");
validation.config_regex_formatpattern = new RegExp("([-]?[\\w]*)[ ]*,[ ]*([-]?[\\w]*)");
validation.config_typepattern = new RegExp("([\\w]+)([\\(](.*)[\\)])?");
validation.config_formatpattern = new RegExp("([-]?[^\\s,]*)[ ]*,[ ]*([-]?[^\\s,]*)");

/**
 * Check if the string is a single whitespace character.
 * @param s The string.
 * @return true if the string is a single whitespace character.
 */
validation.isWhiteSpace = function (s){
	if(s == ' ' || s == '\t' || s == '\n' || s == '\r' || s == '\b' || s == '\f')
		return true;
	else
		return false;
};

/**
 * Trim whitespace from the left of the string.
 * @param s The string to trim.
 * @return The trimmed string.
 */
validation.ltrim = function ( s ){
	if(s == '')
		return s;
	var n = s.length;
	for(var i = 0; i < n; i++)
	{
		if(validation.isWhiteSpace(s.charAt(i)) == false)
			return s.substr(i);
	}
	return '';
};

/**
 * Trim whitespace from the right of the string.
 * @param s The string to trim.
 * @return The trimmed string.
 */
validation.rtrim = function ( s ){
	if(s == '')
		return s;
		
	var n = s.length;
	for(var i = n; i > 0; i--)
	{
		if(validation.isWhiteSpace(s.charAt(i-1)) == false)
			return s.substr(0, i);
	}
	return '';
};

/**
 * Trim whitespace from the left and right of the string.
 * @param s The string to trim.
 * @return The trimmed string.
 */
validation.trim = function ( s ){
	return validation.ltrim(validation.rtrim(s));
};

/**
 * Check if the string is a valid integer.
 * @param s The string to check.
 * @return true if the string is a valid integer, false otherwise.
 */
validation.isInteger = function ( s ){
	var re = validation.integerpattern;
	var parse = re.exec( s );
	if(parse == null)
		return false;
	else if(parse[0] == s)
		return true;
	else
		return false;
};

/**
 * Validate a numeric field.
 * @param n The string value of the field.
 * @param lbound The lower bound.
 * @param ubound The upper bound.
 * @return true if in the bounds, false if out of bounds.
 */
validation.checkNumber = function ( n, lbound, ubound ){
	var nn = new Number(n);
	if(lbound != "" && ubound != "")
	{
		lbound = new Number(lbound);
		ubound = new Number(ubound);
		if(nn < lbound || nn > ubound)
			return false;
	}
	else if(lbound == "" && ubound != "")
	{
		ubound = new Number(ubound);
		if(nn > ubound)
			return false;
	}
	if(lbound != "" && ubound == "")
	{
		lbound = new Number(lbound);
		if(nn < lbound)
			return false;
	}

	return true;
};

/**
 * Validate a string field.
 * @param n The string value of the field.
 * @param lbound The lower bound.
 * @param ubound The upper bound.
 * @return true if in the bounds, false if out of bounds.
 */
validation.checkString = function( s, lbound, ubound ){
	var nn = s.length;
	if(lbound != "" && ubound != "")
	{
		lbound = new Number(lbound);
		ubound = new Number(ubound);
		if(nn < lbound || nn > ubound)
			return false;
	}
	else if(lbound == "" && ubound != "")
	{
		ubound = new Number(ubound);
		if(nn > ubound)
			return false;
	}
	if(lbound != "" && ubound == "")
	{
		lbound = new Number(lbound);
		if(nn < lbound)
			return false;
	}
	
	return true;
};

/**
 * Check if the string is a valid date.
 * @param s The string to check.
 * @param dateFormat The date format: mm/dd/yyyy, mm-dd-yyyy, mm/dd/yy, mm-dd-yy
 * @return true if the string is a valid date, false otherwise.
 */
validation.isDate = function( s, dateFormat ){
	var re;
	if(dateFormat == "mm/dd/yyyy")
	{
		re = validation.date_mmddyyyy_slash;
	}
	else if(dateFormat == "mm-dd-yyyy")
	{
		re = validation.date_mmddyyyy_dash;
	}
	else if(dateFormat == "mm/dd/yy")
	{
		re = validation.date_mmddyy_slash;
	}
	else if(dateFormat == "mm-dd-yy")
	{
		re = validation.date_mmddyy_dash;
	}
	var s = validation.trim(s);
	var parse = re.exec( s );
	if(parse == null || parse[0] != s)
	{
		return false;
	}
	else
		return true;
};

/**
 * Check if the string is a valid float.
 * @param s The string to check.
 * @return true if the string is a valid float, false otherwise.
 */
validation.isReal = function ( s ){
	var re = validation.realpattern;
	var parse = re.exec( s );
	if(parse == null)
		return false;
	else if(parse[0] == s)
		return true;
	else
		return false;
};

/**
 * Check if the string is a number, i.e. integer or float.
 * @param s The string to check.
 * @return true if the string is a valid number, false otherwise.
 */
validation.isNumeric = function( s ){
	return validation.isInteger(s) || validation.isReal(s);
};

/**
 * Check if the string is a valid email address.
 * @param s The string to check.
 * @return true if the string is a valid email address, false otherwise.
 */
validation.isEmail = function( s ){
	var re = validation.emailpattern;
	var parse = re.exec(s);
	if(parse == null)
		return false;
	else
		return true;
};

/**
 * Check if validation should be ignored. The return value of this function may change over time.
 * @return true if validation should be ignored.
 */
validation.isIgnored = function(htmlform) {
	return htmlform.elements['btnhit'].value
		&& miwt.$(htmlform.elements['btnhit'].value+'_ignore_validation');
};

/**
 * Validate the form.
 * @param htmlform The Form object.
 */
validation.validateForm = function(htmlform){ // validate form inputs
	if (validation.isIgnored(htmlform))
		return true;
	
	for(var i = 0; i < validation.fields.length; i++)
	{
		if (validation.fields[i]==null
			|| htmlform.elements[validation.fields[i].element.name] == null)
		{
			// field has been removed, recreate validation.fields to free up old elements
			var new_fv_fields = [];
			for(var j = 0; j < validation.fields.length; j++)
			{
				if (validation.fields[j] != null
					&& htmlform.elements[validation.fields[j].element.name] != null)
				{
					new_fv_fields.push(validation.fields[j]);
				}
			}
			validation.fields = new_fv_fields;
			return validation.validateForm(htmlform);
		}
		
		if(validation.fields[i].required == "1") // required field
		{
			var e = validation.fields[i].element;
			if(e.type == "text" || e.type == "textarea")
			{
				if(validation.trim(e.value).length == 0)
				{
					validation.inValidation=true;
					alert(validation.fields[i].message);
					e.focus();
					e.select();
					validation.inValidation=false;
					return false;
				}
			}
			else if(e.type == "select-one" || e.type == "select-multiple")
			{
				if(e.selectedIndex == -1 || e.options[e.selectedIndex].value == "")
				{
					validation.inValidation=true;
					alert(validation.fields[i].message);
					e.focus();
					validation.inValidation=false;
					return false;
				}
			}
			else if(e.type == "radio" || e.type == "checkbox")
			{
				var radios = htmlform.elements[e.name];
				var n = 0;
				for(var k = 0; k < radios.length; k++)
				{
					if(radios[k].checked)
					{
						n++;
						break;
					}
				}
				if(n == 0)
				{
					validation.inValidation=true;
					alert(validation.fields[i].message);
					validation.inValidation=false;
					return false;
				}
			}
		}
		else
		{
			if (!validation.isFieldValid(validation.fields[i]))
			{
				var e = validation.fields[i].element;
				if (!e.validation_called)
				{
					e.focus();
					e.blur();
				}
				return false;
			}
		}

		if(validation.fields[i].type=="doubleentry")
		{
			var value = validation.fields[i].element.value;

			var compareField=miwt.$(validation.fields[i].format);
			if (compareField!=null) // Field could have been removed
			{
				var value2=compareField.value;
				if (value!=value2)
				{
					validation.inValidation=true;
					alert(validation.fields[i].message);
					validation.inValidation=false;
					return false;
				}
			}				
		}

	}
	return true;
};

/**
 * Called when validation fails. Assumes the validation.failedValidationInfo is a
 * "fieldInfo" object.
 */
validation.badValidation = function(){
	if (validation.failedValidationInfo!=null){
		alert(validation.failedValidationInfo.message);
		validation.failedValidationInfo.element.focus();
		validation.failedValidationInfo.element.select();
		validation.failedValidationInfo=null;
	}
};

/**
 * Check if the field value is valid. If the value is empty this method
 * always returns true.
 * @param fieldinfo The fieldInfo object.
 * @return true if the value is empty or valid, false if invalid.
 */
validation.isFieldValid = function (fieldinfo){
	var valid = true;
	var value = fieldinfo.element.value;
	if (validation.trim(value).length > 0)
	{
		if(fieldinfo.type == "int")
		{
			valid=(validation.isInteger(value)
				&& validation.checkNumber(value, fieldinfo.lbound, fieldinfo.ubound));
		}
		else if(fieldinfo.type == "num")
		{
			valid=(validation.isNumeric(value)
				&& validation.checkNumber(value, fieldinfo.lbound, fieldinfo.ubound));
		}
		else if(fieldinfo.type == "float")
		{
			valid=(validation.isReal(value)
				&& validation.checkNumber(value, fieldinfo.lbound, fieldinfo.ubound));
		}
		else if(fieldinfo.type == "text")
		{
			valid=validation.checkString(value, fieldinfo.lbound, fieldinfo.ubound);
		}
		else if(fieldinfo.type == "email")
		{
			valid=validation.isEmail(value);
		}
		else if(fieldinfo.type == "date")
		{
			var dateFormat = (fieldinfo.format == "")? "mm/dd/yyyy" : fieldinfo.format;
			valid=validation.isDate(value, dateFormat);
		}
		else if(fieldinfo.type == "regexp")
		{
			var re = new RegExp(fieldinfo.format);
			var s = validation.trim(value);
			var parse = re.exec(s);
			valid=(parse != null && parse[0] == s);
		}
	}
	
	return valid;
};

/**
 * The "onBlur" event handler for a validated field.
 */
validation.onBlurHandler = function(evt){ // onblur event handler

	if (validation.inValidation)
		return true;
	
	var target = miwt.element(evt);
	if (validation.isIgnored(target.form))
		return true;

	validation.inValidation=true;
	var fieldinfo = validation.getFieldInfo(target);
	var valid = true;
	if(fieldinfo != null)
	{
		valid=validation.isFieldValid(fieldinfo);
	}
	
	target.validation_called = true;

	if (valid)
	{
		validation.inValidation=false;
		return true;
	}
	else
	{
		validation.failedValidationInfo=fieldinfo;
		setTimeout(validation.badValidation, 100, "JavaScript");
		validation.inValidation=false;
		Event.stop(evt);
		
		return false;
	}
};

/**
 * Get the field information for a field.
 * @return fieldInfo or null if the field is not validated.
 */
validation.getFieldInfo = function (field){
	for(var i = 0; i < validation.fields.length; i++)
	{
		if(validation.fields[i].element.name == field.name)
			return validation.fields[i];
	}
	return null;
};

/**
 * Set the event handler(s) for a validated field.
 * @param fieldinfo The fieldInfo object.
 */
validation.setHandler = function (fieldinfo){ // set event handler for the fields in a form
    validation.setEventHandler(fieldinfo.element, fieldinfo);
};

/**
 * Set the event handler(s) for a validated field.
 * @param field The form element object.
 * @param fieldinfo The fieldInfo object.
 */
validation.setEventHandler = function(field, fieldinfo){ // set event handler for a field
	if(field.type == "text" || field.type == "textarea")
	{
		miwt.observe(field, "blur", validation.onBlurHandler, false);
	}
};

/**
 * Create a new "fieldInfo" object.
 * @param element The element.
 * @param message The message to display when the field does not validate.
 * @param type The type of field: email, text[([minlength],[maxlength])],
 *             date(mm/dd/yyyy|mm-dd-yyyy|mm/dd/yy|mm-dd-yy), int[([min],[max])], float[([min],[max])],
 *             num[([min],[max])], regexp(expression), doubleentry(otherfieldid)
 * @param required 0 if not required, 1 if required.
 */
validation.fieldInfo = function (element, message, type, required){ // field information object
	this.element = element;
	this.message = message;
	this.required = required;
	this.type = type.toLowerCase();
	this.format = "";
	this.lbound = "";
	this.ubound = "";
	var parse = validation.config_typepattern.exec( type );
	if(parse != null)
	{
		this.type = parse[1];
		if(parse.length == 4)
			this.format = parse[3];
		parse = validation.config_formatpattern.exec(this.format);
		if(parse != null)
		{
			this.lbound = parse[1];
			this.ubound = parse[2];
		}
	}
};

/**
 * Register a form element for validation.
 * @param element The element.
 * @param message The message to display when the field does not validate.
 * @param type The type of field: email, text[([minlength],[maxlength])],
 *             date(mm/dd/yyyy|mm-dd-yyyy|mm/dd/yy|mm-dd-yy), int[([min],[max])], float[([min],[max])],
 *             num[([min],[max])], regexp(expression), doubleentry(otherfieldid)
 * @param required 0 if not required, 1 if required.
 */
validation.FormValidation_Register = function(element, message, type, required){
	var f = new validation.fieldInfo(element, message, type, required);
	validation.setHandler(f);
	
	// check for existing entry and replace
	for(var i =0; i<validation.fields.length; i++)
	{
		if (validation.fields[i].element.name == element.name)
		{
			validation.fields[i] = f;
			return;
		}
	}
	
	// no existing entry, add to the list
	validation.fields.push(f);
};

/** Array of fieldInfo objects listing the elements being validated. */
validation.fields = [];

/** Indiciates if we are currently processing a field validation. */
validation.inValidation=false;

miwt.AddSetupHandler(['form'], function(tag, node){
	if(miwt.hasClassName(node, 'miwt_form')) node.RegisterOnSubmitHandler(node, validation.validateForm);
});

miwt.AddSetupHandler([ 'dfn' ], function (tag, node){
	if (tag != 'dfn' || !/\bmiwt_validation\b/.exec(node.className))
		return;
		
	var match = /(\S+)_val/.exec(node.id);
	if (!match)
		return;
	var type = node.firstChild.data;
	var msgnode = miwt.$(node.id+"_message");
	var reqnode = miwt.$(node.id+"_required");
	if (msgnode && msgnode.firstChild && reqnode && reqnode.firstChild) {
		var msg = msgnode.firstChild.data;
		var req = reqnode.firstChild.data;
		//miwt.debug("validation.FormValidation_Register("+match[1]+", "+msg+", "+type+", "+req+")");
		var el = miwt.$(match[1]);
		if (el)
			validation.FormValidation_Register(el, msg, type, req);
		else
			miwt.error("Could not find element "+match[1]+" for validation");
	}
});

}// End conditional eval
if(typeof miwttable == 'undefined') {
var miwttable = {};

miwt.AddSetupHandler([ 'table' ], function (tag, node) {
	if (tag != 'table')
		return;
	// column moving
	var headers = miwt.$$("thead th", node),i=0,n;
	if (miwt.$("columnmoving_"+node.id)){
		for(i=0; n = headers[i];i++) {
			if(miwt.hasClassName(n,'control')) continue;
			n.id = "columnmove_"+node.id+"_th_"+i;
			miwt.addClassName(n, "dnd_source");
			miwtdnd.setupDragSource(n);
			miwt.addClassName(n, "dnd_target");
			miwtdnd.setupDropTarget(n);
		}
	}
});

}// End conditional eval
if (typeof miwtdnd == 'undefined') {
var miwtdnd = {};

miwtdnd.active = false;
miwtdnd.dragSource = null;
miwtdnd.dropTarget = null;
miwtdnd.feedbackElement = null;
miwtdnd.dropactiveset = false;

miwtdnd.window_mousemove = function (evt) {
    if (!miwtdnd.dragSource) // sanity check in case events are not received in the order we expect
        return;
    var p = miwt.pointer(evt);
	if (!miwtdnd.active) {
		if (Math.abs(p.x - miwtdnd.startX) > 2 || Math.abs(p.y - miwtdnd.startY) > 2) {

			miwt.stop(evt);
			miwtdnd.active = true;
			if (miwtdnd.menu) {
				miwt.remove(miwtdnd.menu);
				miwtdnd.menu = null;
			}
			miwt.addClassName(document.body, 'dnd_active');
			var ua=navigator.userAgent, ie6 = (miwt.B.IE && ua.indexOf('MSIE 6') > -1), ie7 = (miwt.B.IE && ua.indexOf('MSIE 7') > -1);
			// TODO: test ie8
			
			miwtdnd.feedbackElement = miwtdnd.dragSource.cloneNode(true);
			if (ie6 || ie7) {
				if (miwtdnd.feedbackElement.tagName.toLowerCase() == 'td') {
					miwtdnd.feedbackElement = miwt.wrap(miwtdnd.feedbackElement, 'tr');
					miwtdnd.feedbackElement.style.className = miwtdnd.dragSource.style.className;
					miwtdnd.feedbackElement = miwt.wrap(miwtdnd.feedbackElement, 'table');
					miwtdnd.feedbackElement.style.className = miwtdnd.dragSource.parentNode.style.className;
				}
				else if (miwtdnd.feedbackElement.tagName.toLowerCase() == 'tr') {
					miwtdnd.feedbackElement = miwt.wrap(miwtdnd.feedbackElement, 'table');
					miwtdnd.feedbackElement.style.className = miwtdnd.dragSource.style.className;
				}
				miwtdnd.feedbackElement.style.position = 'absolute';
			} else {
				miwtdnd.feedbackElement.style.position = 'fixed';
			}
			miwtdnd.feedbackElement.style.display = 'block';
			miwtdnd.feedbackElement.style.margin = '0px';
			miwtdnd.feedbackElement.style.padding = '0px';
			miwtdnd.feedbackElement.style.zIndex = '999999';
			miwtdnd.feedbackElement.style.right = '';
			miwtdnd.feedbackElement.style.bottom = '';
			{
				miwtdnd.feedbackElement.removeAttribute("id");
				var node, nodes = miwtdnd.feedbackElement.getElementsByTagName('*');
				for(var i = 0; node = nodes.item(i); ++i) {
					node.removeAttribute("id");
				}
			}
			miwt.removeClassName(miwtdnd.feedbackElement, "dnd_target");
			miwt.removeClassName(miwtdnd.feedbackElement, "dnd_source");
			miwt.addClassName(miwtdnd.feedbackElement, "dnd_feedback");
			// The following two lines look better but prevent the correct drop element from being detected, 
			// the feedback element is the source for further events
//			var dragSourceOffset = miwt.cumulativeOffset(miwtdnd.dragSource);
//			miwtdnd.feedbackOffsetLeft = dragSourceOffset.left - Event.pointerX(evt);
//			miwtdnd.feedbackOffsetTop = dragSourceOffset.top - Event.pointerY(evt);
			miwtdnd.feedbackOffsetLeft = 5;
			miwtdnd.feedbackOffsetTop = 5;
			miwtdnd.feedbackElement.style.width = miwtdnd.dragSource.offsetWidth+"px";
			miwtdnd.feedbackElement.style.height = miwtdnd.dragSource.offsetHeight+"px";
			if (ie6 || ie7)
				document.body.appendChild(miwtdnd.feedbackElement);
			else
				miwtdnd.dragSource.parentNode.appendChild(miwtdnd.feedbackElement);
			miwt.observe(document, "keydown", miwtdnd.window_escape, true);
		}
	}
	else {
		miwt.stop(evt);
	}

	if (miwtdnd.feedbackElement) {
		var scrollOffsets;
		if (miwtdnd.feedbackElement.style.position == 'absolute') {
			scrollOffsets = { left: 0, top: 0 };
		}
		else {
			scrollOffsets = miwt.cumulativeOffset(document.body, true);
		}
		miwtdnd.feedbackElement.style.left = (p.x-scrollOffsets.left+miwtdnd.feedbackOffsetLeft)+"px";
		miwtdnd.feedbackElement.style.top = (p.y-scrollOffsets.top+miwtdnd.feedbackOffsetTop)+"px";
	}
	
	// set drop target class name for CSS styled feedback
	var i, e, dropEl = miwt.element(evt);
	if (dropEl == miwtdnd.feedbackElement)
		return;
	while (dropEl && !miwt.hasClassName(dropEl, "dnd_target"))
		dropEl = dropEl.parentNode;
	/*if (dropEl && !miwt.hasClassName(dropEl, "dnd_target"))
		dropEl = null;*/
	if (dropEl && !miwtdnd.isCompatible(miwtdnd.dragSource, dropEl)){
		miwt.info("Drop "+dropEl + " not compatible");
		dropEl = null;		
	}
	var addStyles = [ 'dnd_target_active' ];
	var removeStyles = [ ];
	if (dropEl && dropEl.locations && dropEl.locationRows && dropEl.locationColumns) {
		var targetOffset = miwt.cumulativeOffset(dropEl);
		var targetDim = miwt.getDimensions(dropEl);
        var row = Math.floor((p.y - targetOffset.top) / Math.max(1, targetDim.height / dropEl.locationRows));
        var col = Math.floor((p.x - targetOffset.left) / Math.max(1, targetDim.width / dropEl.locationColumns));
        //row = Math.min(0, Math.max(dropEl.locationRows-1, row));
        if (row < 0)
        	row = 0;
        else if (row >= dropEl.locationRows)
        	row = dropEl.locationRows-1;
        //col = Math.min(0, Math.max(dropEl.locationColumns-1, col));
        if (col < 0)
        	col = 0;
        else if (col >= dropEl.locationColumns)
        	col = dropEl.locationColumns-1;
        var dropClass = dropEl.locations[row+","+col];
		//miwt.info("Drop "+dropEl.id+" location at cell "+row+","+col+", class "+dropClass);
        if (dropClass) {
        	addStyles.push(dropClass);
        	for(i=0; e=dropEl.allClassNames[i]; i++)
        		if(dropClass != e) removeStyles.push(e);
        } else
        	removeStyles = dropEl.allClassNames;
	}
	if (miwtdnd.dropactiveset) {
		var el, list = miwt.$$(".dnd_target_active");
		while (el = list.pop()) {
			if (el != dropEl)
				el.className = el.className.replace(/\bdnd_target_active\S*\b/g, ' ').trim();
		}
	}
	miwtdnd.dropactiveset = false;
	if (dropEl && dropEl.className) {
		for(i=0; e=addStyles[i]; i++)
			miwt.addClassName(dropEl, e);
		for(i=0; e=removeStyles[i]; i++)
			miwt.removeClassName(dropEl, e);
		miwtdnd.dropactiveset = true;
	}
};

miwtdnd.window_mouseup = function (evt) {
	//miwt.info("Stopping DnD");
	miwt.stopObserving(document, "mousemove", miwtdnd.window_mousemove, true);
	miwt.stopObserving(document, "mouseup", miwtdnd.window_mouseup, true);
	miwt.removeClassName(document.body, 'dnd_active');
	window.setTimeout(miwtdnd.stopOperation, 10);
};

miwtdnd.window_escape = function (evt) {
	var keycode = evt.keyCode || evt.which;
	if (keycode != 27)
		return;
	
	miwt.stop(evt);
	miwtdnd.stopOperation();
	if (miwtdnd.menu) {
		miwtdnd.menu.form.ResetTransient();
		miwtdnd.menu.parentNode.removeChild(miwtdnd.menu);
		miwtdnd.menu = null;
	}
	miwt.stopObserving(document, "keydown", miwtdnd.window_escape, true);
};

/**
 * Stop the current drag and drop operation. This method does not execute the operation.
 */
miwtdnd.stopOperation = function() {
	if (miwtdnd.dropOpPending)
		return;
    //miwt.info("Stop operation");
	miwtdnd.active = false;
	miwtdnd.dragSource = null;
	miwtdnd.dropTarget = null;
	miwtdnd.startX = null;
	miwtdnd.startY = null;
	if (miwtdnd.feedbackElement) {
		miwt.remove(miwtdnd.feedbackElement);
		miwtdnd.feedbackElement = null;
	}
	if (miwtdnd.dropactiveset) {
		var el, list = miwt.$$(".dnd_target_active");
		while (el = list.pop())
			el.className = el.className.replace(/\bdnd_target_active\S*\b/g, ' ').trim();
		miwtdnd.dropactiveset = false;
	}
};

miwtdnd.dragSource_mousedown = function (evt, drag) {
    var src = miwt.element(evt);
    // Abort DnD on form elements.
    if(src && (tag_name = src.tagName.toUpperCase()) && (
      tag_name=='INPUT' ||
      tag_name=='SELECT' ||
      tag_name=='OPTION' ||
      tag_name=='BUTTON' ||
      tag_name=='TEXTAREA')) return;

	miwtdnd.dragSource = drag || src;
	//miwt.info("Starting DnD for "+miwtdnd.dragSource.id);
	var p = miwt.pointer(evt);
	miwtdnd.startX = p.x;
	miwtdnd.startY = p.y;

	miwt.stop(evt);
	miwt.observe(document, "mousemove", miwtdnd.window_mousemove, true);
	miwt.observe(document, "mouseup", miwtdnd.window_mouseup, true);
};
/**
 * Setup a drop target.
 * @param node the drop target node.
 * @param contentTypes an array of provided content types, may be null to not perform a content type check.
 */
miwtdnd.setupDragSource = function (node, contentTypes) {
	//miwt.info("Setup drag source "+node.id);
	var drag = node;
	drag.provides = contentTypes || [ ];
	miwt.addClassName(drag, "dnd_source");
	miwt.observe(node, "mousedown", function(evt) { miwtdnd.dragSource_mousedown(evt || window.event, drag) }, true);
};

miwtdnd.dropTarget_mouseup = function (evt, drop) {
	if (!miwtdnd.active)
		return;
	var eventel = miwt.element(evt);
	while (eventel && !miwt.hasClassName(eventel, "dnd_target"))
		eventel = eventel.parentNode;
	drop = eventel || drop;
	//miwt.info("Drop target mouse up for "+drop.id+" "+drop.nodeName);
	if (!miwtdnd.isCompatible(miwtdnd.dragSource, drop))
		return;
	//miwt.stop(evt); // do not do this, we need to get events for all targets in case one encloses the other
	if (miwtdnd.dropTarget) {
		var el = miwtdnd.dropTarget;
		while (el) {
			if (drop == el) {
				//miwt.info("Skipping target "+drop.id+" for child target "+miwtdnd.dropTarget.id);
				return;
			}
			el = el.parentNode;
		}
	}
	miwtdnd.dropTarget = drop;
	if (miwtdnd.dropTimer) {
		clearTimeout(miwtdnd.dropTimer);
		miwtdnd.dropTimer = null;
	}
	miwtdnd.dropOpPending = true;
	var form = miwt.findElement(evt, 'form');
	var p = miwt.pointer(evt);
	miwtdnd.dropTimer = setTimeout(function() { miwtdnd.handleDropTargetActivate(drop, form, p.x, p.y); }, 10);
};

miwtdnd.handleDropTargetActivate = function (drop, form, x, y) {
	//miwt.info("Processing DnD from "+miwtdnd.dragSource.id+" to "+miwtdnd.dropTarget.id);
	miwtdnd.active = false;
	if (miwtdnd.dropTimer) {
		clearTimeout(miwtdnd.dropTimer);
		miwtdnd.dropTimer = null;
	}
	if (form) {
		form.elements['dnd_source'].value=miwtdnd.dragSource.id;
		form.elements['dnd_target'].value=miwtdnd.dropTarget.id;
		var left, top, dropDim, dropOffset, scrollOffset, docOffset;
        docOffset = miwt.cumulativeOffset(document.body, true);
        scrollOffset = miwt.cumulativeOffset(miwtdnd.dropTarget, true); 
        dropOffset = miwt.cumulativeOffset(miwtdnd.dropTarget);
		dropDim = miwt.getDimensions(miwtdnd.dropTarget);
        left = dropOffset.left - (scrollOffset.left - docOffset.left);
        top =  dropOffset.top - (scrollOffset.top - docOffset.top);
		form.elements['dnd_location'].value="("+left+","+top+","+dropDim.width+","+dropDim.height+"),("+x+","+y+")";
		miwtdnd.dropOpPending = false;
		miwtdnd.stopOperation();
		if (drop.hasOptions) {
			// check for options
			miwtdnd.menu = document.createElement("div");
			miwtdnd.menu.form = form;
			miwtdnd.menu.className = "dropoptions";
			miwtdnd.menu.style.position = 'absolute';
			miwtdnd.menu.style.top = y+"px";
			miwtdnd.menu.style.left = x+"px";
			document.getElementsByTagName("body")[0].appendChild(miwtdnd.menu);
			miwtdnd.menu.innerHTML = '<div class="loading">Loading...</div>';
			new Ajax.Request(miwt.$$("dfn.ajax_uri", form).pop().firstChild.data, {
					method: 'get',
					parameters: { ajax: 'true', alt: 'dropoptions', dnd_source: form.elements['dnd_source'].value, dnd_target: form.elements['dnd_target'].value },
					onSuccess: function(transport) {
						try {
							var tmpnode=document.createElement("div");
							tmpnode.innerHTML = transport.responseText;
							miwtdnd.menu.removeChild(miwtdnd.menu.firstChild);
							miwtdnd.menu.appendChild(tmpnode.firstChild);
							var el, list, count = 0;
							list = miwt.$$("a", miwtdnd.menu);
							while (el = list.pop()) {
								count++;
								el.dndoption = el.href.substring(el.href.indexOf("#")+1);
								el.href='#';
								el.onclick = function(evt) {
									miwt.stop(evt);
									miwtdnd.menu.parentNode.removeChild(miwtdnd.menu);
									miwtdnd.menu = null;
									form.elements['dnd_option'].value=this.dndoption;
									miwt.stopObserving(document, "keydown", miwtdnd.window_escape, true);
									try{this.onclick = null;}catch(e){}
									form.MIWTSubmit();
									
								};
							}
							if (count == 0)
							{
								// no options
								miwtdnd.menu.parentNode.removeChild(miwtdnd.menu);
								miwtdnd.menu = null;
								miwt.stopObserving(document, "keydown", miwtdnd.window_escape, true);
								form.MIWTSubmit();
							}
						}
						catch (e) {
							miwt.info("drop options", e);
						}
			        },
			        onFailure: function() {
						miwt.stopObserving(document, "keydown", miwtdnd.window_escape, true);
			        	form.MIWTSubmit();
			        },
			        onException: function() {
						miwt.stopObserving(document, "keydown", miwtdnd.window_escape, true);
			        	form.MIWTSubmit();
			        }
			});
		}
		else {
			miwt.stopObserving(document, "keydown", miwtdnd.window_escape, true);
			form.MIWTSubmit();
		}
	} else {
		miwtdnd.dropOpPending = false;
		miwtdnd.stopOperation();
	}
};

/**
 * Setup a drop target.
 * @param node the drop target node.
 * @param hasOptions true if drop options may be available.
 * @param contentTypes an array of accepted content types, may be null to not perform a content type check.
 * @param locations an array of cells and class names for drop location classes, in the 
 * format [ "rowsXcolumns", "(row1,col1)(row2,col2)(row3,col3)", "className", "(row4,col4)", "className", ... ]
 */
miwtdnd.setupDropTarget = function (node, hasOptions, contentTypes, locations) {
	//miwt.info("Setup drop target "+node.id+" "+node.nodeName);
	
	var drop = node;
	drop.accepts = contentTypes || [];
	drop.hasOptions = !!hasOptions;
	miwt.addClassName(drop, "dnd_target");
	
	// decode drop locations and class names
	drop.locations = [];
	drop.allClassNames = [];
	drop.locationRows = 1;
	drop.locationColumns = 1;
	if (locations && locations.length > 0) {
		var dim = /(\d+)X(\d+)/.exec(locations[0]);
		drop.locationRows = dim[1];
		drop.locationColumns = dim[2];
		for(var i = 1, cells, className; (cells = locations[i++]) && (className = locations[i++]); ) {
			className = "dnd_target_active_" + className;
			drop.allClassNames.push(className);
			var values = cells.match(/\d+/g);
			for(var r, c; (r = values.shift()) && (c = values.shift()); ) {
				drop.locations[r+","+c] = className;
				//miwt.info("Drop "+node.id+" location, cell "+r+","+c+" is "+className);
			}
		}
		//drop.allClassNames = drop.allClassNames.uniq();
		//miwt.info("Drop "+node.id+" allClassNames = "+drop.allClassNames);
	}
	
	miwt.observe(node, "mouseup", function(evt) { miwtdnd.dropTarget_mouseup(evt, drop) }, true);
};

/**
 * Check if the drag source may be dropped onto the drop target.
 * @param dragSource the drag source.
 * @param dropTarget the drop target.
 * @return true if the drag source may be dropped onto the drop target, false otherwise.
 */
miwtdnd.isCompatible = function (dragSource, dropTarget) {
	if (dragSource == null)
		return false;
	if (dropTarget == null)
		return false;
	if (dragSource.provides.length == 0)
		return true;
	if (dropTarget.accepts.length == 0)
		return true;
	for(var i=0,a;a=dropTarget.accepts[i]; i++){
		for(var j=0,b;b=dragSource.provides[j]; j++)
			if(a == b) return true;
	}
	return false;
};

miwt.AddSetupHandler([ 'dfn' ], function (tag, node)
{
	if (/\bdnd_source_def\b/.exec(node.className)) {
		var a = miwt.words(node.firstChild.data);
		miwtdnd.setupDragSource(miwt.$(a.shift()), a);
	}
	
	if (/\bdnd_target_def\b/.exec(node.className)) {
		var a = miwt.words(node.firstChild.data);
		var drop = miwt.$(a.shift());
		var hasOptions = !/nodropoptions/.test(a.shift());
		var contentTypes = [];
		var locations = [];
		for(var el; el = a.shift(); ) {
			if (locations.length > 0 || /\d+X\d+/.test(el))
				locations.push(el);
			else
				contentTypes.push(el);
		}
		miwtdnd.setupDropTarget(drop, hasOptions, contentTypes, locations);
	}
});

} // End conditional eval
if(typeof miwtcalendar == 'undefined') {
miwtcalendar = {};
miwt.calendarClearHandler = function (evt) {
	var node = miwt.element(evt).node;
	node.value=''; 
	if (/\bmiwt_submit\b/.exec(node.className))
		miwt.calendarUpdateSubmit(node);
	else
		miwt.calendarUpdateNoSubmit(node);
};

miwt.calendarUpdateSubmit = function (node) {
	if (this && this.target) {
		node = miwt.$(this.target);
	}
	if (!node) return;
	
	var form = node.form;
	form.elements['btnhit'].value=node.name || node.id;
	node.hinttexton = false;
	node.style.color = null;
	form.MIWTSubmit();
};

miwt.calendarUpdateNoSubmit = function (node) {
	if (this && this.target) {
		node = miwt.$(this.target);
	}
	if (!node) return;
	
	node.hinttexton = false;
	node.style.color = null;
};

miwt.AddSetupHandler([ 'input' ], function (tag, node) {
	if (!/\bmiwt_calendar\b/.exec(node.className))
		return;
	var submit = /\bmiwt_submit\b/.exec(node.className);
	var form = node.form;

	var yearstart = miwt.$(node.id+'_yearstart');
	var yearend = miwt.$(node.id+'_yearend');
	var yearrange = null;
	if (yearstart && yearend)
		yearrange = [ parseInt(yearstart.firstChild.data), parseInt(yearend.firstChild.data) ];
	else
		yearrange = [1900, 2999];
	
	var funcArg = {target: node.id}, updateFunction = (submit) 
		? function(){miwt.calendarUpdateSubmit.call(funcArg);}
		: function(){miwt.calendarUpdateNoSubmit.call(funcArg);};
			
	var clearbutton = miwt.$(node.id+"_clear");
	if (clearbutton) {
		clearbutton.node = node;
		miwt.observe(clearbutton, "click", miwt.calendarClearHandler);
	}

	try
	{
		/*
		Calendar.setup({
			inputField: node.id,
			ifFormat: $(node.id+'_format').firstChild.data,
			range: yearrange,
			showOthers: true,
			showsTime: ($(node.id+'_time') != null),
			onUpdate: node.updateFunction,
			timeFormat: "12",
			cache: true
		});
		*/
		var openbutton = miwt.$(node.id+"_open");
		if (openbutton) {
			Calendar.setup({
				inputField: node.id,
				button: openbutton,
				ifFormat: miwt.$(node.id+'_format').firstChild.data,
				range: yearrange,
				showOthers: true,
				showsTime: (miwt.$(node.id+'_time') != null),
				onUpdate: updateFunction,
				timeFormat: "12",
				cache: true
			});
		}
	}
	catch (e) { miwt.error("Cannot init calendar, check your classpath", e); }
});

} // End conditional eval
if(typeof miwt.list == 'undefined') {

miwt.list = {};

miwt.list.inputclick = function (evt) {
	var input = miwt.element(evt), p = input.parentNode, el, list;
	if (input.checked) {
		if (input.type == 'radio') {
			list = miwt.$$(".checked", p.parentNode);
			while (el = list.pop())
				miwt.removeClassName(el, "checked");
		}
		miwt.addClassName(p, "checked");
	} else {
		miwt.removeClassName(p, "checked");
	}
};

miwt.list.elementclick = function (evt) {
	var el = miwt.element(evt), input = miwt.$$("input.selector", el).pop();
	if (!input) return;
	input.click();
};

miwt.AddSetupHandler([ 'input' ], function ListSetupFn(tag, node) {
	var el = node.parentNode, richlist = el.parentNode;
	if (!/\belement\b/.exec(el.className))
		return;
	if (!/\brichlist\b/.exec(richlist.className))
		return;

	miwt.observe(node, 'click', miwt.list.inputclick);
	miwt.observe(el, 'click', miwt.list.elementclick);
});

}// End conditional eval
if(document.addEventListener)
	document.addEventListener("DOMContentLoaded", miwt.onLoad, false);
miwt.observe(window, 'load', miwt.onLoad);
if(document.readyState=='complete' || (window.i2rd && window.i2rd.rdy))
	miwt.onLoad();
