/*
 * ProFrom - Professzionális Felhasználói Felületek $ _lib.js,v 1.17 2005/10/10 14:31:55 gyuris Exp $
 */


/**
 * $ prototype_A.js,v 1.7 2005/06/10 12:47:13 gyuris Exp $
 * prototype A
 * @package  lib.prototypeA
 * @author   Gyuris Gellért
 */
/**
 * Function.prototype.getName - visszaadja egy funkció nevét, IE-ben nincs segéd.
 * @return String  A funkció neve.
 */
Function.prototype.getName = function () {
	var aTemp;
	if ( typeof this.name == 'string' ) {
		return this.name;
	}
	else {
		aTemp = /function\s([\w]+)\(/g.exec( this.toString() );
		return this.name = ( aTemp != null && typeof aTemp[1] != 'undefined' ) ? aTemp[1] : '';
	};
};
/**
 * String.prototype.trim - letörli a string végéről a fölösleges üres karatereket.
 * @return String  A String új értéke.
 */
String.prototype.trim = function() {
	return this.replace(/(^\s*)|(\s*$)/g, '');
};
/**
 * String.prototype.escapeHTML - egy Stringet bekódol forráskód-megjelenítésre
 * @return String  A String új, forráskód-megjeleníthető értéke.
 */
String.prototype.escapeHTML = function() {
	var s = this.toString();
	s = s.replace(/\&/g, '&amp;');
	s = s.replace(/\</g, '&lt;');
	s = s.replace(/\>/g, '&gt;');
	return s;
};
/**
 * String.prototype.unescapeHTML - egy Stringet bekódol megjelenítésre
 * @return String  A String új, HTML-ként értzelmezhető értéke.
 */
String.prototype.unescapeHTML = function() {
	var s = this.toString();
	s = s.replace(/\&lt;/g,  '<');
	s = s.replace(/\&gt;/g,  '>');
	s = s.replace(/\&amp;/g, '&');
	return s;
};
/**
 * String.prototype.toInt - parseInt úgy, hogy mindenképpen számot adjon vissza
 * @return Number  A leparsolt szám. Pl.: 'a112' -> 0, '23a1' -> 23,  '1.2a34bc' -> 1
 */
String.prototype.toInt = function( nBase ) {
	var nVal;
	if ( typeof( nBase ) == 'undefined' ) {
		nBase = 10;
	};
	nVal = parseInt( this.toString() , nBase );
	if ( isNaN( nVal ) ) {
		nVal = 0;
	};
	return nVal;
};
/**
 * String.prototype.toFloat - egy string számmá alakítása a tizedeshelyek elvetésével
 * @return Number  A leparsolt szám. Pl.: '01.2a34bc' -> 1234
 */
String.prototype.toFloat = function() {
	return parseFloat( ('0' + this.toString() ).replace(/[^0-9]/g,''), 10)
};
/**
 * String.prototype.toSequence - számok kinyerése egy szringből a tizedeshelyek elvetésével.
 * @return String  A leparsolt szöveg. Pl.: '01.2a34bc' -> '01234'
 */
String.prototype.toSequence = function() {
	return this.toString().replace(/[^0-9]/g,'');
};
/**
 * String.prototype.endsWith - egy String a megadott sztringre végződik-e? (Java)
 * @param sEnd String  A keresett sztring.
 * @return Boolean     true vagy false
 */
String.prototype.endsWith = function( sEnd ) {
	if ( typeof sEnd != 'string' ) {
		sEnd = sEnd.toString();
	};
	return ( this.toString().substring( this.toString().length - sEnd.length, this.toString().length ) == sEnd ) ? true : false;
};
/**
 * String.prototype.startsWith - egy String a megadott sztringgel kezdődik-e? (Java)
 * @param sStart String  A keresett sztring.
 * @param nStart Number  Opcionális. Megadható egy kezdőpont, ahonnan a vizsgálat kezdődik. Elhagyása a 0-t jelenti.
 * @return Boolean       true vagy false
 */
String.prototype.startsWith = function( sStart, nStart ) {
	if ( typeof sStart != 'string' ) {
		sStart = sStart.toString();
	};
	if ( !nStart ) {
		nStart = 0;
	};
	if ( typeof nStart != 'number' ) {
		nStart = nStart.toString().toInt();
	};
	return ( this.toString().substring( nStart, nStart + sStart.length ) == sStart ) ? true : false;
};
/**
 * String.prototype.toUpperCaseFirst - Egy string első betűjét nagybetűssé teszi (Java)
 * @return String  A nagybetűssé tett sztring.
 */
String.prototype.toUpperCaseFirst = function() {
	return this.toString().charAt(0).toUpperCase() + this.toString().substring( 1, this.toString().length );
};
/**
 * String.prototype.toUpperCaseWords - Egy string minden szavának első betűjét nagybetűssé teszi (Java)
 * @return String  A nagybetűssé tett sztring.
 * XXX - más karakterek
 */
String.prototype.toUpperCaseWords = function() {
	var i, aString = this.toString().split(' ');
	for ( i = 0; i < aString.length; i++ ) {
		aString[i] = aString[i].toUpperCaseFirst();
	};
	return aString.join(' ');
};



/**
 * $ browserCheck.js,v 1.12 2005/06/07 13:06:32 gyuris Exp $
 * @package  lib.browserCheck
 * @author   Gyuris Gellért
 */
var is = {
	/**
	 * @constructor
	 */
	getUserAgents : function() { 
		// segédfunkciók
		this.geckoGetRv = function() {
			var aTemp = /rv:(\d+\.)(\d+(\.\d+)?)/g.exec(this.agent);
			return aTemp[1] + aTemp[2].toSequence();
		};
		this.getVersion = function() {
			var sId;
			switch ( this.app ) {
				case 'gecko' :
					return this.geckoRv;
					break;
				case 'ie' :
					sId = 'msie ';
					break;
				case 'opera' :
					sId = ( this.agent.indexOf( 'opera/' ) > -1 ) ? 'opera/' : 'opera ';
					 break;
				case 'khtml' :
					sId = ( this.saf ) ? 'applewebkit/' : 'konqueror/';
					break;
				case 'ns4' :
					sId = 'mozilla/';
					break;
			};
			return parseFloat( '0' + this.agent.substr( this.agent.indexOf( sId ) + sId.length ), 10 );
		};
		// adatok átvétele
		this.ver         = navigator.appVersion.toLowerCase();
		this.agent       = navigator.userAgent.toLowerCase();
		this.platform    = navigator.platform.toLowerCase();
		this.product     = new String( navigator.product ).toLowerCase();
		this.productSub  = new String( navigator.productSub ).toLowerCase();
		this.vendor      = new String( navigator.vendor ).toLowerCase();
		this.vendorSub   = new String( navigator.vendorSub ).toLowerCase();
		this.opera       = typeof ( window.opera ) != 'undefined';
		this.dom         = document.getElementById ? true : false;
		this.compatMode  = new String( document.compatMode ).toLowerCase(); // 'css1compat', 'backcompat', 'quirksmode'
		
		// platformok
		this.win         = this.platform.indexOf("win") > -1;
		this.linux       = ( this.platform.indexOf("linux") > -1 || this.platform.indexOf("x11") > -1 );
		this.mac         = this.platform.indexOf("mac") > -1;
	
		// böngészők
		// khtml
		this.chrome      = ( this.agent.indexOf("chrome") > -1 || this.product.indexOf("chrome") > -1 );
		this.khtml       = ( this.agent.indexOf("khtml") > -1 || this.product.indexOf("khtml") > -1 );
		this.konq        = ( this.agent.indexOf("konqueror") > -1 || this.product.indexOf("konqueror") > -1 );
		this.saf         = ( this.agent.indexOf("safari") > -1 || this.ver.indexOf("safari") > -1 );
		// opera
		this.opera       = ( this.opera || this.agent.indexOf("opera") > -1 ); // nem win platformon az opera obj nem jön létre
		this.opera5      = ( this.opera && this.agent.indexOf("opera 5") > -1 );
		this.opera6      = ( this.opera && ( this.agent.indexOf("opera 6") > -1 || this.agent.indexOf("opera/6") > -1 ) );
		this.opera7      = ( this.opera && ( this.agent.indexOf("opera 7") > -1 || this.agent.indexOf("opera/7") > -1 ) );
		this.opera8      = ( this.opera && ( this.agent.indexOf("opera 8") > -1 || this.agent.indexOf("opera/8") > -1 ) );
		// IE
		this.ie          = ( this.ver.indexOf('msie') != -1 && !this.opera ) ? true : false;
		this.ie4         = ( document.all && !this.dom && !this.opera ) ? true : false;
		this.ie5         = ( document.all && this.ver.indexOf("msie 5.0") > -1 && !this.opera ) ? true : false; 
		this.ie5mac      = ( this.ie5 && this.mac ) ? true : false; 
		this.ie55        = ( document.all && this.ver.indexOf("msie 5.5") > -1 && !this.opera ) ? true : false; 
		this.ie6         = ( document.all && this.ver.indexOf("msie 6" )  > -1 && !this.opera ) ? true : false;
		this.ie7         = ( document.all && this.ver.indexOf("msie 7" )  > -1 && !this.opera ) ? true : false;
		this.ie8         = ( document.all && this.ver.indexOf("msie 8" )  > -1 && !this.opera ) ? true : false;
		this.ieJSBuild   = ( this.ie ) ? ScriptEngineBuildVersion() : '';
		this.ieJSVersion = ( this.ie ) ? ScriptEngineMajorVersion() + '.' + ScriptEngineMinorVersion() : '';
		// mozilla
		this.ns4         = ( document.layers && !this.dom ) ? true : false;
		this.gecko       = ( this.product == "gecko" && !this.khtml ) ? true : false;
		this.geckoRv     = ( this.gecko ) ? this.geckoGetRv() : 0;
		this.gecko1      = ( this.gecko && Number( this.productSub ) > 20020530 ) ? true : false;
		this.moz1        = ( this.gecko && this.vendor == '' && !( this.geckoRv < 1 ) ) ? true : false;
		this.ns6         = ( this.gecko && this.vendor == 'netscape6' && parseFloat( this.vendorSub ) >= 6 && parseFloat( this.vendorSub ) < 7 ) ? true : false;
		this.ns7         = ( this.gecko && this.vendor == 'netscape' && parseFloat( this.vendorSub ) >= 7 ) ? true : false;
		this.ff          = ( this.gecko && ( this.vendor == 'mozilla firebird' || this.vendor == 'phoenix' || this.vendor == 'firefox' ) );
		this.cm          = ( this.gecko && ( this.vendor == 'chimera' || this.vendor == 'camino' ) );
		this.beo         = ( this.gecko && this.vendor == 'beonex' );
		this.kmel        = ( this.agent.indexOf('k-meleon') > -1 ) ? true : false;
		// alkalmazás-verziószám
		this.app         = ( ( this.ie ) ?  'ie' : ( this.gecko ) ? 'gecko' : ( this.opera ) ?  'opera' : ( this.khtml ) ? 'khtml' : ( this.ns4 ) ? 'ns4' : 'undefined' );
		this.appVer      = this.getVersion();
	
		// csoportok
		this.bs4         = ( this.ie || this.ns4 || this.gecko || this.opera || this.khtml );
		this.bs5         = ( ( this.ie && this.appVer >= 5.5 ) || this.gecko || ( this.opera && this.appVer >= 7  ) || this.saf );
		this.bss         = ( this.gecko || ( this.opera && this.appVer >= 7  ) || this.khtml );
		this.min         = ( this.bs5 || this.ie5 || this.opera || this.khtml );
		return this;
	}
};
is.getUserAgents();


/**
 * $ eventBinding.js,v 1.9 2005/10/10 14:06:58 gyuris Exp $
 * @package  lib.eventBinding
 * @author   Gyuris Gellért
 * @see      browserCheck, prototype A
 */
/**
 * addEvent - egy esemény csatolása. Alapfüggvény.
 * @param obj DOMElement     Az elem, amihez csatolunk.
 * @param type String        Az esmeméyn típusa: pl.: 'click', 'mouseover' ('on' nélkül).
 * @param fn Function  A függvény, melyet csatolunk.
 */
function addEvent( obj, type, fn ) {
	if ( obj.addEventListener ) {
		obj.addEventListener( type, fn, false );
	}
	else if	( obj.attachEvent ) {
		obj['e'+type+fn] = fn;
		obj[type+fn] = function(){ obj['e'+type+fn]( window.event ); };
		obj.attachEvent( 'on'+type, obj[type+fn] );
	};
};
/**
 * removeEvent - egy esemény csatolása. Alapfüggvény.
 * @param obj DOMElement     Az elem, amitől elveszünk.
 * @param type String        Az esmeméyn típusa: pl.: 'click', 'mouseover' ('on' nélkül).
 * @param fn Function  A függvény, melyet elveszünk.
 */
function removeEvent( obj, type, fn ) {
	if ( obj.removeEventListener ) {
		obj.removeEventListener( type, fn, false );
	}
	else if ( obj.detachEvent ) {
		obj.detachEvent( 'on'+type, obj[type+fn] );
		obj[type+fn] = null;
	};
};


/**
 * $ className.js,v 1.4 2004/08/19 11:59:21 gyuris Exp $
 * @package  lib.className
 * @author   Gyuris Gellért
 */
/**
 * removeClass - eltávolítja egy elem CSS oszályai közül a megadottat
 * @param el DOMElement      A elem, amelyen módosítunk.
 * @param sClassName String  A CSS osztály neve.
 * @return String            A keletkezett osztálynév.
 */
function removeClass( el, sClassName ) {
	var i, aClass, aNewClass = [];
	if ( hasClass( el, sClassName ) ) {
		aClass = el.className.split(' ');
		for ( i = aClass.length; i > 0; ) {
			if ( aClass[--i] != sClassName ) {
				aNewClass.unshift( aClass[i] );
			};
		};
		el.className = aNewClass.join(' ');
	};
	return el.className;
};
/**
 * addClass - hozzáadja egy elem CSS oszályai közé legutolsó helyre a megadottat,
 * ha már szerepel, akkor kiemeli a legutolsó helyre.
 *
 * @param el DOMElement      A elem, amelyen módosítunk.
 * @param sClassName String  A CSS osztály neve.
 * @return String            A keletkezett osztálynév.
 */
function addClass( el, sClassName ) {
	if ( el.className == '' ) {
		el.className = sClassName;
	}
	else if ( !hasClass( el, sClassName ) ) { // nincs szerepe a sorrendiségnek
		el.className += ' ' + sClassName;
	};
	return el.className;
};
/**
 * hasClass - megnézi, hogy egy elem CSS oszályai között szerepel-e a megadott?
 * @param el DOMElement      A elem, amelyen a vizsgálatot végezzük.
 * @param sClassName String  A CSS osztály neve.
 * @return Boolean           Szerepel-e vagy sem benne?
 */
function hasClass( el, sClassName ) {
	var i, aClass;
	aClass = el.className.split(' ');
	for ( i = aClass.length; i > 0; ) {
		if ( aClass[--i] == sClassName ) {
			return true;
		};
	};
	return false;
};


/**
 * $ child.js,v 1.4 2004/08/19 11:59:21 gyuris Exp $
 * @package  lib.child
 * @author   Gyuris Gellért
 * @see      prototypeA
 */
/**
 * getChildIndex - visszaadja a gyermek sorszámát
 * @param elChild DOMNode  A csomópont, amelynek a sorszámára vagyunk kíváncsiak.
 * @return Number          Hanyadik csomópont.
 * @return null            Nincs szülője.
 */
function getChildIndex( elChild ) {
	var i;
	if ( elChild.parentNode == null ) {
		return null;
	};
	for ( i = 0; i < elChild.parentNode.childNodes.length; i++ ) {
		if ( elChild.parentNode.childNodes.item(i) == elChild ) {
			return i;
			break;
		};
	};
	return null;
}
/**
 * getContextNodes - visszaadja a kért csomópont-típusú leszármazottjait. A 
 * getAllChildElement v2.0, getAllChildNode v2.0 ennek két önálló régebbi 
 * speciális megvalósítása, melyet kompatibilitás miatt megőriztem.
 *
 * @param elRoot DOMNode  A csomópont, amelynek a leszármazottait kérjük 
 * @param aType Array     A leszármazott csomópont-típusok, Lásd a Node
 * @return Array          A megadott csomópont-típusoknak megfelelő leszármazottak.
 */
function getContextNodes( elRoot, aType ) {
	var aNodes = [];
	function searchNodes( el ) {
		var i, j;
		if ( !el.hasChildNodes() ) {
			return;
		};
		for ( i = 0; i < el.childNodes.length; i++ ) {
			for ( j = 0; j < aType.length; j++ ) {
				if ( el.childNodes.item(i).nodeType == aType[j] ) {
					aNodes[aNodes.length] = el.childNodes.item(i);
					break;
				};
			};
			if ( el.childNodes[i].nodeType == Node.ELEMENT_NODE ) {
				searchNodes( el.childNodes.item(i) );
			};
		};
	};
	searchNodes( elRoot );
	return aNodes;
}
/**
 * getAllChildElement - Lásd: getContextNodes;
 * @param elRoot DOMNode  A csomópont, amelynek a leszármazottait kérjük 
 */
function getAllChildElement( elRoot ) {
	elRoot.allEl = getContextNodes( elRoot, [ Node.ELEMENT_NODE ] );
};
/**
 * getAllChildNode - Lásd: getContextNodes;
 * @param elRoot DOMNode  A csomópont, amelynek a leszármazottait kérjük 
 */
function getAllChildNode( elRoot ) {
	elRoot.allNodes = getContextNodes( elRoot, [ Node.ELEMENT_NODE, Node.TEXT_NODE, Node.CDATA_SECTION_NODE, Node.COMMENT_NODE ] );
};
/**
 * getFirstElement - visszaadja egy csomópont első ELEMENT_NODE-ját
 * @param el DOMElement  A csomópont, amelynek első elemét kérjük.
 * @return DOMELement    Az első elem.
 * @return null          Ha nincs első elem.
 */
function getFirstElement( el ) {
	var i;
	if ( !el.hasChildNodes() ) {
		return null; // ha nem ELEMENT_NODE a szülő
	};
	for ( i = 0 ; i < el.childNodes.length; i++ ) {
		if ( el.childNodes.item(i).nodeType == Node.ELEMENT_NODE ) {
			return el.childNodes.item(i);
			break;
		};
	};
	return null;
};
/**
 * getLastElement - visszadja egy csomópont utolsó ELEMENT_NODE-ját
 *
 * @param el DOMElement  A csomópont, amelynek utolsó elemét kérjük.
 * @return DOMELement    Az utoló elem.
 * @return null          Ha nincs utolsó elem.
 */
function getLastElement( el ) {
	var i;
	if ( !el.hasChildNodes() ) {
		return null; // ha nem ELEMENT_NODE a szülő
	};
	for ( i = el.childNodes.length - 1 ; i >= 0; i-- ) {
		if ( el.childNodes.item(i).nodeType == Node.ELEMENT_NODE ) {
			return el.childNodes.item(i);
			break;
		};
	};
	return null;
};
/**
 * getNextElement - visszaadja egy egy elem testvérei közül a következő elemet
 *
 * @param elChild DOMElement  A gyermek-csomópont, amely szülőjének következő elemét kérjük.
 * @return DOMELement         A következő elem.
 * @return null               Ha nincs következő elem.
 */
function getNextElement( elChild ) {
	function getNext( el ) {
		if ( el.nextSibling == null ) {
			return null;
		};
		if ( el.nextSibling.nodeType == Node.ELEMENT_NODE ) {
			return el.nextSibling;
		};
		return getNext( el.nextSibling );
	};
	return getNext( elChild );
};
/**
 * getPreviousElement - visszaadja egy egy elem testvérei közül az előző elemet
 *
 * @param elChild DOMElement  A gyermek-csomópont, amely szülőjének előző elemét kérjük.
 * @return DOMELement         Az előző elem.
 * @return null               Ha nincs előző elem.
 */
function getPreviousElement( elChild ) {
	function getPrevious( el ) {
		if ( el.previousSibling == null ) {
			return null;
		};
		if ( el.previousSibling.nodeType == Node.ELEMENT_NODE ) {
			return el.previousSibling;
		};
		return getPrevious( el.previousSibling );
	};
	return getPrevious( elChild );
};
/**
 * removeEmptyTextNode - eltávolítja egy elem üres TEXT_NODE-jait
 *
 * @param elRoot DOMElement  A csomópont, amely üres TEXT_NODE-jait kitöröljük
 * @return Array             A csomópontok, melyek ki lettek törölve.
 */
function removeEmptyTextNode( elRoot ) {
	var re, aNodes, aRemovedNodes = [];
	re = /^[\s\n\t]*$/;
	aNodes = getContextNodes( elRoot, [ Node.TEXT_NODE ] );
	for ( i = 0; i < aNodes.length; i++ ) {
		if ( aNodes[i].nodeType != Node.TEXT_NODE ) {
			continue;
		};
		if ( re.test( aNodes[i].nodeValue ) ) {
			aRemovedNodes[aRemovedNodes.length] = aNodes[i].parentNode.removeChild( aNodes[i] );
		};
	};
	return aRemovedNodes;
};
/**
 * getTextContent - bármilyen csomópont szöveges tartalmát visszaadja (ha lehetséges neki)
 * @param nodeRoot DOMNode  A csomópont, amelynek szöveges tartalmára vagyunk kiváncsiak
 * @return String           A tartalom
 */
function getTextContent( nodeRoot ) {
	switch ( nodeRoot.nodeType ) {
		case  2 : // Node.ATTRIBUTE_NODE
		case  5 : // Node.ENTITY_REFERENCE_NODE
		case  6 : // Node.ENTITY_NODE
		case  7 : // Node.PROCESSING_INSTRUCTION_NODE
		case  9 : // Node.DOCUMENT_NODE
		case 10 : // Node.DOCUMENT_TYPE_NODE
		case 11 : // Node.DOCUMENT_FRAGMENT_NODE
		case 12 : // Node.NOTATION_NODE
			return '';
			break;
		case  1 : // Node.ELEMENT_NODE
		case  3 : // Node.TEXT_NODE
		case  4 : // Node.CDATA_SECTION_NODE
		case  8 : // Node.COMMENT_NODE
			if ( is.gecko ) {
				return nodeRoot.textContent;
			}
			else {
				return ( nodeRoot.innerText ) ? nodeRoot.innerText : nodeRoot.nodeValue;
			};
	};
};


/**
 * $ attribute.js,v 1.6 2005/03/01 14:44:03 gyuris Exp $
 * @package  lib.attribute
 * @author   Gyuris Gellért
 * @see      browserCheck
 */
/**
 * isSpecified - Egy elem attribútuma deklarálva van-e?
 * Szabványos attr. esetén attributes['valami'].specified; nem szabvanyos 
 * attributum esetén: attributes.getNamedItem('valami') visszatérési értéke 
 * null, de csak 6-os Explorer; hasAttribute minden máshol
 *
 * @param nodeEl DOMElement  Az elem DOM objektumként.
 * @param sAttribute String  Az attribútum neve stringként.
 * @return Boolean           Dekralárva van, vagy sem?
 * @since                    1.4
 */
function isSpecified( nodeEl, sAttribute ) {
	if ( is.ie || ( is.opera && this.appVer >= 7 ) ) {
		/*getItemIndex( nodeEl, sAttribute ) != null ) { // normál 'core' attribútum
			return nodeEl.attributes[sAttribute].specified
		}*/
		if ( typeof nodeEl.attributes[sAttribute] != 'undefined' && null != nodeEl.attributes[sAttribute] ) {
			return nodeEl.attributes[sAttribute].specified;
		};
		if ( is.ie5 || is.ie55 ) {
			return ( nodeEl.getAttribute( sAttribute ) ) ? true : false;
		}
		else if ( is.ie6 || is.ie7 || ( ( is.opera && this.appVer >= 7 ) ) ) {
			return ( nodeEl.attributes.getNamedItem( sAttribute ) ) ? true : false;
		};
	}
	else if ( is.bss ) { // opera7.5
		return nodeEl.hasAttribute( sAttribute );
	};
};
/**
 * getAttributeIndex - IE: visszaadja az attribútum sorszámát az attributes tömben
 * @param nodeEl DOMElement  Az elem DOM objektumként.
 * @param sAttribute String  Az attribútum neve stringként.
 * @return Number            Hanyadik attribútum.
 * @since                    1.0
 */
function getAttributeIndex( nodeEl, sAttribute ) {
	var i;
	sAttribute = sAttribute.toLowerCase();
	for ( i = 0; i < nodeEl.attributes.length; i++ ) {
		if ( nodeEl.attributes.item(i).nodeName.toLowerCase() == sAttribute ) {
			return i;
		};
	};
	return null;
};
/**
 * createId - vagy visszaadja az elem már meglévő Id-jét, vagy készít egy véletlen Id-t
 * @param el DOMELement  Az elem, amelynek id-t akarunk készíteni.
 * @return String        A string, mely idnek felel meg. IE esetén a beépített uniqueID használtatik.
 * @since                0.1
 */
function createId( el ) {
	if ( isSpecified( el, 'id' ) ) {
		return el.id;
	};
	if ( is.ie ) {
		return el.uniqueID;
	}
	else {
		function getRandom() {
			var strNum = Math.random().toString().toFloat();
			if ( strNum == 0 || strNum == 1 ) { 
				return getRandom();
			};
			return strNum;
		};
		return 'rID-' + getRandom();
	};
};


/**
 * $ getComputedStylePropertyValue.js,v 1.8 2005/06/07 13:06:32 gyuris Exp $
 * getComputedStylePropertyValue - visszadja az elem tényleges stílusának elemeit. FONTOS! Nem minden böngésző támogatja.
 * Gond nélkül megy Geckókban és IE-ben. Opera csak a 7.20-tól támogatja, az alatti csak visszadja a normális style 
 * értékeket. Nem megy KHTML (Safari 1.0) alatt, de már hírét hallottam, hogy készítik.
 * @package                       lib.getComputedStylePropertyValue
 * @author                        Gyuris Gellért
 * @see                           
 * @param elNode DOMElement       Az elem, melynek stílus-értékére vagyunk kíváncsiak.
 * @param sStyleProperty String   Az stílus deklaráció neve: pl. 'border-left-color'
 * @param sPseudoProperty String  A pszeudo deklráció neve: pl. 'fist-letter' - Ez csak Geckókban működik!, elhagyható
 * @return String                 A deklarácó értéke.
 */
function getComputedStylePropertyValue( elNode, sStyleProperty, sPseudoProperty ) {
	var aResult, i;
	if ( window.getComputedStyle ) {
		return window.getComputedStyle( elNode, sPseudoProperty ).getPropertyValue( sStyleProperty );
	}
	else if ( elNode.currentStyle ) {
		aResult = sStyleProperty.split('-');
		for ( i = 1; i < aResult.length; i++ ) {
			aResult[i] = aResult[i].toUpperCaseFirst();
		};
		sStyleProperty = aResult.join('');
		return elNode.currentStyle.getAttribute( sStyleProperty );
	};
	return elNode.style.getPropertyValue( sStyleProperty ); // khtml
};


/**
 * $ makeUnselectable.js,v 1.2 2004/08/19 11:59:21 gyuris Exp $
 * makeUnselectable - egy elemenek tiltja a kijelölését és fókuszba kerülését. Opera7 megoldatlan.
 * @package                    lib.makeUnselectable
 * @author                     Gyuris Gellért
 * @see                        browserCheck, prototype A
 * @param el DOMElement        Az elem, amelyen a műveletet végezzük.
 * @return el DOMElement       Az elem, a megváltozott paraméterekkel.
 */
function makeUnselectable( el ) {
	if ( el.nodeType != Node.ELEMENT_NODE ) {
		return false;
	};
	if ( is.ie ) {
		el.setAttribute('unselectable', 'on' );
		el.setAttribute('hidefocus', true );
	}
	else if ( is.gecko ) {
		el.style.MozUserSelect = 'none';
		el.style.MozUserFocus = 'none';
	};
	return el;
};


/**
 * $ displayChanger.js,v 1.6 2005/07/15 11:23:27 gyuris Exp $
 * displayChanger - megfordítja egy elem display-ét, vagy a megadottra állítja. 
 * @package               lib.displayChanger
 * @author                Gyuris Gellért
 * @see                   browserCheck, getComputedStylePropertyValue, prototypeA
 * @param el DOMElement   Az elem, melyneknek megjelenítését változtatjuk.
 * @param bValue Boolean  Opcionális; true: mutatva lesz, false: elrejtve lesz, 
 *                        elhagyásakor megfordul.
 * @return String         A beállított display
 */
function displayChanger( el, bValue ) {
	var oDisplay, sNodeName, sStyle;
	if ( el.nodeType != Node.ELEMENT_NODE ) {
		return null;
	};
	oDisplay = {
		'iframe' : [ 'inline', 'inline' ],
		'body' : [ 'block', 'block' ],
		'p' : [ 'block', 'block' ],
		'div' : [ 'block', 'block' ],
		'span' : [ 'inline', 'inline' ],
		'table' : [ 'table', 'block' ],
		'tbody' : [ 'table-row-group', 'block' ],
		'tfoot' : [ 'table-footer-group', 'block' ],
		'thead' : [ 'table-header-group', 'block' ],
		'tr' : [ 'table-row', 'block' ],
		'td' : [ 'table-cell', 'block' ],
		'th' : [ 'table-cell', 'block' ],
		'ul' : [ 'block', 'block' ],
		'ol' : [ 'block', 'block' ],
		'li' : [ 'list-item', 'list-item' ],
		'dl' : [ 'block', 'block' ],
		'dt' : [ 'block', 'block' ],
		'dd' : [ 'block', 'block' ],				
		'input' : [ 'inline', 'inline' ],
		'button' : [ 'inline', 'inline' ],
		'textarea' : [ 'inline', 'inline' ],
		'select' : [ 'inline', 'inline' ],
		'a' : [ 'inline', 'inline' ]
	};
	sNodeName = el.nodeName.toLowerCase();
	if ( typeof oDisplay[sNodeName] == 'undefined' ) {
		return null;
	};
	if ( typeof( bValue ) != 'undefined' ) { // ha megvan adva, hogy mire kell cserélni
		el.style.display = ( bValue == false ) ? 'none' : is.ie ? oDisplay[sNodeName][1] : oDisplay[sNodeName][0];
	}
	else { // ha meg kell fordítani
		sStyle = el.style.display == '' ? getComputedStylePropertyValue( el, 'display', '' ) : el.style.display;
		el.style.display = !( sStyle == 'none' || sStyle == '' ) ? 'none' : is.ie ? oDisplay[sNodeName][1] : oDisplay[sNodeName][0];
	};
	return el.style.display;
};

/**
 * $ createFullOffset.js,v 1.5 2005/02/21 08:27:43 gyuris Exp $
 * createFullOffset - visszadja az elem abszolút elhelyezekedését a látképen, 
 * vagy az elRoot-hoz viszonyítva.
 * @package              lib.createFullOffset
 * @author               Gyuris Gellért
 * @see                  browserCheck
 * @param el DOMElement  Az elem, melynek pozícióira kiváncsiak vagyunk.
 * @param elRoot DOMElement  Az elem, melynek pozícióira kiváncsiak vagyunk.
 * @return Object        offsetX, offsetY: x és y pozíciók számokkal
 */
function createFullOffset( el, elRoot ) {
	if ( el.nodeType != Node.ELEMENT_NODE ) {
		return { offsetX : null, offsetY : null };
	};
	if ( typeof elRoot != 'undefined' || !( document.getBoxObjectFor || el.getBoundingClientRect ) ) {
		function getFullOffset( el ) {
			var aOffset = [], aTempOffset = [];
			aOffset[0] = el.offsetLeft;
			aOffset[1] = el.offsetTop;
			if ( el.offsetParent != null && el.offsetParent != elRoot ) {
				aTempOffset = getFullOffset( el.offsetParent );
				aOffset[0] += aTempOffset[0];
				aOffset[1] += aTempOffset[1];
			};
			return aOffset;
		};
		if ( typeof elRoot == 'undefined' ) {
			elRoot = el.ownerDocument.documentElement || el.ownerDocument.body;
		};
		var aFullOffset = getFullOffset( el );
		el.offsetX = aFullOffset[0];
		el.offsetY = aFullOffset[1];
		return { offsetX : el.offsetX, offsetY : el.offsetY };
	};
	if ( document.getBoxObjectFor ) {
		var oBoxObject = el.ownerDocument.getBoxObjectFor( el ); // el bordertől meghüjül
		return { offsetX : oBoxObject.x, offsetY : oBoxObject.y };
	};
	if ( el.getBoundingClientRect ) {
		var oTextRectangle = el.getBoundingClientRect(); // body bordertől meghüjül
		return { offsetX : oTextRectangle.left, offsetY : oTextRectangle.top };
	};
};

/**
 * getPageSize()
 * @return	arrayPageSize Returns array with page width, height and window width, height
 * Core code from - quirksmode.com
 * Edit for Firefox by pHaez
 */
function getPageSize(){
	
	var xScroll, yScroll;
	
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = window.innerWidth + window.scrollMaxX;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	

	if (self.innerHeight) {	// all except Explorer
		if(document.documentElement.clientWidth){
			windowWidth = document.documentElement.clientWidth; 
		} else {
			windowWidth = self.innerWidth;
		}
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}


	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = xScroll;		
	} else {
		pageWidth = windowWidth;
	}

	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
	return arrayPageSize;
}

/**
 * $ flash.js,v 1.8 2005/11/05 07:31:26 gyuris Exp $
 * @package  lib.flash
 * @author   Gyuris Gellért
 * @since    3.14
 * @see      browserCheck, eventBinding
 */
/**
 * flash detektálás - telepítettség és szkriptelhetőség
 * A telepített flash bővítményt kérdezi le, a gecko scriptable egy kis időzítés
 * után kérdezjezhető le. Hibaüzenetet adni(=felülbírálni) a flash.getFlashCheck
 * újbóli meghívásával kell: első függ. a verzió a második a scriptable
 * elvárásnak való megfelelés hiányában hajtódik végre.
 */
var flash = {
	getFlashCheck : function ( nVer, fError, fScriptableError ) { // fScriptableError :: gecko nincs szkriptelhető plugin telepítve
		var sDesc, strCommand;
		this.shockMode = false;  // telepítve van-e
		this.flashVer = 0;       // nagyverzió
		this.rv = 0;             // alverzió
		this.ver = 0;            // együtt
		this.scriptable = false; // van-e js kapcsolat
		this.minVerRound = parseInt( nVer );
		this.elEmbed;            // gecko Scriptable-hez kell
		this.timeout;
		this.interval;
		this.bAppend = false;
		this.fScriptableError = ( typeof fScriptableError == 'function' ) ? fScriptableError : false;
		if ( is.ns4 || is.gecko || is.opera || is.ie5mac || is.khtml ) {
			if ( navigator.mimeTypes && 
				 navigator.mimeTypes["application/x-shockwave-flash"] && 
				 navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin && 
				 navigator.plugins && 
				 navigator.plugins["Shockwave Flash"] ) {
				sDesc = navigator.plugins["Shockwave Flash"].description + '';
				this.shockMode = true;
				this.flashVer = parseInt( /\s\d*\.\d*\s/.exec(sDesc).toString().substring( 0, /\s\d*\.\d*\s/.exec(sDesc).toString().indexOf('.') ) );
				this.rv = sDesc.substr( sDesc.lastIndexOf("r") + 1, sDesc.length );
			};
		}
		else if ( is.ie ) { //  && is.win
			strCommand =    'function checkIE( obj ) { ' +
							'	aFlashPlugins = [];' +
							'	for ( i = 2; i < 11; i++ ) {' +
							'		try {' +
							'			aFlashPlugins[i] = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + i );' +
							'		}' +
							'		catch ( ex ) {};' +
							'	}' +
							'	for ( i = 0; i < aFlashPlugins.length; i++ ) {' +
							'		if ( typeof aFlashPlugins[i] == "object" ) {' +
							'		obj.shockMode = true;' +
							'		obj.flashVer = i;' +
							'		}' +
							'	}' +
							'}';
			eval( strCommand );
			checkIE( this );
		};
		this.ver = parseFloat( this.flashVer + '.' + this.rv );
		// nincs plugin
		if ( !this.shockMode ) {
			fError();
		};
		// IE és kisebb az activeX fő verziószáma
		if ( ( is.ie && is.win ) && this.flashVer < this.minVerRound ) {
			fError();
		};
		// a plugin alapú böngészőkben a plugin kiadását is ellenőrizzük (rv)
		if ( ( is.ns4 || is.gecko || is.opera || is.ie5mac || is.khtml ) && this.ver < nVer ) {
			fError();
		};
		// scriptable: alapbeállítások szerint ezekben van scriptelhető flash plugin
		// win  : ie5, ie55, ie6;      moz1, ns7 && plugin v6.47;  ! fb, ns4, o6, o7
		// linux: moz1, ns7
		// mac  : ns7 && plugin v6.47;                             ! moz, cm, ie5, saf
		if ( is.ie && !is.mac ) {
			this.scriptable = true;
		};
		if ( is.gecko ) {
			// ha a geckó és scriptable = null, akkor még nem futott le az időzítés
			this.scriptable = null;
			this.elEmbed = document.createElement('embed');
			this.elEmbed.type = 'application/x-shockwave-flash';
			this.elEmbed.src = 'data:application/x-shockwave-flash;base64,RldTBhsAAABIAZAAZAAADAEAQwL%2F%2F%2F9AAAAA';
			this.elEmbed.width = 0;
			this.elEmbed.height = 0;
			// általában load a gyorsabb!
			// XXX Firefox 1.5 Bad NPOject as provate data
			//addEvent( window, 'load', flash.appendGeckoScriptable );
			//this.interval = setInterval( 'flash.appendGeckoScriptable()', 1 );
		};
	},
	appendGeckoScriptable : function() {
		if ( document.body && !this.bAppend ) {
			flash.bAppend = true;
			clearInterval( flash.interval );
			document.body.appendChild( flash.elEmbed );
			flash.interval = setInterval( function() { flash.checkGeckoScriptable(false) }, 1 );
			flash.timeout  = setTimeout(  function() { flash.checkGeckoScriptable(true) }, 20000 );
		};
	},
	checkGeckoScriptable : function( bEnd ) {
		flash.scriptable = ( typeof flash.elEmbed.SetVariable == 'function' ) ? true : false; 
		if ( flash.scriptable || bEnd ) {
			flash.elEmbed.parentNode.removeChild( flash.elEmbed );
			clearInterval( flash.interval );
		};
		/*if ( flash.fScriptableError && !flash.scriptable ) {
			flash.fScriptableError();
		};*/
	}
};
flash.getFlashCheck( 6.49, function() {}, function() {} ); // ez itt nem változtatható meg!
/**
 * sendToFlash - visszatérési értéket NEM kívánó flash föggvények hívása. Maga végzi el a letöltődési vizsgálatot.
 * @param sId String            A object id-je.
 * @param sFunctionName String  A meghívandó funkció neve nagy- és kisbetűérkékenyen.
 * @param aArguments Array      A függvénynek átadandó argumentumok, ezek száma minden függvény esetén egyediek.
 */
function sendToFlash( sId, sFunctionName, aArguments ) {
	var elFlash;
	elFlash = ( is.ie ) ? document.all[sId] : document.embeds[sId];
	if ( !elFlash ) {
		return false;
	};
	if ( typeof elFlash.PercentLoaded == 'undefined' ) {
		setTimeout( function() {
			sendToFlash( sId, sFunctionName, aArguments )
		}, 200 );
		return null;
	};
	if ( elFlash.PercentLoaded() != 100 ) {
		setTimeout( function() {
			sendToFlash( sId, sFunctionName, aArguments )
		}, 200 );
		return null;
	};
	if ( typeof elFlash[sFunctionName] == 'undefined' ) {
		return false;
	};
	switch( sFunctionName ) {
		case 'GotoFrame' :
			elFlash.GotoFrame( aArguments[0] ); // GotoFrame( frameNumber ) :: GotoFrame(24);
			break;
		case 'LoadMovie' :
			elFlash.LoadMovie( aArguments[0], aArguments[1] ); // LoadMovie( layerNumber, url ) :: LoadMovie(0, "mymovie.swf");
			break;
		case 'Pan' :
			elFlash.Pan( aArguments[0], aArguments[1], aArguments[2] ); // Pan ( x, y, mode )  :: Pan(50, 50, 1) 
			break;
		case 'Play' :
			elFlash.Play() ; // Play()
			break;
		case 'Rewind' :
			elFlash.Rewind() ; // Rewind()
			break;
		case 'SetVariable' :
			elFlash.SetVariable( aArguments[0], aArguments[1] ); // SetVariable( variableName, value ) :: SetVariable("/Form:UserName", "John Smith");
			break;
		case 'SetZoomRect' :
			elFlash.SetZoomRect( aArguments[0], aArguments[1], aArguments[2], aArguments[3] ); // SetZoomRect ( left, top, right, bottom ) :: SetZoomRect(0, 0, 200, 200);
			break;
		case 'StopPlay' :
			elFlash.StopPlay() ; // StopPlay()
			break;
		case 'Zoom' :
			elFlash.Zoom( aArguments[0] ); // Zoom( percent ) :: Zoom(50)
			break;
		case 'TCallFrame' :
			elFlash.TCallFrame( aArguments[0], aArguments[1] ); // TCallFrame( target, frameNumber ) :: TCallFrame("/", 4);
			break;
		case 'TCallLabel' :
			elFlash.TCallLabel( aArguments[0], aArguments[1] ); // 	TCallLabel( target, label ) :: TCallLabel("/", "HandleScriptNotify");
			break;
		case 'TGotoFrame' :
			elFlash.TGotoFrame( aArguments[0], aArguments[1] ); // TGotoFrame( target, frameNumber ) :: TGotoFrame("/MovieClip", 2);
			break;
		case 'TGotoLabel' :
			elFlash.TGotoLabel( aArguments[0], aArguments[1] ); // TGotoLabel( target, label ) :: TGotoLabel("/MovieClip", "MyLabel");
			break;
		case 'TPlay' :
			elFlash.TPlay( aArguments[0] ); // TPlay( target ) :: TPlay("/MovieClip");
			break;
		case 'TSetProperty' :
			elFlash.TSetProperty( aArguments[0], aArguments[1], aArguments[2] ); // TSetProperty( target, property, value) :: TSetProperty("/MovieClip", nameIndex, "NewName");
			break;
		case 'TStopPlay' :
			elFlash.TStopPlay( aArguments[0] ); // TStopPlay( target )
			break;
	};
	return true;
};
/**
 * getFromFlash - visszatérési értéket kívánó flash föggvények hívása.
 * @param sId String            A object id-je.
 * @param sFunctionName String  A meghívandó funkció neve nagy- és kisbetűérkékenyen.
 * @param aArguments Array      A függvénynek átadandó argumentumok, ezek száma minden függvény esetén egyediek.
 * @return String               Az egyes függvények más-más visszatérési értéket adnak.
 */
function getFromFlash( sId, sFunctionName, aArguments ) {
	elFlash = ( is.ie ) ? document.all[sId] : document.embeds[sId];
	if ( !elFlash ) {
		return false;
	};
	if ( typeof elFlash[sFunctionName] == 'undefined' ) {
		return false;
	};
	switch( sFunctionName ) {
		// TCurrentFrame( target ), TCurrentLabel(target), TGetProperty( target, property), TGetPropertyAsNumber (target, property)
		case 'GetVariable' :
			return elFlash.GetVariable( aArguments[0] ); // GetVariable( varName ) :: GetVariable("/Form/RadioButton:Value");
			break;
		case 'IsPlaying' :
			return elFlash.IsPlaying(); // IsPlaying();
			break;
		case 'PercentLoaded' :
			return elFlash.PercentLoaded(); // PercentLoaded();
			break;
		case 'TotalFrames' :
			return elFlash.TotalFrames(); // TotalFrames();
			break;
		case 'TCurrentFrame' :
			return elFlash.TCurrentFrame( aArguments[0] ); // TCurrentFrame( target ) :: TCurrentFrame("/MovieClip");
			break;
		case 'TCurrentLabel' :
			return elFlash.TCurrentLabel( aArguments[0] ); // TCurrentLabel( target ) :: TCurrentLabel("/MovieClip")
			break;
		case 'TGetProperty' :
			return elFlash.TGetProperty( aArguments[0], aArguments[1] ); // TGetProperty( target, property) :: TGetProperty("/", nameIndex);
			break;
		case 'TGetPropertyAsNumber' :
			return elFlash.TGetPropertyAsNumber( aArguments[0], aArguments[1] ); // 	TGetPropertyAsNumber (target, property) :: TGetProperty("/", framesLoadedIndex);
			break;
	};
};
/**
 * createFlashVBSriptHandler - csak IE: flash -> js kapcsolat kiépítése: fsCommand
 * @param aObjectId Array  Azon OBJECT elemek id-i, amelyekkel kapcsolatot akarunk létrehozni.
 */
function createFlashVBSriptHandler( aObjectId ) {
	if ( !is.ie || is.ie5mac ) return false;
	var elVbs, elHead, i;
	elHead = document.getElementsByTagName('HEAD')[0];
	if ( !elHead ) {
		return alert( 'A Flash VBSript eseménykezelőjét nem sikerült létrehozni' );
	};
	for ( i = 0; i < aObjectId.length; i++ ) {
		elVbs = document.createElement('SCRIPT');
		elVbs.language = 'VBScript';
		elVbs.text = '\n'
				 + 'on error resume next \n'
				 + 'Sub ' + aObjectId[i] + '_FSCommand(ByVal command, ByVal args)\n'
				 + '  call ' + aObjectId[i] + '_DoFSCommand(command, args)\n'
				 + 'end sub\n';
		elHead.appendChild( elVbs );
	};
};
/**
 * createFlashEmbed - csak Gecko: egy OBJECT scriptelhető EMBED-ra való cseréje
 * @param aObjectId Array  Azon OBJECT elemek id-i, amelyeket szkriptelhetővé akarjuk tenni.
 */
function createFlashEmbed( aObjectId ) {
	var i, elObject, elEmbed, sSrc, j, elChild;
	if ( !( is.gecko && navigator.mimeTypes && navigator.mimeTypes['application/x-shockwave-flash'] ) ) {
		return false;
	};
	for ( i = 0; i < aObjectId.length; i++ ) {
		elObject = document.getElementById( aObjectId[i] );
		if ( !elObject ) {
			continue;
		};
		elEmbed = document.createElement('embed');
		elEmbed.name = elObject.id;
		elEmbed.className = elObject.className;
		elEmbed.setAttribute( 'pluginspage', 'http://www.macromedia.com/go/getflashplayer' );
		elEmbed.type = 'application/x-shockwave-flash';
		elEmbed.width = elObject.width;
		elEmbed.height = elObject.height;
		elEmbed.swLiveConnect = true;
		for ( j = 0; j < elObject.childNodes.length; j++ ) {
			elChild = elObject.childNodes[j];
			if ( elChild.nodeType != Node.ELEMENT_NODE ) {
				continue;
			};
			if ( elChild.tagName.toLowerCase() == 'param' ) {
				switch ( elChild.name.toLowerCase() ) {
					case 'movie' :
						elEmbed.src = elChild.value;
						break;
					case 'quality' :
					case 'scale' :
					case 'wmode' :
					case 'menu' :
					case 'flashvars' :
						elEmbed.setAttribute( elChild.name.toLowerCase(), elChild.value );
						break;
				};
			};
		};
		elObject.parentNode.replaceChild( elEmbed, elObject );
		elEmbed.id = elEmbed.name;
	};
};
function searchClassinelement( el, classname) {
	var elList = el.getElementsByTagName("*");
	var elListlength = elList.length;
	var s = 0;
	var list = Array();

	for( s; s<elListlength; s++) {

		if(hasClass(elList[s], classname)) {
			list[list.length] = elList[s];
		}
	}
	return list;
};

function URLDecode( encoded )
{
   // Replace + with ' '
   // Replace %xx with equivalent character
   // Put [ERROR] in output if %xx is invalid.
   var HEXCHARS = "0123456789ABCDEFabcdef"; 
   //var encoded = document.URLForm.F2.value;
   var plaintext = "";
   var i = 0;
   while (i < encoded.length) {
	   var ch = encoded.charAt(i);
	   if (ch == "+") {
		   plaintext += " ";
		   i++;
	   } else if (ch == "%") {
			if (i < (encoded.length-2) 
					&& HEXCHARS.indexOf(encoded.charAt(i+1)) != -1 
					&& HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
				plaintext += unescape( encoded.substr(i,3) );
				i += 3;
			} else {
				alert( 'Bad escape combination near ...' + encoded.substr(i) );
				plaintext += "%[ERROR]";
				i++;
			}
		} else {
		   plaintext += ch;
		   i++;
		}
	} // while
   return plaintext;
};
/**
*
*  URL encode / decode
*  http://www.webtoolkit.info/
*
**/

var Url = {

	// public method for url encoding
	encode : function (string) {
		return escape(this._utf8_encode(string));
	},

	// public method for url decoding
	decode : function (string) {
		return this._utf8_decode(unescape(string));
	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

}

/**
 * 
 * @param {Object} currentValue
 * @param {Object} newValue
 * @param {Object} element
 */
function ranger( element, newValue ){
	var currentValue = element.value;

	if( element.lastValue && element.lastValue.length > ( currentValue.length + 1 ) ){
		element.lastValue = currentValue;
		return true;
	}
	if( element.autocomplete == null || element.autocomplete == 'on' ){
		element.setAttribute( 'autocomplete', 'off' );
		element.autocomplete = 'off';
	}
	//"off"
	proform.helper.XMLHttpRequest.markUpdate(element);
	if (element.createTextRange) {//IE
		element.value = newValue;
		sRange = element.createTextRange();
		newValue = newValue.substr(currentValue.length);
		if (newValue != '') {
			sRange.findText(newValue);
			sRange.select();
		}
	}
	else { //Mozilla or other
		element.value = newValue;
		element.setSelectionRange(currentValue.length, newValue.length);
	}
	element.lastValue = currentValue;
}


function ZipCodeCompleater(res, elementName, oT){
		var i, element, zip, zip_select, country, country_text, town, town_select, address;
		
		eval(res);
		
		element = oT[elementName];
		for (i in oT) {
			switch (true) {
				case /.*zip(\:[ab])?$/.test(i):
					zip = oT[i];
					break;
				case /.*zip_s(\:[ab])?$/.test(i):
					zip_select = oT[i];
					break;
				case /.*country(\:[ab])?$/.test(i):
					country = oT[i];
					break;
				case /.*country_text(\:[ab])?$/.test(i):
					country_text = oT[i];
					break;
				case /.*town(\:[ab])?$/.test(i):
					town = oT[i];
					break;
				case /.*town_s(\:[ab])?$/.test(i):
					town_select = oT[i];
					break;
				case /.*address(\:[ab])?$/.test(i):
					address = oT[i];
					break;
			}
		}
		element.res = res;
		switch (true) {
			case (res === true):
				break;
			case /.*country(\:[ab])?$/.test(elementName):
			case /.*country_text(\:[ab])?$/.test(elementName):
				if (!res) {
					proform.condition.warning(true, [element], [ZipCodeCompleater.prototype.ERROR.Country]);
				}
				town.value = '';
				displayChanger(town_select, false);
				displayChanger(town, true);
				zip.value = '';
				zip.format = res.zip_format;
				displayChanger(zip_select, false);
				displayChanger(zip, true);
				address.value = '';
				break;
			case /.*zip(\:[ab])?$/.test(elementName):
			case /.*zip_s(\:[ab])?$/.test(elementName):
				if (!res) {
					proform.condition.warning(true, [element], [ZipCodeCompleater.prototype.ERROR.Zip.DontIsset]);
					return false;
				}
				if( res.notchecked ){
					proform.condition.warning(false, [element], [ZipCodeCompleater.prototype.ERROR.Zip.DontIsset]);
					country.options[country.selectedIndex].notchecked = true;
					return true;
				}
				if (/.*zip(\:[ab])?$/.test(elementName) && res !== true) {
				//ranger(zip, res[0]);
				}
				if (res[1][1]) {
					while (town_select.childNodes.length != 0) {
						town_select.removeChild(town_select.lastChild);
					}
					for (i in res[1]) {
						clonedNode = document.createElement('option');
						clonedNode.setAttribute('value', res[1][i]);
						clonedNode.appendChild(document.createTextNode(res[1][i]));
						town_select.appendChild(clonedNode);
					}
					displayChanger(town_select, true);
					displayChanger(town, false);
				}
				else {
					town.value = ( res[1][0] ) ? res[1][0] : '';	
					displayChanger(town_select, false);
					displayChanger(town, true);
				}
				proform.condition.warning(false, [element], [ZipCodeCompleater.prototype.ERROR.Zip.DontIsset]);
				
				break;
			case /.*town(\:[ab])?$/.test(elementName):
			case /.*town_s(\:[ab])?$/.test(elementName):
				if (!res) {
					proform.condition.warning(true, [element], [ZipCodeCompleater.prototype.ERROR.City]);
					displayChanger(zip_select, false);
					displayChanger(zip, true);
					zip.value = '';
					return false;
				}
				proform.condition.warning(!res, [element], [ZipCodeCompleater.prototype.ERROR.City]);
				if( res.notchecked ){
					country.options[country.selectedIndex].notchecked = true;
					return true;
				}
				
				if (/.*town(\:[ab])?$/.test(elementName) && res !== true) {
					ranger(town, res[0]);
				}
				if (res[1] && res[1][1] && element.value.length >= 3) {
					while (zip_select.childNodes.length != 0) {
						zip_select.removeChild(zip_select.lastChild);
					}
					for (i in res[1]) {
						clonedNode = document.createElement('option');
						if (typeof res[1][i] == 'object') {
							var xobj = res[1][i][0];
							clonedNode.setAttribute('value', xobj.value);
							clonedNode.appendChild(document.createTextNode(xobj.name));
						}
						else {
							clonedNode.setAttribute('value', res[1][i]);
							clonedNode.appendChild(document.createTextNode(res[1][i]));
						}
						zip_select.appendChild(clonedNode);
					}
					displayChanger(zip_select, true);
					displayChanger(zip, false);
					proform.condition.required( true, [zip_select] );
					proform.condition.warning(false, [element], [ZipCodeCompleater.prototype.ERROR.City]);
				}
				else {
					if( res !== true ){
						zip.value = (res[1] && element.value.length >= 3) ? res[1][0] : '';
					}
					displayChanger(zip_select, false);
					displayChanger(zip, true);
					proform.condition.warning(false, [element], [ZipCodeCompleater.prototype.ERROR.City]);
				}
				proform.condition.warning( zip.value != '' && !proform.condition.checkFormat('format:' + zip.format, zip.value), [zip], [ZipCodeCompleater.prototype.ERROR.Zip.NotPass]);
				break;
			case /.*address(\:[ab])?$/.test(elementName):
				
				break;
		}
		return true;
	};
ZipCodeCompleater.prototype.ERROR = { 'Country':'', 'Zip':{'DontIsset':'','NotPass':''},'City':''};

function ZipCodeCheckKeys(oEvent, keyCode){
	if (typeof keyCode == 'undefined') {
		keyCode = oEvent.keyCode;
		if ((keyCode < 32) || (keyCode >= 33 && keyCode <= 46) || (keyCode >= 112 && keyCode <= 123)) {
			return false;
		}
		return true;
	}
	return (oEvent.keyCode == keyCode);
};

/**
 * @param {Object} _parent_
 * @param {Object} oO
 * @param {Object} checkFull
 */
var ZipCodes = function( _parent_, oO, checkFull ){
	/**
	 * Ez egy template amit a new ZipCodes(...) helyére fogunk illeszteni
	 */
	this.template = function(){
		proform.helper.activeForm.disableElement( ( oT.country.value == '000') ? false : true, oT.country_text);
		
		/* Ország kiválasztás */
		if (sEventId == 'onFocusOut' && sFireId == 'country') {
			if( oT.country_text.value != '' && oT.country.value != '000' ){
				oT.country_text.value = '';
			}
			oO.set('setCountry', oT.country.value, function(res){
				return ZipCodeCompleater(res, 'country', oT);
			});
		}
		if ( oEvent && ZipCodeCheckKeys(oEvent) && sEventId == 'onModify' && sFireId == 'country_text' && oT.country_text.value.length >= 1 ) {
			oO.set('setCountryText', Url.encode(oT.country_text.value), function(res){
				return ZipCodeCompleater(res, 'country_text', oT);
			});
		}
		/* IRSZ kiválasztás */
		if ( ( sEventId == 'onModify' || sEventId == 'onFocusOut') && sFireId == 'zip' && RegExp( '^' + oT.zip.format + "$" ).test(oT.zip.value) ) {
			if (oT.country.value != '000' && oT.country.value != '-1') {
				proform.helper.XMLHttpRequest.markUpdate(oT.zip);
			}
			oO.set('setZipCode', Url.encode(oT.zip.value), function(res){
				return ZipCodeCompleater(res, 'zip', oT);
			});
		}
		else 
			if (sFireId == 'zip' && !( oT.country.options[oT.country.selectedIndex].notchecked ) ) {
				displayChanger(oT.town, true);
				displayChanger(oT.town_s, false);
				oT.town.value = '';
			}
		else 
			if (sFireId == 'zip' && RegExp( '^' + oT.zip.format + "$" ).test(oT.zip.value) ) {
			}
		
		if (sEventId == 'onFocusOut' && sFireId == 'zip_s') {
			oO.set('setZipCode', Url.encode(oT.zip_s.value), function( res ){
				return ZipCodeCompleater(res, 'zip_s', oT);
			});
		}
		/* Város kiválasztás */
		if ( oEvent && ZipCodeCheckKeys(oEvent) && sEventId == 'onModify' && sFireId == 'town') {
			if ( oT.country.value == '000' || oT.town.value.length >= 3 ) {
				oO.set('setCityName', Url.encode(oT.town.value), function(res){
					return ZipCodeCompleater(res, 'town', oT)
				});
			}
			else 
				if ( oT.town.value.length < 3 && !( oT.country.options[oT.country.selectedIndex].notchecked ) ) {
					oT.zip.value='';
					oT.town.lastValue= '';
					displayChanger( oT.zip, true );
					displayChanger( oT.zip_s, false );
					ZipCodeCompleater(true, 'town', oT);
				}
		}
		if ( oT.country.value != '000' && oEvent && ZipCodeCheckKeys(oEvent, 8) && sEventId == 'onModify' && sFireId == 'town' ) {
			if( oT.zip.style.display == 'none' ){
				displayChanger( oT.zip, true );
				displayChanger( oT.zip_s, false );
			}
			oT.zip.value = '';
		}
		if (sEventId == 'onFocusOut' && sFireId == 'town_s') {
			oO.set('setCityName', Url.encode(oT.town_s.value), function(res){
				return ZipCodeCompleater(res, 'town_s', oT)
			});
		}

		/* Cím kiválasztás */
		if (oEvent && ZipCodeCheckKeys(oEvent) && ( sEventId == 'onModify' || sEventId == 'onFocusOut' ) && sFireId == 'address') {
			oO.set('setAddress', Url.encode(oT.address.value), true);
		}
		if (sEventId == 'onFocusOut') {
			if (!oT.zip.format) {
				oT.zip.format = '.*';
			}
			proform.condition.warning( oT.zip.value != '' && !proform.condition.checkFormat('format:' + oT.zip.format, oT.zip.value), [oT.zip], []);
		}
		proform.condition.required( oT.zip_s.value == '-1', [oT.zip_s] );

		var empty = true;
		empty = Boolean( empty && oT.zip.value == '' && ( oT.zip_s.selectedIndex <= 0 || oT.zip_s.value == '') );
		empty = Boolean( empty && oT.town.value == '' && ( oT.town_s.value == '-1' || oT.town_s.value == '' ) );
		empty = Boolean( empty && oT.address.value == '' );
		
		
		if ( checkFull || !empty ) {
			aReturn.push(proform.condition.required( ( ( oT.country.value == '-1' || oT.country.value == '000') && oT.country_text.value == ''), [oT.country, oT.country_text]));
			if( sEventId && sEventId != 'onInit' ){
				aReturn.push(proform.condition.warning(  ( oT.zip.value != '' && !RegExp( '^' + oT.zip.format + "$" ).test(oT.zip.value) ), [oT.zip, oT.zip_s], [ZipCodeCompleater.prototype.ERROR.Zip.NotPass] ) );
			}
			aReturn.push(proform.condition.required( ( oT.zip.value == '' && oT.zip_s.selectedIndex <= 0), [oT.zip, oT.zip_s]));
			aReturn.push(proform.condition.required( ( oT.town.value == '' && (oT.town_s.value == '-1' || oT.town_s.value == '')), [oT.town, oT.town_s]));
			aReturn.push(proform.condition.required( ( oT.address.value == ''), [oT.address]));
		}
		
	};

	var sFnTpl = String( this.template );
	sFnTpl = sFnTpl.substring( 13 );
	sFnTpl = sFnTpl.substr( 0, sFnTpl.length-1 );
	if( checkFull == null ){
		checkFull = true;
	}
	var i;
	for ( i in _parent_.elements ){
		i = i.replace( /(\:[ab])?/g, "" );
		switch( true ){
			case /address$/.test(i):
				sFnTpl = sFnTpl.replace( /[\'\"]address[\'\"]/g, "'" + i + "'" );
				sFnTpl = sFnTpl.replace( /oT\.address/g, "oT." + i );
				sFnTpl = sFnTpl.replace( /oT\.address\.value/g, "oT." + i + ".value" );
			break;
			case /country$/.test(i):
				sFnTpl = sFnTpl.replace( /[\'\"]country[\'\"]/g, "'" + i + "'" );
				sFnTpl = sFnTpl.replace( /oT\.country/g, "oT." + i );
				sFnTpl = sFnTpl.replace( /oT\.country\.value/g, "oT." + i + ".value" );
			break;
			case /country_text$/.test(i):
				sFnTpl = sFnTpl.replace( /[\'\"]country_text[\'\"]/g, "'" + i + "'" );
				sFnTpl = sFnTpl.replace( /oT\.country_text/g, "oT." + i );
				sFnTpl = sFnTpl.replace( /oT\.country_text.value/g, "oT." + i + ".value" );
			break;
			case /town$/.test(i):
				sFnTpl = sFnTpl.replace( /[\'\"]town[\'\"]/g, "'" + i + "'" );
				sFnTpl = sFnTpl.replace( /oT\.town/g, "oT." + i );
				sFnTpl = sFnTpl.replace( /oT\.town\.value/g, "oT." + i + ".value" );
			break;
			case /town_s$/.test(i):
				sFnTpl = sFnTpl.replace( /[\'\"]town_s[\'\"]/g, "'" + i + "'" );
				sFnTpl = sFnTpl.replace( /oT\.town_s/g, "oT." + i );
				sFnTpl = sFnTpl.replace( /oT\.town_s\.value/g, "oT." + i + ".value" );
			break;
			case /zip$/.test(i):
				sFnTpl = sFnTpl.replace( /[\'\"]zip[\'\"]/g, "'" + i + "'" );
				sFnTpl = sFnTpl.replace( /oT\.zip/g, "oT." + i );
				sFnTpl = sFnTpl.replace( /oT\.zip\.value/g, "oT." + i + ".value" );
			break;
			case /zip_s$/.test(i):
				sFnTpl = sFnTpl.replace( /[\'\"]zip_s[\'\"]/g, "'" + i + "'" );
				sFnTpl = sFnTpl.replace( /oT\.zip_s/g, "oT." + i );
				sFnTpl = sFnTpl.replace( /oT\.zip_s\.value/g, "oT." + i + ".value" );
			break;
		}
	}
	sFnTpl = sFnTpl.replace( /checkFull/g, checkFull );
	var processor = String( _parent_.processor );
	var aMatch = processor.match(/new ZipCodes\((.*)?this(.*)?,(.*)?,(.*)?\);/);
	if ( aMatch == null ) {
		aMatch = processor.match( /new ZipCodes\((.*)?this(.*)?,(.*)?\);/ );
	}
	oO = aMatch[3].trim();
	
	sFnTpl = sFnTpl.replace( /oO/g, oO );
	var zipcodes_reg = new RegExp('(.*)(new ZipCodes\((.*)?this(.*)?,(.*)\);)(.*)');
	zipcodes_reg.global = true;
	zipcodes_reg.multiline = true;
	processor = processor.replace( zipcodes_reg, sFnTpl );
	eval( '_parent_.processor = ' + processor + ';' );
	_parent_.processor( document.getElementById( _parent_.id ).tBodies[0].oBlockElements.elements );
}

function isset( el ){
	return (typeof(el)!='undefined')? true: false;
}

