// namespace 
if(typeof miwt == 'undefined') {
	var miwt = new Object();
}
if(typeof miwtutil == 'undefined') {
var miwtutil = {};

/** Symbolic names are much more readable than magic numbers. */
if(!Node) {
	var Node = new Object();
	Node.ELEMENT_NODE                   = 1;
  	Node.ATTRIBUTE_NODE                 = 2;
	Node.TEXT_NODE                      = 3;
	Node.CDATA_SECTION_NODE             = 4;
	
	Node.ENTITY_REFERENCE_NODE          = 5;
  	Node.ENTITY_NODE                    = 6;
  	Node.PROCESSING_INSTRUCTION_NODE    = 7;
  	Node.COMMENT_NODE                   = 8;
  	Node.DOCUMENT_NODE                  = 9;
  	Node.DOCUMENT_TYPE_NODE             = 10;
  	Node.DOCUMENT_FRAGMENT_NODE         = 11;
  	Node.NOTATION_NODE                  = 12;
}
//(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 (element, style) {
	if (document.defaultView && document.defaultView.getComputedStyle) {
		return document.defaultView.getComputedStyle(element, "").getPropertyValue(style);
	}
	else if (element.currentStyle) {
		return element.currentStyle[style];
	}
	else {
		return "";
	}
};

/**
 * Close all CKEditors at or below the specified element.
 * @param element the DOM element.
 */
miwt.closeCKEditors = function (element) {
	if(typeof CKEDITOR == 'undefined') return;
	var i, ta, list = element.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.observe = function(element, name, observer, useCapture) {
    element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.attachEvent))
      name = 'keydown';

    if (element.addEventListener) {
      element.addEventListener(name, observer, useCapture);
    } else if (element.attachEvent) {
      element.attachEvent('on' + name, observer);
    }
}

miwt.stopObserving = function(element, name, observer, useCapture) {
    element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.detachEvent))
      name = 'keydown';

    if (element.removeEventListener) {
      element.removeEventListener(name, observer, useCapture);
    } else if (element.detachEvent) {
      try {
        element.detachEvent('on' + name, observer);
      } catch (e) {}
    }
}

miwt.viewResource = function (url, newWindow) {
	//log4js.logger.info("Viewing resource "+url);
	var f = Element.select(document, "form.viewresource").pop();
	if (f) {
		f.action = url;
		if (newWindow)
			f.target = "_new";
		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.
		var nw;
		if (newWindow)
			nw = window.open(url, '_new');
		else
			nw = window.open(url);
		if (!nw) {
            if(confirm($$("dfn.miwt_popup_blocked").pop().firstChild.data))
                window.location.href = url;
        }
	}
}

miwt.saveResource = function (url) {
	//log4js.logger.info("Saving resource "+url);
	var f = Element.select(document, "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($$("dfn.miwt_popup_blocked").pop().firstChild.data))
                window.location.href = url;
        }
	}
}

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

/**
 * MIWT form extension.
 */
 
miwt.prv_FormOnSubmitHandler = function(evt) {
	var form = Event.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 = Class.create();
miwt.Form.prototype = 
{
	// list of element IDs that have form submission handlers
	initialize: function () {
		this.submitters = new Array(); // list of element IDs
		this.submitter_functions = new Array(); // 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;
		for(var i = 0; submitter = this.submitters[i]; i++) {
			var element = $(submitter);
			if (element) {
				var f = this.submitter_functions[element.id];
				if (f && !f(this))
				{
						//log4js.logger.debug("submit handler for element "+(element.name||element.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 ajax_request_complete_callback a function to be called after
	  * an AJAX request is completed. An object is passed giving the form
	  * object as the property 'source'.
	  * @return true if submitted, false if not submitted.
	 */
	MIWTSubmit: function (ajax_request_complete_callback)
	{
		//log4js.logger.debug("MIWTSubmit called for "+(this.id || this.name));
				  		
		// ignore submits too close together, either double-click or default behavior not prevented
		if (this.lastSubmit)
		{
			var now = new Date().getTime();
			var 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 (typeof(miwtajax)=='undefined' || $(this.elements['btnhit'].value+"_noajax"))
		{
			miwtajax.showFormPostWait();
			this.submit();
			return true;
		}
		
		if (ajax_request_complete_callback == null)
			ajax_request_complete_callback = miwtajax.ajax_request_complete_callback;
		else if (typeof(ajax_request_complete_callback.push) == 'undefined') {
			var a = new Array();
			a.push(ajax_request_complete_callback);
			ajax_request_complete_callback = miwtajax.ajax_request_complete_callback.concat(a);
		}

		var ajax = new miwtajax.InputProcessor(this, ajax_request_complete_callback, miwtajax.ajax_failed_update_callback);
		this.lastSubmit = new Date();
		if (!ajax.isRequestSubmitted())
		{
			// AJAX not supported or failed
			miwtajax.showFormPostWait();
			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(element, handler)
	{
		if (element == null)
			return;

 		// set the handler on the element so it will get removed when the element is removed
 		this.submitter_functions[element.id] = handler;
 		
 		if (this.submitters.indexOf(element.id) == -1)
	 		this.submitters.push(element.id);
	},
	
	/**
	 * Clean up handlers whose object has been removed from the DOM.
	 */
	CleanOnSubmitHandlers: function()
	{
		var list = new Array();
		var elementid;
		for(var i = 0; elementid = this.submitters[i]; i++) {
			var element = $(elementid);
			if (element)
				list.push(elementid);
			else
				this.submitter_functions[elementid] = 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 = new Array();
miwt.setupHandlers["any"] = new Array();
miwt.setupHandlers["a"] = new Array();
miwt.setupHandlers["button"] = new Array();
miwt.setupHandlers["div"] = new Array();
miwt.setupHandlers["img"] = new Array();
miwt.setupHandlers["input"] = new Array();
miwt.setupHandlers["select"] = new Array();
miwt.setupHandlers["dfn"] = new Array();
miwt.setupHandlers["table"] = new Array();
miwt.setupHandlers["textarea"] = new Array();

/**
 * 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] = new Array();
		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) {

		if (node.className) {			
			var tag = node.tagName.toLowerCase();
	
			// 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);
		i++;
	}
}

// components that submit on change
miwt.scheduleUpdateKeydownHandler = function (event) { 
	miwttimer.scheduleUpdate(Event.element(event).form.id); 
}
miwt.observerFormSubmit = function (element) { 
	element.form.MIWTSubmit(); 
}
miwt.AddSetupHandler([ 'input', 'select', 'textarea' ], function (tag, node)
{
	if (node.form && /\bmiwt_watch\b/.exec(node.className))
	{
		//log4js.logger.debug("Found watcher "+node.id);
		if ((tag=='input' && node.type == 'text') || tag=='textarea')
			miwt.observe(node, 'keydown', miwt.scheduleUpdateKeydownHandler);
		else
			node.observer = new Form.Element.EventObserver(node, miwt.observerFormSubmit);
	}
	
});

// initial focus
miwt.AddSetupHandler([ 'button', 'input', 'select', 'textarea' ], function (tag, node)
{
	if (node.focus && /\bmiwt_focus\b/.exec(node.className))
		window.setTimeout(function() { node.focus(); }, 200);
});

/**
 * Setup an MIWT form element.
 */  
miwt.setupForm = function(form)
{
	//log4js.logger.debug("Configuring MIWT form "+(form.id || form.name));
	Object.extend(form, miwt.Form.prototype);
	try
	{
		form.initialize();
		miwt.setup(form);
		form.RegisterOnSubmitHandler(form, validation.validateForm);
	}
	catch (exception) { log4js.logger.error("Configuring MIWT form "+(form.id || form.name), exception); }
}

/**
* 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 = $$("div.window");
    while( (w=windows.pop()) ) {
        if(!wz || (parseInt(wz.style.zIndex) < parseInt(w.style.zIndex))) {
          wz = w;
        }
    }
    if(!!wz) {
    	var pos = Element.cumulativeOffset(wz);
    	window.scrollTo(pos[0], pos[1] - 20);
    }
};

miwt.onLoad = function (event)
{
	// setup the components in each form
	var i, form;
	for(i = 0; form = document.forms[i]; i++) {
		if (/\bmiwt_form\b/.exec(form.className)) {
			miwt.setupForm(form);
            miwt.setViewportPosition();			
		} else if (/\bmiwt_external_action\b/.exec(form.className)) {
			var form2 = form;
			setTimeout(function() { form2.submit(); }, 10, 'JavaScript');
		}
	}
}

document.observe("dom:loaded", miwt.onLoad);
//miwt.observe(window, 'load', miwt.onLoad);

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

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

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

miwt.AddSetupHandler(null, function (tag, node)
{
	if (/\bmiwt_reset\b/.exec(node.className))
		miwt.observe(node, "click", miwt.resetEventHandler);
	if (/\bmiwt_submit\b/.exec(node.className))
	{
		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 = new Object();
miwt.imagebutton.groups = new Array();

miwt.imagebutton.imageButtonEnabled = function (button)
{
	var disabledValue = button.attributes.getNamedItem("disabled");
	return disabledValue==null || disabledValue.value != "true";
}

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

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

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

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

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

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

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

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

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

		if (target.miwt_buttonGroup==null || selected)
		{
			miwt.imagebutton.imageButtonSetState(target, null, selected, "normal");
		}
		
		if (target.miwt_watch)
			Event.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)
{
	if (isActive==null)
		isActive=img.miwt_isActive;
	if (isSelected==null)
		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;
		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 (buttonid) {
					if (buttonid != img.id) {
						var button = $(buttonid);
						if (button)
							miwt.imagebutton.imageButtonSetState(button, 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 (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 = $(id+"_value");
		if (valuenode)
			selectedvalue = valuenode.firstChild.data;
	}
	
	var img=$(id);
	if (img==null)
	{
		log4js.logger.warn("There is an error with the generated page, cannot find image button with id '"+id+"'");
		return;
	}
	
	/* Set the variables */
	img.miwt_active=$(id+"_unselected");
	img.miwt_activeselected=$(id+"_selected");
	img.miwt_activepressed=$(id+"_pressed");
	img.miwt_activerollover=$(id+"_rollover");
	img.miwt_inactive=$(id+"_unselected_inactive");
	img.miwt_inactiveselected=$(id+"_selected_inactive");
	img.miwt_inactivepressed=$(id+"_pressed_inactive");
	img.miwt_inactiverollover=$(id+"_rollover_inactive");
	img.miwt_valueid=valueid;
	img.miwt_valuenode=$(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 = new Array();
			miwt.imagebutton.groups[buttonGroupId] = group;
		}
		else
		{
			// clean up
			var bid = null;
			var newa = null;
			for(var i = 0; bid = group[i]; i++) {
				var bobj = $(bid);
				if (!bobj) {
					if (!newa) {
						newa = new Array();
						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=$(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=$(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 = Event.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=Event.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=Event.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 : Event.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 (form) {
	var node = $(this+'');
	if (node.hinttexton) {
		node.value = '';
		node.hinttexton = false;
		node.style.color = null;
	}
	window.setTimeout("miwt.FieldBlurHandler($('"+node.id+"'))", 10, "JavaScript");
	return true;
}

miwt.prv_FCKSubmitHandler = function (form) {
	var node = $(this+'');
	try {
		var editor = CKEDITOR.instances[node.id];
		editor.updateElement();
	} catch(e) { 
		log4js.logger.error("Unable to update CKEditor textarea.", e);
	}			
	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 = $(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';
			}
			node.form.RegisterOnSubmitHandler(node, miwt.prv_FieldSubmitHandler.bind(node.id));
		}
		var maxlength = $(node.id+"_maxlength");
		if (maxlength) {
			var i = parseInt(maxlength.firstChild.data);
			if (!isNaN(i)) {
				node.maxlength = i;
				miwt.observe(node, "keyup", miwt.FieldKeyUpHandler, true);
			}
		}
		
		if (/\bfckeditor\b/.exec(node.className))
		{
			
			CKeditorHelper.fckactivate(node);
			node.form.RegisterOnSubmitHandler(node, miwt.prv_FCKSubmitHandler.bind(node.id));
		}
	}
});

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

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

miwt.SetupSearchableCombo = function (tag, element)
{
	if (tag != 'select' || !/\bmiwt_searchable\b/.exec(element.className))
		return;
		
	try
	{
		var field = $(element.id+"_field");
		field.combo = element;
		Object.extend(element, miwt.SearchBox.prototype);
		element.initialize(field);
		miwt.observe(field, 'keydown', miwt.SearchableComboKeydownHandler);
		var button = $(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 (exception) { log4js.logger.error("Setup searchable combo "+element.id, exception); }
}

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

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

miwt.SearchBox = function()
{
}

miwt.SearchBox.prototype = 
{
	MODE_ITERATE: 0,
	MODE_FILTER: 1,
	
	initialize: function (field)
	{
		this.field = field;
		this.selectOptions = new Array();
		var opt;
		for(var i = 0; opt = this.options[i]; i++)
			this.selectOptions[i] = opt;
		this.mode = this.MODE_ITERATE;
		var me = this;
		$w(this.className).each(function (className) {
			if (/.*_flags_(\w+)/.exec(className))
			{
				me.flags = RegExp.$1.toLowerCase();
			}
			else if (/.*_mode_filter/.test(className))
			{
				me.mode = me.MODE_FILTER;
			}
		});
		//log4js.logger.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 = new Array();
	        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 = new RegExp("(^|\\s)menu(\\s|$)");
	var PAT_MENU_ITEM = new RegExp("(^|\\s)menu_item(\\s|$)");
	var PAT_MENU_COMPONENT = new RegExp("(^|\\s)menu_component(\\s|$)");

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

		Element.addClassName(menu, "active");
		while (miwt.menu.ActiveMenuList.last() != null)
			miwt.menu.DeactivateLastActiveMenu();
		Element.siblings(menu).each(function(el) {
			if (Element.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;
		Element.removeClassName(menu, "active");
		if (Element.up(menu, "div.menu_bar")) {
			miwt.stopObserving(menu, "mouseover", miwt.menu.ShowMenu);
			Element.siblings(menu).each( function(el) {
				miwt.stopObserving(el, "mouseover", miwt.menu.ShowMenu);
			});
		}
	};
	miwt.menu.MenuItemHit = function(evt) {
		Event.stop(evt);
		var target = Event.findElement(evt, 'li').down('.menu_item');
		if (target && !(target.next('.menu_items'))) {
			while (miwt.menu.ActiveMenuList.last()) miwt.menu.HideMenu(evt);
			var form = Event.findElement(evt, 'form');
			form.elements['btnhit'].value = target.id;
			form.MIWTSubmit();
		}
	};
	miwt.menu.HideMenu = function(evt) {
		if (evt.keyCode && evt.keyCode != Event.KEY_ESC) return;
		if (Event.isRightClick(evt)) return;
		
		Event.stop(evt);
		miwt.menu.DeactivateLastActiveMenu();
		if (miwt.menu.ActiveMenuList.last() == null) {
			miwt.stopObserving(document, "click", miwt.menu.HideMenu);
			miwt.stopObserving(document, "keydown", miwt.menu.HideMenu);
		}
	};
	miwt.menu.ShowMenu = function(evt) {
		var target = Event.findElement(evt, 'a')
		if (miwt.menu.ActivateMenu(evt)){
			Event.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) {Event.element(evt).addClassName('active');});
				miwt.observe(node, "mouseleave", function(evt) {Event.element(evt).removeClassName('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 = $(checkbox.name+"_all");
	if (!selectall)
		return;
	if (!selectall.checkboxes)
	{
		selectall.checkboxes = new Array();
		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 = Event.element(event);
	var box;
	for(var i = 0; box = selectall.checkboxes[i]; i++) {
		box.checked = selectall.checked;
	};
}

miwt.selectAllChildChanged = function (event)
{
	var box = Event.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={};

miwtajax.READY_STATE_UNINITIALIZED = 0;
miwtajax.READY_STATE_LOADING = 1;
miwtajax.READY_STATE_LOADED = 2;
miwtajax.READY_STATE_INTERACTIVE = 3;
miwtajax.READY_STATE_COMPLETE = 4;

miwtajax.serial = 1;
miwtajax.ajax_failed_update_callback = [];
miwtajax.ajax_request_complete_callback = [];

/**
 * Get the document content type.
 */
miwtajax.getDocType=function()
{
	// FUTURE : add support for parameters to specify HTML level support (3, 4, 5, etc) or other content type specific information
	var d = document;
	var ct = d.contentType;
	if(!ct) {
	  var dt = d.doctype || ''; // Check doctype before namespaceURI due to google chrome bug
	  if(dt.systemId || dt.publicId) dt = dt.systemId + dt.publicId;
	  else dt = (d.documentElement || d.body).namespaceURI || '';
	  ct = dt.match(/xhtml/i) ? "application/xhtml+xml" : "text/html";
	}
	return ct;
};
/**
 * 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;">'
		+$$("dfn.miwt_loading_message").pop().firstChild.data
        + "<div id=\"miwt_loading_message_503\" style=\"display: none;\">" + $$("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_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, "JavaScript");
	},

	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 scrollTop = 0;
		var scrollLeft = 0;
		if (document.documentElement)
			scrollTop = document.documentElement.scrollTop;
		else if (document.body)
			scrollTop = document.body.scrollTop;
		if (document.documentElement)
			scrollLeft = document.documentElement.scrollLeft;
		else if (document.body)
			scrollLeft = document.body.scrollLeft;
		this.dialog.firstChild.style.top=(scrollTop+((parseInt(h)/2)-17))+"px";
		this.dialog.firstChild.style.left=(scrollLeft+((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_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();
}

/**
 * Create an InputProcessor object to process the miwt form.
 * @param form the form object.
  * @param ajax_request_complete_callback an array of functions to be called after
  * an AJAX request is completed. An object is passed giving the form
  * object as the property 'source'.
  * @param ajax_failed_update_callback an array of functions to call when the update could not be processed. 
  * An object is passed giving the form object as the property 'source'.
 */
miwtajax.InputProcessor=function(form, ajax_request_complete_callback, ajax_failed_update_callback)
{
	this.req = null;
	
	// multipart implies file upload
	if (form.encoding && form.encoding.match(/multipart/))
	{
		var element;
		for(var i = 0; element = form.elements[i]; i++) {
			if (element.type=='file' && element.value != null && element.value.length > 0)
				return;
		}
	}

	this.form = form;
	this.ajax_request_complete_callback = ajax_request_complete_callback;
	this.ajax_failed_update_callback = ajax_failed_update_callback;
	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;
	}
	
	miwtajax.serial++;
	var params = Form.serialize(this.form) + "&ajax="+miwtajax.serial;

	// 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;
		this.timeout_callback = function() {
			ajax.doFailsafe.call(ajax);
		}
			
		this.timeout=setTimeout(this.timeout_callback, 15000, "JavaScript");
	}

	miwt.ajaxprogress.start();
		
	// Initiate the asynchronous call
	//log4js.logger.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 = Element.select(this.form, "dfn.ajax_uri").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.getDocType());
		}
	  },

	  /**
	   * 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="";
		  	var partNodesFound=false;
		  	var partnode;
		  	for(var j =0; partnode = node.childNodes[j]; 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(var 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_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 = Prototype.emptyFunction; // prevents memory leaks on some browsers
		  	
	  		if (this.timeout) {
		  		window.clearTimeout(this.timeout);
		  		this.timeout = null;
		  	}
		  		
	  		var failsafe = false;
	  		var failsafeSkipParam = false;
	  		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");
                if(retryTime != null)  {
                    var mesgElement = $("miwt_loading_message_503");
                    mesgElement.style.display = "block";
                    mesgElement.innerHTML =
                        mesgElement.innerHTML.replace("$(seconds)", retryTime); 
                    var form = this.form;
                    var retryFunc = function() {
                    	mesgElement.style.display = "none";
                    	form.submit();
                    };
                    var retryTimeMillis = parseInt(retryTime) * 1000;
                    window.setTimeout(retryFunc, retryTimeMillis);
                }
                else {
                	this.form.submit();
                }
                return;
            }
	  		else if (this.req.status==301 || this.req.status==302)
	  		{
	  			// perform redirect
	  			//log4js.logger.debug("Redirect HTTP response: "+this.req.status+" => "+this.req.getResponseHeader("Location"));
		  		miwt.ajaxprogress.stop();
	  			this.req=null;
	  			window.location.href=this.req.getResponseHeader("Location");
	  			return;
	  		}
	  		else if (this.req.status!=200)
	  		{
	  			log4js.logger.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
	  			log4js.logger.debug("Received HTML response: "+this.req.responseText);
	  			failsafe = true;
	  		}
	  		else
	  		{
	  			//log4js.logger.debug("Received AJAX XML: "+this.req.responseText);
	  			var actionNodes = this.req.responseXML.getElementsByTagName("action");
	  			var action = "reload";
	  			if (actionNodes.length > 0)
	  			{
	  				action = actionNodes.item(0).firstChild.nodeValue;
	  			}
	  			else
	  			{
		  			log4js.logger.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 = new Array();
			  				stack.push(firstChild);
			  				while (stack.length > 0)
			  				{
			  					var node = stack.pop();
			  					if (node.nodeType == 3)
			  					{
						  			log4js.logger.error("Parse error: "+node.nodeValue);
			  					}
			  					else
			  					{
			  						for(var i =0; i < node.childNodes.length; i++)
			  						{
			  							stack.push(node.childNodes.item(i));
			  						}
			  					}
			  				}
			  			}
			  			
		  				break processXML;
	  				}

		  			log4js.logger.error("Parse error. firstChild is " 
	  					+ (firstChild == null ? "null" : (firstChild.nodeName + " -> " + firstChild.innerHTML)));
	  				failsafe = true;
	  			}
	  			else if (action=='reload')
	  			{
		  			//log4js.logger.debug("Reload action");
	  				failsafe = true;
	  				failsafeSkipParam = true;
	  			}
	  			else if (action=='nochange')
	  			{
					break processXML;
	  			}
	  			else if (action=='update')
	  			{
	  				var lastFocusId = miwt.lastFocusId;
	  				var updatedNodes = new Array();

	  				// handle closing windows
	  				var 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 = $(refid);
		  					if (n) {
		  						miwt.closeWindow(n);
		  					}
	  				}
	  				
	  				// handle content updates
	  				var contentNodes = this.req.responseXML.getElementsByTagName("component");
	  				try
	  				{
		  				for(var i=0; i<contentNodes.length; i++)
		  				{
		  					var updatenode = contentNodes.item(i);
		  					var refid = updatenode.attributes.getNamedItem("ref").nodeValue;
		  					var docnode = $(refid);
		  					if (docnode == null) {
					  			log4js.logger.info("Node not found: "+refid+", likely caused by update to component that was not rendered here");
		  						failsafe = true;
		  						break;
		  					}
		  					miwt.closeCKEditors(docnode);
	  						var newContent=this.decomposeParts(updatenode);
	  						var tmpnode=document.createElement("div");
	  						try {
		  						if (document.all && docnode.tagName!=null && docnode.tagName.toUpperCase() == 'TD' && !newContent.match(/^</))
			  						tmpnode.innerHTML = "<span>"+newContent+"</span>";
			  					else
			  						tmpnode.innerHTML = newContent;
	  						}
	  	  					catch (exception)
	  	  					{
	  	  						log4js.logger.error("Exception creating DOM node from "+newContent, exception);
	  			  				failsafe = true;
	  			  				break;
	  	  					}
		  					tmpnode = Element.cleanWhitespace(tmpnode);
	  						var newnode = tmpnode.firstChild;
	  						if (tmpnode.childNodes.length==1 
	  							&& newnode.nodeName == docnode.nodeName 
	  							&& newnode.getAttribute("id") == docnode.getAttribute("id"))
	  						{
		  						// replace the existing node
			  					//log4js.logger.debug("Replacing "+docnode.nodeName+" node for "+refid+" with "+newContent.length+" bytes: "+newContent);
			  					try{__i2rd_fixIELeak(docnode, false);} catch(e) { 
									log4js.logger.error("(1)Unable to cleanup JScript references for " + refid, e); 
								}
		  						docnode.parentNode.replaceChild(newnode, docnode);
		  						updatedNodes.push(newnode);
	  						}
	  						else
	  						{
	  							// replace all child nodes
			  					//log4js.logger.debug("Replacing child nodes of "+docnode.nodeName+" node for "+refid+" with "+newContent.length+" bytes: "+newContent);
			  					try {
									__i2rd_fixIELeak(docnode, true);
								} catch(e) { 
									log4js.logger.error("(1)Unable to cleanup JScript references for " + refid, e); 
								}
	  							// 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);
	  						}
		  				}
					}
  					catch (exception)
  					{
  						log4js.logger.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");
  						tmpnode.innerHTML = this.decomposeParts(windowNodes.item(i));
  						var newnode = tmpnode.firstChild;
  						var windowcon = $$("form#"+this.form.id+" > div.miwt").pop();
  						if (windowcon) {
  							var refid = windowNodes.item(i).attributes.getNamedItem("ref").nodeValue;
  							var existing = $(refid);
  							if (existing) {
			  					try{__i2rd_fixIELeak(existing, false);} catch(e) { 
									log4js.logger.error("(1)Unable to cleanup JScript references for " + refid, e); 
								}
  								existing.parentNode.replaceChild(newnode, existing);
  							}
  							else {
	  							windowcon.appendChild(newnode);
	  						}
  							updatedNodes.push(newnode);
	  						try{__i2rd_domupdate_fire(newnode);}catch(e){}
  						}
  						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/);
		  					//log4js.logger.debug("Executing JS : "+script);
		  					if (window.execScript)
		  						window.execScript(script, 'JavaScript');
		  					else
			  					window.eval(script);
		  				}
		  				if (locref || oldloc != window.location.href) // page location has been changed
		  				{
		  					/*
		  					if (locref)
			  					log4js.logger.debug("Page location changed in script");
			  				else
			  					log4js.logger.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 = $(lastFocusId);
		  					if (node!=null && node.focus) {
		  						//log4js.logger.debug("Setting focus back to "+lastFocusId);
                                try {
		  						    node.focus();
		  						    focusChanged = true;
                                } catch(e) {
                                    log4js.logger.info("Unable to reset focus for ID = "+lastFocusId, e);
                                }
		  					}
		  				}
		  				
		  				updatedNodes.each(function(n) {
	  						try{__i2rd_domupdate_fire(n);}catch(e){}
		  					miwt.setup(n);
		  					miwt.autoSizeWindow($(n).up("div.window"));
		  				});
		  				
		  				// 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 (Prototype.Browser.IE) {
			  				var fcklist = Element.select(this.form, 'textarea.fckeditor');
			  				if (!focusChanged && fcklist.length > 0) {
			  					var el, nodes = Element.select(this.form, 'input[type="text"]');
			  					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 = Element.select(fck.parentNode, 'iframe');
			  									if (iframes.length == 0) {
				  									window.setTimeout(f, 100);
				  									return;
			  									}
			  									var iframe;
			  									while (iframe = iframes.shift()) {
			  										miwt.observe(iframe, "load", function() {
			  											el.focus(); 
			  										});
			  										// in case the iframe is already loaded
			  										el.focus();
			  									}
			  								}
			  							};
			  							window.setTimeout(f, 100);
			  							break;
			  						}		  							
			  					}
			  				}
		  				}
		  				
		  				// scroll to the top most update
		  				if (updatedNodes.length > 0)
		  				{
			  				var docHeight, scrollTop, clientHeight, scrollBottom, de = document.documentElement, db = document.body;
			  				if (de)
			  				{
				  				scrollTop = de.scrollTop;
				  				clientHeight = de.clientHeight;
				  				docHeight = de.scrollHeight;
				  				scrollBottom = scrollTop+clientHeight;
			  				}
			  				else
			  				{
				  				scrollTop = db.scrollTop;
				  				clientHeight = db.clientHeight;
				  				docHeight = db.scrollHeight;
				  				scrollBottom = scrollTop+clientHeight;
			  				}
			  				if(docHeight > clientHeight)
			  				{
				  				var scrollNode;
				  				var miny = -1;
				  				var node;
				  				for(var i = 0; node = updatedNodes[i]; i++)
				  				{
				  					if (!node.id.match(/c_.*/) || !miwt.isInActiveWindow(node))
				  						continue;
				  					var y = Element.cumulativeOffset(node)[1];
			  						//log4js.logger.debug("Top for "+node.id+" is "+y);
				  					if (miny == -1 || y < miny)
				  					{
				  						miny = y;
				  						scrollNode = node;
				  					}
				  				}
				  					
				  				if (miny != -1 && (miny < scrollTop || 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);
				  						}
				  					}
				  					
			  						//log4js.logger.debug("Scrolling to "+miny+" from "+scrollTop);
					  				window.scrollTo(0, miny);
				  				}
				  			}
		  				}
						updatedNodes = null;
  					}
  					catch (exception)
  					{
  						log4js.logger.error("Exception processing updates", exception);
		  				failsafe = true;
  						break processXML;
  					}
	  				
	  				this.form.CleanOnSubmitHandlers();
	  			}
	  			else if (action=="error")
	  			{
		  			log4js.logger.error("Error occurred during rendering");

	  				// an error occurred while creating the response
	  				var errormessage = "";
	  				var 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 = "";
	  				var 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
	  			{
	  				// unknown action code
		  			log4js.logger.error("Unknown action: "+action);
	  				failsafe = true;
	  			}
	  		}
	  		
	  		// free the request object
			this.req = null;
			// stop the progress window
	  		miwt.ajaxprogress.stop();
			// enable form processing
			window.miwtReady = 1;

	  		// Something went wrong, reload the page
	  		if (failsafe)
	  		{
	  			this.doFailsafe(failsafeSkipParam);
		  		//log4js.logger.debug("MIWT ajax response performed failsafe");
	  		}
			else
			{
				// Clear this for the next form submit
				this.form.ResetTransient();
			}
			if (this.ajax_request_complete_callback != null)
	  		{
		  		window.setTimeout(this.doRequestCompleteCallback.bind(this), 10);
	  		}
	  		//log4js.logger.debug("MIWT ajax response processed");
	  	}
	  },

	  doRequestCompleteCallback: function() {
			var callback_event = new Object();
			callback_event.source = this.form;
			var f;
			for(var i=0; f = this.ajax_request_complete_callback[i]; i++)
				f.call(this.form, callback_event);
	  },
	  
      /**
       * Fall back to reloading the page.
       */	  
	  doFailsafe:function(skipParam)
	  {
	  		if (this.ajax_failed_update_callback != null)
	  		{
	  			var callback_event = new Object();
	  			callback_event.source = this.form;
	  			var f;
	  			for(var i = 0; f = this.ajax_failed_update_callback[i]; i++) {
		  			if (!f.call(this.form, callback_event))
			  			return;
			  	}
	  		}
	  		//log4js.logger.debug("Failsafe: reloading page");
	  		this.failsafe = true;
	  		if(!!skipParam)
	  			window.location.href=this.form.action;
	  		else
	  			window.location.href=this.form.action + (this.form.action.include('?') ? '&' : '?') + "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=$(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 = Event.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 (element, containerId, cardId)
{
	element.cardid = containerId;
	element.cardname = cardId;

	if (element.type) 
	{
		switch (element.type.toLowerCase()) 
		{
			case 'checkbox':
			case 'radio':
				miwt.observe(element, 'click', miwt.CardContainerSelectEvent);
				break;
			case 'password':
			case 'text':
			case 'textarea':
			case 'select-one':
			case 'select-multiple':
				miwt.observe(element, 'change', miwt.CardContainerSelectEvent);
				break;
		}
    }
    else
    {
		Event.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=new Array();

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;
	}
}

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

miwt.moveWindowRelative = function (object,xdelta,ydelta)
{
	var newX1 = parseInt(object.style.left)+xdelta;
	var newY1 = parseInt(object.style.top)+ydelta;
	object.style.left=newX1+"px";
	object.style.top=newY1+"px";
}

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

miwt.getWindowForElement = function (element)
{
    while (element!=null)
	{
    	var tn = (element.tagName || "").toLowerCase();
    	if(tn == "div")
    	{
			var classNames = $w(element.className);
		    if (classNames.include("window")
		    	|| classNames.include("inlinewindow"))
			{
				return element;
			}
    	}

		if (element.parentNode)
			element=element.parentNode;
		else
			element=element.parentElement;
	}
    log4js.logger.error("miwt.getWindowForElement(" + element + "): Unable to find element parent that is a window. element.id = "
    		+ (element ? element.id : "null") + ", element.nodeName = " + (element ? element.nodeName : "null")
    		+ ", element.class = " + (element ? element.className : "null"));
	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 = new Array();
	
	// 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.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 ($(object.id+"_title_div")==null)
		return;

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

    if ($(object.id+"_menu_btn")!=null)
    	miwt.button.imageButtonActivate(object.id+"_menu_btn");
    
    if ($(object.id+"_minimize_btn")!=null)
	    miwt.button.imageButtonActivate(object.id+"_minimize_btn");
    
    if ($(object.id+"_maximize_btn")!=null)
	    miwt.button.imageButtonActivate(object.id+"_maximize_btn");
    
    if ($(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.windowlist[i]);
			if (w !=null && w != object) {
			    miwt.deactivateWindow(w);
				if (dialog)
					miwt.disableChildren(w);
			}
		}
	}
	// 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 ($(object.id+"_title_div")==null)
		return;

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

    if ($(object.id+"_menu_btn")!=null)
    	miwt.button.imageButtonDeactivate(object.id+"_menu_btn");
    
    if ($(object.id+"_minimize_btn")!=null)
	    miwt.button.imageButtonDeactivate(object.id+"_minimize_btn");
    
    if ($(object.id+"_maximize_btn")!=null)
	    miwt.button.imageButtonDeactivate(object.id+"_maximize_btn");
    
    if ($(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.windowlist[0]);
		if (!top) {
			log4js.logger.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.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.windowlist[i]);
				if (!otherwindow.className.match(/inlinewindow/))
				{
					var titletd=$(otherwindow.id+"_title_td");
					if (titletd != null && titletd.className.match(/activewindowtitle/))
						return false;
				}
			}
		}
		return true;
	}
	
	var titletd=$(object.id+"_title_td");
	if (titletd==null)
	{
		return false;
	}
	
	return !!titletd.className.match(/activewindowtitle/);
}

miwt.getWindowContent = function (object)
{
	return $(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.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(Event.element(evt));
	if (miwt.windowMoveTarget==null)
	    return;
	Event.stop(evt);
	miwt.lastWindowX=Event.pointerX(evt);
	miwt.lastWindowY=Event.pointerY(evt);
	miwt.observe(document.body, "mousemove", miwt.doWindowMove, true);
	miwt.observe(document.body, "mouseup", miwt.endWindowMove, true);
	var td = $(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';
	miwt.activateWindow(miwt.windowMoveTarget);
	$(miwt.windowMoveTarget.id+"_content_div").style.visibility="hidden";
}

 miwt.doWindowMove = function (evt)
{
	Event.stop(evt);	
	var difX=Event.pointerX(evt)-miwt.lastWindowX;
	var difY=Event.pointerY(evt)-miwt.lastWindowY;
	miwt.moveWindowRelative(miwt.windowMoveTarget, difX, difY);
	miwt.lastWindowX=Event.pointerX(evt);
	miwt.lastWindowY=Event.pointerY(evt);
}

miwt.endWindowMove = function (evt)
{
	$(miwt.windowMoveTarget.id+"_title_td").style.cursor=miwt.lastWindowCursor;
	document.body.style.cursor=miwt.lastDocumentCursor;
	miwt.stopObserving(document.body, "mousemove", miwt.doWindowMove, true);
	miwt.stopObserving(document.body, "mouseup", miwt.endWindowMove, true);
	$(miwt.windowMoveTarget.id+"_content_div").style.visibility="visible";
	Event.stop(evt);
	miwt.checkForPermiatingElements(miwt.windowMoveTarget);
	miwt.windowMoveTarget=null;
}

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

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

	var difX=Event.pointerX(evt)-miwt.lastWindowX;
	var difY=Event.pointerY(evt)-miwt.lastWindowY;
	miwt.lastWindowX=Event.pointerX(evt);
	miwt.lastWindowY=Event.pointerY(evt);

	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.windowResizeTarget.id+"_table");
	var tableWidth=parseInt(table.style.width);
	var tableHeight=parseInt(table.style.height);
	
	var content=$(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.body, "mousemove", miwt.doWindowResize, true);
	miwt.stopObserving(document.body, "mouseup", miwt.endWindowResize, true);
	$(miwt.windowResizeTarget.id+"_content_div").style.visibility="visible";
	Event.stop(evt);
	
	miwt.checkForPermiatingElements(miwt.windowMoveTarget);
	miwt.windowResizeTarget=null;
}

/** Prevents a window from getting focus. */
miwt.disableWindowActivation = function (evt)
{
	Event.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(Event.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);
	var height=parseInt(object.offsetHeight);
	
	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 scrollTop = 0;
		if (document.documentElement)
			scrollTop = document.documentElement.scrollTop;
		if (document.body.scrollTop && scrollTop == 0)
			scrollTop = document.body.scrollTop;
		var initialTop = scrollTop + 10;

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

		// check for overlap
		for(i=0; i<miwt.windowlist.length; i++)
		{
		    if (miwt.windowlist[i]!=windowObject.id)
			{
				var otherwindow=$(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 scrollLeft = 0;
		if (document.documentElement)
			scrollLeft = document.documentElement.scrollLeft;
		if (document.body.scrollLeft && scrollLeft == 0)
			scrollLeft = document.body.scrollLeft;

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

		// check for overlap
		for(i=0; i<miwt.windowlist.length; i++)
		{
		    if (miwt.windowlist[i]!=windowObject.id)
			{
				var otherwindow=$(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=$(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=$(name);
	var windowTitle=$(name+"_table");
	// TODO: windowTable is now the titlebar - update refs to windowTable
	var windowTable=$(name+"_table");
	var windowContent=$(name+"_content_div");
    var title=$(name+"_title_td");
    var active=miwt.isWindowActive(windowObject);

	//log4js.logger.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.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=$(name+"_windowresize_nw_div");
			miwt.observe(resize, "mousedown", miwt.beginWindowResize, false);
			resize.resizeDir="nw";
			resize=$(name+"_windowresize_ne_div");
			miwt.observe(resize, "mousedown", miwt.beginWindowResize, false);
			resize.resizeDir="ne";
			resize=$(name+"_windowresize_sw_div");
			miwt.observe(resize, "mousedown", miwt.beginWindowResize, false);
			resize.resizeDir="sw";
			resize=$(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.windowlist[i]);
			if (otherwindow!=null
				&& miwt.isWindowOverlapped(windowObject, otherwindow))
			{
			    if (active)
			    {
					//log4js.logger.debug("Hiding elements for "+otherwindow.id+" (other)");
				    miwt.hidePermiatingElements(otherwindow);
			    }
			    else
			    {
					//log4js.logger.debug("Hiding elements for "+windowObject.id+" (me)");
				    miwt.hidePermiatingElements(windowObject);
				}			    
			}
		}
	}
	
	if (active)
	{
		//log4js.logger.debug("Showing elements for "+windowObject.id);
		miwt.showPermiatingElements(windowObject);
	}

	if (!Element.hasClassName(windowObject, "inlinewindow"))
	{
		var  form = Selector.findElement([windowObject].concat(windowObject.ancestors()), 'form', 0);
		form.RegisterOnSubmitHandler(windowObject, miwt.prv_saveWindowPosition.bind(name));

		miwt.autoSizeWindow(windowObject, windowContent, windowTitle);
	}

	// Handle initial position
	miwt.setInitialPosition(windowObject);
	
	if (active || !Element.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
	if(
		(!windowObject.style.height || windowObject.style.height == 'auto')
		|| !!windowObject.autosized
		)
		
	{
		//log4js.logger.info("Auto sizing window " + windowObject.id);
		windowContent = windowContent || $(windowObject.id+"_content_div");
		var hb = 20, contentNode, list = $A(windowContent.childNodes);
		while( (contentNode = list.pop()) && contentNode.nodeType != 1);
		if(contentNode && contentNode.nodeType == 1)
		{
			/* Workaround for min sizing on opera/ie. */
			contentNode.style.minHeight="2em";
			windowTitle = windowTitle || $(windowObject.id+"_table");
			var wth = windowTitle.offsetHeight,cnh,h = miwt.getWindowHeight() - 40;
			try{Element.cleanWhitespace(contentNode);}catch(e){/*MSIE*/}
			cnh = contentNode.offsetHeight ? contentNode.offsetHeight : 0;
			if(contentNode.firstChild === contentNode.lastChild && contentNode.firstChild.offsetHeight > cnh)
				cnh = contentNode.firstChild.offsetHeight;
			var ih = wth + cnh + hb;
			if(ih > h) ih = h;
			if(ih > windowObject.offsetHeight)
				windowObject.style.height = ih + "px";
			else if(windowObject.autosized && (cnh + wth + 40) < windowObject.offsetHeight)
				windowObject.style.height = (cnh + wth + hb) + "px";
			
			// This, autosized, should get replaced if the whole window is updated due to a Dimension change on Window.java
			windowObject.autosized = true; 
		}
	} 
	/*else {
		log4js.logger.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
			Element.getStyle(node, 'z-index') || 0,  // z-index
			true, // focusable
			!isInlineWindow // moveable
		);
	}
});

miwt.isResizable = function(node) {
	return node && $(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;
//log4js.logger.info("User agent: "+navigator.userAgent);

miwt.isElementPermiating = function (node) {
	if (!node.tagName)
		return false;
	var tag = node.tagName.toLowerCase();
	var t;
	for(var i = 0; t = miwt.elementPermiating[i]; 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 element, node;
	for(var i = 0; element = miwt.elementPermiating[i]; i++) {
		var nodes = object.getElementsByTagName(element);
		for(var j = 0; node = nodes[j]; 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 element, node;
	for(var i = 0; element = miwt.elementPermiating[i]; i++) {
		var nodes = object.getElementsByTagName(element);
		nodeLoop:
		for(var j = 0; node = nodes[j]; j++) {
			// check if parent visibility is set
			var parent = node.parentNode;
			while (parent) {
				if (miwt.isVisibilitySet(parent)) {
					try {
						node.style.visibility=null;
						break nodeLoop;
					} catch (e) { }
				}
				parent = parent.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)
{
	return (node.style 
		&& node.style.visibility
		&& node.style.visibility != null
		&& node.style.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=$(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=$(containerDivId);
	if (divObject==null)
		return;
	
	var triggerObject=$(triggerId);
	
	if (triggerObject!=null) {
		var pos = Element.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";
		}

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

	if (inline)
		divObject.style.display="inline";
	else
		divObject.style.visibility="visible";
		
	// hide all exclusive containers
	if (Element.hasClassName(triggerObject, "miwt_collapsable_exclusive"))
	{
		var el, list;
		list = $$('.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=$(containerDivId);
	if (divObject==null)
		return;
	
	if (inline)
		divObject.style.display="none";
	else
		divObject.style.visibility="hidden";
		
	Element.removeClassName(divObject, "miwt_collapsable_shown");
	Element.addClassName(divObject, "miwt_collapsable_hidden");

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

miwt.collapseContainerToggle = function (event) {
	Event.stop(event);
	var element = Event.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 = $(node.id.replace("_collapsable_trigger", "_collapsable"));
		node.state = $(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 = $(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 = $(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 = new Object();
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
		&& $(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 = new Array();
			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=$(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 = Event.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 = new Array();

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

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 = $(node.id+"_message");
	var reqnode = $(node.id+"_required");
	if (msgnode && msgnode.firstChild && reqnode && reqnode.firstChild) {
		var msg = msgnode.firstChild.data;
		var req = reqnode.firstChild.data;
		//log4js.logger.debug("validation.FormValidation_Register("+match[1]+", "+msg+", "+type+", "+req+")");
		var el = $(match[1]);
		if (el)
			validation.FormValidation_Register(el, msg, type, req);
		else
			log4js.logger.error("Could not find element "+match[1]+" for validation");
	}
});

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

/** Functions for table operations. */

miwt.tableRowOnMouseOver = function (evt)
{
	var tr = Event.element(evt);
	while (tr != null && (!tr.tagName || tr.tagName.toLowerCase() != 'tr'))
		tr = tr.parentNode;
	if (tr == null || !tr.highlightColor)
		return;
	var theCells = tr.getElementsByTagName('td');
	var rowCellsCnt  = theCells.length;
	for (var c = 0; c < rowCellsCnt; c++) {
		var cell = theCells[c];
		cell.saveBackgroundColor = cell.style.backgroundColor || tr.style.backgroundColor;
		cell.style.backgroundColor = tr.highlightColor;
	}
}

miwt.tableRowOnMouseOut = function (evt)
{
	var tr = Event.element(evt);
	while (tr != null && (!tr.tagName || tr.tagName.toLowerCase() != 'tr'))
		tr = tr.parentNode;
	if (tr == null || !tr.highlightColor)
		return;
	var theCells = tr.getElementsByTagName('td');
	var rowCellsCnt  = theCells.length;
	for (var c = 0; c < rowCellsCnt; c++) {
		var cell = theCells[c];
		cell.style.backgroundColor = cell.saveBackgroundColor;
	}
}

miwt.tableRowModification = function (element)
{
	if (element.modificationSet)
		return;
	element.modificationSet = true;

	var tr = element.parentNode;
	while (tr != null && (!tr.tagName || tr.tagName.toLowerCase() != 'tr'))
		tr = tr.parentNode;
	if (tr == null)
		return;
		
	var theCells = tr.getElementsByTagName('td');
	var rowCellsCnt  = theCells.length;
	for (var c = 0; c < rowCellsCnt; c++) {
		var cell = theCells[c];
		cell.style.backgroundColor = element.modificationColor;
		cell.saveBackgroundColor = element.modificationColor;
	}
}

miwt.AddSetupHandler([ 'table' ], function (tag, node) {
	if (tag != 'table')
		return;
	// column moving
	var moving = $("columnmoving_"+node.id);
	if (moving) {
		var headers = Element.select(node, "thead th");
		var i, n;
		for(i = 0; n = headers[i]; i++) {
			if (/\bcontrol\b/.test(n.className))
				continue;
			n.id = "columnmove_"+node.id+"_th_"+i;
			Element.addClassName(n, "dnd_source");
			miwtdnd.setupDragSource(n);
			Element.addClassName(n, "dnd_target");
			miwtdnd.setupDropTarget(n);
		}
	}
	
	// highlighting	
	if (!!/\bmiwt_highlight\b/.exec(node.className)) {
		var highlight = $(node.id+"_highlight");
		var modification =$(node.id+"_modification");
		if (!highlight || !modification)
			return;
		var highlightColor = highlight.firstChild.data;
		var modificationColor = modification.firstChild.data;
			
		var trs = $A(node.getElementsByTagName('tr'));
		var node2;
		for(var i = 0; node2 = trs[i]; i++) {
			// must be 'tr', not in head
			if (node2.parentNode.parentNode != node)
				continue;
			if (node2.parentNode.tagName.toLowerCase() == "thead")
				continue;
	
			node2.highlightColor = highlightColor;
			node2.modificationColor = modificationColor;
			miwt.observe(node2, 'mouseover', miwt.tableRowOnMouseOver, false);
			miwt.observe(node2, 'mouseout', miwt.tableRowOnMouseOut, false);
			
			if (!modificationColor)
				continue;
				
			// find inputs in the row
			var inputs = $A(node2.getElementsByTagName('input'));
			inputs.concat(node2.getElementsByTagName('select'));
			var rownode;
			for(var j = 0; rownode = inputs[j]; j++) {		
				if (rownode.className && rownode.className.match(/miwt_row_select/))
					continue;
	
				rownode.modificationColor = modificationColor;
				rownode.observer = new Form.Element.EventObserver(rownode, miwt.tableRowModification);
			}
		}
	}	
});

}// 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;
	if (!miwtdnd.active) {
		if (Math.abs(Event.pointerX(evt) - miwtdnd.startX) > 2 || Math.abs(Event.pointerY(evt) - miwtdnd.startY) > 2) {

			Event.stop(evt);
			miwtdnd.active = true;
			if (miwtdnd.menu) {
				miwtdnd.menu.parentNode.removeChild(miwtdnd.menu);
				miwtdnd.menu = null;
			}
			Element.addClassName(document.body, 'dnd_active');
			var ie6 = (Prototype.Browser.IE && navigator.userAgent.indexOf('MSIE 6') > -1);
			var ie7 = (Prototype.Browser.IE && navigator.userAgent.indexOf('MSIE 7') > -1);
			// TODO: test ie8
			
			miwtdnd.feedbackElement = miwtdnd.dragSource.cloneNode(true);
			if (ie6 || ie7) {
				if (miwtdnd.feedbackElement.tagName.toLowerCase() == 'td') {
					miwtdnd.feedbackElement = Element.wrap(miwtdnd.feedbackElement, 'tr');
					miwtdnd.feedbackElement.style.className = miwtdnd.dragSource.style.className;
					miwtdnd.feedbackElement = Element.wrap(miwtdnd.feedbackElement, 'table');
					miwtdnd.feedbackElement.style.className = miwtdnd.dragSource.parentNode.style.className;
				}
				else if (miwtdnd.feedbackElement.tagName.toLowerCase() == 'tr') {
					miwtdnd.feedbackElement = Element.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");
				}
			}
			Element.removeClassName(miwtdnd.feedbackElement, "dnd_target");
			Element.removeClassName(miwtdnd.feedbackElement, "dnd_source");
			Element.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 = Element.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 {
		Event.stop(evt);
	}

	if (miwtdnd.feedbackElement) {
		var scrollOffsets;
		if (miwtdnd.feedbackElement.style.position == 'absolute') {
			scrollOffsets = { left: 0, top: 0 };
		}
		else {
			scrollOffsets = document.viewport.getScrollOffsets();
		}
		miwtdnd.feedbackElement.style.left = (Event.pointerX(evt)-scrollOffsets.left+miwtdnd.feedbackOffsetLeft)+"px";
		miwtdnd.feedbackElement.style.top = (Event.pointerY(evt)-scrollOffsets.top+miwtdnd.feedbackOffsetTop)+"px";
	}
	
	// set drop target class name for CSS styled feedback
	var dropEl = Event.element(evt);
	if (dropEl == miwtdnd.feedbackElement)
		return;
	while (dropEl && (!dropEl.className || !/\bdnd_target\b/.test(dropEl.className)))
		dropEl = dropEl.parentNode;
	if (dropEl && !/\bdnd_target\b/.test(dropEl.className))
		dropEl = null;
	if (!miwtdnd.isCompatible(miwtdnd.dragSource, dropEl))
		dropEl = null;
	var addStyles = [ 'dnd_target_active' ];
	var removeStyles = [ ];
	if (dropEl && dropEl.locations && dropEl.locationRows && dropEl.locationColumns) {
		var targetOffset = Element.cumulativeOffset(dropEl);
		var targetDim = Element.getDimensions(dropEl);
        var row = Math.floor((Event.pointerY(evt) - targetOffset.top) / Math.max(1, targetDim.height / dropEl.locationRows));
        var col = Math.floor((Event.pointerX(evt) - 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];
		//log4js.logger.info("Drop "+dropEl.id+" location at cell "+row+","+col+", class "+dropClass);
        if (dropClass) {
        	addStyles.push(dropClass);
        	removeStyles = dropEl.allClassNames.without(dropClass);
        } else {
        	removeStyles = dropEl.allClassNames.clone();
        }
	}
	if (miwtdnd.dropactiveset) {
		var el, list;
		list = $$(".dnd_target_active");
		while (el = list.pop()) {
			if (el != dropEl)
				el.className = el.className.replace(/\bdnd_target_active\S*\b/g, ' ').strip();
		}
	}
	miwtdnd.dropactiveset = false;
	if (dropEl && dropEl.className) {
		var el;
		while ((el = addStyles.pop())) {
			if (!new RegExp('\b'+el+'\b').test(dropEl.className)) {
				Element.addClassName(dropEl, el);
			}
		}
		while ((el = removeStyles.pop())) {
			Element.removeClassName(dropEl, el);
		}
		miwtdnd.dropactiveset = true;
	}
};

miwtdnd.window_mouseup = function (evt) {
	//log4js.logger.info("Stopping DnD");
	miwt.stopObserving(document, "mousemove", miwtdnd.window_mousemove, true);
	miwt.stopObserving(document, "mouseup", miwtdnd.window_mouseup, true);
	Element.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;
	
	Event.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;
    //log4js.logger.info("Stop operation");
	miwtdnd.active = false;
	miwtdnd.dragSource = null;
	miwtdnd.dropTarget = null;
	miwtdnd.startX = null;
	miwtdnd.startY = null;
	if (miwtdnd.feedbackElement) {
		Element.remove(miwtdnd.feedbackElement);
		miwtdnd.feedbackElement = null;
	}
	if (miwtdnd.dropactiveset) {
		var el, list;
		list = $$(".dnd_target_active");
		while (el = list.pop()) {
			el.className = el.className.replace(/\bdnd_target_active\S*\b/g, ' ').strip();
		}
		miwtdnd.dropactiveset = false;
	}
};

miwtdnd.dragSource_mousedown = function (evt, drag) {
    var src = Event.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;
	//log4js.logger.info("Starting DnD for "+miwtdnd.dragSource.id);
	miwtdnd.startX = Event.pointerX(evt);
	miwtdnd.startY = Event.pointerY(evt);

	Event.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) {
	//log4js.logger.info("Setup drag source "+node.id);
	var drag = node;
	drag.provides = contentTypes || [ ];
	Element.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 = Event.element(evt);
	while (eventel && !Element.hasClassName(eventel, "dnd_target"))
		eventel = eventel.parentNode;
	drop = eventel || drop;
	//log4js.logger.info("Drop target mouse up for "+drop.id+" "+drop.nodeName);
	if (!miwtdnd.isCompatible(miwtdnd.dragSource, drop))
		return;
	//Event.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) {
				//log4js.logger.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 = Event.findElement(evt, 'form');
	var x = Event.pointerX(evt);
	var y = Event.pointerY(evt);
	miwtdnd.dropTimer = setTimeout(function() { miwtdnd.handleDropTargetActivate(drop, form, x, y); }, 10);
};

miwtdnd.handleDropTargetActivate = function (drop, form, x, y) {
	//log4js.logger.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 = Element.viewportOffset(document.body);
        scrollOffset = Element.cumulativeScrollOffset(miwtdnd.dropTarget); 
        dropOffset = Element.cumulativeOffset(miwtdnd.dropTarget);
		dropDim = Element.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(Element.select(form, "dfn.ajax_uri").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 = Element.select(miwtdnd.menu, "a");
							while (el = list.pop()) {
								count++;
								el.dndoption = el.href.substring(el.href.indexOf("#")+1);
								el.href='#';
								el.onclick = function(evt) {
									Event.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) {
							log4js.logger.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) {
	//log4js.logger.info("Setup drop target "+node.id+" "+node.nodeName);
	
	var drop = node;
	drop.accepts = contentTypes || [];
	drop.hasOptions = !!hasOptions;
	Element.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;
				//log4js.logger.info("Drop "+node.id+" location, cell "+r+","+c+" is "+className);
			}
		}
		drop.allClassNames = drop.allClassNames.uniq();
		//log4js.logger.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;
	var common = dropTarget.accepts.intersect(dragSource.provides);
	//log4js.logger.info("provides: "+dragSource.provides+", accepts: "+dropTarget.accepts+", common: "+common);
	return (common.length > 0);
};

miwt.AddSetupHandler([ 'dfn' ], function (tag, node)
{
	if (/\bdnd_source_def\b/.exec(node.className)) {
		var a = $w(node.firstChild.data);
		miwtdnd.setupDragSource($(a.shift()), a);
	}
	
	if (/\bdnd_target_def\b/.exec(node.className)) {
		var a = $w(node.firstChild.data);
		var drop = $(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 = Event.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 = $(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 = $(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 = $(node.id+'_yearstart');
	var yearend = $(node.id+'_yearend');
	var yearrange = null;
	if (yearstart && yearend)
		yearrange = [ parseInt(yearstart.firstChild.data), parseInt(yearend.firstChild.data) ];
	else
		yearrange = [1900, 2999];
	
	var updateFunction = (submit) ? ( miwt.calendarUpdateSubmit.bind({target: node.id}) ):( miwt.calendarUpdateNoSubmit.bind({target: node.id}) );
			
	var clearbutton = $(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 = $(node.id+"_open");
		if (openbutton) {
			Calendar.setup({
				inputField: node.id,
				button: openbutton,
				ifFormat: $(node.id+'_format').firstChild.data,
				range: yearrange,
				showOthers: true,
				showsTime: ($(node.id+'_time') != null),
				onUpdate: updateFunction,
				timeFormat: "12",
				cache: true
			});
		}
	}
	catch (e) { log4js.logger.error("Cannot init calendar, check your classpath", e); }
});

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

miwt.list = new Object();

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

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

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

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

}// End conditional eval
