	var DATA_SOURCE = "translate.php";
	objSelection = new SelectedText( );
	objMouse = new Mouse( );
	document.onmouseup = checkSelection;
	document.onmousedown = checkSelection1;
	var xmlHttp = false;
	var REQUEST_GET		= 0;
	var REQEST_POST		= 2;
	var REQUEST_HEAD	= 1;
	var REQUEST_XML		= 3;
	function getXMLRequester( )
	{
		var xmlHttp = false;
  		try
		{
			if( window.ActiveXObject )
			{
				for( var i = 5; i; i-- )
				{
					try
					{
						if( i == 2 )
						{
							xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP" );	
						}
						else
						{
							
							xmlHttp = new ActiveXObject( "Msxml2.XMLHTTP." + i + ".0" );
						}
						break;
					}
					catch( excNotLoadable )
					{						
						xmlHttp = false;
					}
				}
			}
			else if( window.XMLHttpRequest )
			{
				xmlHttp = new XMLHttpRequest();
			}
		}
		catch( excNotLoadable )
		{
			xmlHttp = false;
		}
		return xmlHttp ;
	}
	function sendRequest( strSource, strData, intType, intID )
	{
		if( !strData )
			strData = '';
	
		// default type (0 = GET, 1 = xml, 2 = POST )
		if( isNaN( intType ) )
			intType = 0; // GET
	
		if( xmlHttp && xmlHttp.readyState )
		{
			xmlHttp.abort( );
			xmlHttp = false;
		}
		if( !xmlHttp )
		{
			xmlHttp = getXMLRequester( );
			if( !xmlHttp )
				return;
		}
		if( intType != 1 && ( strData && strData.substr( 0, 1 ) == '&' || strData.substr( 0, 1 ) == '?' ) )
			strData = strData.substring( 1, strData.length );
		var dataReturn = strData ? strData : strSource;
		switch( intType )
		{
			case 1:	
				strData = "xml=" + strData;
			case 2: 
				xmlHttp.open( "POST", strSource, true );
				xmlHttp.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
				xmlHttp.setRequestHeader( 'Content-length', strData.length );
				break;
			case 3: 
				xmlHttp.open( "HEAD", strSource, true );
				strData = null;
				break;
			default: 
				var strDataFile = strSource + (strData ? '?' + strData : '' );
				xmlHttp.open( "GET", strDataFile, true );
				strData = null;
		}
		xmlHttp.onreadystatechange = new Function( "", "processResponse(" + intID + ")" ); ;
		xmlHttp.send( strData );	// param = POST data
		return dataReturn;
	}
	function processResponse( intID )
	{
		switch( xmlHttp.readyState )
		{
			case 0:
			case 1:
			case 2:
			case 3:
				break;
			case 4:	
				if( xmlHttp.status == 200 )	// success
				{
					processData( xmlHttp, intID );
				}
				else
				{
					if( window.handleAJAXError )
						handleAJAXError( xmlHttp, intID );
					else
						alert( "ERROR\n HTTP status = " + xmlHttp.status + "\n" + xmlHttp.statusText ) ;
				}
		}
	}		
	function processData( xmlHttp, intID )
	{
		showTranslation( xmlHttp.responseText );
	}
	function handleAJAXError( xmlHttp, intID )
	{
		hideElement( "searchanim" );
		alert( "Leider ist ein Fehler beim Übersetzen des Textes aufgetreten." ) ;
	}
	function translateSelection( strLang, intSource )
	{
		if( !trim( objSelection.text ).length )
			alert( "Bitte erst Text zum übersetzen auswählen" );
		else
		{
			sendRequest( DATA_SOURCE, "?translate=" + objSelection.encodedtext + "&lang=" + strLang + "&source=" + intSource, REQEST_POST );
			document.getElementById( "translate" ).getElementsByTagName( "img" )[ 0 ].style.display = "inline";
			objSelection.update( );
		}
	}
	function showTranslation( strTranslation )
	{
		var objToolTip = document.getElementById( "translation" );
		objToolTip.style.width = "auto";
		objToolTip.getElementsByTagName( "div" )[ 1 ].innerHTML = '<span style="color: #333333;">' + strTranslation.replace( /:::/g, "<br />" ) + '</span>';
		if( objToolTip.offsetWidth > getWindowWidth( ) / 2 )
			objToolTip.style.width = getWindowWidth( ) / 2 + "px";
		if( objSelection.top < objToolTip.offsetHeight )
			objToolTip.style.top = objSelection.bottom + 1 + 'px';
		else
			objToolTip.style.top = objSelection.top - objToolTip.offsetHeight - 2 + 'px';
		objToolTip.style.left = objSelection.left + 'px';
		document.getElementById( "translate" ).getElementsByTagName( "img" )[ 0 ].style.display = "none";
		hideElement( "translate" );
		showElement( "translation" );
	}
	function checkSelection1( objEvent )
	{
		objMouse.update( objEvent );
	}
	function checkSelection( objEvent )
	{
		objMouse.update( objEvent );
		if( objMouse.isNew )
		{
			objSelection.update( objMouse.xStart, objMouse.xEnd, objMouse.yStart, objMouse.yEnd );
			if( objSelection.isSelected )
			{
				hideElement( "translation" );
				var objTranslate = document.getElementById( "translate" );
				objTranslate.style.left = Math.min( getWindowWidth( ) - objTranslate.offsetWidth, Math.max( 0, objSelection.right - objTranslate.offsetWidth ) ) + "px";
				if( objSelection.top < objTranslate.offsetHeight )
					objTranslate.style.top = objSelection.bottom + 1 + "px";
				else
					objTranslate.style.top = objSelection.top - objTranslate.offsetHeight - 1 + "px";
				objTranslate.style.visibility = "visible";
			}
		}
	}
	function Mouse( )
	{
		this.intType	= 1;
		this.xStart		= 0;
		this.xEnd		= 0;
		this.yStart		= 0;
		this.yEnd		= 0;
		this.blnInit	= false; 
		this.isNew		= false;
		this.update		= method_setMousePosition;
	}
	function method_setMousePosition( objEvent )
	{
		if( window.event )
		{
			var intX = event.clientX;
			var intY = event.clientY + getTopScroll( ) ;
		}
		else
		{
			var intX = objEvent.pageX;
			var intY = objEvent.pageY;
		}
		if( this.intType % 2 )
		{
			this.xStart = intX;
			this.yStart = intY;
		}
		else
		{
			this.xEnd = intX;
			this.yEnd = intY;
		}
		if( this.blnInit )
			this.isNew = this.xStart != this.xEnd || this.yStart != this.yEnd;
		else
			this.blnInit = true;
		this.intType++;
	}
	function SelectedText( )
	{
		this.top			= 0;
		this.bottom			= 0;
		this.left			= 0;
		this.right			= 0;
		this.text			= '';
		this.encodedtext	= '';
		this.selection		= null;
		this.isSelected		= false;
		this.isNew			= false;
		this.update			= method_getSelectedText;
	}
	function method_getSelectedText( intXStart, intXEnd, intYStart, intYEnd )
	{
		var intTop = this.top;
		var intBottom = this.bottom;
		var strText = this.text;
		if( window.getSelection )
		{
			this.selection = window.getSelection( );
			this.text = ( this.selection + '' ).replace( /\n/g, ":::" );
			this.encodedtext = encodeURI( this.text );
			this.isSelected = this.text.length;

			if( this.isSelected )
			{
				var objNode1 = this.selection.anchorNode.parentNode;
				var objNode2 = this.selection.focusNode.parentNode;
				
				var blnSwap = ( this.top == objNode2.offsetTop && objNode2.offsetTop != objNode1.offsetTop );
				
				var objParent = blnSwap ? objNode2 : objNode1;
				var intStartOffset = Math.min( this.selection.focusOffset, this.selection.anchorOffset );
				var intEndOffset = Math.max( this.selection.focusOffset, this.selection.anchorOffset );

				if( objParent.nodeName.toUpperCase( ) == "BODY" || objParent.nodeName.toUpperCase( ) == "HTML"
					|| intStartOffset || this.selection.toString( ).length < getNodeText( objParent ).length )
				{
					if( !isNaN( intXStart ) )
					{
						this.top = Math.min( intYStart, intYEnd ) - 6;
						this.right = Math.max( intXStart, intXEnd );
						this.left = Math.min( intXStart, intXEnd );
						this.bottom = Math.max( intYStart, intYEnd ) + 6;
					}
				}
				else
				{
					this.top = Math.min( objNode1.offsetTop, objNode2.offsetTop );
					this.left = Math.min( objNode1.offsetLeft, objNode2.offsetLeft );					
					var objLeft = blnSwap ? objNode2 : objNode1;
					var objClone = objLeft.cloneNode( true );
					objClone.style.visibility = "hidden";
					objClone.style.cssFloat = "left";
					objLeft.parentNode.insertBefore( objClone, objLeft );
					var strContent = objClone.firstChild.nodeValue.substr( 0, intEndOffset );
					if( strContent.substr( strContent.length - 1, 1 ) == ' ' )
						strContent = strContent.substr( 0, strContent.length - 1 ) + "|" ;
					objClone.firstChild.nodeValue = strContent;	
					this.right = this.left + objClone.offsetWidth;
					if( intStartOffset )
					{	
						strContent = strContent.substr( 0, intStartOffset );
						if( strContent.substr( strContent.length - 1, 1 ) == ' ' )
							strContent = strContent.substr( 0, strContent.length - 1 ) + "|" ;
						objClone.firstChild.nodeValue = strContent;					
						this.left += objClone.offsetWidth;
					}
					objClone.parentNode.removeChild( objClone );
				}
				
				this.bottom = Math.max( objNode1.offsetTop + objNode1.offsetHeight, objNode2.offsetTop + objNode2.offsetHeight );
			}
		}
		else if( document.getSelection )
		{
			this.text = document.getSelection( ).replace( /\n/g, ":::" );
			this.encodedtext = encodeURI( this.text );
			this.isSelected = this.text.length;
			if( !isNaN( intXStart ) )
			{
				this.top = Math.min( intYStart, intYEnd ) - 12;
				this.bottom = Math.max( intYStart, intYEnd ) + 12;
				this.right = Math.max( intXStart, intXEnd );
				this.left = Math.min( intXStart, intXEnd );
			}
		}
		else
		{
			this.selection = document.selection.createRange( );
			this.text = this.selection.text.replace( /\n/g, ":::" );
			this.encodedtext = typeof encodeURI == 'undefined' ? escape( this.text ) : encodeURIComponent( this.text );
			this.isSelected = this.text.length;
			if( this.isSelected )
			{
				this.top = this.selection.offsetTop + getTopScroll( );
				this.left = this.selection.offsetLeft;
				this.bottom = this.top + this.selection.boundingHeight + getTopScroll( );
				this.right = this.left + this.selection.boundingWidth;
			}
		}
		this.isNew = intTop != this.top || intBottom != this.bottom || strText != this.text;
	}	
	function hideElement( strID, blnUseDisplay )
	{
		var xmlNode = document.getElementById( strID );
		if( xmlNode )
			blnUseDisplay ? xmlNode.style.display = "none" : xmlNode.style.visibility = "hidden"; 
	}
	function showElement( strID, blnUseDisplay )
	{
		var xmlNode = document.getElementById( strID );
		if( xmlNode )
			blnUseDisplay ? xmlNode.style.display = "block" : xmlNode.style.visibility = "visible"; 
	}
	function getNodeText( xmlNode, blnSkipReplace )
	{
		var strNodeText = '';
		var xmlChildNodes = xmlNode.childNodes;
		for( var i = 0; i < xmlChildNodes.length; i++ )
		{
			if( xmlChildNodes[ i ].nodeType == 3 )	// text node
				strNodeText += xmlChildNodes[ i ].data;
			else
				strNodeText += getNodeText( xmlChildNodes[ i ], true );
		}
		if( blnSkipReplace )
			return strNodeText;
		else
			return trim( strNodeText.replace( /\s+/g, ' ' ) );
	}
	function getWindowWidth()
	{
		if( window.innerWidth )
			return innerWidth;
		return document.body.offsetWidth;
	}
	function getWindowHeight()
	{
		if( window.innerHeight )
			return innerHeight;
		return document.body.offsetHeight;
	}
	function getTopScroll()
	{
		if( window.event )
			return document.documentElement.scrollTop ;
		else
			return pageYOffset ;
	}
	function trim( strText )
	{
		return strText.replace( /^\s+/g, '' ).replace( /\s+$/g, '' );
	}
