// TODO: Verallgemeinern auf beliebige Suchmaschinen.

if(typeof Google == 'undefined') {
	Google = {};
}

Google.Highlight = {};

Object.Extend(Google.Highlight, 
{
	$rgxKeywords: '([^&]+)&?.*$',
	$arrSearchEngines: [
			{ rgxUrl: '^http://(www)?\\.?google.*', rgxParam: 'q=' }
	],
	
	Options: {
		ExactMatch: true
	},
	
	Execute: function($Elements)
	{

		if(!document.referrer) return;
		
		var $Keywords = this.DecodeReferrer(document.referrer);
		//var $Keywords = this.DecodeReferrer('http://www.google.de/search?hs=2vR&hl=de&client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial_s&q=temicon+anreise&btnG=Suche&meta=');
		
		if($Keywords.length == 0) return;
		if(this.Options.ExactMatch) {
			$Keywords = $Keywords.Map(function($s) { return '\\b'+$s+'\\b'; });
		}
		
		var $Regex = new RegExp($Keywords.join('|'), 'i');
		
		var ProcessElement = function($Element)
		{
				// Collect all the text nodes which contains at least
				// one of the words we're looking for.
				//
				var $TextNodes	= [];
				
				var RememberTextNode = function($Node) {
					if($Node.nodeType == DOM.NodeType.Text && $Regex.test($Node.nodeValue)) {
						$TextNodes.push($Node);			
					}
				}
		
				DOM.Traverse($Element, RememberTextNode);

				// Now we'll process any of these nodes to create a wrapper
				// elements around the keywords for highlighting.
				//
				for(var $i = 0; $i < $TextNodes.length; ++$i) {
					this.ProcessTextNode($TextNodes[$i], $Regex);
				}
		}
		
		$Elements.Each(ProcessElement.Bind(this));
	},
	
	
	ProcessTextNode: function($TextNode, $Regex)
	{
		$CurrentNode 				= $TextNode;

		var $WrapperElement	= this.Options.WrapperElement || 'span';
		var $CssClass				= this.Options.CssClass || 'keyword-highlight';
					
		while($CurrentNode)
		{
			var $Match = $Regex.exec($CurrentNode.nodeValue);
						
			if($Match)
			{
				var $s 					= $Match[0];
				
				var $NodeSplit	= $CurrentNode.splitText($Match.index);
				var $NodeAfter 	= $NodeSplit.splitText($s.length);
				
				var $NodeMarker	= DOM.CreateElement($WrapperElement, { 'class': $CssClass });
						
				DOM.Replace($NodeMarker, $NodeSplit);
				DOM.InsertBottom($NodeMarker, $NodeSplit);
							
				$CurrentNode = $NodeAfter;
			}
			else
			{
				$CurrentNode = null;
			}
		}
	},
	
	DecodeReferrer: function($strReferrer)
	{
		var $Match 		= new RegExp('');
		
		for($i = 0; $i < this.$arrSearchEngines.length; ++$i)
		{
			var $se = this.$arrSearchEngines[$i];
			$Match.compile($se.rgxUrl);
			
			if($strReferrer.match($Match))
			{
				$Match.compile('^.*' + $se.rgxParam + '([^&]+)&?.*$');

				var $strQuery = $strReferrer.replace($Match, '$1');
				if($strQuery) 
				{
					return decodeURIComponent($strQuery)
									.replace(/'|"/, '')
									.split(/[\s,\+\.]+/);
				}
			}
		}
			
		return [];
	}
});

function blah()
{
	Google.Highlight.Execute([document.getElementById('content')]);
}

DOM.OnLoad.AddHandler(blah);

