// JavaScript Document

var highlight = {
	exact 		: true,
	debug		: false,
	debugging	: [],
	instances	: [],
	param		: null,
	container	: null,
	expression 	: new RegExp(),
	skip 		: /^(script|style|textarea)/i,
	showDebugging : function(target){
		if(!target) target = this.debug;
		if(typeof target == 'string' && target.length) target = document.getElementById('target');
		if(typeof target == 'object')
			target.innerHTML += this.debugging.join('<br/>');		
		else if(target !== false)
			alert(this.debugging.join('\n'));
	},
	init : function(){
		var terms = highlight.processInlineConfig()+' '+highlight.processReferrer();
		terms = terms.replace(/(^\s+)|\s+$/g,"");
		if(terms.length)
			this.process(terms);		
		if(highlight.debug !== false)
			highlight.showDebugging();		
	},
	process : function(term,obj){
		if(!term || !term.length) return this.debugging.push('ABORT - no search term received'), false;
		if(!obj && this.container) obj = this.container;
		if(typeof obj == 'string' && obj.length) obj = document.getElementById(obj);
		if(!obj) obj = document.body;
		this.debugging.push('---------------------------------------------');
		this.debugging.push('Received Terms : '+term);
		this.debugging.push('Exact Match : '+this.exact);
		this.debugging.push('Container : '+(obj != document.body));
		this.debugging.push(' - HIGHLIGHT STARTING');
		var timer = (new Date).getTime();
		
		this.processSearchTerm(term);
		this.processNode(obj);
		
		timer = (new Date).getTime() - timer;
		
		this.debugging.push(' - Found '+this.instances.length+' instances');
		this.debugging.push(' - HIGHLIGHT FINISHED ('+timer+' ms)');
		this.debugging.push('---------------------------------------------');
		
		
	},
	processNode : function(node){
		if(!this.skip.test(node.tagName) && node.childNodes.length && (!node.innerText || this.expression.test(node.innerText))){
			for(var i=node.childNodes.length-1; i > -1; i--){
				if(node.childNodes[i].nodeType == 3)
					this.processTextNode(node.childNodes[i]);
				else
					this.processNode(node.childNodes[i]);				
			}
		}
	},
	processTextNode : function(node){
		var match = this.expression.exec(node.data);
		if(match){
			var val = match[0];
			var node2 = node.splitText(match.index);
			var node3 = node2.splitText(val.length);
			var span = node.ownerDocument.createElement('SPAN');
			node.parentNode.replaceChild(span, node2);
			span.className = 'highlight';//stylemapper[val.toLowerCase()];
			span.appendChild(node2);
			this.instances.push(span);
			this.processTextNode(node3);
		}
	},
	processSearchTerm : function(term){
		term = decodeURIComponent(term).replace(/\'|"/, '').split(/[\s,\+\.]+/);
		if(this.exact){
			for(var i=0; i < term.length; i++)
				term[i] =  '\\b'+term[i]+'\\b';
		}
		this.expression.compile(term.join('|'),'i');
	},
	processQueryString : function(query,param){
		this.expression.compile('^.*'+param+'=([^&]+)&?.*$','i');
		var value = query.replace(this.expression, '$1');
		return (value != query)?value:'';
	},
	processReferrer : function(){
		var referrer = document.referrer;
		var terms = '';
		for(var i=0, engine; engine = this.searchEngines[i]; i++){
			if(this.expression.compile(engine.expression,'i').test(referrer)){
				terms = this.processQueryString(referrer,engine.param);
            	break;
			}
		}		
		if(terms.length) 
			this.debugging.push('REFERRER - Passing terms : '+terms);
		else
			this.debugging.push('REFERRER - Not from Search Engine');
		return terms;
	},
	searchEngines : [
		{ expression : '^http://(www)?\\.?google.*', 	param : 'q' },
		{ expression : '^http://search\\.yahoo.*', 		param : 'p' },
		{ expression : '^http://search\\.msn.*', 		param : 'q' },
		{ expression : '^http://(www\\.)?altavista.*', 	param : 'q' },
		{ expression : '^http://(www\\.)?feedster.*',	param : 'q' },
		{ expression : '^http://(www\\.)?alltheweb.*', 	param : 'q' },
		{ expression : '^http://news.salinaspd.*', 	param : 'q' },
		{ expression : '^http://search\\.lycos.*', 		param : 'query' },
		{ expression : '^http://search\\.aol.*', 		param : 'userQuery' }					  
	],
	processBoolean : function(boolString){
		if(!isNaN(parseInt(boolString)))
	 		return (parseInt(boolString) != 0)?true:false; 
	  	var bool = { 'yes' : true, '1' : true, 'true' : true };
	 	return (bool[boolString] == true);
	},
	processInlineConfig : function(){
		var custom = { param : '', container : '', debug : '', exact : '' };
		var aryScripts = document.getElementsByTagName('SCRIPT');
		var queryString = document.location.toString().replace(/^[^\?]+\??/,'');
		var config = '';
		var terms = '';
				
		if(!queryString.length) return this.debugging.push('CUSTOM - No Local QueryString'), terms;
		
		this.expression.compile('highlight.js','i');
		for(var i=0, script; script = aryScripts[i]; i++){
			if(script.src && this.expression.test(script.src)){
				config = script.src.replace(/^[^\?]+\??/,'');
				break;
			}
		}
		if(config.length) {		
			config = config.split('&');
			for(var i=0; i < config.length; i++){
				var pair = config[i].split('=');
				custom[pair[0]] = pair[1];				
			}			
			if(custom.container.length) this.container = document.getElementById(custom.container);
			if(custom.debug.length) this.debug = this.processBoolean(custom.debug);
			if(custom.exact.length) this.exact = this.processBoolean(custom.exact);
			if(custom.param.length) this.param = custom.param;
		} 
		if(this.param == null) return this.debugging.push('CUSTOM - Parameters not configured'), terms;
		
		var params = this.param.split(',');
		for(var i=0; i < params.length; i++){
			var term = this.processQueryString(queryString,params[i]);
			if(term.length)
				terms += '+' + term;
		}
		if(terms.length){
			terms = terms.substr(1);
			this.debugging.push('CUSTOM - Passing terms : '+terms);
		} else {
			this.debugging.push('CUSTOM - No search terms found for param : '+this.param);
		}
		return terms;
	}
}

if(window.addEventListener){
	window.addEventListener('load',function(){ highlight.init(); },false);
} else if(window.attachEvent){
	window.attachEvent('onload',function(){ highlight.init(); });
} else {
	highlight.__onload = window.onload;
	window.onload = function() {
		highlight.init();
		highlight.__onload();
	}
}