/**
 * eteleon JavaScript Toolkit
 */

function JS()
{
	this.ns		= (document.layers);
	this.ie		= (document.all);
	this.w3 	= (document.getElementById && !this.ie);
	this.opera 	= ( navigator.userAgent.search( "Opera" ) != -1 );
	this.safari	= ( navigator.userAgent.search( "AppleWebKit" ) != -1 );
	
	/**
	 * Alias für getElementById
	 *
	 * @param String id ID des HTML-Elements
	 * @return Object HTML-Element
	 */	
	this.e = function( id )
	{
		return document.getElementById( id );		
	}

	/**
	 * Alias für getElementsByName
	 *
	 * @param String name Name der HTML-Elemente
	 * @return Array mit HTML-Elements
	 */	
	this.n = function( name )
	{
		return document.getElementsByName( name );
	}
	
	/**
	 * Alias für getElementsByTagName
	 *
	 * @param String name Der Tag-Name des gesuchten HTML-Elements
	 * @return Array mit HTML-Elementen
	 */
	this.tn = function( name )
	{
		return document.getElementsByTagName( name );
	}
	
	/**
	 * Alias für createElement
	 *
	 * @param String tag_name Tag-Name
	 * @return Object
	 */
	this.ce = function( tag_name )
	{
		return document.createElement( tag_name );
	}
	
	/**
	 * Alias für createTextNode
	 *
	 * @param Stirng type Text
	 * @return Object
	 */
	this.ctn = function( text )
	{
		return document.createTextNode( text );
	}
	
	/**
	 * Ersetzt den innerHTML-Value eines HTML-Elements
	 *
	 * @param String id ID des HTML-Elements
	 * @param String value Neuer innerHTML-Value
	 */
	this.replace = function( id, value )
	{
		if ( !_idExists( id ) )
			return;
		
		// innerHTML setzen
		this.e( id ).innerHTML = value;
	}
	
	/**
	 * Blendet ein Element aus bzw. ein
	 *
	 * @param String id ID des HTML-Elements
	 */
	this.toggle = function( id )
	{
		if ( !_idExists( id ) )
			return;
		
		// Nicht ausgeblendet?
		if ( this.e( id ).style.display != 'none' )
			this.e( id ).style.display = 'none';
		else // Auf Standard zurücksetzen
			this.e( id ).style.display = '';
	}
	
	/**
	 * Gibt den Typ eines Elements zurück
	 *
	 * @param String id ID des Elements
	 * @return String Typ-Bezeichnung
	 */
	this.getType = function( id )
	{
		if ( !_idExists( id ) )
			return;
		
		// Rückgabe
		return typeof this.e( id );
	}
	
	/**
	 * Gibt den Tag-Namen eines Elements zurück
	 *
	 * @param String id ID des Elements
	 * @return String Tag-Name
	 */
	this.tagName = function( id )
	{
		if ( !_idExists( id ) )
			return;
		
		// Rückgabe
		return this.e( id ).tagName;
	}
	
	/**
	 * Prüft, ob sich ein bestimmtes Element im Array befindet
	 *
	 * @param Mixed elem zu suchendes Element
	 * @param Array array zu durchsuchendes Array
	 * @return Bool Element im Array enthalten ja/nein
	 */
	this.inArray = function( elem, array )
	{
		if ( !this.isObject( array ) )
			return false;
		
		for ( i = 0; array[i]; ++i )
			if ( array[i] == elem )
				return true;
				
		return false;
	}
	
	/**
	 * Löscht ein Element aus einem Array
	 *
	 * @param Mixed elem Zu löschendes Element im Array
	 * @param Array array Das Array
	 * @return Array
	 */
	this.unsetArrayElem = function( elem, array )
	{
		if ( !this.isObject( array ) )
		{
			alert( 'Als zweiter Parameter wird ein Array erwartet: ' + this.getType( array ) );
			return;
		}
		
		var new_array = new Array();
		
		for ( var i = 0; array[i]; ++i )
			if ( array[i] != elem )
				new_array.push( array[i] );
				
		// Rückgabe
		return new_array;
	}
	
	/**
	 * Prüft, ob es sich bei dem Parameter um einen String handelt
	 *
	 * @param Mixed value zu prüfender Parameter
	 * @return Bool
	 */
	this.isString = function( value )
	{
		return (typeof( value ) == 'string');
	}
	
	/**
	 * Prüft, ob es sich bei dem Parameter um ein Objekt handelt
	 *
	 * @param Mixed value zu prüfender Parameter
	 * @return Bool
	 */
	this.isObject = function( value )
	{
		return (typeof( value ) == 'object');
	}
	
	/**
	 * Prüft, ob es sich bei dem Parameter um eine Zahl handelt
	 *
	 * @param Mixed value zu prüfender Parameter
	 * @return Bool
	 */
	this.isNumber = function( value )
	{
		if( js.isString && value.match( /^\d+$/ ) )
			return true;
		
		return (typeof( value ) == 'number');
	}
	
	/**
	 * Prüft, ob es sich bei dem Parameter um einen Bool'schen Wert handelt
	 *
	 * @param Mixed value zu prüfender Parameter
	 * @return Bool
	 */
	this.isBoolean = function( value )
	{
		return (typeof( value ) == 'boolean');
	}
	
	/**
	 * Prüft, ob es sich bei dem Parameter um einen undefinierten Typ handelt
	 *
	 * @param Mixed value zu prüfender Parameter
	 * @return Bool
	 */ 
	this.isUndefined = function( value )
	{
		return (typeof( value ) == 'undefined');
	}
	
	/**
	 * Prüft, ob der angegebene Parameter leer ist
	 *
	 * @param Mixed value zu prüfender Parameter
	 * @return Bool
	 */
	this.isEmpty = function( value )
	{
		if ( this.isString( value ) && ( value == '' || value == 'undefined' ) )
			return true;
			
		if ( this.isUndefined( value ) )
			return true;

		if ( this.isBoolean( value ) )
			return !value;
		
		if ( this.isObject( value ) && value.length == 0 )
			return true;
			
		// Rückgabe
		return false;
	}
	
	/**
	 * Öffnet ein Popup mit Focus
	 *
	 * @param String url URL der Seite im Popup
	 * @param String name Name des Popups
	 * @param Integer width Breite des Popups (Standard: 400)
	 * @param Integer height Höhe des Popups (Standard: 300)
	 * @param Bool scollbars Scrollbalken ja/nein
	 * @param Bool resizable Skalierbar ja/nein
	 * @param Bool status Statusbar ja/nein
	 * @return Window-Handle
	 */
	this.popup = function( url, name, width, height, scrollbars, resizable, status )
	{
		return _openWindow( url, name, width, height, scrollbars, resizable, status, true );
	}
	
	/**
	 * Öffnet ein Popup ohne Focus
	 *
	 * @param String url URL der Seite im Popup
	 * @param String name Name des Popups
	 * @param Integer width Breite des Popups (Standard: 400)
	 * @param Integer height Höhe des Popups (Standard: 300)
	 * @param Bool scollbars Scrollbalken ja/nein
	 * @param Bool resizable Skalierbar ja/nein
	 * @param Bool status Statusbar ja/nein
	 * @return Window-Handle
	 */
	this.popunder = function( url, name, width, height, scrollbars, resizable, status )
	{
		return _openWindow( url, name, width, height, scrollbars, resizable, status, false );
	}
	
	/**
	 * Legt einen Layer mit 85% Suchtbarkeit über die Seite
	 *
	 * @param Bool display Layer sichtbar ja/nein
	 * @param Integer zindex Z-Index
	 */	
 	this.contentOverlay = function( display, zindex )
 	{
 		if ( display === true ) {
 			
 			if ( js.e('content_overlay') && js.e('content_overlay').style.display != 'none' ) {
 				var arrayPageSize = this.getPageSize();
				js.e('content_overlay').style.height = (arrayPageSize[1]+ 'px'); 				
 				window.onresize = function(){ js.contentOverlay( display, zindex ); };
 				return;
 			} 			
 			
 			var objBody = document.getElementsByTagName("body").item(0);
 			if ( navigator.userAgent.search("MSIE 6") != -1 ) {
			
				objOverlay = document.createElement( 'iframe' );
				objOverlay.id					= 'content_overlay';
				objOverlay.setAttribute( 'border', '0' );
				objOverlay.setAttribute( 'frameborder', '0' );
				objOverlay.setAttribute( 'marginheight', '0' );
				objOverlay.setAttribute( 'marginwidth', '0' );
				objOverlay.frameborder 			= 0;
				objOverlay.marginheight			= 0;
				objOverlay.marginwidth			= 0;
				objOverlay.style.background 	= '#FFFFFF';			
				objOverlay.style.border			= 'none';			
				objOverlay.style.padding		= '0';			
				objOverlay.style.margin			= '0';
 			}
			else {
			
				var objOverlay 	= document.createElement("div");
				
				objOverlay.setAttribute('id','content_overlay');
			}
		 	
			objOverlay.style.display 	= 'none';
			objOverlay.style.position 	= 'absolute';
			objOverlay.style.top 		= '0';
			objOverlay.style.left 		= '0';
			objOverlay.style.zIndex 	= ( zindex ? zindex : 1 );
		 	objOverlay.style.width 		= '100%';			
			
			
			objBody.insertBefore(objOverlay, objBody.firstChild);	
			
			var objOverlay 		= this.e('content_overlay');
			var arrayPageSize 	= this.getPageSize();
				
			// set height of Overlay to take up whole page and show
			objOverlay.style.height = (arrayPageSize[1]+ 'px');
			objOverlay.style.display = 'block';	
			
 		}
 		else {

 			this.e( 'content_overlay' ).style.display = 'none';
		
			// make select boxes visible
//			selects = this.tn("select");
//		    for (i = 0; i != selects.length; i++)
//				selects[i].style.visibility = "visible";
 		}
 		
 		window.onresize = function(){ js.contentOverlay( display, zindex ); };
 	}	
	
 	/**
 	 * Faded elemente aus bzw. ein
 	 *
 	 * @param String id ID des Elements
 	 * @param String mode Modus (in, out)
 	 * @param Integer opacity Transparenz
 	 */
 	this.fadeElem = function( id, mode, opacity, delay )
 	{
		var elem = this.e( id );
 		var self = this;
 		
 		// Sichtbar machen
		if ( elem.style.display != 'block' )
			elem.style.display = 'block';
 		
 		if ( mode == 'in' )
		{
			opacity 		= opacity ? opacity + 10 : 0;
			moz_opacity		= opacity / 100;
			elem.style.opacity 		= moz_opacity;
			elem.style.mozopacity 	= moz_opacity;
			elem.style.khtmlopacity	= moz_opacity;
			elem.style.filter 		= 'Alpha(opacity=' + opacity + ')';
			
			if ( opacity >= 100 )
				return;
		}
		else if ( mode == 'out' )
		{
			opacity 				= opacity ? opacity - 10 : 100;
			moz_opacity				= opacity / 100;
			elem.style.opacity 		= moz_opacity;
			elem.style.mozopacity 	= moz_opacity;
			elem.style.khtmlopacity	= moz_opacity;
			elem.style.filter 		= 'Alpha(opacity=' + opacity + ')';
			
			// Ganz ausblenden
			if ( opacity <= 0 )
			{
				elem.style.display = 'none';
				return;
			}
		}
		else
			alert( 'Falscher Modus angegeben: ' + mode );
			
		// Warten?
		if ( delay > 0 )
 		{
 			setTimeout( function() { self.fadeElem( id, mode, opacity, 0 ); }, delay ); 
 			return;
 		}
			
		// Verzögerung
		setTimeout( function() { self.fadeElem( id, mode, opacity ); }, 100 );	
 	}
 	
	/**
	 * Positioniert ein Element an eine bestimmte Position
	 *
	 * @param String id ID des Elements
	 * @param String pos Positionierung (topLeft, topCenter, leftCenter, center (=centerCenter))
	 */
 	this.moveElem = function( id, pos )
	{
		if ( !_idExists( id ) )
			return;
		
		elem = this.e( id );
			
		if ( elem.style.display != 'block' )
			return;
			
		// Abmessungen
		elemHeight = elem.offsetHeight;
		elemWidth  = elem.offsetWidth;
		
		var yoffset 	= 0;
		var xoffset 	= 0;
		var docWidth 	= 0;
		var docHeight	= 0;
		
		if ( this.ie ) 
		{
			xoffset 	= _trueBody().scrollLeft;
			yoffset 	= _trueBody().scrollTop;
			docWidth	= _trueBody().offsetWidth;
			docHeight	= _trueBody().offsetHeight;
		}
		else 
		{
			xoffset 	= window.pageXOffset;
			yoffset 	= window.pageYOffset;
			docWidth	= self.innerWidth;
			docHeight	= self.innerHeight;		
		}	
		
		switch( pos )
		{
			case 'topLeft':
				elem.style.top 	= yoffset + 'px';
				elem.style.left	= xoffset; + 'px';
				break;
			case 'topCenter':
				elem.style.top	= yoffset + 'px';
				elem.style.left = ((docWidth / 2) - (elemWidth / 2) + xoffset) + 'px';
				break;
			case 'leftCenter':
				elem.style.top	= ((docHeight / 2) - (elemHeight / 2) + yoffset) + 'px';
				elem.style.left	= xoffset + 'px';
				break;
			case 'center':
			case 'centerCenter':
				docWidth 	= 780;
				docHeight   = 100 + elemHeight;
				elem.style.top	= ((docHeight / 2) - (elemHeight / 2) + yoffset) + 'px';
				elem.style.left = ((docWidth / 2) - (elemWidth / 2) + xoffset) + 'px';
				break;
		}
		setTimeout( 'js.moveElem(\'' + id + '\', \'' + pos + '\')', 300 );
	}
	
	/**
	 * Lädt ein JS-File in den Head nach
	 * --> Prüft, ob die Datei bereits included wurde
	 *
	 * @param String file Dateipfad
	 */
	this.loadJSFile = function( file )
	{
		if ( !this.isString( file ) )
			return;
		
		var script_tags = this.tn( 'script' );
		
		// Prüfen, ob die Datei schon geladen wurde
		for ( i = 0; script_tags[i]; ++i )
		{
			if ( !script_tags[i].src )
				continue;
			if ( script_tags[i].src.match(file) )
				return;
		}
		
		// Datei nachladen
		var head 	= js.tn( 'head' )[0];
		var script 	= document.createElement( 'script' );
			script.setAttribute( 'language', 'JavaScript' );
			script.setAttribute( 'type', 'text/javascript' );
			script.setAttribute( 'src', file );
			
		// Script in den Head schreiben
		head.appendChild( script );
	}
	
	/**
	 * Lädt ein JS-File in den Head nach
	 * --> Prüft, ob die Datei bereits included wurde
	 *
	 * @param String file Dateipfad
	 */
	this.loadCSSFile = function( file )
	{
		if ( !this.isString( file ) )
			return;
		
		var tags = this.tn( 'link' );
		
		// Prüfen, ob die Datei schon geladen wurde
		for ( i = 0; tags[i]; ++i )
		{
			if ( !tags[i].rel != 'stylesheet' )
				continue;
			if ( tags[i].href.match( file ) )
				return;
		}
		
		// Datei nachladen
		var body 	= js.tn( 'head' )[0];
		var link 	= document.createElement( 'link' );
			link.setAttribute( 'rel', 'stylesheet' );
			link.setAttribute( 'type', 'text/css' );
			link.setAttribute( 'href', file );
			
		// Script in den Head schreiben
		head.appendChild( link );
	}
 	
	/**
	 * Überprüft die Länge der Eingabe anhand eines Maximal-Wertes
	 *
	 * @param Object src Eingabe-Feld
	 * @param Integer max Maximale Anzahl Zeichen
	 * @param String id ID des HTML-Elements, in das die Ausgabe vorgenommmen wird
	 */
	this.checkFreeChars = function( src, max, id )
	{
		// Freie Zeichen berechnen
		free_chars = _getFreeChars( src, max );
		
		// ggf. Eingabe stoppen
		if ( free_chars <= 0 ) 
		{
			_stopTyping( src, max );
			free_chars = 0;
		}
			
		// Ausgabe
		js.replace( id, free_chars );
	}
	

	/**
	 * Entfernt Whitespaces (oder andere Zeichen) am Anfang und Ende eines Strings 
	 *
	 * @param string
	 * @return string 
	 */
	this.trim = function( string )
	{
		string = string.replace(/^\s*/,'');
		string = string.replace(/\s*$/,'');
		
		return string;
	}
	
	/**
	 * Ermilltelt die Seiten-, und Fenstergröße
	 *
	 * @return array
	 **/
	this.getPageSize = function()
	{
		
		var xScroll, yScroll;
		
		if ( window.innerHeight && window.scrollMaxY ) {	
			
			xScroll = document.body.scrollWidth;
			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
			
			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 = windowWidth;
		} else {
			pageWidth = xScroll;
		}
	
		arrayPageSize = new Array( pageWidth, pageHeight, windowWidth, windowHeight) 
		
		return arrayPageSize;
	}	

	
	//####################//
	//# Private Methoden #//
	//####################//
	
	/**
	 * Berechnet die Anzahl freier Zeichen
	 *
	 * @param Object src Eingabe-Feld
	 * @param Integer max Maximale Anzahl Zeichen
	 * @return Integer Anzahl freie Zeichen
	 */
	function _getFreeChars( src, max )
	{
		chars 		= src.value.length;
		new_lines	= src.value.split('\n').length - 1;
		free_chars 	= max - chars;

		if ( new_lines > 0 )
			free_chars += new_lines;
		
		// Rückgabe
		return free_chars;
	}
	
	/**
	 * Beendet die Länge des Eingabetextes bei dem Maximal-Wert
	 *
	 * @param Object src Eingabe-Feld
	 * @param Integer max Maximale Anzahl Zeichen
	 */
	function _stopTyping( src, max )
	{
		src.value = src.value.substr( 0, max );
	}	
	
	/**
	 * Behebt IE fehler für die Fenstergröße
	 *
	 * @return Object
	 */	
	function _trueBody()
	{
		return ( document.compatMode && document.compatMode != 'BackCompat' ) 
				 ? document.documentElement : document.body;
	}	
	
	
	/**
	 * Prüft, ob ein Element zu einer angegebenen ID existiert
	 *
	 * @param String id ID des Elements
	 * @return Bool
	 */
	function _idExists( id )
	{
		if ( !js.e( id ) ) {
			alert( 'There is no Element with id "' + id + '"' );
			return false;
		}
			
		return true;
	}
	
	/**
	 * Öffnet ein Popup mit/ohne Focus
	 *
	 * @param String url URL der Seite im Popup
	 * @param String name Name des Popups
	 * @param Integer width Breite des Popups (Standard: 400)
	 * @param Integer height Höhe des Popups (Standard: 300)
	 * @param Bool scollbars Scrollbalken ja/nein
	 * @param Bool resizable Skalierbar ja/nein
	 * @param Bool status Statusbar ja/nein
	 * @return false
	 */
	function _openWindow( url, name, width, height, scrollbars, resizable, status, focus )
	{
		var params = [
			'width=' + ( width ? width : 400 ),
			'height=' + ( height ? height : 300 ),
			'scrollbars=' + ( scrollbars ? 'yes' : 'no' ),
			'resizable=' + ( resizable ? 'yes' : 'no' ),
			'status=' + ( status ? 'yes' : 'no' ),
			'menubar=no',
			'toolbar=no'
		];
		
		var parameter 	= params.join( ',' );
		var wnd 		= null;
		var command 	= "wnd = window.open('" + url + "', '" + name + "', '" + parameter + "');";
		
		// Popup erstellen
		eval( command );
		
		// Window immer zentrieren
		wnd.moveTo(Math.ceil((screen.width/2)-(width/2)), Math.ceil((screen.height/2)-(height/2))); 
		
		// Fokussieren?
		if ( focus )
			wnd.focus();
		else
			wnd.blur();
		
		// Rückgabe
		return false;
	}
}

// Klasse instanziieren
var js = new JS();