/*!
 * highlight/highlight.js
 *
 * Copyright (c) 2009 BlueBear Internet Solutions (www.bluebear.nl)
 * Licensed under the MIT license.
 *
 * Based on MooTools 1.2.x
 * Provides: [bbHighlight]
 */
var bbHighlight = new Class({
	Implements: [Options],
	options: {
		// Basic options:
		'autoUnhighlight': false,
		'elements': '*',
		'tag': 'span',
		'tagClass': 'highlight',
		// Options for search term highlighting:
		'search': true,
		'parameters': ['q','as_q','as_epq','as_oq','query','search'],
		// Options for message showing highlighted terms:
		'autoShowMessage': false,
		'messageLocation': false,
		'messageClass': 'message'
	},
	initialize: function(options, words) {
		this.setOptions(options);
		this.elements = $$(this.options.elements);
		this.words = new Array();
		this.message = null;
		if (typeof words !== 'undefined') {
			this.highlight(words);
		} else if (this.options.search) {
			this.highlight(this.getSearchTerms());
		}
	},
	highlight: function(words) {
		if (typeof words == 'string') {
			words = [words];
		}
		if (this.options.autoUnhighlight) {
			this.unhighlight();
		}
		if (words.length) {
			var regex = new RegExp('\\b'+'('+words.join('|')+')'+'\\b', 'i');
			this.elements.each(function(el) {
				this.doHighlight(el, regex);
			}, this);
			if (this.message || this.options.autoShowMessage) {
				this.showMessage();
			}
		}
		return this;
	},
	unhighlight: function(words) {
		if (typeof words == 'string') {
			words = [words];
		}
		if (typeof words === 'undefined') {
			var words = new Array();
			for (var word in this.words) {
				if (typeof this.words[word] === 'object' && word !== '$family') {
					words.push(word);
				}
			}
		}
		words.each(function(word) {
			var word = word.toLowerCase();
			if (this.words[word]) {
				$$(this.words[word]).each(function(el) {
					var text = document.createTextNode(el.get('text'));
					el.getParent().replaceChild(text, el);
				});
				delete this.words[word];
			}
		}, this);

		if (this.message || this.options.autoShowMessage) {
			this.showMessage();
		}

		return this;
	},
	doHighlight: function(el, regex) {
		if (!/(SCRIPT|STYLE|INPUT|TEXTAREA)/.test(el.tagName) && (el.tagName !== this.options.tag && el.className !== this.options.tagClass)) {
			if (el.nodeType === 3) {
				var match = el.data.match(regex);
				if (match) {
					var wordNode = el.splitText(match.index);
					wordNode.splitText(match[0].length);

					var highlight = new Element(this.options.tag, {
						'class': this.options.tagClass
					});
					highlight.appendChild(wordNode.cloneNode(true));
					highlight.replaces(wordNode);

					var word = highlight.get('text').toLowerCase();
					if(typeof this.words[word] === 'undefined') {
						this.words[word] = new Array();
					}
					this.words[word].push(highlight);
				}
			} else if (el.nodeType === 1 && el.hasChildNodes()) {
				for (var i = 0; i < el.childNodes.length; i++) {
					this.doHighlight(el.childNodes[i], regex);
				}
			}
		}
	},
	getSearchTerms: function() {
		var terms = new Array();
		if (document.referrer) {
			var url = document.referrer;
			if (url.indexOf('?') > 0) {
				var query = url.substr(url.indexOf('?') + 1).split('&');
				query.each(function(q) {
					nameValue = q.split('=');
					if (nameValue.length === 2) {
						this.options.parameters.each(function(p) {
							if (nameValue[0] == p) {
								s = unescape(nameValue[1]).toLowerCase();
								s = s.replace(/\+/g, ' ');
								s = s.replace(/(^|\s)(site|related|link|info|cache):[^\s]*(\s|$)/ig, ' ');
								s = s.replace(/[^a-z0-9_-]/ig, ' '); // word chars only.
								s = s.replace(/(^|\s)-/g, ' '); // +required -excluded ~synonyms
								s = s.replace(/\b(and|not|or)\b/ig, ' ');
								s = s.replace(/\b[a-z0-9]\b/ig, ' '); // one char terms
								s.split(/\s+/).each(function(term) {
									if (term != '') {
										terms.push(term);
									}
								}, this);
							}
						}, this);
					}
				}, this);
			}
		}
		return terms;
	},
	showMessage: function() {
		if (this.options.messageLocation && this.options.messageLocation.length == 2) {
			this.hideMessage();
			var words = false;
			for (var word in this.words) {
				if (typeof this.words[word] === 'object' && word !== '$family') {
					words = true;
					continue;
				}
			}
			if (words) {
				var message = new Element('div', {
					'class': this.options.messageClass
				});
				new Element('div', {
					'html': MooTools.lang.get('bbHighlight').get('terms_highlighted')
				}).inject(message);
				for (var word in this.words) {
					if (typeof this.words[word] === 'object' && word !== '$family') {
						new Element('span', {
							'class': this.options.tagClass,
							'html': word,
							'styles': {
								'margin-right': 4
							}
						}).inject(message);
					}
				}
				new Element('a', {
					'href': '#',
					'html': MooTools.lang.get('bbHighlight').get('unhighlight'),
					'events': {
						'click': function(e) {
							if (e) e.stop();
							this.unhighlight();
						}.bind(this)
					}
				}).inject(message);

				message.inject($$(this.options.messageLocation[0])[0], this.options.messageLocation[1]);

				this.message = message;
			}
		}
		return this;
	},
	hideMessage: function(instant) {
		if (this.message) {
			this.message = this.message.destroy();
		}
		return this;
	}
});
MooTools.lang.set('en-US', 'bbHighlight', {
	terms_highlighted: 'These terms have been highlighted:',
	unhighlight: 'Remove highlighting'
});
MooTools.lang.set('nl-NL', 'bbHighlight', {
	terms_highlighted: 'Deze zoektermen zijn gemarkeerd:',
	unhighlight: 'Markering weghalen'
});
MooTools.lang.set('de-DE', 'bbHighlight', {
	terms_highlighted: 'Diese Begriffe sind markiert:',
	unhighlight: 'Markierung entfernen'
});
