/*
 * ProFrom - Professzionális Felhasználói Felületek $ proform.js,v 1.89 2005/12/08 10:09:39 gyuris Exp $
 */

var proform = {
	/**
	 * Működési beállítások tárolása
	 */
	config : {
		// globális beállítások
		repetitionSeparatorNameBefore : '[',   // a mezők többszörözésekor alkalmazott elválasztó előtag a name attribútumon
		repetitionSeparatorNameAfter : ']',    // a mezők többszörözésekor alkalmazott elválasztó utótag a name attribútumon
		repetitionRegExpName : /\[([\d]+)\]$/, // a name attribútumra illeszkedő kifejezés ( az $1 maga a szám)
		repetitionSeparatorIdBefore : ':',     // a mezők többszörözésekor alkalmazott elválasztó előtag az id attribútumon
		repetitionSeparatorIdAfter : '',       // a mezők többszörözésekor alkalmazott elválasztó utótag az id attribútumon
		repetitionRegExpId : /:([\d]+)$/,      // az id attribútumra illeszkedő kifejezés ( az $1 maga a szám)
		idEnding : '_[a-zA-Z0-9_]+',           // nem lézető ID esetén megkeresett elemek végződése (merging!)
		alertOnError : true,                   // rendszerüzenet: nem elküdhető form
		alertOnIEDisabledOption : true,        // IE alatt, ha egy select > option disabled, annak kiválasztásakor van-e hibaüzenet (-> IEDisabledOptionAlert, activeForm.htc )
		overwriteSubmit : null,                // a form elküldésének szabályait figyelmen kivül hagyja - ha nem null - és true vagy hamis értékkel tér vissza az isSendable
		// blokk színtű beállítások
		autoFocus : true,                      // lap indulása és új blokk beszúrásakor
		errorFocus : true,                     // hibás kitöltés után van-e fókusz?
		autoInsertText : true,                 // az insertText automatikus generálása, ha hiányzik
		insertBlockPosition : 'before',        // egy új blokk beszúrásának helye: 'before', 'after'
		showRepetitionPanel : true,            // a többszöröző panel megjelenik-e?
		disableButtonAdd : false,
		disableButtonRemove : false,
		disableButtonMoveup : false,
		disableButtonMovedown : false,
		disableOnInit : false,                 // az onInit esemény ellenárzése kimarad
		onlyFocusOut : false,                  // csak a mező elhagyásakor van esemény
		onlyFireElement : false,               // gyorsítás: csak azt az elemet adjuk át, amely kiváltotta az eseményt (névhivatkozás nincs, összefüggés nincs)
		// CSS osztályok nevei
		proform : 'proform',
		required : 'required',
		warning : 'warning',
		panel : 'panel',
		disabled : 'disabled',
		add : 'add',
		remove : 'remove',
		moveup : 'moveup',
		movedown : 'movedown',
		insert : 'insert',
		insertNonVisible : 'insert-nonvisible',
		// fordítások
		submitError : 'Az adatok rögzítéséhez a megjelölt mezők helyes kitöltése szükséges.',
		IEDisabledOptionAlert : 'A kért elem nem kiválasztható!',
		insertText : 'A mező beillesztéséhez kattintson ide.',
		addTitle : 'Új blokk hozzáadása',
		removeTitle : 'Aktuális blokk törlése',
		moveupTitle : 'Blokk mozgatása felfelé',
		movedownTitle : 'Blokk mozgatása lefelé',
		// debug beállítás
		debug : false                          // az ellenőrzéseket kikapcsolja
	},
	groupConfig : [ 'autoFocus', 'errorFocus', 'autoInsertText', 'insertBlockPosition', 
	                'showRepetitionPanel', 'disableButtonAdd', 'disableButtonRemove', 'disableButtonMoveup', 'disableButtonMovedown',
	                'disableOnInit', 'onlyFocusOut', 'onlyFireElement',
	                'insertText', 'addTitle', 'removeTitle', 'moveupTitle', 'movedownTitle' ],
	/**
	 * Működési beállítások változtatása
	 * @param sConfig String  A beálítás azonosítója, l.: this.config
	 * @param sValue String   
	 */
	setConfig: function( sConfig, sValue ) {
		this.config[sConfig] = sValue;
	},
	translateStrings: function( oConfig ) {
		var i;
		for ( i in oConfig ) {
			proform.setConfig( i, oConfig[i] );
		};
	},
	/**
	 * A form inicializálása, ellenőrzés indítása
	 */
	initForm : function( sId, fOnBeforeSubmit ) {
		proform.form = document.getElementById( sId );
		proform.onBeforeSubmit = ( typeof fOnBeforeSubmit == 'undefined' ) ? null : fOnBeforeSubmit;
		proform.form.onreset = function() { setTimeout( function() { proform.isSendable() }, 100 ) };
		proform.form.onsubmit = function() { 
			var bIsSendable = proform.isSendable();
			if ( bIsSendable == true && proform.onBeforeSubmit != null ) {
				proform.onBeforeSubmit( proform.form );
			};
			return bIsSendable;
		};
	},
	/**
	 * Ellenőrzések tárolása
	 */
	form : null,
	groups : {},
	/**
	 * Csoport - <formfields> hozzáadása ellenőrzésre
	 * @param oConfig Object            beállítási objektum
	 */
	addGroup : function( oConfig, bMerge ) {
		/**
		 * Lézető objektumok megkeresés: normál és merge
		 * Általában minden elemet a saját ID-n kell megadni, úgy hogy az ne tartalmazza az ismétlődési elemeket. Ez alól 
		 * kivétel a választógomb (input type=radio), amit a name értékvel kell megadni. Az Id-k automatikusan meg lesznek
		 * keresve hozzá.
		 * Ha egy olyan azonosító van megadva, amely nem látezik, akkor megpróbálja megkeresni azokat az elemeket amelyek
		 * végződésükkel illeszkednek erre az aznosítóra ( tipikusan ilyenek a több tagból álló mezők: text_a, text_2...)
		 */
		function getExistings( el ) {
			var i, j, rArray = [], sId, sName, oEndingRegExp, oNameRegExp, aMatch, aId, bRepeat, sBase, sSide;
			function checkEnding( els ) {
				for ( j = 0; j < els.length; j++ ) {
					if ( ( aMatch = els[j].id.match( oEndingRegExp ) ) != null ) rArray.push( aMatch[1] );
				};
			};
			oNameRegExp = new RegExp( '^(.+)' + ( proform.config.repetitionSeparatorIdBefore != '' ? '\\' + proform.config.repetitionSeparatorIdBefore : '' ) + '0' + ( proform.config.repetitionSeparatorIdAfter != '' ? '\\' + proform.config.repetitionSeparatorIdAfter : '' ) + '$' );
			aId = el.pfConfig.elements;
			bRepeat = el.pfConfig.repeat;
			for ( i = 0; i < aId.length; i++ ) {
				sBase = bMerge ? aId[i].substring( 0, aId[i].length - 2 ) : aId[i];
				sSide = bMerge ? aId[i].substring( aId[i].length - 1 ) : '';
				// normál sima és normál sima ismétlődő + merge sima és merge sima ismétlődő összeállítása
				sId = bRepeat ? sBase + ( bMerge ? proform.config.repetitionSeparatorIdBefore + sSide + proform.config.repetitionSeparatorIdAfter : '' ) + proform.config.repetitionSeparatorIdBefore + '0' + proform.config.repetitionSeparatorIdAfter :
				                sBase + ( bMerge ? proform.config.repetitionSeparatorIdBefore + sSide + proform.config.repetitionSeparatorIdAfter : '' );
				if ( document.getElementById( sId ) == null || 
				     document.getElementById( sId ).type == 'radio' ) { // bunkó IE
					// input type=radio vizsgálata
					sName = bRepeat ? sBase + ( bMerge ? proform.config.repetitionSeparatorNameBefore + sSide + proform.config.repetitionSeparatorNameAfter : '' ) + proform.config.repetitionSeparatorNameBefore + '0' + proform.config.repetitionSeparatorNameAfter : 
					                  sBase + ( bMerge ? proform.config.repetitionSeparatorNameBefore + sSide + proform.config.repetitionSeparatorNameAfter : '' );
					els = document.getElementsByName( sName ); // XXX azt is le kellene ellnőrizni, hogy az adott blokkon belül van-e...
					for ( j = 0; j < els.length; j++ ) {
						if ( bRepeat ) {
							if ( ( aMatch = els[j].id.match( oNameRegExp ) ) != null ) rArray.push( aMatch[1] );
						} 
						else rArray.push( els[j].id );
					};
					// kiegészítő típusú illeszkedés vizsgálata, egyszerűsítve: '^(' + sBase + proform.config.idEnding + ( bMerge ? proform.config.repetitionSeparatorIdBefore + sSide + proform.config.repetitionSeparatorIdAfter : '' ) + ')' + proform.config.repetitionSeparatorIdBefore + '0' + proform.config.repetitionSeparatorIdAfter + '$' : 
					oEndingRegExp = bRepeat ? 
					                new RegExp( '^(' + sBase + proform.config.idEnding + ( bMerge ? ( proform.config.repetitionSeparatorIdBefore != '' ? '\\' + proform.config.repetitionSeparatorIdBefore : '' ) + sSide + ( proform.config.repetitionSeparatorIdAfter != '' ? '\\' + proform.config.repetitionSeparatorIdAfter : '' ) : '' ) + ')' + ( proform.config.repetitionSeparatorIdBefore != '' ? '\\' + proform.config.repetitionSeparatorIdBefore : '' ) + '0' + ( proform.config.repetitionSeparatorIdAfter != '' ? '\\' + proform.config.repetitionSeparatorIdAfter : '' ) + '$' ) : 
					                new RegExp( '^(' + sBase + proform.config.idEnding + ( bMerge ? ( proform.config.repetitionSeparatorIdBefore != '' ? '\\' + proform.config.repetitionSeparatorIdBefore : '' ) + sSide + ( proform.config.repetitionSeparatorIdAfter != '' ? '\\' + proform.config.repetitionSeparatorIdAfter : '' ) : '' ) + ')' + '$' );
					checkEnding( el.getElementsByTagName('input') );
					checkEnding( el.getElementsByTagName('select') );
					checkEnding( el.getElementsByTagName('textarea') );
				}
				else { // normál sima és normál sima ismétlődő + merge sima és merge sima ismétlődő összeállítása
					rArray.push( aId[i] );
				};
			};
			return rArray;
		};
		function initItem( el ) {
			if ( isSpecified( el, 'title' ) ) {	// alapértelmezett title attribútum eltárolása a warning hibaüzenet után-ra
				el.setAttribute( 'normTitle', el.getAttribute( 'title' ) );
			};
		};
		var el, elInput, j, k, els;
		// alapértelmezett értékek
		if ( typeof oConfig.repeat == 'undefined' ) {
			oConfig.repeat = false;	
		};
		if ( typeof oConfig.repeatMin == 'undefined' ) {
			oConfig.repeatMin = 0; // ha nem ad meg repeatMin-t, de repeat-true, akkor törölni lehet!
		};
		if ( typeof oConfig.repeatMax == 'undefined' ) {
			oConfig.repeatMax = Number.MAX_VALUE;
		};
		if ( typeof oConfig.alter == 'undefined' ) {
			oConfig.alter = null;
		};
		if ( typeof oConfig.config == 'undefined' ) {
			oConfig.config = {};
		};
		if ( typeof oConfig.mode == 'undefined' ) {
			oConfig.mode = 1; // 1 - normál; 2 - merging
		};
		if ( typeof oConfig.processor == 'undefined' ) {
			oConfig.processor = oConfig.checkFunction || function() { return true };
		};
		if ( typeof oConfig.elements == 'undefined' ) {
			oConfig.elements = oConfig.checkElements || [];
		};
		if ( typeof oConfig.validate == 'undefined' ) {
			oConfig.validate = false;
		};
		// csoport csatolás
		if ( ( el = document.getElementById( oConfig.id ) ) == null ) {; // TABLE
			return false;
		};
		el.pfConfig = oConfig;
		el.pfConfig.insertObjAvailable = ( el.pfConfig.repeat && el.pfConfig.repeatMin == 0 && typeof el.pfConfig.insertId != 'undefined' ) ? true : false;
		// repeat == true && repeatMin == undefined || 0 -> repeatText generálás;
		// Ha elfelejti megadni az insertId-t, akkor nem lehet insertText-el kezdeni, de nem okoz hibát, legeneráljuk a 
		// repeatText alapján. Ha megadja a insertId-t ( és a táblázat előtt közvetlenül ott van a XHTML-ben is), akkor attól
		// függ, hogy melyikkel kezdünk, hogy melyiken van az insertNonVisible (table vagy span)
		if ( el.pfConfig.insertObjAvailable ) {
			el.insertObj = document.getElementById( el.pfConfig.insertId );
		};
		// a csoporthoz tartozó mezők incializációja
		if ( el.pfConfig.validate == true ) {
			el.pfConfig.elements = getExistings( el );
		};
		els = {};
		for ( j = 0; j < el.pfConfig.elements.length; j++ ) {
			if ( !el.pfConfig.repeat ) { // egyes elemek inicializálása
				if ( ( elInput = document.getElementById( el.pfConfig.elements[j] ) ) != null  ) {
					initItem( elInput );
					els[el.pfConfig.elements[j]] = true; // eseménykötések megjegyzése
				};
			}
			else { // ismételhető elem
				k = 0;
				while ( ( elInput = document.getElementById( el.pfConfig.elements[j] + proform.config.repetitionSeparatorIdBefore + k + proform.config.repetitionSeparatorIdAfter ) ) != null ) {
					initItem( elInput );
					k++;
				};
				if ( k > 0 ) {
					els[el.pfConfig.elements[j]] = true; // eseménykötések megjegyzése
				};
			};
		};
		el.pfConfig.elements = els;
		// csoport regisztrálása
		proform.groups[el.pfConfig.id] = el;
	},
	/**
	 * Inicializálja a teljes dokumentumban a klónozást és az ellenőrzéseket. Itt kezdődik a futás.
	 */
	init : function() {
		var i, j, k = 0, f, elTable;
		// segédek inidítása
		proform.helper.initTextAreaMaxLength();
		proform.initPlugin();
		if ( document.body.activeForm ) {
			document.body.activeForm.alertOnDisabledOption = proform.config.alertOnIEDisabledOption;
			document.body.activeForm.disabledOptionAlert = proform.config.IEDisabledOptionAlert;
		};
		// csoportok inicializálása
		els = proform.form.getElementsByTagName('fieldset');
		for ( i in proform.groups ) {
			elTable = proform.groups[i];
			// globális config átvétel
			for ( f = 0; f < proform.groupConfig.length; f++ ) {
				if ( typeof elTable.pfConfig.config[proform.groupConfig[f]] == 'undefined' ) {
					elTable.pfConfig.config[proform.groupConfig[f]] = proform.config[proform.groupConfig[f]];
				};					
			};
			// autoFocus megvalósítása, a form első elemére
			if ( elTable.pfConfig.config.autoFocus && k == 0 && elTable.tBodies.length > 0 ) {
				proform.moveFocus( 'firstElement', proform.getBlockElements( elTable.tBodies[0], 0 ).elements );
			};
			k++;
			// KLÓNOZÁS inicializáció
			if ( elTable.pfConfig.repeat ) {
				// klónozás előkészítése
				elTable.cloneBase = ( elTable.tBodies.length > 0 ) ? elTable.tBodies[elTable.tBodies.length - 1].cloneNode( true ) : null;
				// gombok készítése
				if ( elTable.pfConfig.config.showRepetitionPanel ) {
					for ( j = 0; j < elTable.tBodies.length; j++ ) {
						proform.createPanel( elTable.tBodies[j] );
					};
				};
				// ID-k és gombok beállítása
				proform.finish( elTable );
				// beszúrási szöveg inicializáció!
				if ( elTable.pfConfig.repeat && elTable.pfConfig.repeatMin == 0 ) {
					// ha nem volt megadva beszúró szöveg
					if ( !elTable.pfConfig.insertObjAvailable && elTable.pfConfig.config.autoInsertText ) {
						elTable.insertObj = document.createElement( 'span' );
						elTable.insertObj.className = proform.config.insert;
						elTable.insertObj.appendChild( document.createTextNode( elTable.pfConfig.config.insertText ) );
						elTable.parentNode.insertBefore( elTable.insertObj, elTable );
						elTable.pfConfig.insertObjAvailable = true;
					}
					if ( elTable.pfConfig.insertObjAvailable ) {
						elTable.insertObj.onclick = function() { proform.insert( this ); return false };
						// beszúró szöveg vagy az első blokk jelenik meg?
						if ( hasClass( elTable, proform.config.insertNonVisible ) ) {
							while( elTable.tBodies.length != 0 ) {
								elTable.removeChild( elTable.tBodies[0] );
							};
							removeClass( elTable.insertObj, proform.config.insertNonVisible );	
						} 
						else {
							addClass( elTable.insertObj, proform.config.insertNonVisible );	
						};
					};
				};
			};
			// kötelező mezők inicializálása - cloneBase után IE miatt!
			proform.addEvent( elTable.getElementsByTagName('input'),    elTable.pfConfig );
			proform.addEvent( elTable.getElementsByTagName('textarea'), elTable.pfConfig );
			proform.addEvent( elTable.getElementsByTagName('select'),   elTable.pfConfig );
			// ellenörzés első futás
			if ( !elTable.pfConfig.config.disableOnInit ) {
				proform.process( elTable, 'onInit' );
			};
		};
	},
	insert : function( elP ) {
		var elTable = getNextElement( elP );
		removeClass( elTable, proform.config.insertNonVisible );
		addClass( elP, proform.config.insertNonVisible );
		if ( elTable.tBodies.length == 0 ) {
			proform.addRepetitionBlock( elTable );
		}
		else {
			if ( elTable.pfConfig.alter != null && typeof elTable.pfConfig.alter.onAddRepetitionBlock != 'undefined'  ) {
				elTable.pfConfig.alter.onAddRepetitionBlock( elTable, elTable.tBodies[0], proform.getBlockElements( elTable.tBodies[0], 0 ).elements );
			};
			proform.process( elTable, 'onAddRepetitionBlock' );
		};
	},
	/**
	 * Duplikálás
	 * @param elReference elDOMElement    Az a gomb, amelynek blokkjához viszonyítva kell duplikálni. A gombot generáljuk a 
	 *                                    createPanel-ban.
	 */
	addRepetitionBlock : function( elReference ) {
		var elTable, elTBody = null, elNewTBody, elsInput, i, oEls;
		switch( elReference.nodeName.toLowerCase() ) {
			case 'table' : // insert -> nincs egyetlen elem sem (külső vagy belső)
				elTable = elReference;
				break;
			case 'tbody' : // külső meghívás
				elTBody = elReference;
				elTable = elTBody.parentNode;
				break;
			case 'span' : // normál belső hívás
				elTBody = elReference.parentNode.parentNode.parentNode.parentNode;
				elTable = elTBody.parentNode;
				break;
			default : 
				return false;
		};
		// leklónozzuk a táblázat utolsó TBODY-ját
		if ( elTable.cloneBase == null ) {
			return false;
		};
		elNewTBody = elTable.cloneBase.cloneNode( true );
		// ellenőrzés inicializálása, amelyiknél szükséges
		proform.addEvent( elNewTBody.getElementsByTagName('input'),    elTable.pfConfig );
		proform.addEvent( elNewTBody.getElementsByTagName('textarea'), elTable.pfConfig );
		proform.addEvent( elNewTBody.getElementsByTagName('select'),   elTable.pfConfig );
		// INPUT, TEXTAREA elemek üresítése, OPTION mezők selected értékének ürítése
		elsInput = elNewTBody.getElementsByTagName('input');
		for ( i = 0; i < elsInput.length; i++ ) {
			if ( elsInput[i].type == 'text') {
				elsInput[i].value = '';
			};
			if ( elsInput[i].type == 'checkbox' || elsInput[i].type == 'radio' ) {
				elsInput[i].checked = false;
			};
		};
		elsInput = elNewTBody.getElementsByTagName('textarea');
		for ( i = 0; i < elsInput.length; i++ ) {
			elsInput[i].value = '';
		};
		elsInput = elNewTBody.getElementsByTagName('select');
		for ( i = 0; i < elsInput.length; i++ ) {
			elsInput[i].selectedIndex = elsInput[i].type == 'select-one' ? 0 : -1;
		};
		// elhelyezés
		if ( elTBody != null ) {
			if ( elTable.pfConfig.config.insertBlockPosition == 'after' || ( is.gecko && is.geckoRv < 1.4 ) ) { // mozilla1.0 bug: csak after lehet mozilla1.0-ban
				elTable.insertBefore( elNewTBody, elTBody.nextSibling );
			}
			else if ( elTable.pfConfig.config.insertBlockPosition == 'before' ) {
				elTable.insertBefore( elNewTBody, elTBody );
			};
		}
		else {
			elTable.appendChild( elNewTBody );
			if ( is.gecko && is.geckoRv < 1.4 ) { // mozilla1.0 bug: különben nem jelneik meg a képernyőn...
				elTable.style.display = 'table';
			};
		};
		// a kezelőfelülete legyártása
		if ( elTable.pfConfig.config.showRepetitionPanel ) {
			proform.createPanel( elNewTBody );
		};
		// rendbetétel: újraszámozás és '-' gomb (kötelező blokkcsoport vizsgálata)
		proform.finish( elTable );
		// autoFocus a beszúrt blokk első elemére
		oEls = proform.getBlockElements( elNewTBody ).elements;
		if ( elTable.pfConfig.config.autoFocus ) {
			proform.moveFocus( 'firstElement', oEls );
		};
		// módosító
		if ( elTable.pfConfig.alter != null && typeof elTable.pfConfig.alter.onAddRepetitionBlock != 'undefined'  ) {
			elTable.pfConfig.alter.onAddRepetitionBlock( elTable, elNewTBody, oEls );
		};
		//elTBody.elsInput = elsInput;
		// pluginek újrainicializálása
		proform.resetPlugin();
		// ellenőrzés
		proform.process( elTable, 'onAddRepetitionBlock' );
		proform.helper.initTextAreaMaxLength();
	},
	/**
	 * Törlés
	 * @param elReference elDomElement    Az a gomb, amelynnek a blokk-ját el kell távolítani.  A gombot generáljuk a 
	 *                                    createPanel-ban.
	 */
	removeRepetitionBlock : function( elReference ) {
		var elTBody, elTable, oEls;
		switch( elReference.nodeName.toLowerCase() ) {
			case 'tbody' :
				elTBody = elReference;
				elTable = elTBody.parentNode;
				break;
			case 'span' :
				elTBody = elReference.parentNode.parentNode.parentNode.parentNode;
				elTable = elTBody.parentNode;
				break;
			default : 
				return false;
		};
		// törlés előtt lekérjük az elemeket
		oEls = proform.getBlockElements( elTBody );
		elTable.removeChild( elTBody );
		// rendbetétel: újraszámozás és '-' gomb (kötelező blokkcsoport vizsgálata)
		proform.finish( elTable );
		// módosító
		if ( elTable.pfConfig.alter != null && typeof elTable.pfConfig.alter.onRemoveRepetitionBlock != 'undefined'  ) {
			elTable.pfConfig.alter.onRemoveRepetitionBlock( elTable, elTBody, oEls.elements );
		};
		// ellenőrzés
		proform.process( elTable, 'onRemoveRepetitionBlock' );
		// insert Object beszúrása
		if ( elTable.tBodies.length == 0 && elTable.pfConfig.insertObjAvailable ) { // vagyis repeatMin == 0 és repeat == true
			removeClass( elTable.insertObj, proform.config.insertNonVisible );
		};
	},
	/**
	 * Mozgatás fel és le
	 * @param elReference elDomElement    Az a gomb, amelynnek a blokk-ját el kell távolítani.  A gombot generáljuk a 
	 *                                    createPanel-ban.
	 * @param nDirection Number           Az irány jelzése ( 1 vagy -1), külső meghívása nincs.
	 */
	moveRepetitionBlock : function ( elReference, nDirection ) {
		var elTBody, elSibling;
		switch( elReference.nodeName.toLowerCase() ) {
			case 'tbody' :
				elTBody = elReference;
				break;
			case 'span' :
				elTBody = elReference.parentNode.parentNode.parentNode.parentNode;
				break;
			default : 
				return false;
		};
		if ( nDirection == -1 ) {
			if ( ( elSibling = getPreviousElement( elTBody ) ).nodeName.toLowerCase() == 'tbody' ) {
				if ( is.gecko && is.geckoRv < 1.4 && elSibling == elSibling.parentNode.tBodies[0] ) { // mozilla1.0 bug, első helyre nem lehet beszúrni
					if ( elSibling.parentNode.tBodies.length == 2 ) {
						elSibling.parentNode.appendChild(elSibling);
					}
					else {
						elTBody.parentNode.insertBefore( elSibling, getNextElement( elTBody ) )
					};
				}
				else {
					elTBody.parentNode.insertBefore( elTBody, elSibling );
				};
			};
		}
		else {
			if ( ( elSibling = getNextElement( elTBody ) ) != null ) {
				if ( is.gecko && is.geckoRv < 1.4 && elTBody == elTBody.parentNode.tBodies[0] ) { // mozilla1.0 bug, első helyre nem lehet beszúrni
					if ( elSibling.parentNode.tBodies.length == 2 ) {
						elTBody.parentNode.appendChild(elTBody);
					}
					else {
						elTBody.parentNode.insertBefore( elTBody, getNextElement( elSibling ) )
					};
				}
				else {
					elTBody.parentNode.insertBefore( elSibling,  elTBody );
				};
			};
		};
		proform.finish( elTBody.parentNode );
		// módosító
		if ( elTBody.parentNode.pfConfig.alter != null && typeof elTBody.parentNode.pfConfig.alter.onMoveRepetitionBlock != 'undefined'  ) {
			elTBody.parentNode.pfConfig.alter.onMoveRepetitionBlock( elTBody.parentNode, elTBody, proform.getBlockElements( elTBody ).elements );
		};
		proform.process( elTBody.parentNode, 'onMoveRepetitionBlock' );
	},
	/**
	 * Az id-k és name-k beállítása, +-▲▼  gombok beállítása, repeatMin és repeatMax alapján
	 * A hozzáadások és törlések során kialakult sorrendben beszámozza az elemeket egy táblázatban (beállítható config a
	 * formája). Meghívódik törléskor és duplikáláskor is.
	 * @param elTable HTMLTableElement  A táblázat, amelynek mezőit rakjuk rendbe.
	 */
	finish : function( elTable ) {
		var i, elsInput, aCollected = [], els, bDisable = false, sFor;
		function changeIds( els, nId, bLabel ) {
			var i;
			for ( i = 0; i < els.length; i++ ) {
				if ( !bLabel ) {
					// input type=radio name és id különbözik!
					if ( els[i].id.indexOf( proform.config.repetitionSeparatorIdBefore ) > -1 ) {
						els[i].name = els[i].name.replace( proform.config.repetitionRegExpName, proform.config.repetitionSeparatorNameBefore + nId + proform.config.repetitionSeparatorNameAfter );
						els[i].id = els[i].id.replace( proform.config.repetitionRegExpId, proform.config.repetitionSeparatorIdBefore + nId + proform.config.repetitionSeparatorIdAfter );
					};
				}
				else {
					sFor = ( is.ie ) ? 'htmlFor' : 'for'; // stupid IE, nagyon stupid : isSpecified esetén 'for' attribútum, getAttribute pedig 'htmlFor'
					if ( isSpecified( els[i], 'for' ) && els[i].getAttribute(sFor).indexOf( proform.config.repetitionSeparatorIdBefore ) > -1 ) {
						els[i].setAttribute( sFor, els[i].getAttribute(sFor).replace( proform.config.repetitionRegExpId, proform.config.repetitionSeparatorIdBefore + nId + proform.config.repetitionSeparatorIdAfter ) );
					};
				};
			};
		};
		if ( !elTable.pfConfig.config.showRepetitionPanel ) {
			return true;
		};
		for ( i = 0; i < elTable.tBodies.length; i++ ) {
			// egy táblázatban levő űrlapelemeket növekvő sorrendben újraszámozzuk (táblázat = csoport)
			changeIds( elTable.tBodies[i].getElementsByTagName('input'), i, false );
			changeIds( elTable.tBodies[i].getElementsByTagName('textarea'), i, false );
			changeIds( elTable.tBodies[i].getElementsByTagName('select'), i, false );
			changeIds( elTable.tBodies[i].getElementsByTagName('label'), i, true );
			// minden +-▲▼ gomb feloldása
			if ( !elTable.pfConfig.config.disableButtonAdd ) { 
				removeClass( elTable.tBodies[i].panelButtons.add, proform.config.disabled );
			};
			if ( !elTable.pfConfig.config.disableButtonRemove ) {
				removeClass( elTable.tBodies[i].panelButtons.remove, proform.config.disabled );
			};
			if ( !elTable.pfConfig.config.disableButtonMoveup ) {
				removeClass( elTable.tBodies[i].panelButtons.moveup, proform.config.disabled );
			};
			if ( !elTable.pfConfig.config.disableButtonMovedown ) {
				removeClass( elTable.tBodies[i].panelButtons.movedown, proform.config.disabled );
			};
			// +- tiltás: repeatMin és repeatMax szerint
			if ( elTable.pfConfig.repeatMin == elTable.tBodies.length ) {
				addClass( elTable.tBodies[i].panelButtons.remove, proform.config.disabled );
			};
			if ( elTable.pfConfig.repeatMax == elTable.tBodies.length ) {
				addClass( elTable.tBodies[i].panelButtons.add, proform.config.disabled );
			};
		};
		// ▲▼ tiltás: első és utoló blokkban
		if ( elTable.tBodies.length > 0 ) {
			addClass( elTable.tBodies[0].panelButtons.moveup, proform.config.disabled );
			addClass( elTable.tBodies[elTable.tBodies.length - 1].panelButtons.movedown, proform.config.disabled );
		};
	},
	/**
	 * A kezelő gombok legyártása
	 */
	createPanel : function( elTBody ) {
		var elPanel, panelButtons;
		function createButton( sClass, sTitle, fClick ) {
			var elButton;
			elButton = document.createElement('span');
			elButton.className = sClass + ' ' + proform.config.disabled;
			elButton.setAttribute( 'type', 'proformpanelbutton' );
			elButton.setAttribute( 'title', sTitle );
			elButton.setAttribute( 'onclick', fClick );
			return elButton;
		};
		if ( typeof proform.panelBase == 'undefined' ) { // teljesítmény miatt ezt fogjuk csak másolni
			elPanel = document.createElement('div');
			elPanel.className = proform.config.panel;
			elPanel.appendChild( createButton( proform.config.movedown, elTBody.parentNode.pfConfig.config.movedownTitle, 'if ( !hasClass( this, proform.config.disabled ) ) { proform.moveRepetitionBlock(this, 1) }' ) );
			elPanel.appendChild( createButton( proform.config.moveup,   elTBody.parentNode.pfConfig.config.moveupTitle,   'if ( !hasClass( this, proform.config.disabled ) ) { proform.moveRepetitionBlock(this, -1) }' ) );
			elPanel.appendChild( createButton( proform.config.remove,   elTBody.parentNode.pfConfig.config.removeTitle,   'if ( !hasClass( this, proform.config.disabled ) ) { proform.removeRepetitionBlock(this) }' ) );
			elPanel.appendChild( createButton( proform.config.add,      elTBody.parentNode.pfConfig.config.addTitle,      'if ( !hasClass( this, proform.config.disabled ) ) { proform.addRepetitionBlock(this) }' ) );
			proform.panelBase = elPanel;
		};
		if ( is.ie ) { // teljesítménykülönbség miatt más módszerrel
			elTBody.rows[0].cells[0].innerHTML += proform.panelBase.outerHTML;
			elTBody.panelButtons = elTBody.rows[0].cells[0].lastChild;
		}
		else {
			elTBody.panelButtons = proform.panelBase.cloneNode( true );
			elTBody.rows[0].cells[0].appendChild( elTBody.panelButtons );
		};
		elTBody.panelButtons.movedown = elTBody.panelButtons.childNodes[0];
		elTBody.panelButtons.moveup   = elTBody.panelButtons.childNodes[1];
		elTBody.panelButtons.remove   = elTBody.panelButtons.childNodes[2];
		elTBody.panelButtons.add      = elTBody.panelButtons.childNodes[3];
		proform.helper.activeForm.update( elTBody );
	},
	/**
	 * Hozzáadja a szükséges formelemekhez az ellenőrzés kérését.
	 * @param elsInput namedNodeMap  Az elemek, amelyekre esetleg inicializálni kell;
	 */
	addEvent : function( elsInput, oPfConfig ) {
		var j, sId = 'undefined', rE;
		for ( j = 0; j < elsInput.length; j++ ) {
			if ( !oPfConfig.repeat ) {
				sId = elsInput[j].id;
			}
			else if ( ( rE = elsInput[j].id.match( proform.config.repetitionRegExpId ) ) != null ) {
			 	sId = elsInput[j].id.substring( 0, rE.index );
			};
			if ( oPfConfig.elements[sId] ) {
				if ( elsInput[j].nodeName.toLowerCase() == 'input' && ( elsInput[j].type == 'radio' || elsInput[j].type == 'checkbox' ) ) {
					addEvent( elsInput[j], 'change', proform.onModify ); 
					addEvent( elsInput[j], 'click', proform.onModify ); 
				}
				else if ( elsInput[j].nodeName.toLowerCase() == 'select' ) {
					addEvent( elsInput[j], 'change', proform.onModify ); 
				}
				else { // input type=text, textarea
					if ( !oPfConfig.config.onlyFocusOut ) {
						addEvent( elsInput[j], 'keyup', proform.onModify );
					};
					addEvent( elsInput[j], 'blur', proform.onModify ); // a proform és a datepicker együttműködés miatt van erre szükség
				};
			};
		};
	},
	/**
	 * Egy olyan mező hívja meg, amelynek ellenőrzését beállították az inicializációs előtt
	 */
	onModify : function( e, el ) {
		function getRoot( el ) {
			if ( el.nodeName.toLowerCase() == 'tbody' ) {
				return el;
			};
			return getRoot( el.parentNode );
		};
		if ( is.ie ) {
			e = window.event;
		};
		if ( e == null ) { // datepicker onUpdate elkapása
			e = { type : '' };
		};
		if ( !el ) {
			el = this;
		};
		proform.process( getRoot( el ), ( e.type == 'blur' || e.type == 'change' ) ? 'onFocusOut' : 'onModify', el ); // TABLE, input mező
	},
	getBlockElements : function( elTBody, elFire, j ) {
		var oElements, i, el, sFireId = null;
		elTable = elTBody.parentNode;
		if ( typeof j == 'undefined' ) {
			for ( j = 0; j < elTable.tBodies.length; j++ ) {
				if ( elTable.tBodies[j] == elTBody ) {
					break;
				};
			};
		};
		oElements = {};
		for ( i in elTBody.parentNode.pfConfig.elements ) {
			el = elTBody.parentNode.pfConfig.repeat ? document.getElementById( i + proform.config.repetitionSeparatorIdBefore + j + proform.config.repetitionSeparatorIdAfter ) : document.getElementById( i );
			if ( typeof elFire != 'undefined' && el == elFire ) {
				sFireId = i;
			};
			oElements[ elTBody.parentNode.pfConfig.mode == 1 ? i : i.match( proform.merging.config.sideRegExpStart )[1] ] = el;
		};
		return  { elements : oElements, fireId : sFireId };
	},
	/**
	 * Ellenőrzéseket kéri le.
	 * @param el HTMLTableElement  Az a táblázat, amelyben ellenőrzünk
	 */
	process : function( elT, sCommand, elFire ) {
		var i, bReturn = true;
		function processElement( elTBody, elFire ) {
			var	sFireId, oElements = {};
			sFireId = elTBody.parentNode.pfConfig.repeat ? elFire.id.substring( 0, elFire.id.lastIndexOf( proform.config.repetitionSeparatorIdBefore ) ) : elFire.id;
			oElements[elTBody.parentNode.pfConfig.mode == 1 ? i : i.match( proform.merging.config.sideRegExpStart )[1]] = elFire;
			return elTBody.parentNode.pfConfig.processor( oElements, sCommand, sFireId );
		};
		function processBlock( elTBody, i ) {
			var oBlockElements = proform.getBlockElements( elTBody, elFire, i );
			return elTBody.parentNode.pfConfig.processor( oBlockElements.elements, sCommand, oBlockElements.fireId );
		};
		if ( elT.nodeName.toLowerCase() == 'tbody' ) { // csak egy TBODY-ra vizsgálunk
			if ( elFire && elT.parentNode.pfConfig.config.onlyFireElement ) {
				return processElement( elT, elFire );
			};
			return processBlock( elT );
		}
		else { // vagy egy egész táblázatra - ilyenkor nincs elFire...
			if ( elT.pfConfig.repeatMin == 0 && elT.tBodies.length == 0 ) {
				return true;
			};
			for ( i = 0; i < elT.tBodies.length; i++ ) {
				if ( processBlock( elT.tBodies[i], i ) == false ) {
					bReturn = false;
				};
			};
			return bReturn;
		};
	},
	/**
	 * Egy űrlap elküldhető-e, összesített csoport ellenőrzés
	 */
	isSendable : function() {
		var i, elTable;
		if ( proform.config.overwriteSubmit != null ) {
			return proform.config.overwriteSubmit;
		};
		for ( i in proform.groups ) { // ha bármelyik csoport nem küldhető, akkor az egész form sem küldhető
			elTable = proform.groups[i];
			if ( !proform.process( elTable, 'onIsSendable' ) ) {
				if ( proform.config.alertOnError ) {
					alert( proform.config.submitError );
				};
				if ( elTable.pfConfig.config.errorFocus ) {
					proform.moveFocus( 'firstError', proform.form );
				};
				return false;
			};
		};
		return true;
	},
	/**
	 * autoFocus megvalótítása
	 */
	moveFocus : function( sCommand, el ) {
		var i;
		switch ( sCommand ) {
			case 'firstElement' :
				for ( i in el ) {
					if ( el[i].type != 'hidden' && el[i].disabled != true && el[i].readOnly != true  ) {
						try {
							el[i].focus();
						} catch( ex ) {};
						break;
					};
				};
				break;
			case 'firstError' : // el -> form
				for ( i = 0; i < el.elements.length; i++ ) {
					if ( el.elements[i].nodeName.toLowerCase() == 'input' && ( el.elements[i].type == 'checkbox' || el.elements[i].type == 'radio' ) ) {
						if ( hasClass( proform.helper.getLabel( el.elements[i], true ), proform.config.required ) ) {
							el.elements[i].focus();
							break;
						};
					}
					else if ( hasClass( el.elements[i], proform.config.required ) || hasClass( el.elements[i], proform.config.warning ) ) {
						el.elements[i].focus();
						break;
					};
				};
				break;
		};
	},
	/**
	 * Kisegítők
	 */
	helper : {},
	plugin : {},
	initPlugin : function() {
		var i;
		for ( i in proform.plugin ) {
			proform.plugin[i].init();
		};
	},
	resetPlugin : function() {
		if ( proform.plugin.datepicker ) {
			proform.plugin.datepicker.start();
		};
	}
};
/**
 * Egyszerű feltételvizsgálatok
 */
proform.condition = {
	addFormat : function( sName, oRe, sFormat ) {
		var bReturn = ( typeof proform.condition.format[sName] == 'undefined' ) ? false : true;
		proform.condition.format[sName] = oRe;
		proform.plugin.datepicker.config.formatString[sName] = sFormat;
		return bReturn;
	},
	/* a dátumok date-[xy] fomátumúak */
	supportedDateFormats : /(?:^| )((datetime|local-datetime|date|month|week|time)(-[a-z]{2})?)(?:$| )/,
	/**
	 * datetime       : 1995-09-31T23:59:59.99Z  1995-09-31T23:59:59.99+12:00
	 * datetime-hu    : 2002.12.31. 23:59:59
	 * datetime-de    : 31.12.2002 23:59:59
	 * datetime-en    : 32-12-2002 23:59:59
	 * local-datetime :
	 * date           : 1995-12-31
	 * date-hu        : 1995.12.31. 
	 * date-de        : 31.12.1995
	 * date-en        : 31/12/1995
	 * month          : 1995-12
	 * month-hu       : 1995.12.
	 * month-de       : 12.1995
	 * month-en       : 12/1995
	 * week           : 1995-W52
	 * week-hu        : 1995 52. hét
	 * week-de        : 52. Woche 1995
	 * week-en        : 1995 52. week
	 * time           : 23:59:00.0 vagy 00:00:00.0000
	 * time-hu        : 23:59:00
	 * time-de        : 23:59:00
	 * time-en        : 23:59:00 (britt)
	 * number         : -12.1234567890
	 * phone          : +381 345-12-56(234)
	 */          
	format : {
		'datetime'       : /^\d{4}[\-]\d{2}[\-]\d{2}T\d{2}:\d{2}:\d{2}.\d{2}(Z|(\+|[\-])\d{2}:\d{2})$/,
		'datetime-hu'    : /^[\ ]*(\d{2,4})([\.\\\/]|[\.\\\/] |[ -])(\d{1,2})([\.\\\/]|[\.\\\/] |[ -])(\d{1,2})[\.]? (\d{1,2})[:\-\. ](\d{1,2})([:\-\. ](\d{1,2}))?$/,
		'datetime-de'    : /^[\ ]*(\d{1,2})([\.\\\/]|[\.\\\/] |[ -])(\d{1,2})([\.\\\/]|[\.\\\/] |[ -])(\d{2,4})[\.]? (\d{1,2})[:\-\. ](\d{1,2})([:\-\. ](\d{1,2}))?$/,
		'datetime-en'    : /^[\ ]*(\d{1,2})([\.\\\/]|[\.\\\/] |[ -])(\d{1,2})([\.\\\/]|[\.\\\/] |[ -])(\d{2,4})[\.]? (\d{1,2})[:\-\. ](\d{1,2})([:\-\. ](\d{1,2}))?$/,
		'local-datetime' : /^[1-2]{1}\d{3}-[0-1]{1}[0-9]{1}-[0-3]{1}[0-9]{1}T[0-2]{1}[0-9]{1}:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}.[0-9]{2}(Z|(\+|\-)[0-2]{1}[0-9]{1}:[0-5]{1}[0-9]{1})?$/,
		'date'           : /^[1-2]{1}\d{3}-[0-1]{1}[0-9]{1}-[0-3]{1}[0-9]{1}$/,
		'date-hu'        : /^[1-2]{1}\d{3}([\.\\\/]|[\.\\\/] |[ -])[0-1]{1}[0-9]{1}([\.\\\/]|[\.\\\/] |[ -])[0-3]{1}[0-9]{1}[\.]?$/,
		'date-de'        : /^[0-3]{1}[0-9]{1}([\.\\\/]|[\.\\\/] |[ -])[0-1]{1}[0-9]{1}([\.\\\/]|[\.\\\/] |[ -])[1-2]{1}\d{3}[\.]?$/,
		'date-en'        : /^[0-3]{1}[0-9]{1}([\.\\\/]|[\.\\\/] |[ -])[0-1]{1}[0-9]{1}([\.\\\/]|[\.\\\/] |[ -])[1-2]{1}\d{3}[\.]?$/,
		'month'          : /^[1-2]{1}\d{3}-[0-1]{1}[0-9]{1}$/,
		'month-hu'       : /^[1-2]{1}\d{3}([\.\\\/]|[\.\\\/] |[ -])[0-1]{1}[0-9]{1}[\.]?$/,
		'month-de'       : /^[0-1]{1}[0-9]{1}([\.\\\/]|[\.\\\/] |[ -])[1-2]{1}\d{3}[\. ]?$/,
		'month-en'       : /^[0-1]{1}[0-9]{1}([\.\\\/]|[\.\\\/] |[ -])[1-2]{1}\d{3}[\. ]?$/,
		'week'           : /^[1-2]{1}\d{3}-W[0-5]{1}[0-9]{1}$/,
		'week-hu'        : /^[1-2]{1}\d{3}([\.\\\/]|[\.\\\/] |[ -])[0-5]{1}[0-9]{1}[\. ]? hét$/,
		'week-de'        : /^[0-5]{1}[0-9]{1}[\.]? Woche [1-2]{1}\d{3}[\. ]?$/,
		'week-en'        : /^[1-2]{1}\d{3}([\.\\\/]|[\.\\\/] |[ -])[0-5]{1}[0-9]{1}[\. ]? week$/,
		'time'           : /^[0-2]{1}[0-9]{1}:[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}.[0-9]+$/,
		'time-hu'        : /^[0-2]{1}[0-9]{1}[:\-\. ][0-5]{1}[0-9]{1}([:\-\. ][0-5]{1}[0-9]{1})?$/, 
		'time-de'        : /^[0-2]{1}[0-9]{1}[:\-\. ][0-5]{1}[0-9]{1}([:\-\. ][0-5]{1}[0-9]{1})?$/, 
		'time-en'        : /^[0-2]{1}[0-9]{1}[:\-\. ][0-5]{1}[0-9]{1}([:\-\. ][0-5]{1}[0-9]{1})?$/, 
		'number'         : /^(-)?[\d]+(\.[\d]+)?$/,
		'phone'          : /^[a-zA-Z0-9\ \-\+\/\#\*\(\)]{4,40}$/
	},
	/**
	 * A feltételek összesített kiértékelés : nem lehet egy false sem
	 */
	totalize : function( aCondition ) {
		return ( aCondition.toString().indexOf('false') > -1 ) ? false : true;
	},
	/**
	 * Legegyszerűbb, egy feltétel kap, ha a feltétel igaz, akkor a kötelező 
	 * mező kijelzést illeszti a megadott elemre.
	 * @param aEl Array           Az elemek, melyre 'kötelező'-t kell kijelezni
	 * @param bCondition Boolean  A megkapott feltétel kiértékelése
	 * @return Boolean            A bCondition fordítottját adja vissza.
	 */
	required : function ( bCondition, aEl ) {
		/**
		 * vagy az elemet, vagy ha szükséges a labeljét adja vissza
		 */
		function getRequiredElement( el ) {
			if ( is.saf ) {
				return proform.helper.getLabel( el, true );
			};
			if ( el.tagName.toLowerCase() == 'input' && ( el.type == 'checkbox' || el.type == 'radio' ) ) {
				return proform.helper.getLabel( el, true );
			};
			if ( is.cm && ( el.tagName.toLowerCase() == 'select' ) ) {
				return proform.helper.getLabel( el, true );
			};
			return el;
		};
		var i;
		if ( proform.config.debug ) {
			return true;
		};
		if ( bCondition ) {
			for ( i = 0; i < aEl.length; i++ ) {
				addClass( getRequiredElement( aEl[i] ), proform.config.required );
			};
		}
		else {
			for ( i = 0; i < aEl.length; i++ ) {
				removeClass( getRequiredElement( aEl[i] ), proform.config.required );
			};
		};
		return !bCondition;
	},
	/**
	 * Egy feltétel kap, ha a feltétel igaz, akkor a rosszul kitöltött 
	 * mező kijelzést illeszti a megadott elemre.
	 * @param aEl Array           Az elemek, melyre 'rosszul kitöltött'-et kell kijelezni
	 * @param bCondition Boolean  A megkapott feltétel kiértékelése
	 * @return Boolean            A bCondition fordítottját adja vissza.
	 */
	warning : function ( bCondition, aEl, aErrorMessage ) {
		if ( proform.config.debug ) {
			return true;
		};
		if ( bCondition ) {
			for ( i = 0; i < aEl.length; i++ ) {
				addClass( aEl[i], proform.config.warning );
				aEl[i].setAttribute( 'title', aErrorMessage[i] );
			};
		}
		else {
			for ( i = 0; i < aEl.length; i++ ) {
				removeClass( aEl[i], proform.config.warning );
				if ( isSpecified( aEl[i], 'normTitle' ) ) {
					aEl[i].setAttribute( 'title', aEl[i].getAttribute( 'normTitle' ) );
				}
				else {
					aEl[i].removeAttribute( 'title' );
				};
			};
		};
		return !bCondition;
	},
	checkFormat : function( sType ) {
		var i, aIP, sAtom, sWord, aDom, aMatch;
		if ( proform.config.debug ) {
			return true;
		};
		switch ( sType ) {
			case 'number' :
				return proform.condition.format.number.test( arguments[1] );
				break;
			case 'range' : // -123, -156, 346
				if ( proform.condition.checkFormat( 'number', arguments[1] ) ) {
					if ( arguments[1] >= arguments[2] && arguments[1] <= arguments[3] ) {
						return true;
					};
				};
				return false;
				break;
			case 'email' : // gellért@nexúm.hu  root@127.0.0.1
				sAtom = '\[^\\s\\(\\)<>@,;:\\\\\\\"\\.\\[\\]\]+';
				sWord = '(' + sAtom + '|(\"[^\"]*\"))';
				// alapvető megfelelés
				aMatch = arguments[1].match( /^(.+)@(.+)$/ );
				if ( aMatch == null ) {
					return false;
				};
				// user megfelel-e?
				if ( aMatch[1].match( new RegExp("^" + sWord + "(\\." + sWord + ")*$" ) ) == null ){
					return false;
				};
				// a domain ip?
				if ( proform.condition.checkFormat( 'ip', aMatch[2] ) ) {
					return true;
				}
				// a domain megfelel?
				if ( aMatch[2].match( new RegExp("^" + sAtom + "(\\." + sAtom +")*$") ) == null ) {
					return false;
				};
				aDom = aMatch[2].match( new RegExp( sAtom, "g" ) );
				if ( aDom[ aDom.length-1 ].length < 2 || aDom[ aDom.length-1 ].length > 3 ){
					return false;
				};
				if ( aDom.length < 2 ) {
					return false;
				};
				return true;
				break;
			case 'phone' :
				return proform.condition.format.phone.test( arguments[1] );
				break;
			case 'ip' : // 127.0.0.1
				if ( /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.test( arguments[1] ) ) {
					aIP = arguments[1].split( "." );
					for ( i = 0; i < 4; i++ ) {
						if ( aIP[i] > 255 ) {
							return false;
						};
					};	
					return true;
				};
				return false;
				break;
			default:
				// hibás kérés
				if ( typeof proform.condition.format[sType] == 'undefined' ) { 
					return false;
				};
				// dátumok
				aMatch = arguments[2].match( proform.condition.supportedDateFormats );
				if ( ( typeof proform.condition.format[aMatch[1]] == 'undefined' ) || ( sType != aMatch[2] ) ) { 
					return false; // nincs telepítve ilyen nyelvi dátumformátum, vagy nem felel-meg a kért nyelvi formátumnak
				};
				return proform.condition.format[aMatch[1]].test( arguments[1] ); // nyelvi formátum egyezésének visszaadása
		};
	}	
};
/**
 * az activeForm kiegészítése
 */
proform.helper.activeForm = {
	disableElement : function( bValue, el ) {
		// fontos a fordított sorrend, mert a disabled attribútum megállít minden propertychange eseményt!
		var elLabel;
		if ( bValue == false ) {
			el.removeAttribute('disabled');
			el.activeFormDisabled = bValue;
			if ( (elLabel = proform.helper.getLabel(el, false)) != null ) {
				removeClass( elLabel, proform.config.disabled );
			};
		}
		else {
			el.activeFormDisabled = bValue;
			el.setAttribute('disabled', 'disabled');
			if ( (elLabel = proform.helper.getLabel(el, false)) != null ) {
				addClass( elLabel, proform.config.disabled );
			};
		}
	},
	update : function( elRoot ) {
		// csak IE-ben va rá szükség!
		if ( typeof( document.body.activeFormUpdate ) != 'undefined' ) {
			document.body.activeFormUpdate( elRoot );
		};
	}
};
/**
 * A label for="" fordítottja, ha nem talál, akkor saját magát adja vissza.
 */
proform.helper.getLabel = function ( el, bReturnElement ) {
	var els, i, sFor;
	sFor = ( is.ie ) ? 'htmlFor' : 'for';
	// tejesítményoptimalizáció: először csak a környezetében nézünk szét -
	els = el.parentNode.getElementsByTagName('label');
	for ( i = 0; i < els.length; i++ ) {
		if ( els[i].getAttribute( sFor ) == el.id ) {
			return els[i];
		};
	};
	// - majd, ha nem találjuk, akkor a teljes formban
	els = proform.form.getElementsByTagName('label');
	for ( i = 0; i < els.length; i++ ) {
		if ( els[i].getAttribute( sFor ) == el.id ) {
			return els[i];
		};
	};
	return bReturnElement ? el : null;
};
/**
 * Textarea maxlength implementáció a cols attribútum alapján
 */
proform.helper.initTextAreaMaxLength = function() {
	var els, i;
	els = proform.form.getElementsByTagName('textarea');
	for ( i = 0; i < els.length; i++ ) {
		els[i].maxLength = els[i].getAttribute('cols');
		if ( els[i].maxLength < 1 ) {
			els[i].maxLength = Number.MAX_VALUE;
		};
		els[i].onkeypress = function() {
			if ( this.value.length > this.maxLength ) {
				this.value = this.value.substring( 0, this.maxLength );
			};
		};
		els[i].onkeyup = els[i].onkeypress;
		els[i].onchange = els[i].onkeypress;
		// ie paste hack
		if ( is.ie ) {
			els[i].onbeforepaste = function() {
				window.event.returnValue = false;
			};
			els[i].onpaste = function() {
				var oTR;
				window.event.returnValue = false;
				oTR = this.document.selection.createRange();
				oTR.text = window.clipboardData.getData("Text").substr( 0, ( this.maxLength - this.value.length + oTR.text.length ) );
			};
		};
	};
};
proform.helper.XMLHttpRequest = {
	config : {
		updateClass : 'xmlhttprequest-update-',
		updateUnit : 5,
		updateDelayFase1 : 1000,
		updateDelayFase2 : 50
	},
	markUpdate : function( el ) {
		if ( el.updateState != null ) {
			return;
		};
		el.updateState = 0;
		addClass( el, proform.helper.XMLHttpRequest.config.updateClass + el.updateState );
		el.updateTime = ( is.ie ) ? setTimeout( 'proform.helper.XMLHttpRequest.doUpdatePhase1("' + el.uniqueID + '")', proform.helper.XMLHttpRequest.config.updateDelayFase1 ) : 
		                            setTimeout( proform.helper.XMLHttpRequest.doUpdatePhase1, proform.helper.XMLHttpRequest.config.updateDelayFase1, el );
	},
	markUpdateOk : function( el ) {
		proform.helper.XMLHttpRequest.markUpdate( el );
	},
	doUpdatePhase1 : function( el ) {
		if ( is.ie ) {
			el = document.all[el];
		};
		el.updateTime = ( is.ie) ? setInterval( 'proform.helper.XMLHttpRequest.doUpdatePhase2("' + el.uniqueID + '")', proform.helper.XMLHttpRequest.config.updateDelayFase2 ) : 
		                           setInterval( proform.helper.XMLHttpRequest.doUpdatePhase2, proform.helper.XMLHttpRequest.config.updateDelayFase2, el );
	},
	doUpdatePhase2 : function( el ) {
		if ( is.ie ) {
			el = document.all[el];
		};
		if ( el.updateState < proform.helper.XMLHttpRequest.config.updateUnit ) {
			removeClass( el, proform.helper.XMLHttpRequest.config.updateClass + el.updateState );
			addClass( el, proform.helper.XMLHttpRequest.config.updateClass + ++el.updateState );
		}
		else {
			removeClass( el, proform.helper.XMLHttpRequest.config.updateClass + el.updateState );
			clearInterval( el.updateTime );
			el.updateState = null;
		};
	}
}; 