/*
 * EasyGUI 1.0.53
 * Copyright(c) 2005-2009, Gaetan Lauff <glauff@plansoft.de>.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *    
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *   
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
 * OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

BUILD = true;

function $GE( obj ) {
	return Element.getElement( obj );
}

function navigate( evt )
{
	var element = $GE( evt );
	
	var id 			= Element.getParentAttributeValue(element, 'id' );
	var href 		= Element.getParentAttributeValue(element, 'url' );
	var target 		= Element.getParentAttributeValue(element, 'target', '_self');
	var submitField	= Element.getParentAttributeValue(element, 'submitfield' );
	var targetDlg 	= Element.getParentAttributeValue(element, 'targetdlg' );
	
	if (targetDlg) {
		Form.Element.setValue('EK_TARGET', targetDlg);
	}
	
	if (submitField) {
		Form.Element.setValue(submitField, id);
	}
	
	if (!href) {	
		ekSubmit( id, target);
	} else {
		href = href.urldecode();
		
		if (href.indexOf('javascript:') != -1) {
			if (href.indexOf('ekSubmit(') != -1 ) {
				if (href.indexOf('this') != -1) {
					ekSubmit( element );
				} else {
					var test = href.match(/\((\'.*\')\)/);
					var test = test.slice(1);
					var cmd = 'ekSubmit(' + test + ');'
					eval ( cmd );
				}
			} else {
				code = href.substring(11, href.length) + ";";
				code = code.ltrim();
				eval(code);
			}
		} else {
			if ( href.indexOf('http:') != -1 && href.indexOf('void') == -1 && href.indexOf('#') == -1 ) {
				window.open(href, target);
			}
			
			if (href.indexOf('ekSubmit(') != -1) {
				if (href.indexOf('this') != -1) {
					ekSubmit( element );
				} else {
					var test = href.match(/\((\'.*\')\)/);
					var test = test.slice(1);
					var cmd = 'ekSubmit(' + test + ');'
					eval ( cmd );
				}
			} else {
				code = href.ltrim();
				eval(code);
			}
		}
	}

	return false;
}


function ekSubmit( evt, target, timeout)
{
	if (evt == null)
		throw new Error ('ekSubmit: No Submitevent set !');
		
	var form 		= document.forms[0];
	var action 		= null;
	var targetDlg 	= $F('DLG_ID');
	var element 	= null;
	
	var proceed 	= ( target == 'easygui_proceed' );
	var upload 		= ( target == 'easygui_upload' );
	
	var target = ( target == null || target == 'undefined' || target == 'easygui_proceed' || target == 'easygui_upload' ) ? '_self' : target;
	
	if ( typeof document.body.isubmit != "undefined" ) {
		return;
	}
	// @@@Hack
	if ( self != top && target == "_self" ) {
		document.body.isubmit = true;
	}
	
	if (typeof(evt) == 'object' ) {
		element = $GE( evt );
		evt = ( !element.id ) ? Element.getParentAttributeValue( element, 'id') : element.id;
	}
	
	if ( element = $GE( evt ) ) {
		var validate	= Element.getAttributeValue( element, 'validateform', false);
	
		if ( validate )
			if (!Form.validate( document.forms[0] ) )
				return false;
			
		target 		= Element.getAttributeValue( element, 'target', target );
		action		= Element.getAttributeValue( element, 'action', '' );
		targetDlg 	= Element.getAttributeValue( element, 'targetdlg', '');
		submitevt	= element.id;
	}
	
	var ajax 	= ( target == 'easygui_ajax' );
	var remote	= ( target == 'isyiframe' );
	
	if ( proceed )
		action = '';
		
	form.EK_TARGET.value 	= targetDlg;
	form.EK_REQUEST.value 	= 'false';
	form.EK_NOSTACK.value 	= 'false';
	form.EKSUBMITEVENT.value= evt;
	form.EK_ACTION.value 	= action;
	
	if ( DEBUG ) {
		alert( "--EKSUBMIT--\r\nin targetwin: " + target + 
				"\r\n validate: " + validate + 
				"\r\najax: " + ajax +
				"\r\naction: " + $F('EK_ACTION') + 
				"\r\ntargetdlg: " + $F('EK_TARGET') + 
				"\r\nevt: " + $F('EKSUBMITEVENT') + 
				"\r\nvalues: " + Form.serialize( form ) );
	}
	
	sleep(timeout);
	
	if ( remote ) {
		form.EK_NOSTACK.value = 'true';
	}
	
	if ( upload ) {
		form.EK_REQUEST.value = 'iframe';
		form.target = 'isyajax';
		form.submit();
		return;
	}
	
	if ( ajax ) {
		if ( Ajax.getTransport() ) {
			form.EK_REQUEST.value = 'ajax';
			this.params = '__eksubmit_values__=' + Form.serialize( document.forms[0] );
			var ajax = new Ajax.Request( document.forms[0].action, { postBody: this.params, onComplete: onComplete } );
			return;
		} else {
			form.EK_REQUEST.value = 'iframe';
			target = 'isyajax';
		}
	}
	
	var subForm = document.createElement('form');
	
	subForm.name 	= 'easygui_submit';
	subForm.method 	= 'post';
	subForm.action 	= document.forms[0].action;
	
	subForm.target 	= target;
	document.body.appendChild( subForm );

	if (DEBUG) {
		var timer = new JS_Timer();
		timer.startTimer();
	}
	
	var submitValues = Form.serialize( form );
	submitValues = submitValues.replace(/_EK_WIDGET_VALUE/g, '' );
	
	Form.insertHidden( "__eksubmit_values__", submitValues , subForm.name );
	
	if (DEBUG) {
		alert(timer.stopTimer());
	}
	
	$(subForm).fire('form:eksubmit');
	subForm.submit();
	document.body.removeChild(subForm);
}


function ekRemoteSubmit( element ) 
{
	ekSubmit( element, 'isyiframe' );
	dialog.enable();
}


function ekRequest( element )
{
	ekSubmit( element, 'easygui_ajax' );
	dialog.enable();
}

function ekProceed( element )
{
	ekSubmit( element, 'easygui_proceed' );
	dialog.enable();
}

function ekConfirm( element, msg, request )
{
	if (msg == null) {
		ok = window.confirm('Are you sure ?');
	} else {
		msg = dialog.getMessage( msg );
		ok = window.confirm( msg );
	}
	
	if (ok) {
		if ( request ) {
			ekRequest( element );
		} else {
			ekSubmit( element );
		}
	}
	
	return false;
}

function ekUpload( element )
{
	ekSubmit( element, 'easygui_upload' );
	dialog.enable();
}


function getVersion() {
	return $F( $('IDC_EASYGUI_VERSION') );
}


function getBuild() {
	return $F( $('IDC_EASYGUI_BUILD') );
}



function componentShow( element )
{
	Element._show( element );
}


function componentHide( element )
{
	Element._hide( element );
}


function componentDisable( id )
{
	dialog[id].disable();
}


function componentEnable( id )
{
	dialog[id].enable();
}


function addEvent(obj, evType, fn, useCapture)
{
	Event.observe(obj, evType, fn, useCapture);
}


function removeEvent(obj, evType, fn, useCapture)
{
	Event.stopObserving( obj, evType, fn, useCapture);
}


function makeHandcursor( element )
{
	if (is.nav6up) {
   		element.style.cursor = 'pointer';
	} else {
    	element.style.cursor = 'hand';
	}
}


function makeWaitcursor(element)
{
   	element.style.cursor = 'wait';
}


function makeDefaultcursor(element) 
{
	element.style.cursor = 'default';
}


function createNewHiddenFormField(id, value) 
{
	Form.insertHidden(id, value);
}


function initCombobox( id ) 
{
	dialog[id].setOptionList();
}


function openFolder( element ) 
{
	focusItem( element );
}


function sortColumn(evt) 
{
	sortTable( evt );
}


function scrollToTableElement( id ) 
{
	scrollIntoView( id );
}

 
function getColumnFrom(element) 
{
	var element = Element.getParentElementByTagName( element, 'TD', true );
	return element.id
}


function getRowFrom( element ) 
{
	var element = Element.getParentElementByTagName( element, 'TR', true );
	return element.id
}


function getTableFrom(element) 
{ 
	var element = Element.getParentElementByTagName( element, 'DIV', true ); 
    return element.id; 
} 

function getRowNumFrom(obj) 
{
	var rowid	= getRowFrom(obj);
	var tableid	= getTableFrom(obj);
	
	return rowid.substr(tableid.length+1, rowid.length - tableid.length - 1);
}


function getElementFrom( element ) 
{
	return $GE( element );
}


function ekSubmitInIframe() 
{
	callToServer('isycat');
}


function ekSubmitInNewWindow(element, width, height)
{
	if (width == null) {
		width = 800;
	}
	
	if (height == null) {
		height = 600;
	}
	
	if (typeof(element) == "string") {
    	var winId = element;
    } else {
    	var winId = element.id;
    }
    
	var win = window.open("about:blank", winId + "_win" ,"width=" + width + " height=" + height + " toolbar=no");
	dialog.winRegistry.registerWindow(new guiWindow(winId + "_win", win));
	
	ekSubmit(element, winId + "_win");
}


function showContentInNewWindow(element) 
{
	var newWindowUrl 		= "about:blank";
	var newWindowName 		= "newWindow";
	var newWindowHeight 	= 600;
	var newWindowWidth 		= 800;
	var newWindowToolbar 	= "yes";
	var newWindowMenuBar 	= "no";
	
	if (element.getAttribute('docref')) {
		newWindowUrl 		= element.getAttribute('docref');
	}
   	
   	if(element.getAttribute('newwindowname')) {
   		newWindowName 		= element.getAttribute('newwindowname');
   		newWindowName		= newWindowName.replace(/(\s+|-)/g, '_');
   	}
    
    if (element.getAttribute('newwindowwidth')) {
    	newWindowWidth 		= element.getAttribute('newwindowwidth');
    }
         
    if (element.getAttribute('newwindowheight')) {
    	newWindowHeight 	= element.getAttribute('newwindowheight');
    }
         
    if (element.getAttribute('newwindowtoolbar')) {
    	newWindowToolbar 	= element.getAttribute('newwindowtoolbar');
    }
    
    if (element.getAttribute('newwindowmenubar')) {
    	newWindowMenuBar 	= element.getAttribute('newwindowmenubar');
    }

    var newWindowAttributes = "menubar="+newWindowMenuBar+" toolbar="+newWindowToolbar+" width="+newWindowWidth+" height="+newWindowHeight;
    window.open(newWindowUrl, newWindowName, newWindowAttributes);
}


function flipImage (evt) 
{
	var element = $GE(evt);
	
	var overimg = element.getAttribute('mouseoverimage' );
	
	if ( typeof (overimg) == "undefined" ) {
		return;
	}
	
    var imagesrc 			= element.src;
    element.src 			= overimg;
    element.setAttribute( 'mouseoverimage', imagesrc );
}

function confirmDelete( element, msg )
{
	ekConfirm( element, msg );
}

function navigate2(element)
{
	navigate(element);
}
//<--
// Ultimate client-side JavaScript client sniff. Version 3.03
// (C) Netscape Communications 1999.  Permission granted to reuse and distribute.
// Revised 17 May 99 to add is.nav5up and is.ie5up (see below).
// Revised 21 Nov 00 to add is.gecko and is.ie5_5 Also Changed is.nav5 and is.nav5up to is.nav6 and is.nav6up
// Revised 22 Feb 01 to correct Javascript Detection for IE 5.x, Opera 4, 
//                      correct Opera 5 detection
//                      add support for winME and win2k
//                      synch with browser-type-oo.js
// Revised 26 Mar 01 to correct Opera detection
// Revised 02 Oct 01 to add IE6 detection

// Everything you always wanted to know about your JavaScript client
// but were afraid to ask ... "Is" is the constructor function for "is" object,
// which has properties indicating:
// (1) browser vendor:
//     is.nav, is.ie, is.opera, is.hotjava, is.webtv, is.TVNavigator, is.AOLTV
// (2) browser version number:
//     is.major (integer indicating major version number: 2, 3, 4 ...)
//     is.minor (float   indicating full  version number: 2.02, 3.01, 4.04 ...)
// (3) browser vendor AND major version number
//     is.nav2, is.nav3, is.nav4, is.nav4up, is.nav6, is.nav6up, is.gecko, is.ie3, 
//     is.ie4, is.ie4up, is.ie5, is.ie5up, is.ie5_5, is.ie5_5up, is.ie6, is.ie6up, is.hotjava3, is.hotjava3up
// (4) JavaScript version number:
//     is.js (float indicating full JavaScript version number: 1, 1.1, 1.2 ...)
// (5) OS platform and version:
//     is.win, is.win16, is.win32, is.win31, is.win95, is.winnt, is.win98, is.winme, is.win2k
//     is.os2
//     is.mac, is.mac68k, is.macppc
//     is.unix
//     is.sun, is.sun4, is.sun5, is.suni86
//     is.irix, is.irix5, is.irix6
//     is.hpux, is.hpux9, is.hpux10
//     is.aix, is.aix1, is.aix2, is.aix3, is.aix4
//     is.linux, is.sco, is.unixware, is.mpras, is.reliant
//     is.dec, is.sinix, is.freebsd, is.bsd
//     is.vms
//
// See http://www.it97.de/JavaScript/JS_tutorial/bstat/navobj.html and
// http://www.it97.de/JavaScript/JS_tutorial/bstat/Browseraol.html
// for detailed lists of userAgent strings.
//
// Note: you don't want your Nav4 or IE4 code to "turn off" or
// stop working when Nav5 and IE5 (or later) are released, so
// in conditional code forks, use is.nav4up ("Nav4 or greater")
// and is.ie4up ("IE4 or greater") instead of is.nav4 or is.ie4
// to check version in code which you want to work on future
// versions.
function Is ()
{   // convert all characters to lowercase to simplify testing
    var agt=navigator.userAgent.toLowerCase();
	// *** BROWSER VERSION ***
    // Note: On IE5, these return 4, so use is.ie5up to detect IE5.

    this.major = parseInt(navigator.appVersion);
    this.minor = parseFloat(navigator.appVersion);
	
    // Note: Opera and WebTV spoof Navigator.  We do strict client detection.
    // If you want to allow spoofing, take out the tests for opera and webtv.
    this.nav  = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
                && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
                && (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1));
    this.nav2 = (this.nav && (this.major == 2));
    this.nav3 = (this.nav && (this.major == 3));
    this.nav4 = (this.nav && (this.major == 4));
    this.nav4up = (this.nav && (this.major >= 4));
    this.navonly      = (this.nav && ((agt.indexOf(";nav") != -1) ||
                          (agt.indexOf("; nav") != -1)) );
    this.nav6 = (this.nav && (this.major == 5));
    this.nav6up = (this.nav && (this.major >= 5));
    this.gecko = (agt.indexOf('gecko') != -1);


    this.ie     = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
    this.ie3    = (this.ie && (this.major < 4));
    this.ie4    = (this.ie && (this.major == 4) && (agt.indexOf("msie 4")!=-1) );
    this.ie4up  = (this.ie  && (this.major >= 4));
    this.ie5    = (this.ie && (this.major == 4) && (agt.indexOf("msie 5.0")!=-1) );
    this.ie5_5  = (this.ie && (this.major == 4) && (agt.indexOf("msie 5.5") !=-1));
    this.ie5up  = (this.ie  && !this.ie3 && !this.ie4);
    this.ie5_5up =(this.ie && !this.ie3 && !this.ie4 && !this.ie5);
    this.ie6    = (this.ie && (this.major == 4) && (agt.indexOf("msie 6.")!=-1) );
    this.ie6up  = (this.ie  && !this.ie3 && !this.ie4 && !this.ie5 && !this.ie5_5);

    // KNOWN BUG: On AOL4, returns false if IE3 is embedded browser
    // or if this is the first browser window opened.  Thus the
    // variables is.aol, is.aol3, and is.aol4 aren't 100% reliable.
    this.aol   = (agt.indexOf("aol") != -1);
    this.aol3  = (this.aol && this.ie3);
    this.aol4  = (this.aol && this.ie4);
    this.aol5  = (agt.indexOf("aol 5") != -1);
    this.aol6  = (agt.indexOf("aol 6") != -1);

    this.opera = (agt.indexOf("opera") != -1);
    this.opera2 = (agt.indexOf("opera 2") != -1 || agt.indexOf("opera/2") != -1);
    this.opera3 = (agt.indexOf("opera 3") != -1 || agt.indexOf("opera/3") != -1);
    this.opera4 = (agt.indexOf("opera 4") != -1 || agt.indexOf("opera/4") != -1);
    this.opera5 = (agt.indexOf("opera 5") != -1 || agt.indexOf("opera/5") != -1);
    this.opera5up = (this.opera && !this.opera2 && !this.opera3 && !this.opera4);

    this.webtv = (agt.indexOf("webtv") != -1); 

    this.TVNavigator = ((agt.indexOf("navio") != -1) || (agt.indexOf("navio_aoltv") != -1)); 
    this.AOLTV = this.TVNavigator;

    this.hotjava = (agt.indexOf("hotjava") != -1);
    this.hotjava3 = (this.hotjava && (this.major == 3));
    this.hotjava3up = (this.hotjava && (this.major >= 3));

    // *** JAVASCRIPT VERSION CHECK ***
    if (this.nav2 || this.ie3) this.js = 1.0;
    else if (this.nav3) this.js = 1.1;
    else if (this.opera5up) this.js = 1.3;
    else if (this.opera) this.js = 1.1;
    else if ((this.nav4 && (this.minor <= 4.05)) || this.ie4) this.js = 1.2;
    else if ((this.nav4 && (this.minor > 4.05)) || this.ie5) this.js = 1.3;
    else if (this.hotjava3up) this.js = 1.4;
    else if (this.nav6 || this.gecko) this.js = 1.5;
    // NOTE: In the future, update this code when newer versions of JS
    // are released. For now, we try to provide some upward compatibility
    // so that future versions of Nav and IE will show they are at
    // *least* JS 1.x capable. Always check for JS version compatibility
    // with > or >=.
    else if (this.nav6up) this.js = 1.5;
    // note ie5up on mac is 1.4
    else if (this.ie5up) this.js = 1.3

    // HACK: no idea for other browsers; always check for JS version with > or >=
    else this.js = 0.0;

    // *** PLATFORM ***
    this.win   = ( (agt.indexOf("win")!=-1) || (agt.indexOf("16bit")!=-1) );
    // NOTE: On Opera 3.0, the userAgent string includes "Windows 95/NT4" on all
    //        Win32, so you can't distinguish between Win95 and WinNT.
    this.win95 = ((agt.indexOf("win95")!=-1) || (agt.indexOf("windows 95")!=-1));

    // is this a 16 bit compiled version?
    this.win16 = ((agt.indexOf("win16")!=-1) || 
               (agt.indexOf("16bit")!=-1) || (agt.indexOf("windows 3.1")!=-1) || 
               (agt.indexOf("windows 16-bit")!=-1) );  

    this.win31 = ((agt.indexOf("windows 3.1")!=-1) || (agt.indexOf("win16")!=-1) ||
                    (agt.indexOf("windows 16-bit")!=-1));

    // NOTE: Reliable detection of Win98 may not be possible. It appears that:
    //       - On Nav 4.x and before you'll get plain "Windows" in userAgent.
    //       - On Mercury client, the 32-bit version will return "Win98", but
    //         the 16-bit version running on Win98 will still return "Win95".
    this.win98 = ((agt.indexOf("win98")!=-1) || (agt.indexOf("windows 98")!=-1));
    this.winnt = ((agt.indexOf("winnt")!=-1) || (agt.indexOf("windows nt")!=-1));
    this.win32 = (this.win95 || this.winnt || this.win98 || 
                    ((this.major >= 4) && (navigator.platform == "Win32")) ||
                    (agt.indexOf("win32")!=-1) || (agt.indexOf("32bit")!=-1));

    this.winme = ((agt.indexOf("win 9x 4.90")!=-1));
    this.win2k = ((agt.indexOf("windows nt 5.0")!=-1));
	this.winxp = ((agt.indexOf("windows nt 5.1")!=-1));
	this.winvista = ((agt.indexOf("windows nt 6.0")!=-1));
	this.win7  = ((agt.indexOf("windows nt 6.1")!=-1));
	
    this.os2   = ((agt.indexOf("os/2")!=-1) || 
                    (navigator.appVersion.indexOf("OS/2")!=-1) ||   
                    (agt.indexOf("ibm-webexplorer")!=-1));

    this.mac    = (agt.indexOf("mac")!=-1);
    // hack ie5 js version for mac
    if (this.mac && this.ie5up) this.js = 1.4;
    this.mac68k = (this.mac && ((agt.indexOf("68k")!=-1) || 
                               (agt.indexOf("68000")!=-1)));
    this.macppc = (this.mac && ((agt.indexOf("ppc")!=-1) || 
                                (agt.indexOf("powerpc")!=-1)));
	this.macintel = (this.mac && ((agt.indexOf("intel")!=-1)));
	
    this.sun   = (agt.indexOf("sunos")!=-1);
    this.sun4  = (agt.indexOf("sunos 4")!=-1);
    this.sun5  = (agt.indexOf("sunos 5")!=-1);
    this.suni86= (this.sun && (agt.indexOf("i86")!=-1));
    this.irix  = (agt.indexOf("irix") !=-1);    // SGI
    this.irix5 = (agt.indexOf("irix 5") !=-1);
    this.irix6 = ((agt.indexOf("irix 6") !=-1) || (agt.indexOf("irix6") !=-1));
    this.hpux  = (agt.indexOf("hp-ux")!=-1);
    this.hpux9 = (this.hpux && (agt.indexOf("09.")!=-1));
    this.hpux10= (this.hpux && (agt.indexOf("10.")!=-1));
    this.aix   = (agt.indexOf("aix") !=-1);      // IBM
    this.aix1  = (agt.indexOf("aix 1") !=-1);    
    this.aix2  = (agt.indexOf("aix 2") !=-1);    
    this.aix3  = (agt.indexOf("aix 3") !=-1);    
    this.aix4  = (agt.indexOf("aix 4") !=-1);    
    this.linux = (agt.indexOf("inux")!=-1);
    this.sco   = (agt.indexOf("sco")!=-1) || (agt.indexOf("unix_sv")!=-1);
    this.unixware = (agt.indexOf("unix_system_v")!=-1); 
    this.mpras    = (agt.indexOf("ncr")!=-1); 
    this.reliant  = (agt.indexOf("reliantunix")!=-1);
    this.dec   = ((agt.indexOf("dec")!=-1) || (agt.indexOf("osf1")!=-1) || 
                  (agt.indexOf("dec_alpha")!=-1) || (agt.indexOf("alphaserver")!=-1) || 
                  (agt.indexOf("ultrix")!=-1) || (agt.indexOf("alphastation")!=-1)); 
    this.sinix = (agt.indexOf("sinix")!=-1);
    this.freebsd = (agt.indexOf("freebsd")!=-1);
    this.bsd = (agt.indexOf("bsd")!=-1);
    this.unix  = ((agt.indexOf("x11")!=-1) || this.sun || this.irix || this.hpux || 
                 this.sco ||this.unixware || this.mpras || this.reliant || 
                 this.dec || this.sinix || this.aix || this.linux || this.bsd || this.freebsd);
				 
    this.vms   = ((agt.indexOf("vax")!=-1) || (agt.indexOf("openvms")!=-1));
}

var is;
var isIE3Mac = false;
// this section is designed specifically for IE3 for the Mac

if ((navigator.appVersion.indexOf("Mac")!=-1) && (navigator.userAgent.indexOf("MSIE")!=-1) && 
(parseInt(navigator.appVersion)==3))
       isIE3Mac = true;
else   is = new Is();


function EKAT_RESIZE(w,h) {;}
function EKAT_CENTER_WINDOW() {;}


var Dialog = Class.create();

Dialog.prototype = 
{
	
	id: null,
	
	
	widgets: [],
	
	
	width: 0,
	
	
	height: 0,
	
	
	winRegistry: null,
	
	
	initialized: false,
	
	popupsBlocked: false,
	
	
	initialize: function() 
	{
		if(is.ie5_5up){
			try{
				document.execCommand("BackgroundImageCache", false, true);
			}catch(e){}
		}

		if (self != top) {
			try {
				top.dialog.enable();
			} catch( e ) {}
		} else {
			try {   
				if (self.opener) {
					var modal = Element.getAttributeValue( document.body, 'modal' );
				
					if (modal) {
						self.opener.dialog.winRegistry.startModalObserver( self.name );
					} else {
						self.opener.dialog.enable();
					}
				} else {
					//$('GUI_DISABLE').style.visibility = 'hidden';
					this.enable();
				}
			} catch( e ) {
				
				//alert("Cross site opening !" + document.domain);
			}
		}
	
		Event.observe(document, "keydown", toggleEnterKey, true);
		if ( document.body.getAttribute('allowselect') != "true" )
			Event.observe(document, "selectstart", noSelect, true);
		
		this.id = document.body.id;
		this.winRegistry = new windowRegistry();
		
		Form.insertHidden('DLG_ID', this.id);

		Dialog.setWindowSize();
		
		if (is.ie5up)
			Event.observe( window, "unload", this.destroy.bindAsEventListener(this) );
			
		// Beim Submit wird der Dialog disabled um User Interaktion zu stoppen
		document.observe('form:eksubmit', function() {
			dialog.disable();
		});
	},
	
	
	getVersion: function()
	{
		alert( "Client Side System Properties \nEasyGUI: " + EasyGUI.Version + " " + EasyGUI.Build + "\nPrototype: " + Prototype.Version + "\nScriptaculous: " + Scriptaculous.Version );
	},
	
	
	getMessage: function( id )
	{
		var element = $(id);
		
		if ( element ) {
			return Element.getInnerText( element );
		}
		
		return id;
	},
	
	
	init: function()
	{
		//var allElements = document.getElementsByTagName('*');
		var tables 		= [];
		var widgetCons 	= [];
		var tabctrls 	= [];
		
		for (var i=0; i < widgets.length; i++) {
			var widget = widgets[i].split(':');
			var widgetName = '';
			
			for (var j=1; j < widget.length; j++ ) {
				widgetName += (widgetName == "" ) ? widget[j] : ":" + widget[j];
			}
			
			switch( widget[0] ) {
				case 'EasyGUI_table':
					tables[tables.length] = widgetName;
					break;
					
				case 'EasyGUI_TabCtrl':
					tabctrls[tabctrls.length] = widgetName;
					break;
					
				default:
					var widgetConstructor = widget[0] + '(\'' + widgetName + '\')';
					widgetCons[widgetCons.length] = widgetConstructor;
					break;
			}
		}
	
		for ( var i=0; i < tabctrls.length; i++ )
			this.registerWidget( new EasyGUI_TabCtrl( tabctrls[i] ) );
		
		for ( var i=0; i < widgetCons.length; i++ )
			this.registerWidget( eval( 'new ' + widgetCons[i] ) );
		
		for ( var i=0; i < tables.length; i++ ) {
			this.registerWidget( new EasyGUI_table( tables[i] ) );
		}
			
		this.renderWidgets();
		this.finalizeWidgets();
		
		this.initialized = true;
		
		// For nested iframes in iframes
		// very dangerous
		document.body.dialog = this;
	},
	
	
	renderWidgets: function()
	{
		for (var i=0; i < this.widgets.length; i++) {
			var windowname = self.name;
			
			if ( DEBUGTIME ) {
				var timer = new JS_Timer();
				timer.startTimer();
			}
			
			this.widgets[i].render();
			
			if( DEBUGTIME )		
				GUITIME += this.widgets[i].id + ': ' + timer.stopTimer() + "s\r\n";
		}
	},
	
	
	finalizeWidgets: function() 
	{
		for ( var i=0; i < this.widgets.length; i++ )
			this.widgets[i].finalize();
	},
	
	
	destroy: function()
	{
		for (var i=0; i < this.widgets.length; i++) {
			this.widgets[i].destroy();
		}
	},
	
	
	registerWidget: function ( widget )
	{
		this[widget.id] = widget;
		this.widgets.push(widget);
	},
	
	
	getWidget: function( id )
	{
		return (this[id]) ? this[id] : false;
		
	},
	
	
	getWidgets: function()
	{
		return this.widgets;
	},
	
	
	enable: function()
	{
		// $() for IE
		if (this.disabler !== undefined )
			$(this.disabler).remove();
		//Element._hide('GUI_DISABLE');
	},
	
	
	disable: function ()
	{
		this.disabler = document.createElement('div');
		document.body.appendChild(this.disabler);
		var dialogSize = document.viewport.getDimensions();
		
		this.disabler.style.position = 'absolute';
		this.disabler.style.width = dialogSize.width + 'px';
		this.disabler.style.height = dialogSize.height + 'px';
		this.disabler.setAttribute('id', 'INPUT_DISABLE');
		this.disabler.className = 'disableInput';
		
		
	}
};



Object.extend( Dialog, {
	
	getInnerWidth: function()
	{
		if (self.innerWidth) {
			return self.innerWidth;
		} else if (document.documentElement && document.documentElement.clientWidth) {
			return document.documentElement.clientWidth;	
		} else if (document.body) {
			return document.body.clientWidth;	
		}
	},
	
	
	getInnerHeight: function() 
	{
		if (self.innerHeight) {
			return self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) {
			return document.documentElement.clientHeight;
		} else if (document.body) {
			return document.body.clientHeight;
		}
	},
	
	
	getPageYOffset: function()
	{
		if (self.pageYOffset) {
			return self.pageYOffset;
		} else if (document.documentElement && document.documentElement.scrollTop) {
			return document.documentElement.scrollTop;
		} else if (document.body) {
			return document.body.scrollTop;
		}
	},
	
	
	getPageXOffset: function()
	{
		if (self.pageXOffset) {
			return self.pageXOffset;
		} else if (document.documentElement && document.documentElement.scrollLeft) {
			return document.documentElement.scrollLeft;
		} else if (document.body) {
			return document.body.scrollLeft;
		}
	},
	
	
	getPageHeight: function()
	{
		var test1 = document.body.scrollHeight;
		var test2 = document.body.offsetHeight;
		
		if (test1 > test2) {
			return document.body.scrollHeight;
		} else {
			return document.body.offsetHeight;
		}
	},
	
	
	getPageWidth: function()
	{
		var test1 = document.body.scrollHeight;
		var test2 = document.body.offsetHeight;
		
		if (test1 > test2) {
			return document.body.scrollWidth;
		} else {
			return document.body.offsetWidth;
		}
	},
	
	
	setWindowSize: function()
	{
		var appmode = ( document.forms[0].action.indexOf('easygui.plso') === -1 ) ? 'ek_internet' : 'ek_cdrom';
		
		var resizeDialog 	= Element.getAttributeValue( document.body, 'resizedialog');
		var centerDialog 	= Element.getAttributeValue( document.body, 'centerdialog' );
		
		var width 	= parseInt( Element.getAttributeValue( document.body, 'dialogwidth' ));
		var height 	= parseInt( Element.getAttributeValue( document.body, 'dialogheight' ));
	
		if (self == top && ( resizeDialog || appmode == 'ek_cdrom') ) {
			try {
				self.resizeTo(width + 10, height + 4);
				width += 4;
			    height +=4;
				var hrefCMD="javascript:void(EKAT_RESIZE("+width+","+height+"))";
				window.location.href=hrefCMD;
			} catch(e) {
				;
			}
		}
		
		if (self == top && centerDialog) {
			if ( appmode != 'ek_cdrom' ) {
				try {
					self.moveTo(((screen.width/2) - (width/2)), ((screen.height/2) - (height/2)));
					var hrefCMD="javascript:void(EKAT_CENTER_WINDOW())";
					window.location.href = hrefCMD;
				} catch(e) {
					;
				}
			}
		}
	},
	
	
	showMessage: function( msgId ) {
		var msg = Element.getInnerText( msgId );
		alert( msg );
		return false;
	},
	
	
	submit: function( id, target, timeout ) 
	{
		ekSubmit( id, target, timeout );
	}
});

Dialog.Style = {
	
	getSheet: function( idx )
	{
		if (!idx) {
			var idx = 1;
		} else {
			if (typeof(idx) == 'string') {
				for (var i=0; i < document.styleSheets.length; i++) {
					if (document.styleSheets[i].title == idx) {
						var idx = i;
					}
				}
			}
		}
		
		return document.styleSheets[idx];
	},
	
	
	getRules: function( idx )
	{
		if (!document.styleSheets) {
			return false;
		}
		
		if (document.styleSheets[idx].cssRules) {
			return document.styleSheets[idx].cssRules;
		} else if (document.styleSheets[idx].rules) {
			return document.styleSheets[idx].rules;
		}
	},
	
	
	getIdx: function( idx )
	{
		if (idx == null) {
			var idx = 1;
		} else {
			if (typeof(idx) == 'string') {
				var sheets = document.styleSheets;
				for (var i=0; i < sheets.length; i++) {
					var id = sheets[i].ownerNode ? sheets[i].ownerNode.id : sheets[0].owningElement.id;
					if (id == idx) {
						//console.log( "Found Sheet: " + idx + " at idx: " + i );
						var idx = i;
					}
				}
			}
		}
				
		return idx;
	},
	
	
	getStyle: function (selector, attribute, idx)
	{
		if (!selector) {
			return false;
		}
		
		var idx 	= Dialog.Style.getIdx( idx );
		var rules 	= Dialog.Style.getRules( idx );
		
		for (var i=0; i < rules.length; i++) {
			if (rules[i].selectorText.indexOf("." + selector) != -1) {
				return rules[i].style[attribute];
			}
		}
				
		return Dialog.Style.getDefaultValue( selector, attribute );
	},
	
	
	ruleExists: function( selector )
	{
		for (var i = (document.styleSheets.length - 1); i > 0; i--) {
			var rules = Dialog.Style.getRules( i );
		
			for (var j=0; j < rules.length; j++) {
				if (rules[j].selectorText.indexOf("." + selector) != -1) {
					return true;
				}
			}
		}
				
		return false;
	},
		
	
	getDefaultValue: function( selector, attribute )
	{
		var idx = Dialog.Style.getIdx('easygui');
		var rules = Dialog.Style.getRules( idx );
		
		for (var i=0; i < rules.length; i++) {
			if ("." + selector == rules[i].selectorText) {
				return rules[i].style[attribute];
			}
		}
	
		return false;
	},
	
	
	setProperty: function(property, propertyValue, styleSheet)
	{
		;
	}
};


Error.prototype.getError = function ()
{
	return 	"EasyGUI Exception Handler:\n" + 
			"Exception Type: " + this.name + "\n\n" + 
			this.message;
}


Object.extend( Array.prototype, 
{
	toUserString: function( glue ) {
		var usrStr = '';
		
		for (  var i=0; i < this.length; i++ ) {
			usrStr += this[i] + glue;
		}

		return usrStr;
	},
	
	inArray: function( attribute ) 
	{
		for ( var i=0; i < this.length; i++ ) {
			if ( this[i] == attribute ) {
				return true;
			}
		}
		return false;
	},
	
	keyExists: function( key ) 
	{
		if ( this[key] != null ) {
			return true;
		}
		
		return false;
	},
	
	removeEntry: function( value ) 
	{
		var newArr = new Array();
	 
		for (var i=0; i < this.length; i++) {
			if (this[i] != value) {
				newArr[newArr.length] = this[i];
			}
		}
		
		this.length = newArr.length;
		
		for ( var i=0; i < newArr.length; i++ )
			this[i] = newArr[i];
	}
});



Object.extend( String.prototype, {
	
	
	sprintf: function() {
	   if (!arguments || arguments.length < 1 || !RegExp)
	   {
	      return;
	   }
	   var str = arguments[0];
	   var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
	   var a = b = [], numSubstitutions = 0, numMatches = 0;
	   while (a = re.exec(str))
	   {
	      var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
	      var pPrecision = a[5], pType = a[6], rightPart = a[7];
	
	      numMatches++;
	      if (pType == '%')
	      {
	         subst = '%';
	      }
	      else
	      {
	         numSubstitutions++;
	         if (numSubstitutions >= arguments.length)
	         {
	            alert('Error! Not enough function arguments (' + (arguments.length - 1)
	               + ', excluding the string)\n'
	               + 'for the number of substitution parameters in string ('
	               + numSubstitutions + ' so far).');
	         }
	         var param = arguments[numSubstitutions];
	         var pad = '';
	                if (pPad && pPad.substr(0,1) == "'") pad = leftpart.substr(1,1);
	           else if (pPad) pad = pPad;
	         var justifyRight = true;
	                if (pJustify && pJustify === "-") justifyRight = false;
	         var minLength = -1;
	                if (pMinLength) minLength = parseInt(pMinLength);
	         var precision = -1;
	                if (pPrecision && pType == 'f')
	                   precision = parseInt(pPrecision.substring(1));
	         var subst = param;
	         switch (pType)
	         {
	         case 'b':
	            subst = parseInt(param).toString(2);
	            break;
	         case 'c':
	            subst = String.fromCharCode(parseInt(param));
	            break;
	         case 'd':
	            subst = parseInt(param) ? parseInt(param) : 0;
	            break;
	         case 'u':
	            subst = Math.abs(param);
	            break;
	         case 'f':
	            subst = (precision > -1)
	             ? Math.round(parseFloat(param) * Math.pow(10, precision))
	              / Math.pow(10, precision)
	             : parseFloat(param);
	            break;
	         case 'o':
	            subst = parseInt(param).toString(8);
	            break;
	         case 's':
	            subst = param;
	            break;
	         case 'x':
	            subst = ('' + parseInt(param).toString(16)).toLowerCase();
	            break;
	         case 'X':
	            subst = ('' + parseInt(param).toString(16)).toUpperCase();
	            break;
	         }
	         var padLeft = minLength - subst.toString().length;
	         if (padLeft > 0)
	         {
	            var arrTmp = new Array(padLeft+1);
	            var padding = arrTmp.join(pad?pad:" ");
	         }
	         else
	         {
	            var padding = "";
	         }
	      }
	      str = leftpart + padding + subst + rightPart;
	   }
	   return str;
	},
	
	
	ltrim: function( trimchar ) 
	{
		var str = this.valueOf();
		
		while ((str.charAt(0) == " ") || (str.charAt(0) == "\t") || (str.charAt(0) == trimchar) ) 
		{
  			str = str.substring(1, str.length);
		}
		
		return str;
	},
	
	
	rtrim: function( trimchar ) 
	{
		var str = this.valueOf();

		while ((str.charAt(str.length-1) == " " || str.charAt(str.length-1) == "\t" || str.charAt( str.length-1) == trimchar ))
		{
			str = str.substring(0, str.length - 1);
		}
		
		return str;
	},
	
	
	trimright: function( strTrim ) 
	{
		var str = this.valueOf();
		
		if (strTrim.length == 0 || strTrim.length > str.length)
		{
			return str;
		}

		var nDifflen = strTrim.length;
		var nEndPos = str.length - 1;
		
		while (str.lastIndexOf(strTrim, nEndPos) == (nEndPos - nDifflen + 1)) 
		{
			nEndPos -= nDifflen;
		}
		
		str = str.substring(0, nEndPos + 1);
		
		return str;
	},
	
	
	urldecode: function()
	{
		var str = this.valueOf();
		str = str.replace(/%20/g, ' ');
		return str;
	}
});


Object.extend( Element, 
{
	
	getElement: function( evt )
	{
		try {
			if (evt.tagName)
				return $(evt);

			if (typeof evt == 'string')
				return $(evt);
				
			if (window.event)
			  	el = window.event.srcElement;
			else 
				if (evt.type == 'scroll')
					el = evt.currentTarget;
				else
					el = (evt.target.tagName ? evt.target : evt.target.parentNode);
		
			return $(el);
		} catch (e) {
			if (e instanceof Error)
				throw new Error('Element::getElement(): ' + e.name + ' ' + e.message);
		}
	},
	
	
	getDepth: function( node, tagName, ektype )
	{
		var depth = -1;
		
		while (node = Element.getParentElementByTagName( node, tagName)) {
			var nodetype = Element.getAttributeValue(node, 'ektype');
			
			if (nodetype != ektype )
				depth++;
			else
				break;
			
			node = node.parentNode;
		}
		
		return depth;
	},
	
	getPageOffsetTop: function( domElement )
	{
		var y;
	
		y = domElement.offsetTop;
	
		if ( domElement.offsetParent != null ) {
			y +=Element.getPageOffsetTop( domElement.offsetParent );
		}
	
		return y;
	},
	
	
	getPageOffsetLeft: function( domElement )
	{
		var x;
	
		x = domElement.offsetLeft;
		
		if ( domElement.offsetParent != null ) {
			x += Element.getPageOffsetLeft( domElement.offsetParent );
		}
	
		return x;
	},
	
	
	create: function(tagName, id, width, height, left, top)
	{
		try {
			var newElement = document.createElement(tagName);
			newElement.setAttribute( 'id', id );
			
			var width = ( width == null ) ? 100 : width;
			var height = ( height == null ) ? 25 : height;
			
			Element.setDimension( newElement, width, height );
			
			if ( left != null || top != null ) {
				newElement.style.position = "absolute";
				Element.setPosition( newElement, top, left );
			}
		
			return newElement;
		} catch (e) {
			if (e instanceof Error)
				throw new Error('Element::create(): ' + e.name + ' ' + e.message);
		}
	},
	
	
	getIEWidth: function( element )
	{
		var width = parseInt(element.offsetWidth);
		var offset = 0;
		
		
		if (!is.ie5 && !is.ie5_5) {
			var offset = Element.getIEBoxWidthOffset( element );
		}
			
		return width - offset;
	},
	
	
	getIEHeight: function( element )
	{
		var height = parseInt(element.offsetHeight);
		var offset = 0;
		
		
		if (!is.ie5 && !is.ie5_5) {
			var offset = Element.getIEBoxHeightOffset( element );
		}
			
		return height - offset;
	},
	
	
	getIEBoxWidthOffset: function( element )
	{
		var paddingLeft 	= Element.getStyle( element, 'padding-left' );
		var paddingRight 	= Element.getStyle( element, 'padding-right' );
		
		var borderLeft		= Element.getStyle( element, 'border-left-width' );
		var borderRight 	= Element.getStyle( element, 'border-right-width' );
		
		paddingLeft 	= (paddingLeft) ? isNaN(parseInt(paddingLeft)) ? 0 : parseInt(paddingLeft) : 0;
		paddingRight 	= (paddingRight) ? isNaN(parseInt(paddingRight)) ? 0 : parseInt(paddingRight) : 0;
		
		borderLeft 		= (borderLeft) ? isNaN(parseInt(borderLeft)) ? 0 : parseInt(borderLeft) : 0;
		borderRight 	= (borderRight) ? isNaN(parseInt(borderRight)) ? 0 : parseInt(borderRight) : 0;
	
		return borderLeft + borderRight + paddingLeft + paddingRight;
	},
	
	
	getIEBoxHeightOffset: function( element )
	{
		var paddingTop	= Element.getStyle( element, 'padding-top' );
		var paddingBot 	= Element.getStyle( element, 'padding-bottom' );
		
		var borderTop	= Element.getStyle( element, 'border-top-width' );
		var borderBot 	= Element.getStyle( element, 'border-bottom-width' );
		
		paddingTop = (paddingTop) ? isNaN(parseInt(paddingTop)) ? 0 : parseInt(paddingTop) : 0;
		paddingBot = (paddingBot) ? isNaN(parseInt(paddingBot)) ? 0 : parseInt(paddingBot) : 0;
		
		borderTop = (borderTop) ? isNaN(parseInt(borderTop)) ? 0 : parseInt(borderTop) : 0;
		borderBot = (borderBot) ? isNaN(parseInt(borderBot)) ? 0 : parseInt(borderBot) : 0;
		
		return borderTop + borderBot + paddingTop + paddingBot;
	},

	
	getElementsByTagName: function( element, tagName ) 
	{
		return element.getElementsByTagName( tagName );
	},
	
	getAttributeValue: function( element, attribute, defaultValue )
	{
		var attributeValue = element.getAttribute( attribute );
	
		if (!attributeValue) {
			if ( defaultValue != null )
				return defaultValue;
				
			return false;
		}
		
		switch (attributeValue) {
			case 'true':
				attributeValue = true;
				break;
			case 'false':
				attributeValue = false;
				break;
			default:
				break;
		}
	
		return attributeValue;
	},
	
	setDimension: function( element, width, height )
	{
		try {
			var element = $(element);
		
			if (typeof width != 'string')
				width += 'px';
			
			if (typeof height != 'string')
				height += 'px';
			
			element.style.width = width;
			element.style.height = height;
		} catch(e) {
			if (e instanceof Error)
				throw new Error('Element::setDimension(): ' + e.name + ' ' + e.message);
		}
	},
	
	setPosition: function( element, top, left ) 
	{
		try {
			var element = $(element);
			
			if (typeof top != 'string')
				top += 'px';
			
			if (typeof left != 'string')
				left += 'px';
				
			element.style.top = top;
			element.style.left = left;
		} catch (e) {
			if (e instanceof Error)
				throw new Error('Element::setPosition(): ' + e.name + ' ' + e.message);
		}
	},
	
	getChildNodesByTagName: function( element, tagName )
	{
		var cNodes = [];
		var element = $(element);
		
		for (var i=0; i < element.childNodes.length; i++) {
			if (element.childNodes[i].nodeType == 1 && element.childNodes[i].tagName.toLowerCase() == tagName.toLowerCase()) {
				cNodes[cNodes.length] = element.childNodes[i];
			}
		}
				
		return cNodes;
	},
	
	getFirstChildByTagName: function( element, tagName )
	{	
		for (var i=0; i < element.childNodes.length; i++) {
			if (element.childNodes[i].nodeName.toLowerCase() == tagName.toLowerCase()) {
				return element.childNodes[i];
			}
		}
		
		return false;
	},
	
	getFirstChild: function( element )
	{
		for (var i=0; i < element.childNodes.length; i++) {
			if ( element.childNodes[i].nodeType == 1 ) {
				return element.childNodes[i];
			}
		}
		
		return false;
	},
	
	getParentAttributeValue: function(element, attribute, defaultValue)
	{
		while (element != null && element.nodeType != 9 ) {
			if (element.getAttribute( attribute ) ) {
				return element.getAttribute( attribute );
			}
			
			element = element.parentNode;
		}
		
		if ( !isEmptyValue( defaultValue ) ) {
			return defaultValue;
		}
		
		return false;
	},
	
	
	getParentElementByTagName: function( element, tagName, checkelement )
	{
		var tagName = tagName.toLowerCase();
		
		if (checkelement != null && checkelement) {
			if( element.tagName.toLowerCase() == tagName.toLowerCase() ) {
				return element;
			}
		}
			
		while (element != null && element.nodeType != 9) {
	    	if (element.nodeType == 1 && element.tagName.toLowerCase() == tagName.toLowerCase()) {
	    		return element;
	    	}
	      	
	    	element = element.parentNode;
		}
		
		return false;
	},
	
	
	getParentElementByTagNameAndAttribute: function( element, tagName, attribute, checkelement )
	{
		if (element == null) {
			var element = element.parentNode;
		}
		
		var tagName = tagName.toLowerCase();
		
		if (checkelement != null && checkelement) {
			if ( element.tagName.toLowerCase() == tagName.toLowerCase() && element.getAttribute( attribute ) ) {
				return element;
			}
		}
		
		while ( element != null && element.nodeType != 9) {
			if (element.nodeType == 1 && element.tagName.toLowerCase() == tagName.toLowerCase() && element.getAttribute( attribute ) ) {
				return element;
			}
			
			element = element.parentNode;
		}
		
		return false;
	},
	
	
	getParentElementByNodeType: function( element, nodeType, checkelement)
	{	
		while (element != null && element.nodeType != 9) {
	    	if (element.nodeType != null && element.nodeType == nodeType) {
	    		return element;
	    	}
	      	
	    	element = element.parentNode;
		}
		
		return false;
	},
	
	getInnerText: function( element )
	{
		if (typeof(element) == "string")
			var element = $( element );
			
		if (typeof element == "undefined")
			return element;
		
		if (element.innerText)
			return element.innerText;
			
		var text 		= "";
		var childNodes 	= element.childNodes;
		var length 		= element.childNodes.length;
		
		for (var i = 0; i < length; i++) {
			switch (childNodes[i].nodeType) {
				case 1:
					text += Element.getInnerText(childNodes[i]);
					break;
				case 3:
					text += childNodes[i].nodeValue;
					break;
			}
		}
		
		return text;
	},
	
	hasChildNodesWithNodeType: function( element, nodeType )
	{
		if (nodeType == null) {
			var nodeType = 1;
		}
		
		for (var i=0; i < element.childNodes.length; i++) {
			if (element.childNodes[i].nodeType == nodeType) { 
				return true;
			}
		}
			
		return false;
	},
	
	hasChildNodesWithTagName: function( element, tagName )
	{
		for (var i=0; i < element.childNodes.length; i++) {
			if (element.childNodes[i].nodeName == tagName) {
				return true;
			}
		}
				
		return false;
	},
	
	
	
	hasParentWithAttribute: function( element, attribute )
	{
		while ( element != null && element.nodeType != 9 ) {
			if ( element.hasAttribute ) {
				if ( element.hasAttribute( attribute) ) {
					return true;
				}
			} else {
				if ( element.getAttribute( attribute ) != null ) {
					return true;
				}
			}
			
			element = element.parentNode;
		}
		
		return false;
	},
	
	
	hasParentWithAttributeValue: function( element, attribute, value )
	{
		while (element != null && element.nodeType != 9) {
			attributeValue = element.getAttribute( attribute );
			
			if (attributeValue != null && attributeValue == value) {
				return true;
			}
			
			element = element.parentNode;
		}
		
		return false;
	},
	
	
	isChildOf: function( element, type )
	{
		var parentItem = element.parentNode;
		
		while(parentItem != null && parentItem.nodeType != 9) {
			if (parentItem.nodeName == 'DIV' && ( parentItem.getAttribute( 'ektype' ) == type || parentItem.getAttribute( 'ctrltype' ) == type)) {
				return parentItem.id;
			}
			
			parentItem = parentItem.parentNode;
		}
		
		return false;
	},
	
	
	isInTab: function( id )
	{
		var parentItem = $(id).parentNode;
		
		while(parentItem != null && parentItem.nodeType != 9) {
			if (parentItem.nodeName == 'DIV' && parentItem.getAttribute('ctrltype') == 'tabpanel') {
				return parentItem.id;
			}
			
			parentItem = parentItem.parentNode;
		}
		
		return false;
	},
	
	
	isInTable: function( element )
	{
		var parentItem = $(element).parentNode;
	
		while(parentItem != null && parentItem.nodeType != 9 ) {
			if (parentItem.nodeName == 'TABLE' && parentItem.getAttribute('ektype') == 'Table') {
				return parentItem.id;
			}
			
			parentItem = parentItem.parentNode;
		}
		
		return false;
	},
	
	
	allowSelect: function( element )
	{
		var element = $( element );
	
		if (element.onselectstart) {
			Event.observe( element, 'selectstart', Event.stop );
		}
	},
	
	_toggle: function() {
		for (var i = 0; i < arguments.length; i++) {
			var element = $(arguments[i]);
			
			if( element == null ) {
				return;
			}
			
			Element[Element.visible(element) ? 'hide' : 'show'](element);
		}
	},
	
	_hide: function() {
		for (var i = 0; i < arguments.length; i++) {
			var element = $(arguments[i]);
			
			if ( element == null ) {
				return;
			}
			
			if ( dialog && element ) {
				if ( dialog[arguments[i]] ) {
					dialog[element.id].hide();
					return;
				}
			}	 
			
			element.style.visibility = 'hidden';
		}
	},
	
	_show: function() {
		for (var i = 0; i < arguments.length; i++) {
			var element = $(arguments[i]);
			
			if ( element == null ) {
				return;
			}
			
			if ( dialog && element ) {
				if ( dialog[arguments[i]] ) {
					dialog[element.id].show();
					return;
				}
			} 
			
			element.style.visibility = 'visible';
		}
	}
});

if ( is.ie5_5 || is.ie5) {
	document._getElementsByTagName = document.getElementsByTagName;
	document.getElementsByTagName = function ( sTagName )
	{
		if ( sTagName == "*" ) {
			return document.all;
		} else {
			return document._getElementsByTagName( sTagName );
		}
	};
}

Object.extend( Event, 
{
	getModifier: function( evt ) 
	{
		if (window.event)
			evt = window.event;
			
		if ( evt.altKey )
			return 'alt';
			
		if ( evt.ctrlKey ) {
			return 'ctrl';
		}
		
		if ( evt.shiftKey ) {
			return 'shift'
		}
		
		return false;
	}
});

Object.extend( Form, 
{
	
	serializeElements: function(elements, getHash) 
	{
    	var data = elements.inject({}, function(result, element) 
    	{
    		if ( element.name) 
    		{
        		var key = element.name, value = $(element).getValue();
	        	
        		if (value != undefined) 
        		{
	          		if (result[key]) 
	          		{
	            		if (result[key].constructor != Array) result[key] = [result[key]];
	            		{
	            			result[key].push(value);
	            		}
	          		}
	          		else 
	          		{
	          			result[key] = value;
	          		}
	        	}
      		}
      	
      		return result;
    	});

   		return getHash ? data : Hash.toQueryString(data);
  	},
  	
	getHidden: function(form) 
	{
	    var elements = Form.getElements($(form));
	    var queryComponents = new Array();
	
	    for (var i = 0; i < elements.length; i++) {
	      var queryComponent = Form.Element.serialize(elements[i]);
	      if (queryComponent)
	        queryComponents.push(queryComponent);
	    }
	
	    return queryComponents;
  	},
  	
	validate: function(form) 
	{
		var form = $(form);
		var elements = Form.getElements(form);
		
    	for (var i = 0; i < elements.length; i++) {
      		var element = elements[i];
      		
      		if ( !Form.Element.required( element ) || !Form.Element.validate( element ) ) {
      			
      			Field.focus( element );
      			return false;
      		}
    	}
    	
    	return true;
  	},
  	
  	
	getIdx: function( form )
	{
		if (form == null) {
			formIdx = 0;
		}
	
		if ( document.forms.length == 0 ) {
			return false;
		}
			
		for (var i=0; i < document.forms.length; i++) {
			if (document.forms[i].name == form) {
				formIdx = i;
			}
		}
		
		return formIdx;
	},
	
  	
	insertNew: function (type, name, value, form )
	{
		var idx = Form.getIdx( form );
		var form = document.forms[idx];
		
		if (value == null)
			value = '';
		
		if ( form[name] != null ) {
			form[name].value = value;
			return form[name];
		}
		
		var field = Form.Element.getNewInput( name, value, type );
		form.appendChild( field );
		
		return field;
	},
	
	
	insertHidden: function( name, value, form )
	{
		return Form.insertNew( 'hidden', name, value, form );
	}
});

Object.extend( Form.Element,
{
	validate: function( element )
	{
		var element 	= $(element);
		
		var obj 		= new Object();
		obj.validator 	= '';
		
		var rules 		= Element.getAttributeValue( element, 'validationrules' );
		
		if ( rules )
		{
			var obj 	= Util.getJSObject( rules );
		}

		eval( "var validator = new EasyGUI_" + obj.validator + "Validator( obj );" );
	
		if ( !validator )
		{
			eval( "var validator = new " + obj.validator + "( obj );" );
	
			if ( !validator )
			{
				throw new Error('EasyGUI Form Validator: The validator: ' + obj.validator + ' you indicated on Element: ' + element.id + ' is not implemented !');
			}
		}

		return ( validator.validate( element ) );
	},
	
	required: function( element ) 
	{
		var element = $(element);
		
		if ( !Element.getAttributeValue( element, 'required' ) )
		{
			return true;
		}
			
		var value 	= $F(element);
		var valid = false;
		
		var rules 		= Element.getAttributeValue( element, 'validationrules' );
		
		if ( rules )
		{
			var obj 	= Util.getJSObject( rules );
			var custommsg = dialog.getMessage( obj.messages['required'] );
		} 
		else 
		{
			var custommsg = dialog.getMessage( Element.getAttributeValue(element, 'validationerrormsg', '') );			
		}
		
		switch ( element.type ) {	
			case 'checkbox':
				valid = element.checked;
				defaultmsg 	= element.id + " is required to be checked !";
				break;
				
			case 'select-one':
				valid = (element.selectedIndex != 0);
				defaultmsg	= element.id + " You have to make a selection !";
				break;
				
			case 'select-multiple':
				var selectallitems = Element.getAttributeValue( element, 'selectallitems' );
				
				if ( selectallitems ) 
				{
					valid = ( element.options.length > 0 );
				} 
				else 
				{
					valid = ( element.selectedIndex != -1);
				}
				
				defaultmsg = element.id + " You have to make at least one selection !";
				break;
				
			default:
				valid = ( value != '' );
				defaultmsg 	= element.id + " is a required field !";
				break;
		}
		
		if (!valid) 
		{
			var msg = ( custommsg == '' ) ? defaultmsg : custommsg;
			alert( msg );
		}
		
		return valid;
	},
	
	
	setValue: function(field, value, form)
	{
		try 
		{
			if (form == null)
			{
				form = 0;
			}
		
			var form = document.forms[form];
	
			if (form[field] != null)
			{
				form[field].value = value;
			}
		} 
		catch (e) 
		{
			if (e instanceof Error)
			{
				throw new Error('Form::setValue(): ' + e.name + ' ' + e.message);
			}
		}
	},
	
	
	getNewInput: function( name, value, type )
	{
		switch ( type.toLowerCase() ) 
		{
			case 'submit':
			case 'hidden':
			case 'password':
			case 'text':
			case 'checkbox':
			case 'radio':
				break;
				
			default:
				type = 'text';
				break;
		}
		
		try 
		{
			var field 	= document.createElement('input');
		
			field.type 	= type;
			field.id	= name;
			field.name	= name;
			field.value	= value;
		
			return field;
		} 
		catch (e) 
		{
			if (e instanceof Error)
			{
				throw new Error('Form::getNewInput(): ' + e.name + ' ' + e.message);
			}
		}
	},
	
	
	isEmpty: function( element )
	{
		var element = $(element);
		var value 	= $F(element);
		
		return ( value == '' || value == null );
	},

	
	disable: function( element ) 
	{
		$(element).disabled = 'true';
	},
	
	enable: function( element ) 
	{
		$(element).disabled = '';
	}
});

Object.extend( Form.Element.Serializers, 
{
	inputSelector: function(element) 
	{
		if (element.checked) 
		{
			return ( element.value == 'on' || element.value == '' ) ? 'true' : element.value;
		}
			
		return (element.type.toLowerCase() == 'radio') ? "" : 'false';
	},
	
	selectMany: function(element) 
	{
		var value = [];
		
		var addremove = element.getAttribute('addremove');
		var selectall = element.getAttribute('selectallitems');
		var selected  = false;
		
		if ( addremove || selectall ) 
		{
			selected = true;
			for (var i = 0; i < element.length; i++) 
			{
				var opt = element.options[i];
				var optValue = opt.value;
				
				if ( !optValue && !('value' in opt ) )
				{
					optValue = opt.text;
				}
					
				value.push(optValue);
			}
		} 
		else 
		{
			var options = [];
			for (var i = 0; i < element.length; i++) 
			{
				var opt = element.options[i];
				
				if (opt.selected) 
				{
					selected = true;
					var optValue = opt.value;
					
					if (!optValue && !('value' in opt)) 
					{
						optValue = opt.text;
					}
						
					options.push(optValue);
				}
			}
			
			value.push(options.join('|'));
		}
		
		return (selected) ? value : [''];
	}
});



function noSelect(evt)
{
	var element = $GE(evt);
	
	if (element.type == "text" || element.nodeName == 'TEXTAREA')
	{
		return true;
	}
	
	return false;
}


function isEmptyValue( value )
{
	switch(value) 
	{
		case 'undefined':
		case null:
		case '0':
		case '':
		case false:
		
			return true;
			break;
	}
	
	return false;
}


function sleep( ms )
{
	if ( !ms ) 
	{
		return;
	}
	
	var d = new Date();
	
	while ( true )	
	{
		var mill = new Date();
		var diff = mill - d;
		
		if( diff > ms) 
		{ 
			break;
		}
	}
}


function toggleEnterKey(evt)
{
	var element = $GE(evt);
	
	var keyCode = 	evt.keyCode ? evt.keyCode :
               		evt.charCode ? evt.charCode :
					evt.which ? evt.which : void 0;
					
	if (element.nodeName != 'INPUT' || (keyCode && keyCode != 13)) 
	{
		return;
	}

	if ( keyCode && window.event && !window.opera ) 
	{
		window.event.keyCode = 9;
		return true;
	} 
	else if (evt.keyCode) 
	{
		
		//return evt.which = 9;
	}
}


function changeKey (textControl, evt, keyChecker) 
{
	var keyCode = 	evt.keyCode ? evt.keyCode :
               		evt.charCode ? evt.charCode :
					evt.which ? evt.which : void 0;
				
  	var key;
  
	if (keyCode)
	{
	  	key = String.fromCharCode(keyCode);
	}

	var keyCheck = keyChecker(keyCode, key);

	if (keyCode && window.event && !window.opera)
	{
	    if (keyCheck.cancelKey)
	    {
	    	return false;
	    } 
	    else if (keyCheck.replaceKey) 
	    {
	    	window.event.keyCode = keyCheck.newKeyCode;
	    	
	      	if (window.event.preventDefault)
	      	{
	      		window.event.preventDefault();
	      	}
	      	
	     	return true;
	    } 
	    else
	    {
	      	return true;
	    }
	  } 
	  else if (typeof textControl.setSelectionRange != 'undefined') 
	  {
	    	if (keyCheck.cancelKey) 
	    	{
	      		if (evt.preventDefault)
	      		{
	        		evt.preventDefault();
	      		}
	      		
	      		return false;
	    	} 
	    	else if (keyCheck.replaceKey) 
	    	{
    			// cancel the key event and insert the newKey for the current selection
	      		if (evt.preventDefault)
	      		{
		  			evt.preventDefault();
	      		}
	      		
	      		var oldSelectionStart = textControl.selectionStart;
	      		var oldSelectionEnd = textControl.selectionEnd;
	      		var selectedText = textControl.value.substring(oldSelectionStart, oldSelectionEnd);
	      		var newText = typeof keyCheck.newKey != 'undefined' ? keyCheck.newKey : String.fromCharCode(keyCheck.newKeyCode);
	      		
	      		textControl.value = textControl.value.substring(0, oldSelectionStart) + newText +
	        						textControl.value.substring(oldSelectionEnd);
	      
	        	textControl.setSelectionRange(oldSelectionStart + newText.length, oldSelectionStart + newText.length);
	      		return false;
	    	} 
	    	else
	    	{
	      		return true;
	    	}
	  } 
	  else if (keyCheck.cancelKey) 
	  {
	    	if (evt.preventDefault)
	    	{
	      		evt.preventDefault();
	    	}
	      		
	    	return false;
	  } 
	  else
	  {
			return true;
	  }
}




function lettersToUpperCase (keyCode, key)
{
	var newKey = key.toUpperCase();
	
  	if (newKey != key)
  	{
    	return { replaceKey: true, newKeyCode: newKey.charCodeAt(), newKey:newKey };
  	}
  	else
  	{
   		return { cancelKey: false };
  	}
}


function digitsToX (keyCode, key)
{
	if ("0123456789".indexOf(key) != -1)
	{
		return { replaceKey: true, newKeyCode: "X".charCodeAt(), newKey: "X" };
	}
	else
	{
		return { cancelKey: false };
	}
}


function cancelDigits (keyCode, key) 
{
 	return { cancelKey: "0123456789".indexOf(key) != -1 };
}



var Util = 
{
	getJSObject: function ( literal ) 
	{
		try 
		{
			eval ( "obj = " + literal + ";" );
			return ( typeof obj != 'number' ) ? obj : false;
		} 
		catch( e ) 
		{
			return false;
		}
	},
	
	getIframe: function() 
	{
		var myframe = document.createElement("IFRAME");
		myframe.frameBorder = 0;
		myframe.scrolling = 'no';
		myframe.src = "javascript: false";
	
		return myframe;
	}
};

var Sort = 
{
	
	compareValues: function(a, b)
	{
		if ( typeof a.value != "undefined" )
		{
			a = a.value;
		}
			
		if ( typeof b.value != "undefined" )
		{
			b = b.value;
		}
			
		if ( a == null || a == 'undefined' || a === false )
		{
			return -1;
		}
		
		if ( b == null || b == 'undefined' || b === false )
		{
			return 1;
		}
	
		var res;
		
		if ( a.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/) || a.match(/^\d\d[\/-]\d\d[\/-]\d\d$/) ) 
		{
			if (a.length == 10) 
			{
		        var date1 = a.substr(6,4) + a.substr(3,2) + a.substr(0,2);
		    } 
		    else 
		    {
		        var year = a.substr(6,2);
		
		        if ( parseInt( year ) < 50 ) 
		        {
		        	year = '20' + year; 
		        } 
		        else 
		        {
		        	year = '19' + year;
		        }
		        
		        date1 = year + a.substr(3,2) + a.substr(0,2);
		    }
		    
		    if (b.length == 10) 
		    {
		        var date2 = b.substr(6,4) + b.substr(3,2) + b.substr(0,2);
		    } 
		    else 
		    {
		        var year = b.substr(6,2);
		        
		        if (parseInt(year) < 50) 
		        {
		        	year = '20' + year;
		        } 
		        else 
		        {
		       		year = '19' + year;
		        }
		       		
		        date2 = year + b.substr(3,2) + b.substr(0,2);
		    }
		    
		    if (date1 == date2)
		    {
		    	res = 0;
		    }
		    	
		    if ( date1 < date2 )
		    {
		    	res = -1;
		    }
	    	
	    	res = 1;
	    
		} 
		else if ( a.match(/^[��$]|EURO/) || a.match(/[\d\.]\s+(EURO|[��$])/) ) 
		{
			//alert(" a before replace: " + a + " b before replace: " + b + "!");
			
			var c = a.replace(/[^0-9.]/g,'');
	    	var d = b.replace(/[^0-9.]/g,'');
			//alert("a has type " + typeof(a) + " and value " + a + "|b has type " + typeof(b) + " and value: " + b);
			    
	    	res = parseFloat(c) - parseFloat(d); 
	    
		} 
		else if (!isNaN( parseInt(a) ) && !isNaN( parseInt(b) ) ) 
		{
			if ( a.indexOf('.') != -1 || a.indexOf(',') != -1 ) 
			{
				
				var c = parseFloat(a);
	    
	    		if (isNaN(c)) 
	    		{
	    			c = 0;
	    		}
	    
	    		var d = parseFloat(b);
	    
	    		if (isNaN(d)) 
	    		{
	    			d = 0;
	    		}
	    	
	    		res = c - d;
			} 
			else 
			{
				
				res = parseInt( a ) - parseInt( b);
			}
		} 
		else 
		{
			
			res = 1;
			
			if ( a == b ) 
			{
	    		res = 0;
			}
	    	
	   		if ( a < b ) 
	   		{
	    		res = -1;
	   		}
		}
		
		if (descend) 
		{
	    	res = res * -1;
		}
	
	    return res;
	},
	
	compareRight : function(a,b)
	{
		var bias = 0;
		var ia = 0;
		var ib = 0;

		var ca;
		var cb;

		// The longest run of digits wins.  That aside, the greatest
		// value wins, but we can't know that it will until we've scanned
		// both numbers to know that they have the same magnitude, so we
		// remember it in BIAS.
		for (;; ia++, ib++) {
			ca = a.charAt(ia);
			cb = b.charAt(ib);

			if (!Sort.isDigitChar(ca)
					&& !Sort.isDigitChar(cb)) {
				return bias;
			} else if (!Sort.isDigitChar(ca)) {
				return -1;
			} else if (!Sort.isDigitChar(cb)) {
				return +1;
			} else if (ca < cb) {
				if (bias == 0) {
					bias = -1;
				}
			} else if (ca > cb) {
				if (bias == 0)
					bias = +1;
			} else if (ca == 0 && cb == 0) {
				return bias;
			}
		}
	},
	
	isWhitespaceChar : function(a) {
		return ( a.charCodeAt(0) <= 32 ) ? true : false;
	},
	
	isDigitChar : function(a) {
		var charCode = a.charCodeAt(0);
		return ( charCode >= 48  && charCode <= 57 ) ? true : false;
	},
	
	natCompare: function(a,b) 
	{
		var regexpNumber = /^-?\d+([.,]\d*)?\s*$/;	// numbers (floats) with optional whitespaces at the end
	
		// -gl- 081218 adjusted to EasyGUI Usage
		if ( a.value )
			a = a.value;
			
		if ( b.value )
			b = b.value;
			
		if ( a === null || a === undefined || a === false )
			return -1;
		
		if ( b === null || b === undefined || b === false )
			return 1;
		
		//console.log( "Starting to compare a: " + a + " to b: " + b );
		
		if ( regexpNumber.test( a ) && regexpNumber.test( b ) ) 
		{
			// -og- 080701: two doubles -> we don't need to use natcompare
			a = a.replace( ',', '.' );
			b = b.replace( ',', '.' );
			
			var da = parseFloat( a );
			var db = parseFloat( b );
			if ( !isNaN( da ) && !isNaN( db ) )
			{
				if ( descend || descend == "true" ) 
				{
					if ( da <= db )
						return 1;
					else if ( da > db )
						return -1;
				}
				else
				{
					if ( da <= db ) 
						return -1;
					else if ( da > db )
						return +1;
				}
			}
			else if ( !isNaN( da ) )
			{
				if ( descend || descend == "true" ) 
					return 1;
				else return -1;
			}
			else if ( !isNaN( db ) )
			{
				if ( descend || descend == "true" ) 
					return -1;
				else return 1;
			}
			
			return 1;
		}
		
		if ( a.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/) && b.match(/^\d\d[\/-]\d\d[\/-]\d\d$/) ) 
		{
			if (a.length == 10) {
				var date1 = a.substr(6,4) + a.substr(3,2) + a.substr(0,2);
			} 
			else {
				var year = a.substr(6,2);
				year = (parseInt(year) < 50) ? '20' + year : '19' + year;
				date1 = year + a.substr(3,2) + a.substr(0,2);
			}
			
			if (b.length == 10) {
				var date2 = b.substr(6,4) + b.substr(3,2) + b.substr(0,2);
			}
			else {
				var year = b.substr(6,2);
				year = (parseInt(year) < 50) ? '20' + year : '19' + year;
				date2 = year + b.substr(3,2) + b.substr(0,2);
			}
			
			if (date1 == date2)
				return 0;
				
			if ( date1 < date2 )
				return -1;
				
			return 1;
		} 
		else if ( ( a.match(/^[��$]|EURO/) || a.match(/[\d\.]\s+(EURO|[��$])/) ) && ( b.match(/^[��$]|EURO/) || b.match(/[\d\.]\s+(EURO|[��$])/) ) ) 
		{
			var c = a.replace(/[^0-9.]/g,'');
			var d = b.replace(/[^0-9.]/g,'');
			return parseFloat(c) - parseFloat(d); 
		} 
		
		var ia = 0, ib = 0;
		var nza = 0, nzb = 0;
		var ca, cb;
		var result;

		while (true)
		{
			// only count the number of zeroes leading the last number compared
			nza = nzb = 0;

			ca = a.charAt(ia);
			cb = b.charAt(ib);

			// skip over leading spaces or zeros
			while ( Sort.isWhitespaceChar( ca ) || ca =='0' ) {
				if (ca == '0') {
					nza++;
				} else {
					// only count consecutive zeroes
					nza = 0;
				}

				ca = a.charAt(++ia);
			}

			while ( Sort.isWhitespaceChar( cb ) || cb == '0') {
				if (cb == '0') {
					nzb++;
				} else {
					// only count consecutive zeroes
					nzb = 0;
				}

				cb = b.charAt(++ib);
			}

			// process run of digits
			if (Sort.isDigitChar(ca) && Sort.isDigitChar(cb)) {
				if ((result = Sort.compareRight(a.substring(ia), b.substring(ib))) != 0) {
				
					// -og- 080623 adjusted to IsyCat usage
					if (descend || descend == "true") {
						result = result * -1;
					}
					
					return result;
				}
			}

			if (ca == 0 && cb == 0) {
				// The strings compare the same.  Perhaps the caller
				// will want to call strcmp to break the tie.
				
				// -og- 080623 adjusted to IsyCat usage
				if (descend || descend == "true") {
					return nzb - nza;
				}
				
				return nza - nzb;
			}

			// -og- 080623 adjusted to IsyCat usage
			if (descend || descend == "true") 
			{
				if (ca < cb) {
					return 1;
				} else if (ca > cb) {
					return -1;
				}
			}
			else
			{
				if (ca < cb) {
					return -1;
				} else if (ca > cb) {
					return +1;
				}
			}
			
			++ia; ++ib;
		}
	}
};


var DateTime = {
	
	isFutureDate: function( dateStr, format)
	{
		var parts 	= DateTime.getParts( dateStr, format );
		
		var day		= DateTime.getPart(parts, 'd', format);
		var month	= DateTime.getPart(parts, 'm', format);
		var year	= DateTime.getPart(parts, 'y', format);
		
		var today = new Date();
		
		if (parseFloat(year) <= 50) {
			year = (parseFloat(year) + 2000).toString(); 
		}
		
		if (parseFloat(year) <= 99) {
			year = (parseFloat(year) + 1900).toString();
		}
		
		var dt = new Date(parseFloat(year), parseFloat(month), parseFloat(day), 0, 0, 0, 0);
		
		var tim1 = dt.getTime();
		var tim2 = today.getTime();
		
		if (tim1 > tim2) {
			return true;
		}
		
		return false;
	},
	
	
	isValidDate: function( dateStr, format )
	{
		var parts 	= DateTime.getParts( dateStr, format );
		
		if ( !parts) {
			return false;
		}
		
		var day		= DateTime.getPart(parts, 'd', format);
		var month	= DateTime.getPart(parts, 'm', format);
		var year	= DateTime.getPart(parts, 'y', format);
		
		if (parseFloat(year) <= 50) {
			year = (parseFloat(year) + 2000).toString(); 
		}
		
		if (parseFloat(year) <= 99) {
			year = (parseFloat(year) + 1900).toString();
		}
		
		var dt = new Date(parseFloat(year), parseFloat(month), parseFloat(day), 0, 0, 0, 0);
		
		if (parseFloat(day) != dt.getDate()) {
			return false;
		}
		
		if (parseFloat(month) != dt.getMonth()) {
			return false; 
		}
		
		return true;
	},
	
	
	getFormat: function( format )
	{
		if (format == null) {
			format = "dmy";
		}
		
		format = format.toLowerCase();
		
		if (format.length != 3) {
	   		format = "dmy";
		}
		   
	   	if ( (format.indexOf("m") == -1) || (format.indexOf("d") == -1) || (format.indexOf("y") == -1) ) {
	      	format = "dmy";
	   	}
	   	
	   	return format;
	},
	
	
	getParts: function(dateStr, format)
	{
		var format = DateTime.getFormat( format );
		
	   	if (format.substring(0, 1) == "y") { // If the year is first
	    	var reg1 = /^\d{2}(\-|\/|\.)\d{1,2}\1\d{1,2}$/;
	      	var reg2 = /^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$/;
	   	} else if (format.substring(1, 2) == "y") { // If the year is second
	    	var reg1 = /^\d{1,2}(\-|\/|\.)\d{2}\1\d{1,2}$/;
	      	var reg2 = /^\d{1,2}(\-|\/|\.)\d{4}\1\d{1,2}$/;
	   	} else { // The year must be third
	    	var reg1 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{2}$/;
	      	var reg2 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;
	   	}
	
	   	if ( (reg1.test(dateStr) == false) && (reg2.test(dateStr) == false) ) {
	   		return false; 
	   	}
	   
	   	var parts = dateStr.split(RegExp.$1); // Split into 3 parts based on what the divider was
	   	return parts;
	},
	
	
	getPart: function(parts, part, format)
	{
		if (part == null) {
			part = 'y';
		}
			
		var part = part.toLowerCase();
		
		if (part != 'm' && part != 'y' && part != 'd') {
			return false;
		}
			
		var format = DateTime.getFormat( format );
		
	   	if (format.substring(0, 1) == part) {
	   		var result = parts[0]; 
	   	} else if (format.substring(1, 2) == part) {
	   		var result = parts[1];
	   	} else {
	   		var result = parts[2];
	   	}
	   	
	   	if ( part == 'm' ) {
	   		return result - 1;
	   	}
	   	
	   	return result;
	},
	
	
	isValidTime: function(hour)
	{
		return /^([01]?[0-9]|[2][0-3])(:[0-5][0-9])?$/.test(hour);
	}
};
function JS_Timer()
{
	// PRIVATE PROPERTIES

    
    this._starttime = '';
    
    this._endtime = '';
    
    this._elapsedtime = '';
   
    
    this.startTimer = function()
    {
        mtime = new Date();
        this._starttime = mtime.getTime();
    };

    
    this.stopTimer = function()
    {
        mtime = new Date();
        this._endtime = mtime.getTime();
        this._setElapsedTime();

        // We are going to assume that when the timer is stopped
        // they will want the elapsed time immediately
        return this.getElapsedTime();
    };

    
    this.restart = function()
    {
        this._endtime = '';
        this._elapsedtime = '';
        
        this.startTimer();      
    };

    
    this.getElapsedTime = function()
    {
        return ( this._elapsedtime / 1000 );
    };

    // PRIVATE METHODS

    
    this._setElapsedTime = function()
    {
        this._elapsedtime = this._endtime - this._starttime;
    };
}

var EasyGUI_Validator = Class.create();

EasyGUI_Validator.prototype = 
{
	initialize: function( obj ) 
	{
		this.rules		= [];
		this.element 	= null;
		this.value		= null;
		this.valid 		= true;
		
		Object.extend( this, obj );
	},
	
	// Check if there's a possibility for sprintf
	
	throwMessage: function( rule )
	{
		if ( this.valid )
		{
			return;
		}
			
		var rule = ( !rule ) ? 'invalid' : rule;
		
		for ( msg in this.messages )
		{
			if ( msg == rule )
			{
				var message = 'No message for ' + rule;
				
				if ( $( this.messages[rule] ) )
				{
					message = dialog.getMessage( this.messages[rule] );
				}
			}
		}
		
		alert( message );
		//alert( message.replace('%d', value) );
	},
	
	validate: function( element ) 
	{
		this.element 	= $( element );
		this.value		= $F( element );
	
		this.valid 		= this.isvalid();
		
		if ( !this.valid )
		{
			this.throwMessage( 'invalid' );
			return this.valid;
		}
		
		var rule = null;
		
		for ( var i=0; i < this.rules.length; i++ )
		{
			var method = this.rules[i][0];
			var value  = this.rules[i][1];
			
			if ( this[method] ) 
			{
				if ( ! (this.valid = this[method].call( this, value ) ) )
				{
					break;
				}
			}
		}
		
		this.throwMessage( method );
		return this.valid;
	},
	
	
	isvalid: function()
	{
		return true;
	},
	
	maxlength: function( value )
	{
		return ( this.value.length < parseFloat( value ) );
	},
	
	minlength: function( value )
	{
		return ( this.value.length > parseInt( value ) );
	},
	
	minvalue: function( value )
	{
		return ( this.value > parseFloat( value.replace( ',','.' ) ) );
	},
	
	maxvalue: function( value )
	{
		return ( this.value < parseFloat( value.replace( ',','.' ) ) );
	},

	range: function( value ) 
	{
		return ( this.value > parseFloat( value.replace(',','.') ) && 
				 this.value < parseFloat( value.replace(',','.') ) );
	}		
}
var EasyGUI_DateValidator = Class.create();

EasyGUI_DateValidator.format = 'dmy';

EasyGUI_DateValidator.messages =
{
	invalid: 	'%d is not a valid date !',
	nofuture:	'Future date is not allowed !',
	before: 	'Date has to be before %d !',
	after: 		'Date has to be after %d !'
}

Object.extend( Object.extend( EasyGUI_DateValidator.prototype, EasyGUI_Validator.prototype ), 
{	
	isvalid: function()
	{
		return DateTime.isValidDate( this.value, this.format );
	},
	
	nofuture: function()
	{
		return !DateTime.isFutureDate( this.value, this.format );
	},
	
	
	before: function( value )
	{
		return true;
	},
	
	
	after: function( value )
	{
		return true;
	}
});
var EasyGUI_AlphaValidator = Class.create();

EasyGUI_AlphaValidator.messages = 
{
	invalid: 'Only alphanumeric values allowed !'
}

Object.extend( Object.extend ( EasyGUI_AlphaValidator.prototype, EasyGUI_Validator.prototype ),
{
	isvalid: function()
	{
		return( !isNaN( value ) && value != '' );
	}
});
var EasyGUI_EmailValidator = Class.create();

EasyGUI_EmailValidator.messages = 
{
	invalid: '%d is not a valid email adress !'
}

Object.extend( Object.extend ( EasyGUI_EmailValidator.prototype, EasyGUI_Validator.prototype ),
{
	isvalid: function()
	{
		return (!this.value.match(/.*\@.*\..*/));
	}
});
var EasyGUI_NumericValidator = Class.create();

EasyGUI_NumericValidator.messages = 
{
	minvalue: 'Only values > %d allowed',
	maxvalue: 'Only values < %d allowed',
	invalid: 'Only numeric values allowed',
	range: 'Value is out of range [%d to %d]'
}

Object.extend( Object.extend ( EasyGUI_NumericValidator.prototype, EasyGUI_Validator.prototype ),
{
	isvalid: function() 
	{
		return ( isNaN( this.value ) );
	}
});
var EasyGUI_TimeValidator = Class.create();

EasyGUI_TimeValidator.messages = 
{
	invalid: '%d is not a valid time !'
}

Object.extend( Object.extend ( EasyGUI_TimeValidator.prototype, EasyGUI_Validator.prototype ),
{
	isvalid: function()
	{
		return DateTime.isValidTime( this.value );
	}
});

function guiWindow(id, obj)
{
	
	this.id = id;
	
	
	this.obj = obj;
	
	
	this.intervalHandler = null;
}

function windowRegistry()
{
	
	this.registry = new Array();
	
	
	this.registerWindow = function(win)
	{
		this.registry.push(win);
	};
	
	
	this.getGuiWindow = function(id)
	{
		for (var i=0; i < this.registry.length; i++) {
			if (this.registry[i] != null) {
				if (this.registry[i].id == id) {
					return this.registry[i];
				}
			}
		}
		
		return false;
	};
	
	
	this.startModalObserver = function(id)
	{
		var observable = this.getGuiWindow(id);
		
		if (!observable) {
			return;
		}
		
		observable.intervalHandler = setInterval("observeModalWindow('" + id + "')", 100);
	};
	
	
	this.removeWindow = function(id)
	{
		for (var i=0; i < this.registry.length; i++) {
			if (this.registry[i] != null && this.registry[i].id == id) {
				this.registry[i] = null;
			}
		}
	};
}


function observeModalWindow(id)
{
	var observable = dialog.winRegistry.getGuiWindow(id);

	if (observable.obj.closed == true) {
		clearInterval(observable.intervalHandler);
		dialog.winRegistry.removeWindow(id);
		dialog.enable();
	}
}


function getWindowName()
{
	return self.name;
}


function getOpener()
{
	if (self.opener == null) return false;	
	return self.opener;
}


function getTopWindow()
{
	if (self.opener == null) return self;
	
	var win = self.opener;
	
	while (win.opener != null) {
		win = win.opener;
	}
	
	return win;
}


var EasyGUI_widget = Class.create();

EasyGUI_widget.prototype = 
{
	
	initialized: false,
	
	
	element: null,
	
	
	widgetElements: [],
	
	
	widget: null,
	
	
	isInTable: false,
	
	
	initialize: function( id )
	{
		this.id = id;
		this.element = $(id);
		this.isInTable = ( Element.isInTable( this.id ) ) ? true : false;
	},
	
	
	setAction: function( action ) 
	{
		this.element.setAttribute( 'action', action );
	},
	
	
	render: function() 
	{
		;
	},
	
	
	update: function()
	{
		;
	},
	
	
	finalize: function() 
	{
		this.initialized = true;
	},
	
	
	destroy: function()
	{
		this.element = null;
		this.widget = null;
	},
	
	
	getClassName: function()
	{
		return this.element.className;
	},
	
	
	getStyleDefinition: function( def )
	{
		return this.element.className + '-' + def;
	},
	
	
	toString: function() 
	{
		return 'object EasyGUI_Widget(' + this.id + ')';
	},
	
	
	getOffsetLeft: function() 
	{
		return parseInt(this.element.offsetLeft);
	},
	
	
	getPageOffsetLeft: function() 
	{
  		return Position.cumulativeOffset( this.element )[0];
	},
	
	
	getOffsetTop: function() 
	{ 
		return parseInt(this.element.offsetTop);
	},
	
	
	getPageOffsetTop: function() 
	{
		return Position.cumulativeOffset( this.element )[1];
	},
	
	
	getOffsetWidth: function() 
	{ 
		return parseInt( this.element.offsetWidth ); 
	},

	
	getOffsetHeight: function() 
	{
		return parseInt( this.element.offsetHeight );
	},
	
	
	getStyleLeft: function() 
	{
		return parseInt( this.element.style.left );
	},
	
	
	getStyleTop: function() 
	{ 
		return parseInt( this.element.style.top );
	},
	
	
	getStyleWidth: function() 
	{ 
		return parseInt( this.element.style.width ); 
	},

	
	getStyleHeight: function() 
	{
		return parseInt( this.element.style.height );
	},
	
	
	moveLeft: function(pixels) 
	{
		this.element.style.left = ( this.getStyleLeft( ) - parseInt( pixels ) ) + 'px';
	},
	
	
	moveRight: function(pixels) 
	{
		this.element.style.left = ( this.getStyleLeft( ) + parseInt( pixels ) ) + 'px';
	},
	
	
	moveUp: function(pixels) 
	{
		this.element.style.top = ( this.getStyleTop() - parseInt( pixels ) ) + 'px';
	},
	
	
	moveDown: function(pixels) 
	{
		this.element.style.top = ( this.getStyleTop() + parseInt(pixels)) + 'px';
	},
	
	
	setPosition: function( top, left ) 
	{
		var top = ( typeof top == 'string' ) ? top : top + 'px';
		var left = ( typeof left == 'string' ) ? left : left + 'px';
		
		this.element.style.top = top;
		this.element.style.left = left;
	},
	
	
	setDimension: function( width, height ) 
	{
		var width = ( typeof width == 'string' ) ? width : width + 'px';
		var height = ( typeof height == 'string' ) ? height : height + 'px';
	
		this.element.style.width = width;
		this.element.style.height = height;
	},
	
	
	disable: function() 
	{ 
		this.element.disabled = true;
	},
	
	
	enable: function() 
	{
		this.element.disabled = false;
	},
	
	
	getValue: function() {
		return $F(this.element);
	},
	
	
	setValue: function( value ) {
		this.element.value = value;
	},
	
	
	
	show: function() 
	{
		this.element.style.visibility = 'visible';
	},
	
	
	hide: function()
	{
		this.element.style.visibility = 'hidden';
	}
};

var EasyGUI_button = Class.create();

Object.extend( Object.extend( EasyGUI_button.prototype, EasyGUI_widget.prototype ),
{
	isPressed: false,
	
	render: function() 
	{
		this.type				= Element.getAttributeValue( this.element, 'type' );
		this.toolbarId 			= Element.getAttributeValue( this.element, 'toolbarid' );
		this.uploadId			= Element.getAttributeValue( this.element, 'uploadid' );
		this.overimg			= Element.getAttributeValue( this.element, 'buttonoverimage' );
		this.pressedimg 		= Element.getAttributeValue( this.element, 'buttonpressedimage' );
		this.inactiveimg 		= Element.getAttributeValue( this.element, 'buttoninactiveimage' );
		
		this.bgimg 				= Element.getStyle( this.element, 'background-image' );
		this.backgroundColor 	= Element.getStyle( this.element, 'background-color' );
		
		Event.observe( this.element, 'mouseover', this.onButtonOver.bindAsEventListener( this ) );
		Event.observe( this.element, 'mouseout', this.onButtonOut.bindAsEventListener( this ) );
		Event.observe( this.element, 'click', this.onButtonClick.bindAsEventListener( this ) );
		
		if ( this.type == 'datepicker' ) {
			this.dateSeparator 		= Element.getAttributeValue( this.element, 'dateseparator' );
			this.dateFormat 		= Element.getAttributeValue( this.element, 'dateformat' );
			this.dateField			= $( Element.getAttributeValue( this.element, 'datetargetfield' ) );
			
			this.actualMonthText	= Element.getAttributeValue( this.element, 'dateactualmonthtext', 'this month' );
			this.closeText			= Element.getAttributeValue( this.element, 'dateclosetext', 'close' );
			
			if ( isEmptyValue(this.element.className) ) {
				this.element.className = 'easygui-dp';
			}
			
			this.dpid = 'EasyGUI_DatePicker';
			this.idpid = 'EasyGUI_DatePickerIframe';
			
			this.element.onclick = function() { return false; };			
			var dateDays = Element.getAttributeValue( this.element, 'datedays' );
			this.dayArrayShort = (!dateDays) ? ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] : Util.getJSObject( dateDays );
			var dateMonths = Element.getAttributeValue( this.element, 'datemonths' );
			this.monthArrayLong = (!dateMonths) ? ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] : Util.getJSObject( dateMonths );
		}
		
		this.reset();
	},
	
	reset: function() {
		if (this.bgimg) {
			this.element.style.backgroundImage = this.bgimg;
		} else {
			if ( this.backgroundColor != '#ece9d8' ) {
				this.element.style.backgroundColor = this.backgroundColor;
			}
		}
		
		this.isPressed = false;
		this.element.blur();
	},
	
	pageMousedown: function( evt )
	{
		if ($( this.dpid ) ) {
			Element.hide( this.dpid );
			Element._hide( this.dpid );
	
			this.setIFrame();
		}
	},
	
	onButtonOver: function( evt ) {
		if ( this.overimg ) {
			this.element.style.backgroundImage = 'url(' + this.overimg + ')';
		}
	},
	
	onButtonOut: function( evt ) {
		if ( this.overimg && !this.isPressed) {
			this.reset();
		} else {
			if (this.pressedimg) {
				this.element.style.backgroundImage = 'url(' + this.pressedimg + ')';
			}
		}
	},
	
	onButtonClick: function( evt ) {
		if ( this.pressedimg ) {
			var allButtons = document.getElementsByTagName('button');
			
			for (var i=0; i < allButtons.length; i++) {
				var button = gui.getWidget( allButtons[i].id );
				
				if ( this.toolbarId && button.toolbarId && this != button) {
					if (this.toolbarId == button.toolbarId) {
						button.reset();
					}
				}
			}
			
			this.isPressed = true;
			this.element.style.backgroundImage = 'url(' + this.pressedimg + ')';
		}
		
		if ( this.type == 'upload' ) {
			ekUpload.call( this, this.element );
		}
			
		if ( this.type == 'submit' ) {
			ekSubmit( this.id );
		}
			
		if ( this.type == 'request' ) {
			ekRequest( this.id );
		}
		
		if ( this.type == 'datepicker') {
			this.drawDatePicker();
		}
	},
	
	drawDatePicker: function() 
	{
		var dt = this.getFieldDate( $F( this.dateField ) );
		
		if (!$( this.dpid ) ) {
			var newNode = document.createElement("div");
			newNode.setAttribute("id", this.dpid);
			newNode.setAttribute("class", this.getStyleDefinition( "div" ) );
			newNode.setAttribute("style", "visibility: hidden;");
			document.body.appendChild(newNode);
		}
		
		var pickerDiv = $( this.dpid);
		pickerDiv.style.position = "absolute";
		pickerDiv.style.left = this.getPageOffsetLeft() + 'px';
		pickerDiv.style.top =  this.getPageOffsetTop() + 'px';
		pickerDiv.style.visibility = (pickerDiv.style.visibility == "visible" ? "hidden" : "visible");
		pickerDiv.style.display = (pickerDiv.style.display == "block" ? "none" : "block");
		pickerDiv.style.zIndex = 10000;
		
		this.refreshDatePicker(dt.getFullYear(), dt.getMonth(), dt.getDate());
	},
	
	
	refreshDatePicker: function(year, month, day)
	{
		var thisDay = new Date();
		
		if ((month >= 0) && (year > 0)) {
			thisDay = new Date(year, month, 1);
		} else {
			day = thisDay.getDate();
			thisDay.setDate(1);
		}
		
		var crlf = "\r\n";
		
		var TABLE 			= "<table cols=7 class='" + this.getStyleDefinition('table') + "'>" + crlf;
		var xTABLE 			= "</table>" + crlf;
		var TR 				= "<tr class='" + this.getStyleDefinition('row') + "'>";
		var TR_title 		= "<tr class='" + this.getStyleDefinition('title-row') + "'>";
		var TR_days 		= "<tr class='" + this.getStyleDefinition( 'day-row') + "'>";
		var TR_todaybutton 	= "<tr class='" + this.getStyleDefinition( 'today-button-row' ) + "'>";
		var xTR 			= "</tr>" + crlf;
		var TD 				= "<td class='" + this.getStyleDefinition( 'cell') + "' onMouseOut='this.className=\""+ this.getStyleDefinition('cell') + "\";' onMouseOver=' this.className=\"" + this.getStyleDefinition( 'cell-hover') + "\";' ";    // leave this tag open, because we'll be adding an onClick event
		var TD_title 		= "<td colspan=5 class='" + this.getStyleDefinition( 'title-cell') + "'>";
		var TD_buttons 		= "<td class='" + this.getStyleDefinition( 'button-cell' ) + "'>";
		var TD_todaybutton 	= "<td colspan=7 nowrap=\"nowrap\" class='" + this.getStyleDefinition( 'today-button-cell' ) + "'>";
		var TD_days 		= "<td class='" + this.getStyleDefinition( 'day-cell' ) + "'>";
		var TD_selected 	= "<td class='" + this.getStyleDefinition( 'day-hl-cell' ) + "' onMouseOut='this.className=\"" + this.getStyleDefinition( 'day-hl-cell') + "\";' onMouseOver='this.className=\"" + this.getStyleDefinition( 'cell-hover' ) + "\";' ";    // leave this tag open, because we'll be adding an onClick event
		var xTD 			= "</td>" + crlf;
		var DIV_title 		= "<div class='" + this.getStyleDefinition( 'title-text' ) + "'>";
		var DIV_selected 	= "<div class='" + this.getStyleDefinition( 'day-hl' ) + "'>";
		var xDIV 			= "</div>";
		
		var html = TABLE;
		
		html += TR_title;
		html += TD_buttons + this.getButtonCode(thisDay, -1, "&lt;") + xTD;
		html += TD_title + DIV_title + this.monthArrayLong[ thisDay.getMonth()] + " " + thisDay.getFullYear() + xDIV + xTD;
		html += TD_buttons + this.getButtonCode(thisDay, 1, "&gt;") + xTD;
		html += xTR;
		
		html += TR_days;
		
		for(i = 0; i < this.dayArrayShort.length; i++) {
			html += TD_days + this.dayArrayShort[i] + xTD;
		}
			
		html += xTR;
		html += TR;
		
		for (i = 0; i < thisDay.getDay(); i++) {
			html += TD + "&nbsp;" + xTD;
		}
		
		// now, the days of the month
		do {
			dayNum = thisDay.getDate();
			TD_onclick = " onclick=\"dialog." + this.id + ".updateDateField('" + this.getDateString(thisDay) + "');\">";
		
			if (dayNum == day) {
				html += TD_selected + TD_onclick + DIV_selected + dayNum + xDIV + xTD;
			} else {
				html += TD + TD_onclick + dayNum + xTD;
			}
			
			if (thisDay.getDay() == 6) {
				html += xTR + TR;
			}
			
			thisDay.setDate(thisDay.getDate() + 1);
		} while (thisDay.getDate() > 1)
		
		if (thisDay.getDay() > 0) {
			for (i = 6; i > thisDay.getDay(); i--) {
				html += TD + "&nbsp;" + xTD;
			}
		}
		
		html += xTR;
	
		var today = new Date();
		html += TR_todaybutton + TD_todaybutton;
		html += "<button class='" + this.getStyleDefinition('today-button') + "' onClick='dialog." + this.id + ".refreshDatePicker();'>" + this.actualMonthText + "</button> ";
		html += "<button class='" + this.getStyleDefinition('today-button') + "' onClick='dialog." + this.id + ".updateDateField();'>" + this.closeText + "</button>";
		html += xTD + xTR;
	
		html += xTABLE;
		
		$(this.dpid).innerHTML = html;
		this.setIFrame();
	},
	
	
	updateDateField: function( dateString )
	{
		if (dateString) {
			this.dateField.value = dateString;
		}
		
		Element.hide( this.dpid );
		Element._hide( this.dpid );
	
		this.setIFrame();
		this.dateField.focus();
	},
	
	
	getDateString: function(dateVal)
	{
		var dayString 	= "00" + dateVal.getDate();
		var monthString = "00" + (dateVal.getMonth()+1);
		
		dayString 		= dayString.substring(dayString.length - 2);
		monthString 	= monthString.substring(monthString.length - 2);
		
		switch (this.dateFormat) {
			case "dmy" :
				return dayString + this.dateSeparator + monthString + this.dateSeparator + dateVal.getFullYear();
			case "ymd" :
				return dateVal.getFullYear() + this.dateSeparator + monthString + this.dateSeparator + dayString;
			case "mdy" :
			default :
				return monthString + this.dateSeparator + dayString + this.dateSeparator + dateVal.getFullYear();
		}
	},
	
	
	getButtonCode: function( dateVal, adjust, label )
	{
		var newMonth = (dateVal.getMonth () + adjust) % 12;
		var newYear = dateVal.getFullYear() + parseInt((dateVal.getMonth() + adjust) / 12);
		
		if (newMonth < 0) {
			newMonth += 12;
			newYear += -1;
		}
		
		return "<button class='" + this.getStyleDefinition( 'button' ) + "' onClick='dialog." + this.id + ".refreshDatePicker( " + newYear + ", " + newMonth + ");' style=\"width:20px\">" + label + "</button>";
	},
	
	
	getFieldDate: function(dateString)
	{
		var dateVal;
		var parts;
		var day, month, year;
		
		try {
			parts = DateTime.getParts( dateString, this.dateFormat );
			
			if (parts) {
				var day		= DateTime.getPart(parts, 'd', this.dateFormat);
				var month	= DateTime.getPart(parts, 'm', this.dateFormat);
				var year	= DateTime.getPart(parts, 'y', this.dateFormat);
				
				dateVal = new Date(year, month, day);
			} else if (dateString) {
				dateVal = new Date(dateString);
			} else {
				dateVal = new Date();
			}
		} catch(e) {
			dateVal = new Date();
		}
		
		return dateVal;
	},
	
	
	setIFrame: function()
	{
		if (is.ie5up) {
			var cal = $( this.dpid );
			
			if ( !cal.iframeEl ) {
				cal.iframeEl = cal.parentNode.insertBefore( Util.getIframe(), cal);
			}
			
			Element.setPosition( cal.iframeEl, cal.offsetTop, cal.offsetLeft );
			Element.show( cal.iframeEl );
			
			cal.iframeEl.style.position = 'absolute';
			cal.iframeEl.zIndex = parseInt( cal.style.zIndex ) - 1;
			
			Element.setDimension(cal.iframeEl, cal.clientWidth, cal.clientHeight);
			cal.iframeEl.style.display = cal.style.display;
			cal.iframeEl.style.visibility = cal.style.visibility;
		}
	},
	
	disable: function() {
		this.element.addClassName('disabled');
		this.element.disabled = true;
	},
	
	enable: function() {
		this.element.removeClassName('disabled');
		this.element.disabled = false;
	}
});

var EasyGUI_checkbox = Class.create();

Object.extend( Object.extend( EasyGUI_checkbox.prototype, EasyGUI_widget.prototype ),
{
	checked: false,
	label: '',
	
	render: function()
	{
		this.checked	= Element.getAttributeValue( this.element, 'checked' );
		this.label		= Element.getAttributeValue( this.element, 'label' );
		
		if ( this.checked )
			this.element.checked = 'checked';
			
		//this.element.onfocus = function() { this.blur(); };
		Event.observe(this.element, "focus", this.onFocus.bindAsEventListener(this) );
		this.onclicked = eval( this.element.onclick );
		
		this.element.onclick = null;
		
		Event.observe( this.element, 'click', this.onCheckboxClicked.bindAsEventListener(this) );
	},
	
	onFocus: function( evt )
	{
		var element = $GE(evt);
		element.blur();
	},
	
	show: function()
	{
		if ( this.label )
			$(this.id + '_LABEL').style.visibility = 'visible';
			
		this.element.style.visibility = 'visible';
	},
	
	hide: function()
	{
		if ( this.label )
			$(this.id + '_LABEL').style.visibility = 'hidden';
			
		this.element.style.visibility = 'hidden';
	},
	
	isChecked: function()
	{
		return ( this.element.checked );
	},
	
	
	onCheckboxClicked: function( evt )
	{
		if ( this.onclicked )
			window.setTimeout( this.onclicked, 1 );
	}
});



var EKCombos = {};
var EasyGUI_combobox = Class.create();

Object.extend( Object.extend( EasyGUI_combobox.prototype, EasyGUI_widget.prototype ),
{
	active: false,
	
	bgColor: 'white',
	
	
	textColor: 'black',
	
	
	bgColorHl: 'highlight',
	
	
	leftPos: 0,
	
	
	topPos: 0,
	
	
	itemList: '',
	
	
	selected: null,
	
	
	isEnhanced: false,
	
	
	isAddRemove: false,
	
	
	isInTable: false,
	
	
	addButton: null,
	
	
	removeButton: null,
	
	
	comboButton: null,
	
	
	optionList: null,
	
	
	targetList: null,
	
	
	textDisplay: null,
	
	
	textDisplayColumn: null,
	tableId : '',
	
	render: function() 
	{
		var tabCtrl = null;

		if ( tabid = Element.isInTab( this.id ) ) {
			tabCtrl = dialog[$( tabid ).getAttribute('widgetid')];
			tabCtrl.switchTab( tabid );
		}
		
		this.bgColor	= Element.getStyle( this.element, 'background-color', this.bgColor );
		this.bgColor 	= (this.bgColor == 'transparent') ? 'white' : this.bgColor;
		
		this.textColor 	= Element.getStyle( this.element, 'color', this.textColor );
		
		this.leftPos 	= this.getPageOffsetLeft();
		this.topPos  	= this.getPageOffsetTop();
	
		var items = Element.getAttributeValue( this.element, 'items' );
	
		this.setItemList(items);
		
		this.selected		= Element.getAttributeValue(this.element, 'selected', this.selected );
		
		this.isEnhanced 	= Element.getAttributeValue(this.element, 'enhanced' );
		this.isAddRemove 	= Element.getAttributeValue(this.element, 'addremove' );
		this.multiple		= this.element.readAttribute('multiple') || false;
		
		if ( this.multiple )
			this.selectedList = this.selected.split('|');
		
		this.displayTextColIdx = parseInt( Element.getAttributeValue( this.element, 'displaycol', 1 ) );
		this.displayTextColIdx--;
		
		if ( this.displayTextColIdx < 0 ) this.displayTextColIdx = 0;
		
		this.element.observe('change', this.onChange.bindAsEventListener(this));
		
		if ( isEmptyValue(this.element.className) )
			this.element.className = 'easygui-combobox';
			
		if ( this.isInTable || this.element.parentNode.nodeName.toLowerCase() === "td") {
			//this.tableId = this.element.up('table[ektype="Table"]' ).readAttribute('tableid');						
			
			//this.table = dialog[this.tableId];
			
			this.isInTable = true;
			this.column		= this.element.up('td');
			
			this.columnId = this.element.parentNode.id;
			this.posTable = document.createElement('table');
			
			this.posTable.cellSpacing = 0;
			this.posTable.cellPadding = 0;
			this.posTable.border = 0;
		
			this.posTr = this.posTable.insertRow(0);
			this.textDisplayColumn = this.posTr.insertCell(0);
			this.comboButtonColumn = this.posTr.insertCell(1);
		}
				
		if (this.isEnhanced) {
			this.createEnhancedCombo();
			Element.hide( this.element );
			Event.observe(document, 'click', this.closeCombo.bindAsEventListener(this), false);
		} else if (this.isAddRemove) {
			this.createAddRemoveBox();
		} else {
			this.setOptionList();

			this.element.style.margin 	= '0px';
			this.element.style.padding 	= '0px';
			
			
		}
	
		if ( tabCtrl != null ) {
			tabCtrl.switchTab( tabCtrl.getSelected() );
		}
	},
	
	onChange : function(evt) {
		var value = this.getSelected();
		
		if ( typeof this.items == 'object' ) {
			for ( var id in this.items ) {
				if ( id == value ) {
					this.element.fire('combo:change', { id: this.id, value: this.getSelected() } );
					this.selected = value;
					break;
				}
			}	
		} else {
			for (var i=0, len = this.items.length; i < len; ++i ) {
				if ( this.items[i].value == value && (this.items[i].disabled === false || this.items[i].disabled === undefined )) {
					this.element.fire('combo:change', { id: this.id, value: this.getSelected() } );
					this.selected = value;
					break;
				}
			}
		}
	},
	
	setItemList: function( items ) 
	{	
		this.items = {};
		
		if ( !items )
			return;
		
		if ( typeof items == "string" ) {
			if ( items && items.indexOf('=') == -1 && items.indexOf('|') == -1 && items.indexOf('{') == -1 )
				items = items + "=" + items;
			
			this.items = Util.getJSObject( items );
			
			if ( !this.items ) {
				this.items = {};
				items = items.split('|');
			
				if ( items.length > 0 ) {
					for (var i=0; i < items.length; i++) {
						if ( items[i] == '' )
							continue;
						 
						var option = items[i].split('=');

						if ( option.length == 1 ) {
							option[1] = option[0];
						}
						
						this.items[option[0]] = option[1].split('#');
					}
				}
			}
		} else {
			this.items = items;
		}
	},
	
	
	setOptionList: function( obj )
	{
		
		if ( obj != null ) {
			this.items = obj;
		} else if ( typeof EKCombos[this.id] != "undefined" ) {
			this.items = EKCombos[this.id];
		}
		
		if (this.isEnhanced) 
		{
			this.setEnhancedOptionList( obj );
		} 
		else 
		{
			this.element.options.length = this.items.length;
			var options = "";
			
			if ( typeof this.items == "object" && this.items instanceof Array ) 
			{
				for ( var i=0; i < this.items.length; i++ ) 
				{
					var item = this.items[i];
					
					if ( typeof item.value != "undefined" ) {
						this.element.options[i] = new Option( '', item.value, false, false );
						this.element.options[i].innerHTML = item.text;
						
						if ( this.multiple ) {
							if ( this.selected !== false && this.selectedList.indexOf(item.value) !== -1 ) {
								this.element.options[i].selected = true;
							}
						} else {
							if ( this.selected !== false && item.value == this.selected ) {
								this.element.options[i].selected = true;
							}
						}
						// Not working in IE
						if ( typeof item.disabled != "undefined" && item.disabled ) {
							this.element.options[i].disabled = true;
						}
						
						if ( item.style === undefined ) {
							this.element.options[i].style.backgroundColor = 'white';
						} else {
							this.element.options[i].className = item.style;
						}						
					} else {
						for ( var id in item ) 
						{
							if ( item.hasOwnProperty(id) ) 
							{
								var text = item[id];
								this.element.options[i] = new Option( '', id, false, false );
								this.element.options[i].innerHTML = text[0];
								
								if ( this.multiple ) {
									if ( this.selectedList !== false && this.selectedList.indexOf(id) !== -1 ) {
										this.element.options[i].selected = true;
									}
								} else {
									if ( this.selected !== false && id == this.selected ) {
										this.element.options[i].selected = true;
									}
								}
							}
						}
					}
				}
			} 
			else 
			{
				var i=0;
				
				for ( idx in this.items ) {
					if ( this.items.hasOwnProperty( idx ) ) {
						var text=this.items[idx][0].replace(/&equal;/g,"=");
						this.element.options[i] = new Option('', idx, false, false);
						this.element.options[i].innerHTML = text;
						
						if (this.multiple) {
							if ( this.selectedList !== false && this.selectedList.indexOf(idx) !== -1 ) {
								this.element.options[i].selected = true;
							}
						} else {
							if ( this.selected !== false && idx == this.selected ) {
								this.element.options[i].selected = true;
							}
						}
						i++;
					}
				}
			}	
		}
	},
	
	
	setEnhancedOptionList: function( obj ) 
	{
		if ( obj != null ) {
			this.items = obj;
		} else if ( typeof EKCombos[this.id] != "undefined" ) {
			this.items = EKCombos[this.id];
		}
		
		//var optionList			= document.createElement('TABLE');
		var optionList			= new Element('TABLE');
		
		optionList.className 	= this.element.className + '-options';
		//optionList.style.width	= "100%";
		optionList.cellPadding 	= 0;
		optionList.cellSpacing 	= 0;
		optionList.border		= 0;
		
		optionList.style.borderWidth 	= '0px';
		optionList.style.padding 		= '0px';
		
		var length = this.items.length;
		
		if ( typeof this.items == "object" && this.items instanceof Array ) 
		{
			for ( var i=0; i < this.items.length; i++ ) 
			{
				var item = this.items[i];
				
				if ( typeof item.value != "undefined" ) {
					if ( typeof item.text == "string" )
						item.text = [item.text];
					
					this.insertEnhancedOption( optionList, item, i );
				} else {
					for ( var id in item ) 
					{}
				}
			}
		} else {
			var i=0;
			
			for ( idx in this.items ) 
			{
				var selected 	= false;
				var options 	= this.items[idx];
				
				this.insertEnhancedOption(optionList, { value: idx, text: options }, i);
				i++;
			}
		}
		
		document.body.appendChild(optionList);
		var dim = optionList.getWidth();
		
		this.optionList = optionList.remove();
		this.optionList.style.width = "100%";
		this.setOptionsContainer(dim);
	},
	
	insertEnhancedOption : function (optionList, item, i ) 
	{
		var idx = item.value;
		var options 	= item.text;
		var row 		= $(optionList.insertRow(i));
		
		row.className	= this.element.className + '-rows';
		row.style.backgroundColor = 'white';
		
		Event.observe( row, 'click', this.onOptionClick.bindAsEventListener(this) );
		Event.observe( row, 'mouseover', this.onOptionOver.bindAsEventListener(this) );
		Event.observe( row, 'mouseout', this.onOptionOut.bindAsEventListener(this) );
		
		row.writeAttribute( 'value', idx );
		
		if ( typeof item.disabled != "undefined" && item.disabled ) {
			row.writeAttribute( 'disabled', true );
			row.addClassName( 'disabled' );
		}
		
		if ( typeof item.style != "undefined" ) {
			row.addClassName( item.style );
		}
		
		var selected = false;
		
		if ( this.selected !== false && ( idx == this.selected || i == this.selected ) )
		{
			selected = true;
		}
			
		for (var k=0; k < options.length; k++) 
		{
			var text 		= options[k];
			
			var cellValue 	= (text == '') ? '&nbsp;' : text;
			var cell 		= $(row.insertCell(k));
			
			cell.style.padding 	= '2px';
			cell.style.color 	= this.textColor;
			
			cell.update( cellValue );
			
			if (k == this.displayTextColIdx)
			{
				row.setAttribute( 'displayText', text );
				
				if (selected) 
				{
					this.element.options[i] = new Option(text, this.selected, false, true);
					this.textDisplay.value = text;
				}
			}
		}
	},
	
	onOptionOver: function(evt) 
	{
		var row = Event.element(evt).up('tr.' + this.element.className + '-rows' ); //$GE(evt).parentNode;
		
		if ( row === undefined ) return;
		
		if ( row.readAttribute('disabled') == "true" )
			return;
			
		row.style.backgroundColor = ( color = row.getAttribute('bgColorHl') ) ? color : this.bgColorHl;
		
		if ( ! (cells = row.cells) )
		{
			return;
		}
		
		var textColorHl = (color = row.getAttribute('textColorHl') ) ? color : this.textColorHl;
		var length 		= cells.length;
		
		for ( i=0; i < length; i++ ) 
		{
			cells[i].style.color = textColorHl;
		}
		
		Event.stop( evt );
	},
	
	onOptionOut: function(evt)
	{
		//var row = Event.element(evt).up(); //$GE(evt).parentNode;
		var row = Event.element(evt).up('tr.' + this.element.className + '-rows' ); //$GE(evt).parentNode;
		
		if ( row === undefined ) return;
		
		if ( row.readAttribute('disabled') == "true" )
			return;
			
		row.style.backgroundColor = ( color = row.getAttribute('bgColor') ) ? color : this.bgColor;
		var cells = row.cells;
		
		if ( ! (cells) )
		{
			return;
		}

		var textColor 	= (color = row.getAttribute('textColor') ) ? color : this.textColor;
		var length		= cells.length;
		
		for ( i=0; i < length; i++ )
		{
			cells[i].style.color = textColor;
		}
			
		Event.stop( evt );
	},
	
	onOptionClick: function(evt)
	{
		//var row = Event.element(evt).up();//$GE(evt).parentNode;
		var row = Event.element(evt).up('tr.' + this.element.className + '-rows' ); //$GE(evt).parentNode;
		
		if ( row === undefined ) return;
		
		if ( row.readAttribute('disabled') == "true" )
			return;
			
		if ( ! row.cells )
		{
			return;
		}
		
		this.element.options[0] = new Option( row.getAttribute('value'), row.getAttribute('value'), false, true );
		
		this.textDisplay.value 			= row.getAttribute('displayText');
		this.textDisplay.style.color 	= this.textColor;
		
		if ( this.element.onchange )
		{
			this.element.onchange.call( this.element );
		}
		
		this.element.fire('combo:change', { id: this.id, value: this.getSelected() } );
	},
		
	
	
	createEnhancedCombo: function()
	{
		this.element.style.visibility = 'hidden';
		
		if (this.isInTable)
		{
			var select = this.element.parentNode.removeChild( this.element );
			this.element = select;
			
			var combo = $(document.forms[0]).down('select[id="' + this.id + '"]' );
			
			if ( combo )
				document.forms[0].removeChild( combo );
				
			document.forms[0].appendChild( this.element );
		}
		
		this.bgColorHl 		= Element.getAttributeValue( this.element, 'backgroundcolorhighlight', 'highlight');
		this.textColorHl 	= Element.getAttributeValue( this.element, 'textcolorhighlight', 'highlighttext');
		
		this.setTextDisplay();
		this.setComboButton();
		
		Event.observe(this.textDisplay, 'click', this.toggleCombo.bindAsEventListener(this), false);
		Event.observe(this.comboButton, "click", this.toggleCombo.bindAsEventListener(this), false);
		
		if (this.isInTable)
		{
			var column = $GE( this.columnId );
			column.appendChild( this.posTable );
		}
		
		this.setEnhancedOptionList();
	},
	
	
	
	setTextDisplay: function()
	{
		var textDisplay = new Element('input'); //document.createElement('INPUT');
		
		textDisplay.className 		= 'easygui-combobox-textdisplay';
		
		if ( is.ie5 || is.ie5_5 ) 
		{
			textDisplay.className 		= 'easygui-combobox-textdisplay-ie5';
		}
		
		textDisplay.readOnly 		= true;
		
		if ( this.element.selectedIndex > -1 )
			textDisplay.value			= this.element.options[this.element.selectedIndex].text;
		
		var padding = '0px';
		var paddingLeft = '4px';
		var paddingTop = '2px';
		
		var height = '18px';
		var width  = parseInt( this.getOffsetWidth() ) - 24 + 'px';
		
		if (is.ie5 || is.ie5_5) 
		{
			height = '22px';
			width  = parseInt( this.getOffsetWidth() ) - 18 + 'px';
		}
	
		if (is.ie5 || is.ie5_5)
		{
			paddingLeft = '3px';
			paddingTop = '1px';
		}
		
		textDisplay.style.backgroundColor = this.bgColor;
		textDisplay.style.color = this.textColor;
		textDisplay.style.height = height;
		textDisplay.style.width = width;
		
		
		
		//var editable = Element.getAttributeValue(this.element, 'editable' );
	
		//if (editable) {
			
			
		//}
	
		//Event.observe( textDisplay, 'mouseover', this.setHighlightColors.bindAsEventListener(this), false);
		//Event.observe( textDisplay, 'mouseout', this.setNormalColors.bindAsEventListener(this), false);
		
		
		if (this.isInTable)
		{
			textDisplay.style.position = 'relative';
			this.textDisplayColumn.appendChild( textDisplay );
		} 
		else 
		{
			var offset = this.element.positionedOffset();
			Element.setPosition( textDisplay, offset.top, offset.left );
			//document.body.appendChild( textDisplay );
			this.element.up().insert(textDisplay);
		}
		
		this.textDisplay = textDisplay;
	},
	
	
	setComboButton: function()
	{
		var comboButton 		= new Element('img'); //document.createElement('IMG');
		
		comboButton.style.padding = '1px';
		
		var border 		= '1px solid #7f9db9';
		var borderLeft 	= '1px solid #ffffff';
			
		if (is.ie5 || is.ie5_5)
		{
			var border = '2px inset';
			var borderLeft = '0px solid #ffffff';
		} 

		comboButton.style.backgroundColor = 'white';
		comboButton.style.border = border;
		comboButton.style.borderLeft = borderLeft;
				
		if ( is.winxp && (is.ie6up || is.gecko) )
		{
			comboButton.src = Element.getAttributeValue(this.element, 'combobuttonsrc', ek_path + '/gfx/combobut_xp.gif');
			comboButton.mouseoverimage = Element.getAttributeValue(this.element, 'combobuttonhlsrc', ek_path + '/gfx/combobut_xp_hl.gif');
			
			if (is.ie6up) {
				Event.observe(comboButton, "mouseover", flipImage, false);
				Event.observe(comboButton, "mouseout", flipImage, false);
			}
		} 
		else if (is.winvista && (is.ie6up || is.gecko) ) {
			comboButton.src = Element.getAttributeValue(this.element, 'combobuttonsrc', ek_path + '/gfx/combobut_vista.gif');
			comboButton.mouseoverimage = Element.getAttributeValue(this.element, 'combobuttonhlsrc', ek_path + '/gfx/combobut_vista_hl.gif');
			
			if (is.ie6up) {
				Event.observe(comboButton, "mouseover", flipImage, false);
				Event.observe(comboButton, "mouseout", flipImage, false);
			}
		}
		else 
		{
			comboButton.src = Element.getAttributeValue(this.element, 'combobuttonsrc', ek_path + '/gfx/combobut.gif');
			comboButton.mouseoverimage = Element.getAttributeValue(this.element, 'combobuttonhlsrc', ek_path + '/gfx/combobut_hl.gif');
		}
		
		this.comboButton = comboButton;
		
		if (this.isInTable) 
		{
			this.comboButtonColumn.appendChild( this.comboButton);
		} 
		else 
		{
			var offset = this.element.positionedOffset();
			this.comboButton.style.position = 'absolute';
			Element.setPosition( this.comboButton, offset.top, offset.left + this.textDisplay.offsetWidth );
			this.element.up().insert(this.comboButton);
			//document.body.appendChild( this.comboButton );
		}
	},
	
	
	setOptionsContainer: function(dim)
	{
		if (this.optionsContainer != null)
		{
			this.optionsContainer = null;
		}
		
		var width = this.element.getWidth();
		
		if ( dim > width ) width = dim;
		
		if ( is.ie6up )
			width += 22;
			
		var optionsContainer 	= document.createElement('DIV');
		
		var droppedWidth 		= parseInt( this.element.readAttribute('droppedwidth')) || width;
		var droppedHeight 		= parseInt( this.element.readAttribute('droppedheight')) || 100;

		this.droppedHeight 		= droppedHeight;
		
		optionsContainer.className 	= this.element.className + '-optionsContainer';
		
		optionsContainer.style.overflowX 	= 'hidden';
		optionsContainer.style.overflowY 	= 'auto';
		optionsContainer.style.position 	= 'absolute';
		optionsContainer.style.border 		= '1px solid black';
		
		Element._hide( optionsContainer );
		
		optionsContainer.appendChild(this.optionList);
		
		document.body.appendChild(optionsContainer);
		
		var optionsHeight = parseInt(this.optionList.offsetHeight);
		var optionsWidth = parseInt(this.optionList.offsetWidth);
		
		if (droppedHeight > optionsHeight)
		{
			droppedHeight = optionsHeight;
		}
		
		Element.setDimension(optionsContainer, droppedWidth, droppedHeight);
		Element.setPosition(optionsContainer, 0, 0);
	
		this.optionsContainer = optionsContainer;
		
		if (is.ie5up)
		{
			optionsContainer.iframeEl = optionsContainer.parentNode.insertBefore( Util.getIframe(), optionsContainer);
			
			Element.hide( optionsContainer.iframeEl );
			optionsContainer.iframeEl.style.position = "absolute";
		}
	},
	
	
	toggleCombo: function( evt )
	{
		if (this.active)
		{
			this.closeCombo();
			return;
		}

		this.openCombo();
		Event.stop( evt );
	},
	
	openCombo: function()
	{
		this.active = true;
		
		var container 	= this.optionsContainer;
		var display 	= this.textDisplay;
		//var table 		= dialog[this.tableId]; //this.table;
		
		var height = this.optionList.offsetHeight;
		
		if ( this.droppedHeight > height ) {
			this.droppedHeight = height;
		}
		
		container.style.height = this.droppedHeight + 'px';
		
		var pos = display.cumulativeOffset();
		
		var left 	= pos.left;
		var top 	= pos.top + display.offsetHeight;
		
		if (this.isInTable)
		{
			var scrollOffset = display.cumulativeScrollOffset();
			
			left 	-= scrollOffset.left;
			top 	-= scrollOffset.top;
		}
		
		var openHeight 	= top + container.offsetHeight;
		var innerHeight = Dialog.getInnerHeight();
			
		if ( openHeight > innerHeight )
		{
			top = top - display.offsetHeight - container.offsetHeight;
		}
		
		Element.setPosition(container, top , left );
		
		if (this.optionsContainer.iframeEl != null)
		{
			var iframeEl = container.iframeEl;
			
			Element.setPosition( iframeEl, container.style.top,  container.style.left);
			Element.setDimension( iframeEl, container.offsetWidth, container.offsetHeight);
	    	
			Element.show( container.iframeEl );
		}
		
		container.style.visibility = 'visible';
		container.style.zIndex = 100000;
	},
	
	
	closeCombo: function( evt )
	{
		this.active = false;
		this.optionsContainer.style.visibility = 'hidden';
		
		if (this.optionsContainer.iframeEl != null)
		{
	      	Element.hide( this.optionsContainer.iframeEl );
		}
	},
	
	
	showCombo : function(evt) {
		return false;
	},
	
	
	hideCombo : function(evt) {
		return false;
	},
	
	
	createAddRemoveBox: function()
	{
		var element = this.element;

		this.setOptionList();
		var width = (this.getOffsetWidth() / 2 - 25) + 'px';
		
		element.style.width = width;
		
		var leftOffset = this.leftPos + this.getOffsetWidth();
		targetList = element.cloneNode(false);
		targetList.multiple = true;
		
		element.setAttribute('id', this.id + '_SOURCE');
		element.setAttribute('name', this.id + '_SOURCE');
	
		targetList.style.position = 'absolute';
		targetList.style.zIndex = 0;
		
		Element.setPosition( targetList, this.topPos, leftOffset + 50 );
		
		var topOffset 	= this.topPos + (this.getOffsetHeight() / 2);
		
		this.addButton 		= Element.create('button', this.id + '_ADD_BUTTON', 23, 23, (leftOffset + 12), (topOffset - 23) );
		this.removeButton 	= Element.create('button', this.id + '_REMOVE_BUTTON', 23, 23, (leftOffset + 12), (topOffset) );
		
		this.addButton.style.position = 'absolute';
		this.addButton.style.padding = '0px';
		this.addButton.style.fontFamily = 'Arial, sans serif';
		this.addButton.style.fontSize = '12px';
		
		this.removeButton.style.position = 'absolute';
		this.removeButton.style.padding = '0px';
		this.removeButton.style.fontFamily = 'Arial, sans serif';
		this.removeButton.style.fontSize = '12px';
		
		this.addButton.innerHTML 	= '<b>>></b>';
		this.removeButton.innerHTML = '<b><<</b>';
		
		Event.observe(this.addButton, 'click', this.addItems.bindAsEventListener( this ), false);
		Event.observe(this.removeButton, 'click', this.removeItems.bindAsEventListener(this), false);
		
		this.targetList = targetList;
		
		document.forms[0].appendChild(this.targetList);
		document.body.appendChild(this.addButton);
		document.body.appendChild(this.removeButton);
	},
	
	
	removeItems: function()
	{
		var tgtList = this.targetList;
		
		for (var i = tgtList.length - 1; i >= 0; i--)
		{
			if (tgtList.options[i].selected)
			{
				tgtList.options[i] = null;
				i = tgtList.length;
			}
		}
	},
	
	
	addItems: function()
	{
		var srcList = this.element;
		var tgtList = this.targetList;
		
		for ( var i = 0; i < srcList.options.length; i++ )
		{
			if ( srcList.options[i].selected )
			{
				var tgtListIdx 	= tgtList.length;	
				var exists 		= false;
				
				for (var j=0; j < tgtList.length; j++)
				{
					if (srcList.options[i].value == tgtList.options[j].value)
					{
						exists = true;
					}
					
					tgtList.options[j].selected = true;
				}
				
				if (!exists)
				{
					tgtList.options[tgtListIdx] = new Option(srcList.options[i].text, srcList.options[i].value, false, false);
					tgtList.options[tgtListIdx].selected = true;
				}			
			}
		}
		
		srcList.selectedIndex = -1;
	},
	
	
	update: function()
	{
		this.init();
	},
	
	
	disable: function() 
	{
		this.element.disabled = true;
		
		if (this.isAddRemove)
		{	
			this.addButton.disabled 	= true;
			this.removeButton.disabled 	= true;
			this.targetList.disabled	= true;
		}
		
		if (this.isEnhanced)
		{
			this.textDisplay.disabled = true;
			this.comboButton.disabled = true;
			
			Event.stopObserving(this.textDisplay, 'click', this.toggleCombo, false);
			Event.stopObserving(this.comboButton, 'click', this.toggleCombo, false);
		}
	},
	
	
	enable: function() 
	{
		this.element.disabled = false;
		
		if (this.isAddRemove)
		{
			this.addButton.disabled 	= false;
			this.removeButton.disabled 	= false;
			this.targetList.disabled 	= false;
		}
		
		if (this.isEnhanced)
		{
			this.textDisplay.disabled 	= false;
			this.comboButton.disabled 	= false;
			
			Event.observe(this.textDisplay, 'click', this.toggleCombo.bindAsEventListener( this ), false);
			Event.observe(this.comboButton, 'click', this.toggleCombo.bindAsEventListener( this ), false);
		}
	},
	
	
	getValue: function() 
	{
		return $F(this.element);
	},
	
	
	getSelected: function()
	{
		return this.getValue();
	},
	
	
	getSelectedText: function()
	{
		return this.element.options[this.element.selectedIndex].text;
	},
	
	
	setSelectedIndex: function( idx ) 
	{
		if ( idx < 0 ) 
		{
			alert( 'New selected Index out of range !');
		}
		
		if (!this.isEnhanced) 
		{
			if ( idx == null )
			{
				idx = 0;
			}
			
			if ( typeof idx == 'string' )
			{
				for ( var i=0; i < this.element.options.length; i++ )
				{
					var option = this.element.options[i].value;
				
					if ( option == idx )
					{
						idx = i;
					}
				}
			}
				
			this.element.selectedIndex = idx;
			
		} 
		else 
		{
			for ( var i=0; i < this.optionList.rows.length; i++)
			{
				if ( i == idx ) 
				{
					this.textDisplay.value = this.optionList.rows[i].getAttribute('displayText');
					this.textDisplay.style.color = this.optionList.rows[i].textColor;
					
					this.element.options[0].value = this.optionList.rows[i].value;
					this.element.selectedIndex = 0;
				}
			}
		}
	},

	
	setOptionColor: function( idx, color, hl ) 
	{
		if (idx == null)
		{
			return;
		}
		
		var color 	= (color == null) ? 'black' : color;
		var hl		= (hl == null) ? 'highlighttext': hl;
		
		if (this.isEnhanced)
		{
			var rows 	= this.optionList.rows;
			var rlength 	= rows.length;
			
			for (var i=0; i < rlength; i++)
			{
				if (idx == i)
				{
					var cells = rows[i].cells;
					var clength = cells.length;
					
					for (var j=0; j < clength; j++)
					{
						cells[j].style.color = color;
					}
				
					rows[i].setAttribute( 'textColor', color );
					rows[i].setAttribute( 'textColorHl', hl );
				}
			}
		} 
		else
		{
			this.element.options[idx].style.color = color;
		}
	},
	
	
	setOptionBgColor: function( idx, color, hl )
	{
		if (idx == null)
		{
			return;
		}
		
		var color = (color == null) ? 'white' : color;
		var hl		= (hl == null) ? 'highlight': hl;
		
		if (this.isEnhanced)
		{
			var rows 	= this.optionList.rows;
			var length 	= rows.length;
			
			for (var i=0; i < length; i++) 
			{
				if (idx == i)
				{
					rows[i].style.backgroundColor = color;
					rows[i].setAttribute( 'bgColor', color );
					rows[i].setAttribute( 'bgColorHl', hl );
				}
			}
		} 
		else
		{
			this.element.options[idx].style.backgroundColor = color;
		}
	},
	
	
	setComboValue: function() 
	{
		this.textDisplay.value = this.element.options[this.element.selectedIndex].text;
		this.textDisplay.style.color = this.element.options[this.element.selectedIndex].style.color;
	},
	
	setNewItemList: function ( items ) 
	{
		this.setItemList( items );
		this.setOptionList();
	}
});

var EasyGUI_edit = Class.create();

Object.extend( Object.extend( EasyGUI_edit.prototype, EasyGUI_widget.prototype ), {
	multiline: false,
	maxlength: null,
	value: null,
	defaultText: '',
	
	
	render: function() {
		this.multiline = Element.getAttributeValue( this.element, 'multiline' );
		this.value = Element.getAttributeValue( this.element, 'value' );
		
		if ( this.multiline ) {
			this.maxlength = Element.getAttributeValue( this.element, 'maxlength' );
			this.value = Element.getAttributeValue( this.element, 'text' );
		}
			
		this.defaultText = Element.getAttributeValue( this.element, 'defaulttext', '');

		if (!this.value) {
			if(this.defaultText){
				this.element.value = this.defaultText.replace(/(<br\s+\/>|<br>|\\\\r\\\\n|\\r\\n)/g, '\r\n');
			}
		} else {
			this.element.value = this.value.replace(/(<br\s+\/>|<br>|\\\\r\\\\n|\\r\\n)/g, '\r\n');
		}

		Event.observe(this.element, "focus", this.onFocus.bindAsEventListener(this) );
		Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
		
		if (this.multiline)
			 Event.observe(this.element, "keyup", this.onKeyUp.bindAsEventListener(this));
		
		this.element.blur();
	},
	
	
	onFocus: function() {
		this.delDefaultText();
		this.selectText();
	},
	
	
	onBlur: function() {
		this.setDefaultText();
	},
	
	
	onKeyUp: function() {
		this.checkMaxLength();
	},
	
	
	delDefaultText: function() {
		if ( this.defaultText && ( $F(this.element) == this.defaultText ) ) {
			this.element.value = '';
		}
	},
	
	
	setDefaultText: function() {
		if ( this.defaultText && ($F(this.element) == '') ) {
			this.element.value = this.defaultText;
		}
	},
	
	
	selectText: function() {
		this.element.select();
	},
	
	
	checkMaxLength: function() {
		if (this.maxlength && (parseInt($F(this.element).length) > this.maxlength) )
			this.element.value = $F(this.element).substring(0, this.maxlength);
	},
	
	
	update: function() {
		this.init();
	},
	
	
	setReadonly: function() 
	{
		this.element.readOnly = true;
	},
	
	
	setReadWrite: function() 
	{
		this.element.readOnly = false;
	},
	
	
	setText: function( value ) 
	{
		this.setValue( value );
	},
	
	getText: function()
	{
		return this.getValue();
	},
	
	getValue: function()
	{
		return this.element.value;
	}
});
var EasyGUI_image = Class.create();

Object.extend( Object.extend(EasyGUI_image.prototype, EasyGUI_widget.prototype ), {
	render: function() {
		document.writeln( 'image.src' + this.image );
	},
	
	update: function( src ) {
		this.element.src = src;
	}
});


var zIndex= 100000;


var EasyGUI_Menu = Class.create();

Object.extend( Object.extend( EasyGUI_Menu.prototype, EasyGUI_widget.prototype), 
{
	
	activeButton: null,
	
	
	activeContextMenu: null,
	
	
	cmi: null,
	
		
	activateOnMouseover: null,
	
	
	orientation: 'horizontal',
	
	
	isContextMenu: null,
	
	
	defaulticon: null,
	
	
	icons: null,
	
	
	submitHandler: null,
	
	
	render: function()
	{
		this.activateOnMouseover 	= Element.getAttributeValue( this.element, 'activateonmouseover' ),
		this.orientation 			= Element.getAttributeValue( this.element, 'orientation', this.orientation ),
		this.isContextMenu 			= Element.getAttributeValue( this.element, 'contextmenu' ),
		this.defaulticon 			= Element.getAttributeValue( this.element, 'defaulticon', ek_path + '/gfx/blank.gif' ),
		this.icons 					= Element.getAttributeValue( this.element, 'icons' );
		
		if ( isEmptyValue(this.element.className) ) {
			this.element.className = 'easygui-menu';
		}
		
		if ( !this.isContextMenu ) {
			this.menubuttons = [];
			this.menubar = this.buildMenubar();
			this.element.parentNode.appendChild( this.menubar );
		} else {
			this.buildContextMenu();
		}
		
		Event.observe(document, 'mousedown', this.pageMousedown.bindAsEventListener(this) );
		
		if ( this.element.onclick ) {
			this.submitHandler = this.element.onclick;
			this.element.onclick = null;
		} else {
			this.submitHandler = navigate;
		}
	},
	
	
	buildContextMenu: function()
	{
		this.buildMenu( this.element, true, this.id );
		
		if ((contextElementId = Element.getAttributeValue(this.element, 'contextelement') ) == false ) {
			this.contextElement = document;
			this.cmi = this.id;
		} else {
			this.contextElement = $(contextElementId);
			this.contextElement.setAttribute('contextmenuid', this.id );
		}
		
		Event.observe( this.contextElement, "contextmenu", this.displayContextMenu.bindAsEventListener( this ) );
		Event.observe( this.contextElement, "click", this.hideContextMenu.bindAsEventListener( this ) );
	},
	
	
	buildMenubar: function ()
	{
		var menubar = document.createElement( 'DIV' );
		document.body.appendChild( menubar );
		
		menubar.className 	= this.getStyleDefinition('menubar');
		
		var position = this.element.style.position;
		var width = this.element.style.width;
			
		menubar.style.position = position;
		menubar.style.width = width;
		menubar.style.margin = '0px';
		
		Element.setPosition( menubar, this.element.style.top, this.element.style.left );
		
		var menubuttons = Element.getChildNodesByTagName( this.element, 'DIV' );
		
		
		for (var i=0; i < menubuttons.length; i++) {
			if (Element.getDepth( menubuttons[i], 'DIV', 'Menu' ) == 0) {
				menubutton = Element.getFirstChildByTagName( menubuttons[i], 'A');
			
				menubutton.className = this.getStyleDefinition('menubutton');
				menubutton.menuId = menubutton.id + '_MENU';
				
				if (this.orientation == 'vertical') {
					//menubutton.style.display = 'block';
				}
				
				//menubutton.onfocus = function() { this.blur() };
				Event.observe(menubutton, "focus", this.onFocus.bindAsEventListener(this) );
				Event.observe(menubutton, 'click', this.openMenu.bindAsEventListener(this), false);
				Event.observe(menubutton, 'mouseover', this.menuButtonOver.bindAsEventListener(this), false);
				
				menubar.appendChild( menubutton );
				
				if (is.ie5) {
					menubutton.style.width = '10px';
				}
	
				this.buildMenu( menubuttons[i], true, menubutton.id );
			}
		}
		
		return menubar;
	},
	
	
	buildMenu: function ( menuitem, isButton, parentId, parentMenu )
	{
		if (! Element.hasChildNodesWithTagName( menuitem, 'DIV' )) {
			return;
		}
		
		if (!isButton) {
			var parentMenuItem = Element.getFirstChildByTagName( menuitem, 'A');
			var menuItemIcon = this.getIcon( menuitem );
			
			var menuId = parentMenuItem.id + '_MENU';				
			var menuItemText = document.createElement('span');
							
			menuItemText.className = this.getStyleDefinition('menuitem') + '-text';
			menuItemText.menuId = menuId;
							
			var menuItemArrow = document.createElement('span');
						
			menuItemArrow.className = this.getStyleDefinition('menuitem') + '-arrow';
			menuItemArrow.menuId = menuId;
							
			menuItemText.innerHTML = parentMenuItem.innerHTML;
			
			if ( is.ie5up ) {
				menuItemArrow.innerHTML = '<b>></b>';
			} else {
				menuItemArrow.innerHTML = '<b>&#9658;</b>';
			}
			
			parentMenuItem.innerHTML = '';
			
			if (menuItemIcon) {
				parentMenuItem.appendChild(menuItemIcon);
			}
				
			parentMenuItem.appendChild(menuItemText);
			parentMenuItem.appendChild(menuItemArrow);
	
			parentMenuItem.menuId = menuId;
			
			Event.observe( parentMenuItem, 'mouseover', this.menuItemOver.bindAsEventListener( this) );
			Event.observe( parentMenu, 'mouseover', this.menuOver.bindAsEventListener( this ) );
		}
	
		var menu = document.createElement('DIV');
		
		menu.style.lineHeight = '2.5ex';
		menu.style.zIndex = zIndex++;
						
		menu.id = parentId + '_MENU';
						
		menu.className 	= this.getStyleDefinition('menu');
		menu.setAttribute('isMenu', 'true');
		
		var cNodes  = Element.getChildNodesByTagName( menuitem, 'DIV' );
		
		for (var i=0; i < cNodes.length; i++) {
			menuitem = Element.getFirstChildByTagName( cNodes[i], 'A');
			var sep =  Element.getAttributeValue(menuitem, 'separator');
	
			if ( sep ) {
				menu.appendChild(this.getSeparator());
				continue;
			}
			
			//menuitem.onfocus = function() { this.blur(); };
			Event.observe(menuitem, "focus", this.onFocus.bindAsEventListener(this) );
			this.buildMenu(cNodes[i], false, menuitem.id, menu);
			menuitem.className = this.getStyleDefinition('menuitem');
			
			if (! Element.hasChildNodesWithTagName(menuitem, 'SPAN') ) {
				var menuItemIcon = this.getIcon( cNodes[i] );
				var menuItemText = document.createElement('span');
				var menuItemLabel = document.createTextNode( Element.getInnerText(menuitem) );
				
				menuItemText.className = this.getStyleDefinition('menuitem') + '-text';
				menuitem.innerHTML 		= '';
				menuItemText.appendChild( menuItemLabel );
				menuItemText.itemId 	= menuitem.id;
				
				if (menuItemIcon) {
					menuitem.appendChild( menuItemIcon );
				}
					
				menuitem.appendChild( menuItemText );
				
				Event.observe( menuitem, 'click', this.onClick.bindAsEventListener( this ) );
			}
			
			menu.appendChild( menuitem );
		}
		
		document.body.appendChild(menu);
		this.correctMenu(menu);
	},
	
	onFocus : function( evt )
	{
		var element = $GE(evt);
		element.blur();
	},
	
	
	enable: function( element )
	{
		var element = $( element );
		element.disabled = false;
	},
	
	
	disable: function( element )
	{
		var element = $( element );
		element.disabled = true;
	},
	
	
	getIcon: function(menuitem)
	{
		if (!this.icons) {
			return false;
		}
		
		var menuItemIcon = document.createElement('span');
		menuItemIcon.className = this.getStyleDefinition('menuitem') + '-icon';
			
		var iconImg = document.createElement('img');	
		var icon = Element.getAttributeValue(menuitem, 'icon', this.defaulticon);
			
		iconImg.src 			= icon;
		iconImg.border 			= 0;
		
		iconImg.style.position = 'relative';
		Element.setDimension( iconImg, '16px', '16px');
		
		iconImg.height 	= 16;
		iconImg.width 	= 16;
		
		menuItemIcon.appendChild( iconImg );
		
		return menuItemIcon;
	},
	
	
	correctMenu: function ( menu )
	{
		var itemList = menu.getElementsByTagName("A");
		
		if (itemList.length > 0) {
			itemWidth = itemList[0].offsetWidth;
		} else {
			return;
		}
		
		for (i = 0; i < itemList.length; i++) {
			spanList = itemList[i].getElementsByTagName("SPAN");
			
			textEl  = null;
			arrowEl = null;
			
			for (j = 0; j < spanList.length; j++) {
		  		if ( Element.hasClassName(spanList[j], this.getStyleDefinition("menuitem") + "-text")) {
		  			textEl = spanList[j];
		  		}
		  			
		  		if ( Element.hasClassName(spanList[j], this.getStyleDefinition("menuitem") + "-arrow")) {
		    		arrowEl = spanList[j];
		  		}
		  	}
			
			if (textEl != null && arrowEl != null) {
	  			textEl.style.paddingRight = (itemWidth - ( textEl.offsetWidth  + arrowEl.offsetWidth)) + "px";
			
	  			if (is.opera5up) {
	    			arrowEl.style.marginRight = '0px';
	  			}
			}
			
		}
		
		if (is.ie5up) {
			w = itemList[0].offsetWidth;
			itemList[0].style.width = w + 'px';
			
			dw = itemList[0].offsetWidth - w;
			w -= dw;
			
			itemList[0].style.width = w + 'px';
			
			menu.iframeEl = menu.parentNode.insertBefore( Util.getIframe(), menu);
			
			Element.hide( menu.iframeEl );
			menu.iframeEl.style.position = 'absolute';
			menu.iframeEl.style.zIndex = 10000;
		}
		
		menu.isInitialized = true;
	},
	
	
	getSeparator: function( menuitem )
	{
		var separator = document.createElement( 'DIV' );
		separator.className = this.getStyleDefinition('menuitem') + '-separator';
		return separator;
	},
	
	
	openMenu: function( evt )
	{
		var button = $GE( evt );
		button.blur();
	
		if ( this.activeButton != null ) {
			this.resetButton( this.activeButton );
		}
		
		if ( button != this.activeButton ) {
			this.activeButton = button;
			this.menuButtonOut();
		} else {
			this.activeButton = null;
		}
	},
	
	
	menuButtonOver: function( evt )
	{
		var button = $GE( evt );
		
		if ( this.activateOnMouseOver) {
			if ( this.activeButton == null ) {
				this.openMenu( evt );
				return;
			}
		}
		
		if ( this.activeButton != null && this.activeButton != button ) {
			this.openMenu( evt );
		}
	},
	
	
	menuButtonOut: function()
	{
		var x, y;
		var button = this.activeButton;
		
		button.className += ' ' + this.getStyleDefinition("menubutton") + "-active";
		var menu = $(button.menuId);
		
		if (this.activateOnMouseover) {
			Event.observe( button, 'mouseout', buttonOrMenuMouseout, false );
			
			if ( menu != null )
	  			Event.observe( menu, 'mouseout', buttonOrMenuMouseout, false );
		}
	
		var pos = Position.cumulativeOffset( button );
		x = pos[0];
		y = pos[1];
		
		if (button.style.display == 'block') {
			x += button.offsetWidth;
		} else {
	  		y += button.offsetHeight;
		}
		
	  	if (menu != null) {
	  		Element.setPosition( menu, y, x );
	  		Element._show( menu );
	
	  		if (menu.iframeEl != null) {
	    		Element.setPosition( menu.iframeEl, y , x );
	    		Element.setDimension( menu.iframeEl, menu.offsetWidth, menu.offsetHeight );
	    		Element.show( menu.iframeEl );
	  		}
		}
	},
	
	
	resetButton: function( button )
	{
		Element.removeClassName( button, this.getStyleDefinition("menubutton") + '-active' );
		var menu = $(button.menuId);
		
		if ( menu != null ) {
			this.closeSubMenu( menu );
			
			menu.style.visibility = "hidden";
		    	
			if (menu.iframeEl != null) {
		  		menu.iframeEl.style.display = "none";
			}
		}
	},
	
	
	menuOver: function( evt )
	{
		var menu = $GE(evt);
		
		if (menu.nodeName != 'DIV') {
			menu = Element.getParentElementByTagName( menu, 'DIV');
		}
		
	  	if (menu.activeItem != null) {
	    	this.closeSubMenu(menu);
	  	}
	},
	
	
	menuItemOver: function( evt )
	{
		var x, y;
		var element = $GE(evt);
	
		var item = Element.getParentElementByTagName( element, 'A');
		var menu = Element.getParentElementByTagName( item, 'DIV' );
		
	  	if (menu.activeItem != null)
	    	this.closeSubMenu(menu);
	  	
	    if (menu.activeItem == item )
	    	return;
	    	
	    menu.activeItem = item;
	    
	  	item.className += " " + this.getStyleDefinition("menuitem") + "-over";
	  	
	  	if (item.subMenu == null)
	    	item.subMenu = $(item.menuId);
	    	
	    if (this.activateOnMouseover) {
	    	if (item.subMenu.onmouseout == null) {
	    		Event.observe( item.subMenu, 'mouseout', this.buttonOrMenuMouseout.bindAsEventListener(this) );
	    	}
	    }
	    
	    var itempos = Position.cumulativeOffset( item );
	    
	  	x = itempos[0] + item.offsetWidth;
	  	y = itempos[1]
	  	
	  	var maxX, maxY;
	
	  	if (is.ie5up) {
	    	maxX = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft) +
	      		(document.documentElement.clientWidth != 0 ? document.documentElement.clientWidth : document.body.clientWidth);
	    	maxY = Math.max(document.documentElement.scrollTop, document.body.scrollTop) +
	      		(document.documentElement.clientHeight != 0 ? document.documentElement.clientHeight : document.body.clientHeight);
	  	}
	  	
	  	if (is.opera5up) {
	    	maxX = document.documentElement.scrollLeft + window.innerWidth;
	    	maxY = document.documentElement.scrollTop  + window.innerHeight;
	  	}
	  	
	  	if (is.nav6up || is.gecko) {
	   		maxX = window.scrollX + window.innerWidth;
	    	maxY = window.scrollY + window.innerHeight;
	  	}
	  	
	  	maxX -= item.subMenu.offsetWidth;
	  	maxY -= item.subMenu.offsetHeight;
	
	  	if (x > maxX) {
	    	x = Math.max(0, x - item.offsetWidth - item.subMenu.offsetWidth + (menu.offsetWidth - item.offsetWidth));
	  	}
	  		
	    y = Math.max(0, Math.min(y, maxY));

	    
	  	item.subMenu.style.left       = x + "px";
	  	item.subMenu.style.top        = y + "px";
	  	item.subMenu.style.visibility = "visible";
		
	  	if (item.subMenu.iframeEl != null) {
	    	item.subMenu.iframeEl.style.left    = item.subMenu.style.left;
	    	item.subMenu.iframeEl.style.top     = item.subMenu.style.top;
	    	item.subMenu.iframeEl.style.width   = item.subMenu.offsetWidth + "px";
	    	item.subMenu.iframeEl.style.height  = item.subMenu.offsetHeight + "px";
	    	item.subMenu.iframeEl.style.display = "";
	  	}
	  	
		Event.stop( evt );
	},
	
	
	closeSubMenu: function( menu )
	{
		if (menu == null || menu.activeItem == null) {
	    	return;
		}
	
	  	if (menu.activeItem.subMenu != null) {
	    	this.closeSubMenu(menu.activeItem.subMenu);
	
	    	menu.activeItem.subMenu.style.visibility = "hidden";
	    	
			if (menu.activeItem.subMenu.iframeEl != null) {
	      		menu.activeItem.subMenu.iframeEl.style.display = "none";
			}
	      		
	    	menu.activeItem.subMenu = null;
	  	}
	
	  	Element.removeClassName(menu.activeItem, this.getStyleDefinition("menuitem") + "-over");
	  	menu.activeItem = null;
	},
	
	
	pageMousedown: function( evt )
	{
		var el = $GE(evt);
		
		if (this.activeButton == null) {
	    	return;
		}
	    	
		if (el == this.activeButton) {
			return;
		}
	
		if (!Element.hasParentWithAttribute( el, 'isMenu')) {
			this.resetButton( this.activeButton );
		    this.activeButton = null;
		}
	},
	
	
	buttonOrMenuMouseout: function( evt ) 
	{
		if (this.activeButton == null) {
	    	return;
	  	}
	    
	    var el = getTargetElement(evt);
	 
	  	if (!Element.hasParentWithAttribute( el, 'isMenu')) {
	    	this.resetButton( this.activeButton );
	    	this.activeButton = null;
	  	}
	},
	
	
	frameMousedown: function( evt )
	{
		if (this.activeButton == null) {
	    	return;
		}
	    	
		this.resetButton( this.activeButton );
		this.activeButton = null;
	},
	
	
	hideContextMenu: function( evt )
	{
		if (this.activeContextMenu != null ) {
			this.activeContextMenu.style.visibility = 'hidden';
		}
		
		Event.stop( evt );
		return false;
	},
	
	
	displayContextMenu: function( evt ) 
	{
		if ( this.activeContextMenu != null ) {
			Element.show( this.activeContextMenu );
		}
		
		var element = $GE( evt );
		var contextMenuId = Element.getAttributeValue( element, 'contextmenuid' );
	
		if ( !contextMenuId ) {
			contextMenuId = this.cmi;
		}
		
		var contextMenu = $( contextMenuId + '_MENU' );
	
		x = Event.pointerX( evt );
		y = Event.pointerY( evt );
		
		x -= 2; y -= 2;
	
		Element.setPosition( contextMenu, y, x );
		Element._show( contextMenu );
		Event.stop( evt );
		
		this.activeContextMenu = contextMenu;
		return false;
	},
	
	
	onClick: function( evt )
	{	
		var element = Element.getParentElementByTagName( $GE(evt), 'A' );
		
		if ( element.disabled ) {
			return;
		}
		
		this.submitHandler.call( this, element );
		this.pageMousedown( this.id );
		Event.stop( evt );
	},
	
	
	show: function()
	{
		Element.show( this.menubar );
	},
	
	
	hide: function()
	{
		Element.hide( this.menubar );
	}
});



var EasyGUI_MenuTree = Class.create();

Object.extend( Object.extend( EasyGUI_MenuTree.prototype, EasyGUI_widget.prototype ),
{ 
	
	modus: 'TreeCtrl',
	
	render: function() {
		this.modus = Element.getAttributeValue( this.element, 'modus', 'TreeCtrl' );
		
		if (this.modus == 'TreeCtrl') {
			this.element.setAttribute( 'ektype', 'TreeCtrl' );
			dialog.registerWidget( new EasyGUI_TreeCtrl( id ) );
		} else {
			this.domElement.setAttribute( 'ektype', 'Menu' );
			dialog.registerWidget( new EasyGUI_Menu( id ) );
		}
	}
});

var EasyGUI_radiobutton = Class.create();


Object.extend( Object.extend( EasyGUI_radiobutton.prototype, EasyGUI_widget.prototype ), {
	selected: null,
	checked: false,
	
	render: function() {
		this.group = document.forms[0].elements[this.element.name];
		this.groupElement = $( this.element.name + '_GROUP' );
		this.checked = Element.getAttributeValue( this.element, 'checked' );
		
		if (this.groupElement) {
			this.selected = Element.getAttributeValue( this.groupElement, 'selected' );
			this.switchRadio( this.selected );
		}
		
		if (this.checked) {
			this.reset();
			this.element.checked = true;
		}
		
		this.initialized = true;
	},
	
	
	switchRadio: function ( value, fireEvent ) {
		var group 		= this.group;
		var fireEvent 	= (fireEvent || fireEvent == null) ? true : false;
		
		if (!group.length) {
			if ( group.value == value ) {
				group.checked = true;
			}
		} else {
			for (i=0; i < group.length; i++) {
				group[i].checked = false;
				
				if (group[i].value == value || group[i].id == value) {
					
					group[i].checked = true;
				
					if (this.initialized && document.fireEvent && fireEvent ) {
						bfired = group[i].fireEvent('onclick');
					}
				}
			}
		}
	},
	
	
	getValue: function () {
		var group = this.group;
		
		if ( !group.length ) {
			return group.value;
		} else {
			for (i=0; i < group.length; i++) {
				if (group[i].checked == true) {
					return group[i].value;
				}
			}
		}
		
		return false;
	},
	
	
	getSelected: function()
	{
		return this.getValue();
	},
	
	
	reset: function () {
		var group = this.group;
		
		if ( !group.length ) {
			group.checked = false;
		} else {
			for (var i=0; i < group.length; i++) {
				if (group[i].checked == true) {
					group[i].checked == false;
				}
			}
		}
	},
	
	hide: function() {
		var group = this.group;
		
		if ( !group.length ) {
			Element.hide( group );
		} else {
			for ( var i=0; i < group.length; i++ ) {
				Element.hide( group[i] );
			}
		}
	},
	
	show: function() {
		var group = this.group;
		
		if ( !group.length ) {
			Element.show( group );
		} else {
			for ( var i=0; i < group.length; i++ ) {
				Element.show( group[i] );
			}
		}
	}
});

var EasyGUI_EKTabCtrl = Class.create();


Object.extend( Object.extend( EasyGUI_EKTabCtrl.prototype, EasyGUI_widget.prototype ),
{
	panels: null,
	tabs: [],
	tabArea: null,
	leftButton: null,
	rightButton: null,
	selectedIndex: 0,
	activateScrollCtrl: false,
	hiddenTabs: [],
	
	init: function() 
	{
		if ( isEmptyValue(this.element.className) ) {
			this.element.className = 'easygui-tabctrl';
		}
		this.realWidth =  this.element.getWidth();
		
		
		this.selected 	= Element.getAttributeValue( this.element, 'selected' );
		this.stacked 	= Element.getAttributeValue( this.element, 'stacked', false );
		this.stackSize 	= Element.getAttributeValue( this.element, 'stacksize', 1 );
		
		
		this.panels = Element.getChildNodesByTagName( this.element, 'div' );
		
		if ( this.panels.length == 0 ) {
			return;
		}
		
		this.tabs = [];
		
		
		this.tabAreas = [];
		
		this.tabAreas.push(new Element('div'));
		this.tabAreas[0].className = this.getStyleDefinition( 'area' );
		
		//var firstPanel = Element.getFirstChildByTagName( this.element, 'DIV' );
		firstPanel = this.element.down('div');
		firstPanel.insert({before: this.tabAreas[0]});
		
		//firstPanel.parentNode.insertBefore( this.tabAreas[0], firstPanel );
		
		
		this.selectedIndex = 0;
		this.element.style.visibility = 'hidden';
		
		var offsetWidth = 0;
		
		// Fix for TabCtrl nested inside another TabCtrl
		var tabId = Element.isInTab(this.element);
		
		if (tabId)
			Element.show(tabId);
		
		for (var i=0; i < this.panels.length; i++) {
			if (this.panels[i].id == this.selected) {
				this.selectedIndex = i;
			}
			
			var tab = Element.getFirstChildByTagName( this.panels[i], 'A' );
			tab.setAttribute('panelid', this.panels[i].id );
			
			
			var isyheader = Element.getFirstChild( this.panels[i] );
			var isytext = "";
			
			if ( isyheader && isyheader.nodeName == "SPAN" ) {
				isyheaderTable = Element.getFirstChildByTagName( isyheader, 'TABLE' );
				
				isytext = Element.getInnerText( isyheaderTable.rows[0].cells[0] );
				this.panels[i].removeChild( isyheader );
			} 
			
			tabtext = Element.getInnerText( tab );
						
			if (!tabtext)
				tab.innerHTML = isytext;
			
			var header = tab.cloneNode(true);
			
			if (header.style.visibility == 'hidden') {
				Element.hide( header );
				Element._show( header );
			}
			
			if (is.ie5)
				header.style.width = '10px';
				
			header.className = this.getStyleDefinition( 'tab');
			header.style.position = 'relative';
			header.style.whiteSpace = 'nowrap';
			
			Event.observe( header, 'click', this.switchTab.bindAsEventListener(this), false);
			
			// Find a better solution one day to handle all user defined event handlers
			header.onclick = this.panels[i].onclick;
			//header.onfocus = function() { this.blur(); };
			Event.observe(header, "focus", this.onFocus.bindAsEventListener(this) );
			
			this.panels[i].onclick = function() { return true; };
			
			header.setAttribute('panelid', this.panels[i].id );
			header.setAttribute('widgetid', this.id );
			this.panels[i].setAttribute('widgetid', this.id );
			
			this.tabAreas[0].appendChild( header );
			this.tabs[this.tabs.length] = header;
			
			offsetWidth += header.offsetWidth;
			
			// Zuerst muss man zuverl�ssig rausfinden wieviele Stacks man braucht.
			// Dazu 
			if ( offsetWidth > this.element.offsetWidth - 50) {
				this.activateScrollCtrl = true;
				this.hiddenTabs[this.hiddenTabs.length] = header;
			}
			
			this.panels[i].className = this.getStyleDefinition( 'panel' );
			
			this.panels[i].style.position = 'relative';
			this.panels[i].style.overflow = 'auto';
			this.panels[i].style.zIndex = 101;

			this.panels[i].removeChild( tab );
		}
		
		// Das hier muss in eine Funktion gekapselt werden,
		// denn bei gestackten muss man noch mehr ausrechnen
		//var realHeight 	= this.getOffsetHeight();
		var tabsHeight 	= this.tabs[this.selectedIndex].offsetHeight;
		
		//var height = realHeight - tabsHeight;
		
		Form.insertHidden( this.id + '_EK_WIDGET_VALUE', '' );
		
		this.selected = this.tabs[this.selectedIndex].getAttribute('tabpanel');
		this.renderScrollCtrl( tabsHeight );
		
		
	},
	
	onFocus : function( evt )
	{
		var element = $GE(evt);
		element.blur();
	},
	
	renderScrollCtrl: function( tabsHeight )
	{
		if ( this.activateScrollCtrl )
		{
			if ( this.stacked ) {
			} else {
				var tabArea = new Element('div');
				
				this.element.insert({
					top: tabArea
				});
				
				tabArea.setStyle({
					'position': 'relative',
					'width': this.element.getWidth() + 'px'
				});
				
				this.leftButtonArea = new Element('div',{
					
				});
				
				this.leftButtonArea.setStyle({
					'position': 'absolute',
					'width': '18px', 
					'height': '18px',
					'left': '0',
					'top': '0'
				});
				
				this.leftButton = new Element('button');
				this.leftButton.setStyle({
					'width': '18px',
					'height': '18px'
				});
				
				this.leftButton.insert('<span style="font-size: 10px"><b>&lt;</b></span>');
				
				this.leftButtonArea.insert( this.leftButton );
				
				
				Event.observe( this.leftButton, "focus", this.onFocus.bindAsEventListener(this) );
				Event.observe( this.leftButton, 'click', this.scrollLeft.bindAsEventListener(this) );
				
				this.rightButtonArea = new Element('div', {
					
				});
				
				this.rightButtonArea.setStyle({
					'position': 'absolute',
					'width': '18px',
					'height': '18px',
					'right': '0',
					'top': '0'
				});
				
				this.rightButton = new Element('button');
				
				this.rightButton.setStyle({
					'width': '18px',
					'height': '18px'
				});
				
				this.rightButton.insert('<span style="font-size: 10px"><b>&gt;</b></span>');
				
				this.rightButtonArea.insert( this.rightButton );
				
				Event.observe( this.rightButton, "focus", this.onFocus.bindAsEventListener(this) );
				Event.observe( this.rightButton, 'click', this.scrollRight.bindAsEventListener(this) );
				
				var tabStripWidth = this.tabAreas[0].getWidth();
				tabStrip =  this.tabAreas[0].remove();
				
				tabStrip.style.marginLeft = '18px';
				tabStrip.style.marginRight = '18px';
				tabStrip.style.width = tabStripWidth - 18 + "px";
				
				tabArea.insert( tabStrip );
				
				tabArea.insert({
					top: this.leftButtonArea
				});
				
				tabArea.insert({
					top: this.rightButtonArea
				});
				
				this.leftButton.disabled = true;
			}
		}
	},
	
	onScrollLeftButtonOver : function() {
		this.leftButton.addClassName('over');
	},
	
	onScrollLeftButtonOut: function() {
		this.leftButton.removeClassName('over');
	},
	
	onScrollRightButtonOut : function() {
		this.rightButton.removeClassName('over');
	},
	
	onScrollRightButtonOver : function() {
		this.rightButton.addClassName('over');
	},
	
	finalize: function() 
	{
		this.initialized = true;
		
		if ( this.panels.length == 0 )
			return;
		
		// Fix for TabCtrl nested inside another TabCtrl
		var tabId = Element.isInTab(this.element);
		
		if (tabId)
			Element.show(tabId);
		
		if ( this.hiddenTabs.length > 0 ) {
			if ( this.stacked ) {
				// Das ist die kritische Breite
				var newArea = false;
				var newWidth = 0;
				
				for (var i=0; i < this.hiddenTabs.length; i++ ) {
					var header = $(this.hiddenTabs[i]);
					newWidth += header.getWidth();
					
					if ( !newArea || newWidth > this.realWidth ) {
						newArea = new Element('div',{
							className : this.getStyleDefinition( 'area' )
						});
						
						var tabArea = this.element.down('div.' + this.getStyleDefinition('area'));
						tabArea.insert({before: newArea});
						newWidth = 0;
					}
					
					newArea.insert( header.remove() );
				}
			} else {
				for (var i=0; i < this.hiddenTabs.length; i++ ) {
					this.hiddenTabs[i].style.display = "none";
				}
			}
		}
		
		var realHeight = this.getOffsetHeight();
		
		var tabsHeight = 0;
		var className = this.getStyleDefinition('area');
		
		$$('div.' + this.getStyleDefinition('area')).each( function(area) {
			tabsHeight += area.getHeight();
		});
		
		var height = realHeight - tabsHeight;
		
		for(var i=0; i < this.panels.length; i++) {
			this.panels[i].style.height = height + 'px';
		}
			
		var selectedIndex = this.getSelectedIndex();
		
		if ( this.tabs[selectedIndex].style.display == "none"  ) 
		{
			for (var i=0; i < this.tabs.length; i++ ) {
				this.scrollRight();
				
				if ( this.tabs[selectedIndex].style.display == "" )
					break;
			}
		}
		
		this.switchTab( this.selected );
		Element._show( this.element );
	},
	
	getSelected: function()
	{
		return this.selected;
	},
	
	getSelectedIndex: function()
	{
		for ( var i=0; i < this.tabs.length; i++ )
			if ( this.tabs[i].getAttribute('panelid') == this.selected )
			 	return i;
		
		return 0;
	},
	
	
	updateWidget: function ()
	{
		this.selected = Element.getAttributeValue( this.element, 'selected' );
		
		if (this.selected)
			this.switchTab( this.selected );
	},
	
	
	getTab: function( node )
	{	
		var tab = $GE(node);
		
		if ( typeof( node ) == 'string' ) {
			for (var i=0; i < this.panels.length; i++)
				if ( this.panels[i].id == node )
					this.selectedIndex = i;
	
			tab = this.tabs[this.selectedIndex];
		} else {
			
			if ( node.nodeName == 'DIV' ) {
				for (var i=0; i < this.tabs.length; i++) {
					var tabpanel = this.tabs[i].getAttribute('tabpanel');
					
					if (tabpanel == node.id)
						tab = this.tabs[i];
				}
			}
		}
		
		return $(tab);
	},
	
	
	switchTab: function( evt )
	{
		var tab = this.getTab( evt );
		tab.blur();
		
		
		
		//console.log(sourceArea);
		
		for (var i = 0; i < this.panels.length; i++) {
			Element.hide( this.panels[i] );
			//Element._hide( this.panels[i] );
		}
		
		for (var i = 0; i < this.tabs.length; i++) {
			this.tabs[i].className = this.getStyleDefinition( 'tab' );
		}
		
		if (is.ie5)
			var correctTop = Element.getStyle( tab, 'top' );
		
		tab.className += ' ' + this.getStyleDefinition('tab') + '-active';
		
		if (is.ie5)
			tab.style.top = correctTop;
			
		var id = tab.getAttribute('tabpanel');
		
		Element.show( $( id ) );
		//Element._show( $( id ) );
		
		if ( this.initialized ) {
			this.selected = id;
			Form.Element.setValue( this.id + '_EK_WIDGET_VALUE', id );
		}
		
		if ( typeof evt == "object" ) //&& evt instanceof Event )
			Event.stop( evt );
	},

	
	hideTab: function( tab )
	{
		var tab 	= this.getTab( tab );
		var id 		= tab.getAttribute('tabpanel');
		var panel 	= $GE( id );
		
		Element.hide( panel );
		Element.hide( tab );
        
        for ( var i=0; i < this.tabs.length; i++ )
		{
			if ( this.tabs[i].style.display != 'none' ) {
				this.switchTab( this.tabs[i].getAttribute('panelid'));
				break;
			}
		}
	},
	
	
	showTab: function( tab )
	{
		var tab= this.getTab( tab );
		Element.show(tab);
	},
	
	
	scrollLeft: function( evt )
	{
		for ( var i=( this.tabs.length - 1 );i >= 0; i-- ) 
		{
			if ( this.tabs[i].style.display != 'none' ) {
				this.tabs[i].style.display = 'none';
				break;
			}
		}
		
		for ( --i; i >= 0 ; i-- )
		{
			if ( this.tabs[i].style.display == 'none' ) {
				this.tabs[i].style.display = '';
				break;
			}
		}
		// First Tab
		if ( i == 0 ) {
			this.leftButton.disabled = true;
		}
			
		this.rightButton.disabled = false;
	},
	
	
	scrollRight: function( evt )
	{		
		for ( var i=0; i < this.tabs.length; i++ )
		{
			if ( this.tabs[i].style.display != 'none' ) {
				this.tabs[i].style.display = 'none';
				break;
			}
		}
		
		for ( ++i; i < this.tabs.length; i++ )
		{
			if ( this.tabs[i].style.display == 'none' ) {
				this.tabs[i].style.display = '';
				break;
			}
		}
		// Last Tab
		if ( i == ( this.tabs.length - 1 ) )
			this.rightButton.disabled = true;
			
		this.leftButton.disabled = false;
	},
	
	
	setTabText: function( tab, text )
	{
		var tab = this.getTab( tab );
		tab.innerHTML = text;
	},
	
	
	addSelectionChangedHandler: function()
	{
		if (!this.selectionChangedHandler)
			return;
			
		Event.observe( this.element, 'click', this.onSelectionChanged.bindAsEventListener(this) , false );
	},
	
	
	removeTab: function( tab )
	{
		this.hideTab( tab );
	},
	
	
	disableTab: function( tab )
	{
		;
	},
	
	
	enableTab: function( tab )
	{
		;
	}
});

var EasyGUI_TabCtrl = Class.create();

Object.extend( Object.extend( EasyGUI_TabCtrl.prototype, EasyGUI_widget.prototype ),
{
	render : function() {
		var modus = this.element.readAttribute('modus') || 'normal';
		
		if ( modus == 'normal' ) {
			Object.extend( this, new EasyGUI_EKTabCtrl( this.id ) );
		} else {
			Object.extend( this, new EasyGUI_ExtTabCtrl( this.id ) );
		}
		
		this.init();
	}
});

var EasyGUI_ExtTabCtrl = Class.create();

Object.extend( Object.extend( EasyGUI_ExtTabCtrl.prototype, EasyGUI_widget.prototype ),
{
	
	panels: [],
	
	
	tabs: [],
	
	
	selectedIndex: 0,
	
	
	tabBody: {},
	
	selected: 0,
	
	
	init: function() 
	{
		var panels = this.element.getElementsBySelector('div[ctrltype="tabpanel"]');
		
		if ( isEmptyValue(this.element.className) ) {
			this.element.className = 'easygui-tabs';
		}
		
		var tabStrip = document.createElement('div');
		tabStrip.className = this.getStyleDefinition('wrap');
		this.element.appendChild( tabStrip );
		
		this.tabBody = document.createElement('div');
		this.tabBody.className = this.getStyleDefinition('body');
		this.tabBody.style.height = this.element.getHeight() + "px";
		this.tabBody.style.position = 'relative';
		
		this.element.appendChild( this.tabBody );
		
		var html = '<div class="' + this.getStyleDefinition('strip-wrap') + '">';
		html += '<table class="' + this.getStyleDefinition('strip') + '" cellspacing="0" cellpadding="0" border="0">';
		html += '<tbody><tr></tr></tbody></table></div>';
		
		tabStrip.innerHTML = html;
		
		// Jetzt f�gen wir die Strip Elemente hinzu
		stripEl = tabStrip.firstChild.firstChild.firstChild.firstChild;
		
		for (var i=0; i < panels.length; i++ ) {
			var text = panels[i].readAttribute('text');
			var col = document.createElement('td');
			
			var td = stripEl.insertCell(i);
			
			html = '<a href="#" class="' + this.getStyleDefinition('right') + '">';
			html += '<span class="' + this.getStyleDefinition('left') + '">';
			html += '<em class="' + this.getStyleDefinition( 'inner' ) + '">';
			html += '<span title="' + text + '" class="' + this.getStyleDefinition('text') + '">' + text + '</span>';
			html += '</em></span></a>';
			
			td.innerHTML = html;
			
			Event.observe( td, 'click', this.switchTab.bindAsEventListener(this), false);
			// Hier ziehen wir jetzt noch das Panel aus dem Document und f�gen es wieder
			
			panels[i].firstDescendant().remove();
			panels[i].firstDescendant().remove();
			
			var panel = panels[i].remove();
			panel.addClassName( this.getStyleDefinition('item-body') );
			panel.setAttribute( 'widgetid', this.id );
			td.setAttribute('panelid', panel.id );
			td.onclick = panel.onclick;
			panel.onclick = null;
			
			this.tabBody.appendChild( panel );
		}
		
		this.panels = $(this.tabBody).getElementsBySelector('div[ctrltype="tabpanel"]');
		this.tabs = $(stripEl).childElements();
		this.element.addClassName( this.getStyleDefinition('top') );
		
		Form.insertHidden( this.id + '_EK_WIDGET_VALUE', '' );
		
		this.selected = this.element.readAttribute('selected') || 0;
	},
	
	
	finalize: function() 
	{
		this.switchTab( this.selected );
		this.initialized = true;
	},
	
	
	getSelected: function()
	{
		return $F( this.id + '_EK_WIDGET_VALUE');
	},
	
	
	getSelectedIndex: function()
	{
		var selectedIndex = 0;
		
		this.tabs.each( function( tab, id ) {
			if ( tab.hasClassName('selected') ) {
				selectedIndex = id;
			}
		});
		
		return selectedIndex;
	},
	
	
	getTab: function( node )
	{},
	
	
	switchTab: function( evt )
	{
		var idx;
		var fieldId = this.id + '_EK_WIDGET_VALUE';
		
		if ( typeof evt == "object" ) {
			var el = Event.findElement(evt, 'td' );
			el.addClassName('selected');
			idx = el.cellIndex;
		} else {
			idx = evt;
		}
		
		this.tabs.each( function( tab, id ) {
			tab.removeClassName('selected');
			var panelid = tab.getAttribute('panelid');
			
			if ( idx == id || idx == panelid ) {
				tab.addClassName('selected');
				idx = id;
				
				$( fieldId ).value = panelid;
				tab.down('a').blur();
			}
		});
		
		this.panels.each( function( panel, id ) {
			panel.hide();
			
			if ( idx == id ) {
				panel.show();
			}
		});
	},
	
	
	hideTab: function( idx )
	{
		if ( typeof tab == "number" ) {
			this.tabs[tab].hide();
		} else {
			this.tabs.each( function( tab, id ) {
				var panelid = tab.getAttribute('panelid');
				if ( idx == panelid ) {
					tab.hide();
				}
			});
		}
	},
	
	
	showTab: function( idx )
	{
		if ( typeof tab == "number" ) {
			this.tabs[tab].show();
		} else {
			this.tabs.each( function( tab, id ) {
				var panelid = tab.getAttribute('panelid');
				if ( idx == panelid ) {
					tab.show();
				}
			});
		}
	},
	
	
	setTabText: function( tab, text )
	{},
	
	
	removeTab: function( tab )
	{},
	
	
	disableTab: function( tab )
	{},
	
	
	enableTab: function( tab )
	{}
});

var EasyGUI_text = Class.create();


Object.extend( Object.extend( EasyGUI_text.prototype, EasyGUI_widget.prototype ), {
	text: '',
	
	render: function() {
		this.text = Element.getInnerText( this.element );
		return;
		
		this.text = Element.getAttributeValue( this.element, 'text' );
		
		if ( !this.text ) {
			this.text = Element.getInnerText( this.element );
			this.element.innerHTML = Element.getInnerText( this.element );
		}else {
			this.element.innerHTML = this.text;
		}
	},
	
	getText: function() {
		return this.text;
	},
	
	setText: function( text ) {
		this.text = text;
		this.element.innerHTML = text;
	},
	
	setPosition: function( top, left ) {
		var top = ( typeof top == 'string' ) ? top : top + 'px';
		var left = ( typeof left == 'string' ) ? left : left + 'px';
		
		this.element.up('table').setStyle({
			top : top,
			left: left
		});
	}
});

var activeButton = null;


var EasyGUI_TreeCtrl = Class.create();

Object.extend( Object.extend( EasyGUI_TreeCtrl.prototype, EasyGUI_widget.prototype), {
	
	type: 'easygui-treectrl',
	
	
	closeSiblings: true,
	
	
	closeChilds: true,
	
	
	items: null,
	
	
	target: '_self',
	
	
	styleDefinitions: null,
	
	
	targetDlg: null,
	
	
	selected: null,
	
	
	treeitems: [],
	
	
	search: null,
	
	
	searchInitialized: false,
	
	
	currentSearchExpr: false,
	
	
	currentSearchIdx: 0,
	
	
	currentDepth: 0,
	
	root: null,
	
	handlers: [],
	
	evt: null,
	
	setEvent: function( evt ) {
		this.evt = evt;
	},
	
	
	render: function()
	{
		if (!this.element.childNodes.length) {
			return;
		}

		this.styleDefinitions = { defaults: 'easygui-treectrl-node-default', leaf: null, levels:[] };
		
		this.items 				= Element.getElementsByTagName( this.element, 'DIV' );
		
		var defs			= Element.getAttributeValue( this.element, 'styledefinitions', null );
		styleDefinitions 	= Util.getJSObject( defs );
		
		if ( !styleDefinitions ) {
			this.setStyleDefinitions( defs );
		} else {
			this.styleDefinitions = styleDefinitions;
		}
		
		this.target 			= Element.getAttributeValue( this.element, 'target', this.target );
		this.targetDlg 			= Element.getAttributeValue( this.element, 'targetdlg' );
		this.focusFirstItem		= Element.getAttributeValue( this.element, 'focusfirstitem', false );
		this.openRoot		    = Element.getAttributeValue( this.element, 'openroot', false );
		this.closeChilds		= Element.getAttributeValue( this.element, 'closechilds', true );
		this.prevSelChange 		= Element.getAttributeValue( this.element, 'preventselectionchange', false );
		
		this.onSelectionChange = Element.getAttributeValue( this.element, 'onselectionchange', 'navigate' );
		
		if ( this.onSelectionChange ) 
			this.onSelectionChange = eval( this.onSelectionChange );
		
		Event.observe( this.element, 'click', this.defaultHandler.bindAsEventListener( this ), false );
		Event.observe( this.element, 'click', this.focusItem.bindAsEventListener( this ) );

		this.element.style.display 	= 'block';
		this.element.state 			= 'opened';

		this.root = Element.getFirstChild( this.element );
		
		Form.insertHidden( this.id + '_EK_WIDGET_VALUE' );
		
		this.openTreeItem( this.element );
		
        this.selected = Element.getAttributeValue( this.element, 'selected' );
        
        if ( this.focusFirstItem )
            this.selected = Element.getAttributeValue( this.element, 'selected', Element.getFirstChild( this.root ).id );
		
		if ( ( this.selected && this.selected != this.id ) || this.focusFirstItem ) {
			this.focusItem( this.selected );
			
			if ( this.target != '_self' && !this.prevSelChange ) {
				this.onSelectionChange.call( this, this.selected );
			}
				
			this.setSelected( this.selected );
		} else {
            if ( this.openRoot ) {
                this.openTreeItem( this.root );
            }
        }
	},
	
	setStyleDefinitions: function( defs ) {	
		if ( defs == null ) {
			return;
		}
			
		var definition;
		var pattern = /\[([^\]]*)\]/g;
		
		while ((definition = pattern.exec(defs)) != null) {
			var def		= definition[1].split(':');	
			var defName = parseInt( def[0] );
			
			if ( isNaN( defName ) ) {
				//alert( def[0] );
				if ( def[0] == 'default' ) {
					this.styleDefinitions['defaults'] = def[1];
				}
				else {
					this.styleDefinitions[def[0]] = def[1];
				}
			}
			else {
				this.styleDefinitions.levels[defName] = def[1];
			}
		}
	},
	
	
	getStyleDefinition: function(level, childNodes, treeitem )
	{
		var customstyle = Element.getAttributeValue( treeitem, 'customstyle' );
		
		if (!customstyle) {
			if (this.styleDefinitions['leaf'] != null && childNodes == 0) {
				if ( this.styleDefinitions['leaf'] != null ) {
					return this.styleDefinitions['leaf'];
				}
			}
				
			if (typeof(level) == 'number') {
				if ( this.styleDefinitions.levels ) {
					while (this.styleDefinitions.levels[level] == null && level > 0) {
						level--;
					}
					
					if (this.styleDefinitions.levels[level] != null) {
						return this.styleDefinitions.levels[level];
					}
				}
			}
			
			return this.styleDefinitions.defaults;
		} else {
			return customstyle;
		}
	},
	
	onDblClick: function( evt ) {
		alert( 'Detected a Dbl Click on ' + $GE(evt).id );
	},
	
	
	prepareSubTree: function( subtree )
	{
		if (subtree == null) {
			subtree = this.element;
		}
		
		var prepared = Element.getAttributeValue( subtree, 'prepared' );
		
		if (prepared == 'true' || prepared) {			
			return ;
		}
		
		for (var i=0; i < subtree.childNodes.length; i++ ) 
		{
			if ( subtree.childNodes[i].nodeName == 'DIV' ) 
			{
				var treeitem 	= Element.getFirstChildByTagName( subtree.childNodes[i], 'A');
				var depth	 	= Element.getDepth( subtree.childNodes[i], 'DIV', 'TreeCtrl' );
				
				var cn			= subtree.childNodes[i].getElementsByTagName('DIV');
				var selector	= this.getStyleDefinition( depth, parseInt( cn.length ), treeitem );
				
				var paddingLeft = parseInt( Dialog.Style.getStyle( selector, 'paddingLeft', 'custom') );

				//console.log("Selector: " + selector + " paddingLeft: " + paddingLeft );
				
				if (isNaN(paddingLeft)) {
					paddingLeft = 0;
				}
				
				var marginLeft = parseInt( Dialog.Style.getStyle( selector, 'marginLeft', 'custom' ) );
			
				if (isNaN(marginLeft)) {
					marginLeft = 0;
				}
				
				var bgPos = Dialog.Style.getStyle( selector, 'backgroundPosition', 'custom' );
				
				if (!bgPos) {
					bgPos = "0 0";
				}
				
				var bgPos = bgPos.split(' ');
				
				vPos = parseInt(bgPos[0]);
				hPos = parseInt(bgPos[1]);
				
				if (isNaN(hPos)) {
					hPos = bgPos[1];
				} else {
					hPos += 'px';
				}
				
				if (isNaN(vPos)) {
					vPos = bgPos[0];
				} else {
					vPos = (((depth * paddingLeft) - (depth * marginLeft)) + vPos)
					vPos += 'px';
				}
				
				subtree.childNodes[i].style.marginLeft = marginLeft + 'px';
				treeitem.className = selector + ' ' + selector + '-closed';
				
				
				
				//treeitem.onfocus = function() { this.blur(); };
				Event.observe(treeitem, "focus", this.onFocus.bindAsEventListener(this) );
				treeitem.style.marginLeft = '0px';
				var paddingLeft = (( (depth * paddingLeft) - (depth * marginLeft) ) + paddingLeft);
			
				treeitem.style.paddingLeft = paddingLeft + 'px';
				treeitem.style.backgroundPosition =  vPos + ' ' + hPos;
			}
		}
		
		subtree.setAttribute( 'prepared', true );
	},
	
	onFocus : function( evt )
	{
		var item = $GE( evt );
		item.blur();;
	},
	
	onTreeItemClick: function( evt ) {
		var element = $GE(evt);
		this.setSelected( element.id );
		this.setEvent( evt );
		
		if (this.handlers[element.id] )
			this.handlers[element.id].call( this, evt );
	},
	
	defaultHandler: function( evt ) {
		var element = Event.element(evt);
		
		if ( element === this.element ) 
			return;
			
		this.onSelectionChange.call( this, evt );
		Event.stop( evt );
	},
			
	
	setSelected: function( id )
	{
		Form.Element.setValue( this.id + '_EK_WIDGET_VALUE', id );
		
		this.element.selected 	= id;
		this.selected			= id;
	},
	
	
	getSelected: function()
	{
		return this.selected;
	},
		
	
	openTreeItem: function( item )
	{
		this.prepareSubTree( item );
		var cNodes = item.childNodes;
		
		for (var i=0; i < cNodes.length; i++) {
			if (cNodes[i].nodeName == 'DIV' ) {
				cNodes[i].style.display = 'block';
			}
		}
	},
	
	
	closeTreeItem: function( item )
	{
		if ( item.nodeName == 'DIV' ) {
			var cNodes = item.childNodes;
			
			if (cNodes.length == 0 ) {
				return;
			}
			
			for (var i=0; i < cNodes.length; i++) {
				if (cNodes[i].nodeName == 'DIV') {
					if (this.closeChilds && (cNodes[i].state == 'opened-sibling' || cNodes[i].state == 'opened' || cNodes[i].state == 'focused') ) {
						this.closeTreeItem( cNodes[i] );
					}
					
					this.setTreeStyle( cNodes[i], 'closed' );
					cNodes[i].style.display = 'none';
				}
			}
		}
	},
	
	
	hideTreeItem: function( item )
	{
		var element = Element.getParentElementByTagName( $(item), "DIV" );
		element.setAttribute( 'display', 'false' );
		this.prepareSubTree( element.parentNode );
		
		if ( element.parentNode.state == "focused" )
			element.style.display = "none";
	},
	
	
	displayTreeItem: function( item )
	{
		var element = Element.getParentElementByTagName( $(item), "DIV" );
		element.setAttribute( 'display', 'true' );
		this.prepareSubTree( element.parentNode );
		
		if ( element.parentNode.state == "focused" )
			element.style.display = "block";
	},

	
	setTreeStyle: function(item, state)
	{
		if ( item.nodeName == 'DIV' ) {
			var treeitem = Element.getFirstChildByTagName(item, 'A');
		
			styleClass = treeitem.className.split(' ');
			treeitem.className = styleClass[0] + ' ' + styleClass[0] + '-' + state;
		}
	},

	
	resetTree: function()
	{
		var currentItem 	= $( this.selected ).parentNode;
		var currentDepth 	= Element.getDepth( currentItem, 'DIV', 'TreeCtrl' );
	
		while ( currentDepth > 1 ) {
			if ( currentItem.nodeName == 'DIV' ) {
				currentDepth = Element.getDepth( currentItem, 'DIV', 'TreeCtrl' );
			}
			
			currentItem = currentItem.parentNode;
		}
		
		if (currentItem) 
			this.closeTreeItem( currentItem );
	},
	
	
	searchTree: function( expr )
	{
		var match = '';
		
		if ( expr != this.currentSearchExpr ) {
			this.currentSearchIdx 	= 0;
			this.currentSearchExpr 	= expr;
			this.search 			= [];
			
			for ( var i=0; i < this.items.length; i++ ) {
				var treeitem 	= Element.getFirstChildByTagName( this.items[i], 'A');
				var text 		= Element.getInnerText( treeitem );
				
				if ( text.indexOf( expr ) != -1 ) {
					this.search[this.search.length] = treeitem.id;
				}
			}
		} else {
			this.currentSearchIdx++;
			
			if ( (this.currentSearchIdx + 1)  > this.search.length) {
				this.currentSearchIdx = 0;
			}
		}
	
		if ( this.search.length > 0 ) {
			this.focusItem( this.search[ this.currentSearchIdx ] );
			
			var treeitem = $( this.search[ this.currentSearchIdx ] );
			treeitem.parentNode.parentNode.scrollIntoView( true );
			
			return true;
		} 
			
		return false;
	},
	
	
	focusItem: function( el )
	{
		var el = $GE(el);
		
		if ( el === this.element ) 
			return;
			
		el = Element.getParentElementByTagName( el, 'A', true );
		el.blur();
		this.setSelected( el.id );
		
		var targetDlg = Element.getAttributeValue( el, 'targetdlg' );

		var evtEl = el;
		
		var id 	= el.id;
		
		el = el.parentNode;

		if (!targetDlg) {
			if ( this.targetDlg )
				targetDlg = this.targetDlg;
			else targetDlg = '';
		} 
		
		evtEl.setAttribute( 'targetdlg', targetDlg );
		
		this.resetTree();
		this.openTreeItem( el );
		
		el.state = 'focused';
		
		sourceElement = el;
		var parentItem = sourceElement.parentNode;
		
		this.prepareSubTree( parentItem );
		this.setTreeStyle( el, el.state );
		
		while( el = el.nextSibling ) {
			if (el.nodeName == 'DIV') {
				el.state = 'focused-sibling';
				this.closeTreeItem( el );
				this.setTreeStyle( el, el.state );
			}
		}
		
		el = sourceElement;
		
		while ( el = el.previousSibling ) {
			if (el.nodeName == 'DIV' ) {
				el.state = 'focused-sibling';
			
				this.closeTreeItem( el );
				this.setTreeStyle( el, el.state );
				lastel = el;
			}
		}
		
		while (parentItem.nodeType != 9 ) {
			var ektype = Element.getAttributeValue( parentItem, 'ektype' );
			
			if ( ektype == 'TreeCtrl') break;
			
			if (parentItem.nodeName == 'DIV') {
				parentItem.state = 'opened';
				
				this.openTreeItem( parentItem );
				this.setTreeStyle( parentItem, parentItem.state );
				
				sibling = parentItem.nextSibling;
				
				while ( sibling != null ) {
					if ( sibling.nodeName == 'DIV' ) {
						sibling.state = 'opened-sibling';
						this.setTreeStyle( sibling, sibling.state );
					}
					
					sibling = sibling.nextSibling;
				}
				
				sibling = parentItem.previousSibling;
				
				while( sibling != null ) {
					if (sibling.nodeName == 'DIV' ) {
						sibling.state = 'opened-sibling';
						this.setTreeStyle( sibling, sibling.state );
					}
					
					sibling = sibling.previousSibling;
				}
				
			}
			
			parentItem = parentItem.parentNode;
		}
	}
});

var descend = false;
var EasyGUI_table = Class.create();


Object.extend( Object.extend( EasyGUI_table.prototype, EasyGUI_widget.prototype ),
{
	
	selectedElements: null,
	
	
	submitValues: null,
	
	
	activeFilter: null,
	
	
	lastSortCol: null,
	
	
	rowHeader: null,
	
	
	columnHeader: null,
	
	
	fixedHeader: null,
	
	
	currentScrollTop: 0,
	
	
	currentScrollLeft: 0,
		
	
	toggleRowStyles: false,
	
	
	bgColor: 'white',
	
	
	textColor: 'black',
	
	
	bgColorHl: 'highlight',
	
	
	textColorHl: 'highlighttext',
	
	
	bgColorEven: 'buttonface',
	
	
	textColorEven: 'black',
	
	
	fixedLines: 0,
	
	
	fixedColumns: 0,
	
	
	selectionType: 'none',
	
	
	multipleSelection: false,
	
	
	isSortable: false,
	
	
	sortTitle: '',
	
	
	presortedColumn: 1,
	
	
	cellSpacing: 0,
	
	
	onSelectionChange: null,
	
	
	selected: '',
	
	
	action: null,
	
	
	targetdlg: null,
	
	disabled: false,
	
	
	setAction: function( action ) 
	{
		this.container.setAttribute('action', action );
	},
	
	
	setTargetDlg: function( id ) 
	{
		this.container.setAttribute('targetdlg', id );
	},
	
	
	render: function() 
	{
		//var timer = new JS_Timer();
		//timer.startTimer();
		this.element = $( this.id + '_TABLE' );
		
		var type	= this.element.readAttribute( 'type' );
		var columnStyles = [];
		
		if ( type == "html" ) {
			var container = this.element.up('div');
			var table = container.down('TABLE');
			
			if ( container.up().nodeName.toLowerCase() != "td" )
			{
				table.style.position = 'absolute';
				table.style.top = container.style.top;
				table.style.left = container.style.left;
			} else {
				table.style.position = 'relative';
			}
			
			container.up().appendChild( table );
			return;
		}
		
		this.selectedElements = [];
		this.submitValues = [];
		
		this.toggleRowStyles = this.element.readAttribute('togglerowstyles');
	
		this.bgColor = this.element.getStyle( 'background-color' ) || 'white';
		
		if ( this.bgColor == 'transparent' && this.toggleRowStyles )
			this.bgColor = 'white';
	
		this.fixedLines 	= parseInt( this.element.readAttribute('fixedlines') ) || 0;
		this.fixedColumns 	= parseInt( this.element.readAttribute('fixedcolumns')) || 0;
		
		this.hasRowHeader	= this.element.readAttribute('rowheader');
		this.hasColumnHeader= this.element.readAttribute('columnheader');
		
		this.tableLayout 	= this.element.readAttribute('tablelayout');
		
		if ( this.tableLayout != 'fixed' ) {
			this.element.style.width = "100%";
		} else {
			this.element.style.tableLayout = this.tableLayout;
		}
		
		if ( this.hasRowHeader ) {
			this.fixedColumns = 1;
		}
		
		if ( this.hasColumnHeader ) {
			this.fixedLines = 1;
		}
		
		this.selectionType 		= this.element.readAttribute('selectiontype') || 'none';
		this.selectionType 		= this.selectionType.toLowerCase();
		
		this.multipleSelection 	= this.element.readAttribute('multipleselection');
		

		
		this.onClicked = eval( this.element.onclick );
		
		this.element.onclick = function () { return true; };
		
		if ( this.onClicked != null ) {
			Event.observe( this.element, 'click', this.onRowClicked.bindAsEventListener(this) );
		}
		
		
		if ( this.selectionType != 'none' ) {
			this.element.onmouseover = null;
			this.element.onmouseout = null;
		
			for ( var i=this.fixedLines; i < this.element.rows.length; i++ ) {
				Event.observe(this.element.rows[i],'mouseover',this.onRowOver.bindAsEventListener(this) );
			}
	
			for ( var i=this.fixedLines; i < this.element.rows.length; i++ ) {
				Event.observe(this.element.rows[i],'mouseout', this.onRowOut.bindAsEventListener(this) );
			}	
		}
		
		this.onSelectionChange = Element.getAttributeValue( this.element, 'onselectionchange' );
		
		if ( this.onSelectionChange ) {
			this.onSelectionChange = eval( this.onSelectionChange );
			Event.observe( this.element, 'click', this.onSelectionChanged.bindAsEventListener(this) );
		}
		
		this.onDblClicked				= Element.getAttributeValue( this.element, 'ondblclicked' );
		
		if ( this.onDblClicked ) {
			this.onDblClicked = eval( this.onDblClicked );
			Event.observe( this.element, 'dblclick', this.onRowDblClicked.bindAsEventListener(this) );
		}
			
		this.isSortable = this.element.readAttribute('sortable' );
		this.sortTitle 	= this.element.readAttribute('sorttitle') || 'Click to sort !';
		
		this.presortedColumn = parseInt( Element.getAttributeValue( this.element, 'presortedcolumn', 1));
		
		if (isNaN(this.presortedColumn)) {
			var column = $GE( this.element.readAttribute('presortedcolumn') || '' );
			this.presortedColumn = parseInt(this.presortedColumn.cellIndex);
			
			if (isNaN(this.presortedColumn))
				this.presortedColumn = 1;
		}
		
		
		this.cellSpacing = parseInt( this.element.readAttribute('cellSpacing') ) || 0 ;
		this.cellPadding = parseInt( this.element.readAttribute('cellPadding') ) || 0;
		
		this.element.setAttribute('cellSpacing', this.cellSpacing );
		this.element.setAttribute('cellPadding', this.cellPadding );
		this.element.cellPadding = this.cellPadding;
		this.isFiltrable 		= this.element.readAttribute('filtrable');
		this.filterboxAllText 	= this.element.readAttribute('filterboxalltext') || 'All';
		this.filterTitle 		= this.element.readAttribute('filtertitle') || 'Choose to filter !';
		this.prefilteredColumn 	= parseInt( this.element.readAttribute('prefilteredcolumn')) || 1;
		this.selected 			= this.element.readAttribute('selected');
		this.selectFirstItem	= this.element.readAttribute('selectfirstitem');
		
		this.container 			= this.element.up('div');
		
		//this.container			= $(this.container);
		
		this.scrollSelectionIntoView = this.element.readAttribute('scrollselectionintoview') || true;
		
		this.action			= this.element.readAttribute('action') || '';
		this.targetdlg		= this.element.readAttribute('targetdlg') || '';
		
		var tabCtrl = null;
		
		if ( tabid = Element.isInTab( this.id ) ) {
			tabCtrl = dialog[$( tabid ).readAttribute('widgetid')];
			tabCtrl.switchTab( tabid );
		}
		
		if ( this.element.rows.length == 0 ) {
			return;
		}
		
		if ( isEmptyValue(this.element.className) ) {
			this.element.className = 'easygui-table';
			this.element.style.zIndex = 0;
		}
		
		if (this.fixedLines > 0) {
			var headerHeight		= this.element.readAttribute('headerheight');
			for (var i=0; i < this.fixedLines; i++) {
				if (headerHeight)
					this.element.rows[i].style.height = headerHeight + 'px';
				
				var len = this.element.rows[i].cells.length;
				var cells = this.element.rows[i].cells;
				
				var issetSortable = false;
				var issetFiltrable = false;
				
				for (var j=0; j < len; j++) {
					var cell = $(cells[j]);
					// columnstyles
					if ( i == 0 ) 
						columnStyles[j]		= cell.readAttribute('columnstyle') || this.element.readAttribute('columnstyle');
					
					var headerTextColor 	= cell.readAttribute('headertextcolor') || this.element.readAttribute('headertextcolor');
					var headerBgColor		= cell.readAttribute('headerbackgroundcolor') || this.element.readAttribute('headerbackgroundcolor');
			
					var headerFont 			= cell.readAttribute('headerfont') || this.element.readAttribute('headerfont');
					var headerFontSize 		= cell.readAttribute('headerfontsize') || this.element.readAttribute('headerfontsize');
					var headerFontWeight 	= cell.readAttribute('headerfontweight') || this.element.readAttribute('headerfontweight');
					var headerFontStyle 	= cell.readAttribute('headerfontstyle') || this.element.readAttribute('headerfontstyle');
			
					var headerAlign 		= cell.readAttribute('headerhorizontalalign') || this.element.readAttribute('headerhorizontalalign');
					var headerValign 		= cell.readAttribute('headerverticalalign') || this.element.readAttribute('headerverticalalign');
					
					// @@@Hacked Hacked Hacked
					// @todo find a better solution for attribute value conversions on the server side
					if ( headerValign == 'center' ) {
						headerValign = 'middle';
					}
					
					var sortable = cell.readAttribute('sortable');
					var filtrable = cell.readAttribute('filtrable');
					
					if (sortable && !issetSortable) {
						this.isSortable = true;
						issetSortable = true;
					}
					
					if (filtrable && !issetFiltrable) {
						this.isFiltrable = true;
						issetFiltrable = true;
					}
					
					cell.className += ' header';
					
					cell.style.backgroundRepeat = 'no-repeat';
					cell.style.backgroundPosition = 'center right';
					
					if (headerTextColor)
						cell.style.color = headerTextColor;
								
					if (headerBgColor)
						cell.style.backgroundColor = headerBgColor;
				
					if (headerFont)
						cell.style.fontFamily = headerFont;
					
					if (headerFontSize)
						cell.style.fontSize = headerFontSize + 'pt';
					
					if (headerFontWeight)
						cell.style.fontWeight = headerFontWeight;
					
					if (headerFontStyle)
						cell.style.fontStyle = headerFontStyle;
						
					if (headerAlign)
						cell.style.textAlign = headerAlign;
						
					if (headerValign)
						cell.style.verticalAlign = headerValign;
						
				}
			}
		}
		
		if ( this.fixedColumns > 0 && this.hasRowHeader ) {
			for ( var i=0; i < this.element.rows.length; i++ ) {
				var row = this.element.rows[i];
				
				for (var j=0; j < this.fixedColumns; j++) {
					row.cells[j].className += ' rowheader';
				}
			}
		}
		
		var rowLength = this.element.rows.length;
		
		for (var i = this.fixedLines; i < rowLength; i++) {
			var row = $(this.element.rows[i]);
			row.addClassName("selectable");
			
			if ( i % 2 == 0 && this.toggleRowStyles )
				row.className += ' altrow';
				
			for ( var j=0, len = row.cells.length; j < len; ++j ) {
				var cell = row.cells[j];
				
				if ( typeof columnStyles[j] !== "undefined" && columnStyles[j] !== null)
					cell.className = columnStyles[j];
			}
		}
	
		if ( (this.element.offsetWidth <= this.container.clientWidth) && !this.hasRowHeader ) 
			this.fixedColumns = 0;
			
		if ( (this.element.offsetHeight > this.container.offsetHeight) && 
			 (this.element.offsetWidth == this.container.offsetWidth) ) {
				this.element.style.width = this.container.clientWidth + 'px';
				if (!this.hasRowHeader)
					this.fixedColumns = 0;
		}
		
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		this.container.style.visibility = 'visible';
		this.container.style.zIndex = 0;
		
		if (this.fixedLines > 0 && this.isFiltrable) {
			var sourceRow = this.element.tBodies[0].insertRow(this.fixedLines);
			
			if (this.headerBgColor)
				sourceRow.style.backgroundColor = this.headerBgColor;
				
			var filterCount = 0;
			this.fixedLines++;
			
			for (var i=0; i < this.element.rows[0].cells.length; i++) {
				var filterCell = sourceRow.insertCell(i);
				var filtrable = $(this.element.rows[0].cells[i]).readAttribute('filtrable');
				
				if (filtrable) {
					var filterBox = document.createElement('select');
					
					filterCell.appendChild(filterBox);
					filterBox.options[0] = new Option(this.filterboxAllText, 'ALL', true, true);
					filterBox.setAttribute('isFilterBox', 'true' );
					filterCount++;
				} else
					filterCell.innerHTML = '&nbsp;';
			}
			
			var rowLength 	= this.element.rows.length;
			var cellLength 	= this.element.rows[0].cells.length;
				
			var filters = new Array( filterCount );
			
			for (var i = this.fixedLines; i < rowLength; i++) {
				for (var j=0; j < cellLength; j++) {
					var filtrable = $(this.element.rows[0].cells[j]).readAttribute('filtrable');
					
					if (filtrable) {

						if (!filters[j])
							filters[j] = new Array();
						
						var currentFilter = filters[j];
						var filtercriterium = null;
						
						if (this.element.rows[i].cells[j].firstChild.nodeType == 3)
							var filtercriterium = this.element.rows[i].cells[j].firstChild.data;
							
						filtercriterium = $(this.element.rows[i].cells[j]).readAttribute('filtercriterium') || filtercriterium;
						
						var filterBox = $(this.element.rows[1].cells[j]).down('select');
						
						if ( !currentFilter.inArray( filtercriterium ) )
							currentFilter[currentFilter.length] = filtercriterium;
							
						this.element.rows[i].cells[j].filtercriterium = filtercriterium;
						
						filterCount++;
					} else
						filters[j] = false;
				}
			}
			
			for ( var i=0; i < filters.length; i++ ) {
				var filter = filters[i];
				
				if (filter) {
					//filter.sort( Sort.compareValues );
					filter.sort( Sort.natCompare );
					var filterBox = $(this.element.rows[1].cells[i]).down('select');
				
					for (var j=0; j < filter.length; j++)
						filterBox.options[filterBox.options.length] = new Option( filter[j], filter[j], false, false );
				}
			}
		}
		
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		if (this.fixedColumns > 0) {
			if ( this.rowHeader != null ) {
				this.rowHeader.header.parentNode.removeChild(this.rowHeader.header);
			}
			this.rowHeader	= new EasyGUI_TableRowHeader( this );
				
		}

		if (this.fixedLines > 0) {
			if ( this.columnHeader != null ) {
				this.columnHeader.header.parentNode.removeChild(this.columnHeader.header);
			}
			this.columnHeader = new EasyGUI_TableColumnHeader( this );
			
		}
		
		if (this.fixedColumns > 0 && this.fixedLines > 0) {
			if ( this.fixedHeader != null ) {
				this.fixedHeader.header.parentNode.removeChild(this.fixedHeader.header);
			}
			this.fixedHeader = new EasyGUI_TableFixedHeader( this );
			
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		if (this.fixedLines > 0) {
			
			if (this.isSortable) {
				
				var header = this.columnHeader.headerTable;
				var length = header.rows[0].cells.length;
				
				for (var j=0; j < length; j++) {
					var sortable = !!$(this.element.rows[0].cells[j]).readAttribute('sortable') || false;
					
					if (sortable) {
						if ( this.fixedColumns > 0 ) {
							var fixedHeader = this.fixedHeader.headerTable;
							
							Event.observe( fixedHeader.rows[0].cells[j], 'click', this.sortTable.bindAsEventListener( this ) );
							fixedHeader.rows[0].cells[j].title = this.sortTitle;
						}
						
						Event.observe( header.rows[0].cells[j], 'click', this.sortTable.bindAsEventListener( this ) );
						header.rows[0].cells[j].title = this.sortTitle;
					}
				}
				
				if (this.presortedColumn && this.element.rows.length > this.fixedLines ) {
					//this.sortTable( this.columnHeader.headerTable.rows[0].cells[ ( this.presortedColumn - 1 ) ] );
				}
			}
			
					
			if (this.isFiltrable) {
				for (var i=0; i < cellLength; i++) {
					var filterBox = $(this.element.rows[1].cells[i]).down('select');
					
					if (filterBox) {
						filterBox.style.visibility = 'hidden';
						var cloneBox = $(this.columnHeader.headerTable.rows[1].cells[i]).down('SELECT');
						
						Event.observe( cloneBox, 'change', this.filterTable.bindAsEventListener( this ) );
						
						cloneBox.cellIdx = i;
						cloneBox.selectedIndex = 0;
					}
				}
			}
		}
		
		Form.insertHidden( this.id + '_EK_WIDGET_VALUE', '' );
		
		this.setSelectionHandler();
		this.setSelection();
		
		if ( this.selected && this.scrollSelectionIntoView )
			this.scrollRowIntoView( this.selected );
		
		if ( tabCtrl != null ) {
			tabCtrl.switchTab( tabCtrl.getSelected() );
		}
		
		// Event.observe( this.element, 'resize', this.resizeTable.bindAsEventListener(this) );
		
		if ( this.fixedLines > 0 && this.container.scrollLeft > 0 ) {
			this.columnHeader.headerTable.style.left = - this.container.scrollLeft + 'px';
		}
		this.initialized = true;
		
		//alert( 'Init table took: ' + timer.stopTimer()  + ' seconds' );
	},
	
	setColumnHeaderText : function(text, idx) {
		var cellIdx = this.element.rows[0].cells[idx].cellIndex;
		this.columnHeader.headerTable.rows[0].cells[cellIdx].innerHTML = text;
		this.element.rows[0].cells[cellIdx].innerHTML = text;
	},
	
	onRowOver : function( evt )
	{
		if ( this.container.disabled )
			return;
		
		var target = $(Event.element(evt)).up('tr');
		
		if (target)
			target.addClassName('hilite');
	},
	
	onRowOut : function( evt )
	{
		if ( this.container.disabled )
			return;

		var target = $(Event.element(evt)).up('tr');
		if (target)
			target.removeClassName('hilite');
	},
	
	
	setSelection: function()
	{
		var submitValues = [];
		
		if (!this.selected && this.selectFirstItem ) {
			if (this.element.rows.length > this.fixedLines ) {
				if ( this.selectionType == 'selectrow' ) {
					var row = this.element.rows[this.fixedLines];
					submitValues[0] = row.id;
				}
				
				if (this.selectionType == 'selectcell') {
					cell = this.element.rows[this.fixedLines].cells[this.fixedColumns];
					submitValues[0] = cell.id;
				}
			}
		} else if ( this.selected ) {
			submitValues = this.selected.split(',');
		}
		
		this.setSubmitValue(submitValues);
		
		for ( var i=0; i < submitValues.length; i++) {
			if (this.selectionType == 'selectrow') {
				this.selectRow( submitValues[i] );
			}
			
			if (this.selectionType == 'selectcell') {
				this.selectCell( submitValues[i] );
			}
		}		
	},
	
	
	setSelectionHandler: function() 
	{
		switch (this.selectionType.toLowerCase()) {
			case 'selectrow':
				Event.observe( this.element, 'click', this.selectRow.bindAsEventListener(this), false );
				
				if (this.fixedColumns > 0)
					Event.observe( this.rowHeader.header, 'click', this.selectRow.bindAsEventListener(this), false);
					
				break;
				
			case 'selectcell':
				Event.observe( this.element, 'click', this.selectCell.bindAsEventListener(this), false );
				
				if (this.fixedColumns > 0)
					Event.observe( this.rowHeader.header, 'click', this.selectCell.bindAsEventListener(this), false);
					
				break;
				
			case 'selectrowandsubmit':
				Event.observe( this.element, 'click', this.selectRowAndSubmit.bindAsEventListener(this), false );
				
				if (this.fixedColumns > 0)
					Event.observe( this.rowHeader.header, 'click', this.selectRowAndSubmit.bindAsEventListener(this), false);
					
				break;
				
			default:
				break;
		}
		
		Event.observe( this.container, 'scroll', this.onScrollStart.bindAsEventListener(this), false );
		Event.observe( this.container, 'mousewheel', this.onMouseWheel.bindAsEventListener(this), false);
	},
			
	onRowClicked: function( evt )
	{
		if (this.container.disabled) {
			return;
		}
		
		this.onClicked.call( this, evt );
	},
		
	
	onSelectionChanged: function( evt ) 
	{
		if (this.container.disabled) {
			return;
		}
		
		this.onSelectionChange.call( this, evt );
	},
	
	
	onRowDblClicked: function( evt )
	{
		var element = $GE(evt);
		
		element.setAttribute('action', this.action );
		element.setAttribute('targetdlg', this.targetdlg );
		
		this.onDblClicked.call( this, element );
	},
	
	
	reset: function()
	{
		if (!this.initialized)
			return;
		
		for (var i=0; i < this.selectedElements.length; i++)
			this.deselectRow( this.selectedElements[i] );
		
		this.submitValues = [];
		this.selectedElements = [];
		this.setSubmitValue('');
	},
	
	
	setSubmitValue: function( value )
	{
		if ( value instanceof Array )
			value = value.join();
			
		$(this.id + '_EK_WIDGET_VALUE').value = value;
	},
	
	
	getSubmitValue: function()
	{
		return $F( this.id + '_EK_WIDGET_VALUE' );
	},
	
	
	selectRow: function( evt )
	{
		var element;
		
		if ( this.container.disabled ) {
			return;
		}
			
		var modifier = Event.getModifier( evt );
		
		// Da mehrere Clone der Tabelle existieren muss genau in der
		// richtigen nachgeschaut werden
		if ( typeof evt == "string" ) {
			for ( var i=this.fixedLines, len = this.element.rows.length; i < len; ++i ) {
				if ( this.element.rows[i].id == evt ) {
					element = this.element.rows[i];
					break;
				}
			}
		} else {
			element	 = $GE( evt );
		}
		
		// Sollte es das element nicht geben, selektieren wir den ersten Eintrag
		if ( element == null ) {
			if ( this.element.rows.length <= this.fixedLines ) { 
				return;
			}
				
			element = this.element.rows[this.fixedLines];
		}
		
		if (!this.multipleSelection || (this.multipleSelection && modifier != 'ctrl')) {
			this.reset();
		}
		
		var row = element;
		
		if ( !row.hasClassName( 'selectable' ) ) {
			row = element.up('tr.selectable');
		}
		
		if (!row) {
			this.setSubmitValue('');
			return;
		}
		
		if ( !this.submitValues.inArray( row.id ) ) {
			this.submitValues[this.submitValues.length] = row.id;
			this.selectedElements[this.selectedElements.length] = element;
		} else {
			this.deselectRow( element );
			return;
		}
	
		row.setAttribute( 'selected', true );
		row.className += " selected";
		
		if( this.fixedColumns > 0 && !this.hasRowHeader) {
            this.element.rows[row.rowIndex].className += " selected";
            this.element.rows[row.rowIndex].setAttribute('selected', true);
            
            var fixedRow = this.rowHeader.headerTable.rows[row.rowIndex];
			fixedRow.className += " selected";
			fixedRow.setAttribute( 'selected', true );
		}
		
		if ( this.hasRowHeader ) {
			this.element.rows[row.rowIndex].className += ' rowheader';
		}
		
		this.setSubmitValue( this.submitValues.toString() );
		
		// Stop Event propagation if user clicks on Table
		var el = ( typeof evt == "string" ) ? $(evt) : Event.element(evt);
		
		if ( el && el.nodeName != "INPUT" && el.tagName.toUpperCase() != "A" && typeof evt == "object") {
			Event.stop( evt );
		}
		
		// Hier werfen wir zum ersten mal ein Custom Event.
		this.element.fire('table:selectionchange', { value: this.getSelected() } );
	},
	
	
	deselectRow: function( element )
	{
		var row = $(element);
		
		if ( !row.hasClassName('selectable') ) {
			var row = $(element).up('tr.selectable');
		}
		
		if (!row) {
			this.setSubmitValue('');
			return;
		}
		
		row.className = row.className.replace( "selected", "" );
		row.setAttribute('selected', false);
		
		if (this.fixedColumns > 0 && !this.hasRowHeader) {
            $(this.element.rows[row.rowIndex]).removeClassName('selected'); //.className
            this.element.rows[row.rowIndex].setAttribute('selected', false);
            
			var fixedRow = this.rowHeader.headerTable.rows[row.rowIndex];
			fixedRow.setAttribute('selected', false);
			fixedRow.className = fixedRow.className.replace('selected', '');
		}
		
		if ( this.hasRowHeader ) {
			this.element.rows[row.rowIndex].className = this.element.className + ' rowheader';
		}
			
		this.submitValues.removeEntry( row.id );
		this.setSubmitValue( this.submitValues.toString() );
	},
	
	
	selectRowAndSubmit: function( evt )
	{
		if ( this.container.disabled ) {
			return;
		}
		
		this.selectRow( evt );
		ekSubmit( this.id );
	},
	
	
	selectCell: function( evt )
	{
		if (this.container.disabled) {
			return;
		}
		
		var modifier = Event.getModifier( evt );
		var element	 = $($GE( evt ));
		
		if (!this.multipleSelection || (this.multipleSelection && modifier != 'ctrl'))
			this.reset();
		
		var cell 	= element.up('td');
		
		if ( !cell )
			return;
			
		if ( this.hasRowHeader ) {
			if ( cell.cellIndex < this.fixedLines ) {
				this.selectRow( evt );
				return;
			}
		}
		
		var row		= cell.up('tr');
		var className = this.element.className + '-cell-highlight';
		
		if ( !this.submitValues.inArray( cell.id ) ) {
			this.submitValues[this.submitValues.length] = cell.id;
			this.selectedElements[this.selectedElements.length] = element;
		} else { 
			this.deselectCell( element );
			return;
		}
		
		if (this.fixedColumns > 0 && !this.hasRowHeader) {
			var fixedCell = this.rowHeader.headerTable.rows[row.rowIndex].cells[cell.cellIndex];
			
			fixedCell.setAttribute('selected', true );
			
			fixedCell.className = className
		}
		
		cell.setAttribute('selected', true);
		cell.className = className
		
		this.setSubmitValue( this.submitValues.toString() );
	},
	
	
	deselectCell: function( element )
	{
		var cell = $(element).up('td');
		
		if ( !cell )
			return;

		if ( this.hasRowHeader ) {
			if ( cell.cellIndex < this.fixedColumns ) {
				this.deselectRow( evt );
			}
		}
						
		var row	= $(cell).up('tr');
		
		var className = this.element.className + '-cell';
		
		if ( (row.rowIndex ) % 2 == 0 && this.toggleRowStyles)
			className = this.element.className + '-altcell';
			
		cell.setAttribute('selected', false);
		cell.className = className;
		
		this.submitValues.removeEntry( cell.id );
		this.setSubmitValue( this.submitValues.toString() );
	},	
	 
	
	filterTable: function ( evt )
	{
		if (this.container.disabled) {
			return;
		}
		
		var filterBox	= $GE( evt );
		var rows 		= this.element.rows;
		var cellIdx 	= filterBox.cellIdx;
		var filterVal 	= filterBox.options[filterBox.selectedIndex].value;
		
		if (this.activeFilter != null && this.activeFilter != filterBox)
			this.activeFilter.selectedIndex = 0;
			
		for (var i=this.fixedLines; i < rows.length; i++) {
			if (this.fixedColumns > 0)
				this.rowHeader.headerTable.rows[i].style.display = '';
				
			rows[i].style.display = '';
			
			if (filterVal != 'ALL' && rows[i].cells[cellIdx].filtercriterium != filterVal) {
				rows[i].style.display = 'none';	
				
				if (this.fixedColumns > 0)
					this.rowHeader.headerTable.rows[i].style.display = 'none';
			}		
		}
		
		this.activeFilter = filterBox;

		if ( this.toggleRowStyles )
			this.setRowStyles();
		
		
	},
	
		
	sortTable: function( element )
	{
		if (this.container.disabled) {
			return;
		}
		
		var element = $($GE(element));
		var col = Element.getParentElementByTagName( element, 'TD', true );
		
		var cellIndex = col.cellIndex;
		
		var tmpEl;
	  	var i, j;
	  	var minVal, minIdx;
	  	var compVal;
	  	var cmp;
	  	
		descend = col.descend;
		
		var descendStyle 	= this.getStyleDefinition('header-za-sorted');
		var ascendStyle 	= this.getStyleDefinition('header-az-sorted');
		
		if(descend) {
			col.descend = false;
		
			if (this.isSortable) {
				col.className = this.element.className + ' header ' + descendStyle;
				if (this.fixedLines > 0 ) {
					this.columnHeader.headerTable.rows[0].cells[cellIndex].className = this.element.className + ' header ' + descendStyle;
					this.columnHeader.headerTable.rows[0].cells[cellIndex].descend = false;
				}
			}
		} else {
			col.descend = true;
			
			if (this.isSortable) {
				col.className = this.element.className + ' header ' + ascendStyle;
				
				if (this.fixedLines > 0 ) {
					this.columnHeader.headerTable.rows[0].cells[cellIndex].className = this.element.className + ' header ' + ascendStyle;
					this.columnHeader.headerTable.rows[0].cells[cellIndex].descend = true;
				}
			}
		}

		if (this.lastSortCol && this.lastSortCol != col) {
			if (this.lastSortCol.descend)
				Element.removeClassName( this.lastSortCol, ascendStyle );	
			else
				Element.removeClassName( this.lastSortCol, descendStyle );
					
			this.lastSortCol.descend = false;
		}
		
	  	for (i = this.fixedLines; i < this.element.rows.length; i++) {
			minIdx = i;
			
			minVal = ( sortcriterium = this.element.rows[i].cells[cellIndex].getAttribute( 'sortcriterium' ) ) ? sortcriterium : Element.getInnerText( this.element.rows[i].cells[cellIndex]);
			
	    	//minVal = this.element.rows[i].cells[cellIndex].sortcriterium;
	    	
			for (j = i+1; j < this.element.rows.length; j++) {
	      		//compVal = this.element.rows[j].cells[cellIndex].sortcriterium;
	      		compVal = ( sortcriterium = this.element.rows[j].cells[cellIndex].getAttribute('sortcriterium' ) ) ? sortcriterium : Element.getInnerText( this.element.rows[j].cells[cellIndex]);
	      		//cmp = Sort.compareValues(minVal, compVal);
	      		cmp = Sort.natCompare(minVal, compVal);
	
	      		if (cmp > 0) {
	        		minIdx = j;
	        		minVal = compVal;
	      		}
	    	}
	    	
	    	if (minIdx > i) {
	    		if (this.fixedColumns > 0 ) {
	    			tmpEl = this.rowHeader.headerTable.tBodies[0].removeChild( this.rowHeader.headerTable.rows[minIdx] );
	    			this.rowHeader.headerTable.tBodies[0].insertBefore( tmpEl, this.rowHeader.headerTable.rows[i] );
	    		}
	    		
	      		tmpEl = this.element.tBodies[0].removeChild( this.element.rows[minIdx] );
	      		this.element.tBodies[0].insertBefore(tmpEl, this.element.rows[i]);
	    	}
	  	}
	  	
	  	this.lastSortCol = col;
	  	this.setRowStyles();
	},
	
	 
	
	
	compareByColumn : function (c, d)
	{
		descend = d;
		
		return function (n1, n2) 
		{
			var a = Element.getInnerText( n1.cells[c] );
			var b = Element.getInnerText( n2.cells[c] );
			
			return Sort.natCompare( a, b );
			//return Sort.compareValues( a, b );
		};
	},
	
	
	setRowStyles: function()
	{
		var rows = this.element.rows;
		var rowsLength = rows.length;
		var j=0;
		
		for (var i = this.fixedLines; i < rowsLength; i++) {
			if (rows[i].style.display != 'none') {
				Element.removeClassName( rows[i], 'altrow' );
				if ( (j++ % 2) != 0 )
					Element.addClassName( rows[i], 'altrow' );

				if ( this.selectionType == "selectcell" ) {
					var cells 		= rows[i].cells;
					var cellsLength = cells.length;
				
					if (this.fixedColumns > 0)
						var headerCells = this.rowHeader.headerTable.rows[i].cells;
						
					for (var j=0; j < cellsLength; j++) {
						if (this.fixedColumns > 0 && !headerCells[j].selected )
							headerCells[j].className = className;
						
						if (!cells[j].selected)
							cells[j].className = className;
					}
				}
			}
		}
	},
	
	getRowCount: function()
	{
		return this.element.rows.length - parseInt(this.fixedLines);
	},
		
	hasFixedLines: function()
	{
		return (this.fixedLines > 0);
	},
	
	hasFixedColumns: function()
	{
		return ( this.fixedColumns > 0 );
	},
	
	hide: function()
	{
		Element._hide( this.container );
		
		if ( this.hasFixedLines() ) {
			Element._hide( this.id + '_FL' );
			
			if ( is.ie5up )
				Element._hide( this.columnHeader.header.iframeEl );
		}
		
		if ( this.hasFixedColumns() ) {
			Element._hide( this.id + '_FC' );
			
			if ( is.ie5up )
				Element._hide( this.rowHeader.header.iframeEl );
		}
		
		if ( this.hasFixedLines() && this.hasFixedColumns() ) {
			Element._hide( this.id + '_FIX' );
			
			if ( is.ie5up )
				Element._hide( this.fixedHeader.header.iframeEl );
		}
	},

	show: function()
	{
		Element._show( this.container );
		
		if ( this.hasFixedLines() ) {
			Element._show( this.id + '_FL' );
			
			if ( is.ie5up )
				Element._show( this.columnHeader.header.iframeEl );
		}
		
		if ( this.hasFixedColumns() ) {
			Element._show( this.id + '_FC' );
			
			if ( is.ie5up )
				Element._show( this.rowHeader.header.iframeEl );
		}
		
		if ( this.hasFixedLines() && this.hasFixedColumns() ) {
			Element._show( this.id + '_FIX' );
			
			if ( is.ie5up )
				Element._show( this.fixedHeader.header.iframeEl );
		}
	},
	
	disable : function()
	{
		this.container.disabled = true;
	},
	
	enable : function()
	{
		this.container.disabled = false;
	},
	
	
	getSelected: function()
	{
		return this.getSubmitValue();
	},
	
	resizeTable: function( evt )
	{
		if (this.fixedLines > 0) {
			this.columnHeader.header.style.width 			= this.container.clientWidth + 'px';
			this.columnHeader.header.iframeEl.style.width 	= this.container.clientWidth + 'px';
			self.status = "Resizing to : " + this.columnHeader.header.style.width;
		}
	},
	
	
	scrollRowIntoView: function( element )
	{
		var target 	= $GE( element );

		if (!target)
			return;
			
		var tableScrollTop = 0;
		
		for ( var i=this.fixedLines; i < target.rowIndex; i++ ) {
			tableScrollTop += this.element.rows[i].offsetHeight;
		}
		
		this.container.scrollTop = tableScrollTop;
	},
	
	
	onScrollStart: function( evt )
	{
		var target 	= $GE( evt );
		var table 	= Element.getFirstChildByTagName( target, 'TABLE');
		
		if ( (this.fixedLines == 0 && this.fixedColumns == 0))
			return;
			
		var fixedLine			= $( this.id + "_FL" );
		var fixedColumn			= $( this.id + "_FC" );
		
		var fixedLineTable		= null;
		var fixedColumnTable	= null;
		
		if (this.fixedLines > 0)
			fixedLineTable 		= Element.getFirstChildByTagName( fixedLine, 'TABLE');
	
		if (this.fixedColumns > 0)
			fixedColumnTable 	= Element.getFirstChildByTagName( fixedColumn , 'TABLE');
		
		if (this.currentScrollTop != target.scrollTop) {
			if ( fixedColumnTable )
				fixedColumnTable.style.top = - target.scrollTop + 'px';
		} else {
			if (fixedLineTable)
				fixedLineTable.style.left = - target.scrollLeft + 'px';
		}
		
		this.currentScrollTop 	= target.scrollTop;
		this.currentScrollLeft 	= target.scrollLeft;
	},
	
	onMouseWheel: function( evt )
	{
		if (this.container.disabled) {
			Event.stop(evt);
			return false;
		}
	},
	
	
	update : function( conf )
	{
		if ( typeof conf.url == "undefined" ) {
			return;
		}
		
		if ( typeof conf.handler != "undefined" )
			conf.handler.call(this);
			
		this.empty();
		// Ladeicon einblenden
		this.loadingBar = new Element('div',{
			'class': this.getStyleDefinition('loading-anim')
		});
		
		$(document.body).insert(this.loadingBar);
		
		var left 	= parseInt(this.container.style.left) + (this.container.clientWidth / 2) - (this.loadingBar.getWidth() / 2);
		var top 	= parseInt(this.container.style.top) + (this.container.clientHeight / 2) - (this.loadingBar.getHeight() / 2);
		
		this.loadingBar.setStyle({
			position: 'absolute',
			left: left + "px",
			top: top + "px"
		});
		
		conf.params.sessionid = $F('sessionid');
		
		new Ajax.Request(conf.url, {
			onComplete: this.onComplete.bind(this),
			parameters: conf.params
		});
	},
	
	
	onComplete : function(transport) 
	{	
		var result = transport.responseJSON;
		if ( typeof result.rows != "undefined" )
			rows = result.rows
		else 
			rows = result;
			
		if ( typeof result.msg != "undefined" )
			alert( result.msg );
			
		var idx = this.fixedLines;
		var id = "";
		
		for ( var i=0; i < rows.length; i++ ) {
			var row = rows[i];
			
			var tr = this.element.insertRow(idx);
			tr.id = row.id;
			
			for( var j=0; j < row.cells.length; j++ ) {
				var cell = row.cells[j];
				var td = tr.insertCell(j);
				td.id = cell.id;
				
				if ( typeof cell.img != "undefined" ) {
					td.innerHTML = '<img src="' + cell.img + '">';
				} else {
					td.innerHTML = cell.text;
				}
			}
			
			idx++;
		}
		
		this.render();
		// Ladeicon ausblenden
		this.loadingBar.remove();
		this.element.fire('table:updated', { value: result } );
		
	},
	empty: function() {
		for (var i=this.element.rows.length - 1; i >= this.fixedLines; i-- ) {
			this.element.down().removeChild(this.element.rows[i]);
		}
	}
});

var EasyGUI_TableHeader = Class.create();

 
EasyGUI_TableHeader.prototype =
{
	id: null,
	header: null,
	headerTable: null,
	element: null,
	container: null,
	zIndex: 200,
	fl: 0,
	fc: 0,
	height: 0,
	width: 0,
	
	
	initialize: function( table ) 
	{
		this.id 			= table.id;
		this.element 		= table.element;
		this.container 		= table.container;
		
		this.fl				= table.fixedLines;
		this.fc				= table.fixedColumns;
		
		this.header 		= table.container.cloneNode( true );
		this.table			= table;
		this.headerTable 	= this.header.down();
		
		//this.container.parentNode.appendChild( this.header );
		
		this.headerTable.setStyle( {
			position : 'absolute',
			width : this.container.clientWidth + 'px'
		});
		
		this.setHeight();
		this.setWidth();
		
		this.render();
		
		this.header.setStyle({
			overflow : 'hidden',
			zindex : this.zIndex
		});
	},
	
	
	removeHeaderInputs: function()
	{
		var table = $(this.id + '_FL_TABLE');
		if ( table ) {
			var edits = table.getElementsByTagName('input');
			
			for ( var j=0, jLen = edits.length; j < jLen; ++j ) {
				var el= edits[j];
				el.id = "__" + el.id + "__";
				el.name = "__" + el.id + "__";
				el.style.visibility = 'hidden';
			}
		}
		
		['select','input','textarea'].each( function(name,index) {
			for ( var i=0; i < this.fl; ++i ) {
				$(this.headerTable.rows[i]).select(name).each( function(el) {
					var id = el.id;
					var headerRow = el.parentNode;
					var headerElement = Element.remove(el);
					headerElement.id = "__" + id + "__";
					
					var tableElement = $(id);
					var tableRow = tableElement.parentNode;
					
					tableElement = Element.remove(tableElement);
					tableRow.appendChild(headerElement);
					headerRow.appendChild(tableElement);
					
					headerElement.style.visibility = 'hidden';
				});
			}
		}, this);
		
		for ( var i=0; i < this.fl; ++i ) {
			for ( var j=0, len = this.headerTable.rows[i].cells.length; j < len; ++j ) {
				var cell = this.headerTable.rows[i].cells[j];
				cell.id += '_FL';
			}
		}
	},

	
	setIframe: function() {
		if (is.ie5up) {
			this.header.iframeEl = this.header.parentNode.insertBefore( Util.getIframe(), this.header);
			this.header.iframeEl.id = this.headerIFrameId;
			
			Element.setPosition( this.header.iframeEl, this.header.offsetTop, this.header.offsetLeft );
			
			Element.show( this.header.iframeEl );
			//Element.setStyle( this.header.iframeEl, { 'position': 'absolute', 'z-index': this.zIndex - 1 } );
			
			this.header.iframeEl.style.position = 'absolute';
			this.header.iframeEl.zIndex = this.zIndex - 1;
			Element.setDimension(this.header.iframeEl, this.container.clientWidth, this.height);
		}
	},
	
	
	setWidth: function() {
		for (var i=0; i < this.fl; i++)
			this.width += parseInt(this.element.rows[0].cells[i].offsetWidth);
	},
	
	
	setHeight: function() {
		for (var i=0; i < this.fl; i++)
			this.height += parseInt(this.element.rows[i].offsetHeight);
			
		var tableBorderTop = parseInt( Element.getStyle( this.element, 'border-top-width' ) );
		
		if ( isNaN( tableBorderTop ) )
			tableBorderTop = 0;
			
		this.height += tableBorderTop;
	}
};


var EasyGUI_TableColumnHeader = Class.create();
 
Object.extend( Object.extend( EasyGUI_TableColumnHeader.prototype, EasyGUI_TableHeader.prototype ), 
{
	render: function() 
	{
		this.zIndex		= 300;
		this.header.id 	= this.id + '_FL';
		this.headerTable.id = this.header.id + '_TABLE';
		this.headerIFrameId = this.header.id + '_IFRAME';
		
		var header = $(this.header.id);
		var iframe = $(this.headerIFrameId);
		
		if ( header != null ) {
			header.remove();
		}
		
		if ( iframe != null ) {
			iframe.remove();
		}
		
		this.container.parentNode.appendChild( this.header );
		
		this.setIframe();
		
		Element.setDimension(this.header, this.container.clientWidth, this.height);
		
		this.removeHeaderInputs();
	}
});

var EasyGUI_TableRowHeader = Class.create();

Object.extend( Object.extend( EasyGUI_TableRowHeader.prototype, EasyGUI_TableHeader.prototype ), 
{
	render: function()
	{
		this.header.id 	= this.id + '_FC';
		this.headerTable.id = this.header.id + "_TABLE";
		this.headerIFrameId = this.header.id + '_IFRAME';
		
		var header = $(this.header.id);
		var iframe = $(this.headerIFrameId);
		
		if ( header != null ) {
			header.remove();
		}
		
		if ( iframe != null ) {
			iframe.remove();
		}
		
		this.container.parentNode.appendChild( this.header );
		
		this.setIframe();
		
		Element.setDimension( this.header, this.width, this.container.clientHeight );
		
		this.removeHeaderInputs();
	},

	
	setWidth: function() {
		for (var i=0; i < this.fc; i++)
			this.width += parseInt(this.element.rows[0].cells[i].offsetWidth);
	}
});

var EasyGUI_TableFixedHeader = Class.create();

Object.extend( Object.extend( EasyGUI_TableFixedHeader.prototype, EasyGUI_TableHeader.prototype ), 
{
	render: function()
	{
		this.zIndex 	= 400;	
		this.header.id 	= this.id + '_FIX';
		this.headerTable.id = this.header.id + "_TABLE";
		this.headerIFrameId = this.header.id + '_IFRAME';
		
		var header = $(this.header.id);
		var iframe = $(this.headerIFrameId);
		
		if ( header != null ) {
			header.remove();
		}
		
		if ( iframe != null ) {
			iframe.remove();
		}
		
		this.container.parentNode.appendChild( this.header );
		
		Element.setDimension( this.header, this.width, this.height );
	},
	
	
	setWidth: function() {
		for (var i=0; i < this.fc; i++)
			this.width += parseInt(this.element.rows[0].cells[i].offsetWidth);
	}
});


function onComplete( obj )
{
	
		
	if ( obj.responseText ) 
	{
		var serverResponse = obj.responseText.stripTags();
	} 
	else
	{
		var serverResponse = extractIframeBody( obj ).body.innerHTML;
	}
	
	eval( serverResponse );
}

function extractIframeBody( IFrameObj ) 
{
	if (IFrameObj.contentDocument)
	{
    	return IFrameObj.contentDocument; 
	}
  	else if (IFrameObj.contentWindow)
  	{
    	return IFrameObj.contentWindow.document;
  	}
  	else if (IFrameObj.document)
  	{
    	return IFrameObj.document;
  	}
  	else
  	{
    	return false;
  	}
}

var DEBUGTIME	= false;
var DEBUG 		= false;
var validate 	= true;
var closeWindow = false;
var remoteCall	= false;
var initialized = false;
var IFrameObj; 				// our IFrame object

var GUITIME		= '';

var widgets		= new Array();
var dialog;

var EasyGUI = 
{
  	Version: 'XP',
  	Build: '292',

  	PATH: 		'',
	JS_PATH: 	'',
	CSS_PATH: 	'',
	YUI_PATH:	'',
	YUI_EXT_PATH:'',
	
	DEBUG: 		false,
	DEBUGTIME: 	false,
	
	
	initUI: function()
	{
		if ( EasyGUI.DEBUGTIME ) {
			var timer = new JS_Timer();
			timer.startTimer();
		}
		
		dialog = new Dialog();
		dialog.init();
		
		if ( EasyGUI.DEBUGTIME ) {
			alert( 'Time to build GUI: ' + timer.stopTimer() + "\r\n\r\n" + GUITIME );
		}
	},
	
	
  	setPath: function()
	{
		var allScripts = document.getElementsByTagName('script');
		
		for ( var i=0; i < allScripts.length; i++ )
		{
			if ( allScripts[i].src.match(/easygui\.js(\?.*)?$/) )
			{
				EasyGUI.PATH 		= allScripts[i].src.replace( /\/easygui\.js(\?.*)?$/,'');
				break;
			}
			
		}	
	},
	
	
  	require: function( library )
  	{
  		document.writeln('<script type="text/javascript" src="' + library + '"></script>');
  	},
  	
  	
  	load: function( ) 
  	{
  		if ( typeof( BUILD ) != "undefined" && BUILD ) return;
  		
  		EasyGUI.setPath();
	
  		EasyGUI.require( EasyGUI.PATH + "/core/lib/lib.core.js" );
  		EasyGUI.require( EasyGUI.PATH + "/core/lib/lib.compat.js" );
  		
  		EasyGUI.require( EasyGUI.PATH + "/core/class.browser.js" );
  		EasyGUI.require( EasyGUI.PATH + "/core/class.dialog.js" );
  		
  		EasyGUI.require( EasyGUI.PATH + "/lib/lib.easygui.js" );
  		EasyGUI.require( EasyGUI.PATH + "/lib/lib.element.js" );
  		EasyGUI.require( EasyGUI.PATH + "/lib/lib.event.js" );
  		EasyGUI.require( EasyGUI.PATH + "/lib/lib.form.js" );
  		EasyGUI.require( EasyGUI.PATH + "/lib/lib.util.js" );
  		EasyGUI.require( EasyGUI.PATH + "/lib/lib.sort.js" );
  		EasyGUI.require( EasyGUI.PATH + "/lib/lib.datetime.js" );
  		
		EasyGUI.require( EasyGUI.PATH + "/utils/class.timer.js" );
	
		EasyGUI.require( EasyGUI.PATH + "/validator/class.validator.js" );
		EasyGUI.require( EasyGUI.PATH + "/validator/class.validator.date.js" );
		EasyGUI.require( EasyGUI.PATH + "/validator/class.validator.alphanum.js" );
		EasyGUI.require( EasyGUI.PATH + "/validator/class.validator.email.js" );
		EasyGUI.require( EasyGUI.PATH + "/validator/class.validator.num.js" );
		EasyGUI.require( EasyGUI.PATH + "/validator/class.validator.time.js" );
		
		EasyGUI.require( EasyGUI.PATH + "/win/class.guiwindow.js" );
		EasyGUI.require( EasyGUI.PATH + "/win/class.winregistry.js" );
		
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.widget.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.button.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.checkbox.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.combobox.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.menu.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.treectrl.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.menutree.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.radiobutton.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.tabctrl.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.exttabctrl.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.edit.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/class.text.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/table/class.table.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/table/class.tableheader.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/table/class.fixedheader.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/table/class.columnheader.js" );
		EasyGUI.require( EasyGUI.PATH + "/widgets/table/class.rowheader.js" );
		
		EasyGUI.require( EasyGUI.PATH + "/remote/class.request.js" );
  	}
};

EasyGUI.load();
