var $E = function $E(selector) {
	return $$(selector)[0];
};

if (typeOf(Number.prototype.isInt) !== 'function') {
	Number.prototype.isInt = function() {
		var pattern = /^-?[0-9]+$/;
		return pattern.test(this.toString());
	};
}

var parseUrl = function parseUrl(url, segment) {
	var parts,
		partNames,
		partsObject,
		parseUrl = /^(?:([A-Za-z]+):)?(?:\/{0,3})?([A-Za-z0-9\.\-]+)?(\/[\.A-Za-z_\-0-9\/]+)(?:\?([A-Za-z0-9\s=\.&@$%\*\(\)!,\:\+]+))?(?:#([A-Za-z0-9]+))?$/;
	if (parseUrl.test(url)) {
		parts = parseUrl.exec(url);
		partNames = ['url', 'protocol', 'base', 'path', 'query', 'hash'];
		partsObject = parts.associate(partNames);
		return (segment) ? partsObject[segment]: partsObject;
	} else {
		return false;
	}
};

var stripQuery = function stripQuery(url) {
	var base = url.split('?')[0];
	return base ? base: url;
};

var getQuery = function getQuery(url) {
	var query = (url.split('?')[1]) ? url.split('?')[1].split('#')[0]: false;
	return query;
};

var parseQuery = function parseQuery() {
	var parts = [];
	return function(url, exclude, include) {
		var query = (getQuery(url)) ? getQuery(url).split('&') : null,
			splitQuery;
		parts.length = 0;
		if (query === null) return null;
		for (var i = 0, l = query.length; i < l; i += 1) {
			splitQuery = query[i].split('=');
			if (exclude) {
				if (exclude.indexOf(splitQuery[0]) === -1) parts.push(query[i]);
			} else if (include) {
				if (include.indexOf(splitQuery[0]) !== -1) parts.push(query[i]);
			}
		}
		return parts.join('&');
	}
}();

var getObjectFromQuery = function getObjectFromQuery(url) {
	var query = (getQuery(url)) ? getQuery(url).split('&') : null,
		obj = {}, splitQuery;
	if (query === null) return null;
	for (var i = 0, l = query.length; i < l; i += 1) {
		splitQuery = query[i].split('=');
		obj[splitQuery[0].toLowerCase()] = splitQuery[1];
	}
	return obj;
};

var Overlay = new Class({
	overlay: function(elem, id) {
		var overlay = new Element('div', {'id': 'overlay', 'styles': {'opacity': '0', 'visibility': 'visible', 'height': '0', 'overflow': 'hidden'}}).inject(document.body),
			e = $(id) || new Element(elem, {'id': id}).inject(document.body);
		return e.addClass('lightbox');
	},
	showOverlay: function(close) {
		var h = window.getScroll().y,
			w = (Browser.opera) ? window.innerWidth/2: window.getScrollSize().x/2,
			overlay = $('overlay'),
			lightbox = $$('.lightbox')[0],
			elems;
		overlay.set('tween').setStyles({
			'top': -$(window).getScroll().y,
			'height':$(window).getScrollSize().y+$(window).getScroll().y,
			'visibility': 'visible',
			'display': 'block'
		}).tween('opacity', '0.7');
		lightbox.setStyles({'display': 'block', 'visibility': 'visible'});
		lightbox.setStyles({'top': h + 100 + 'px', 'left': w - (lightbox.getScrollSize().x/2) + 'px'});
		if (close) {
			elems = (typeOf(close) === 'array' || typeOf(close) === 'elements') ? close.push(overlay) : [close, overlay];
			elems.each(function(elem) {
				elem.addEvent('click', function() {
					this.closeLightbox();
				}.bind(this));
			}, this);
		}
	},
	closeLightbox: function() {
		$$('.lightbox').each(function(elem) {
			elem.destroy();
		});
		$('overlay').destroy();
	}
});

var Lightbox = new Class({
	Implements: [Options, Events, Overlay],
	options: {
		// onResponse: function(){},
		// onShow: function(){},
		cache: true,
		closeId: 'closeLightbox',
		closeSelector: false,
		containerId: 'lightbox',
		elems: false,
		url: false
	},
	initialize: function(options) {
		this.setOptions(options);
		this.content = [];
		if (this.options.elems) {
			this.elems = $$(this.options.elems);
			this.elems.each(function(elem, index) {
				var clickEvent = function(event) {
					var query;
					event.preventDefault();
					if (elem.href) query = getQuery(elem.href);
					this.display(index, query);
				}.bind(this);
				elem.addEvent('click', clickEvent);
				elem.store('lightboxClickEvent', clickEvent);
			}, this);
		} else if (this.options.elems !== null) {
			this.display();
		}
	},
	display: function(index, query) {
		var containerId = typeOf(this.options.containerId) === 'array' ? this.options.containerId[index]: this.options.containerId,
			container = this.overlay('div', containerId),
			close;
		this.fireEvent('show', [container, this.options.elems, index]);
		if (this.content[index]) {
			container.innerHTML = this.content[index];
			close = this.options.closeSelector ? $$(this.options.closeSelector) : $(this.options.closeId);
			this.showOverlay(close);
			if (this.options.url) this.fireEvent('onResponse', [container, this.options.elems, index]);
		} else {
			if (this.options.url) {
				this.fetchContent(container, index, this.options.cache, query);
			} else {
				if (this.options.cache) this.content[index] = container.innerHTML;
				close = this.options.closeSelector ? $$(this.options.closeSelector) : $(this.options.closeId);
				this.showOverlay(close);
			}
		}
	},
	fetchContent: function(container, index, cache, query) {
		var close,
		requester = new Request({
			url: this.options.url,
			method: 'get',
			onSuccess: function(responseText) {
				container.innerHTML = responseText;
				if (cache) this.content[index] = responseText;
				close = this.options.closeSelector ? $$(this.options.closeSelector) : $(this.options.closeId);
				this.showOverlay(close);
				this.fireEvent('onResponse', [container, this.options.elems, index]);
			}.bind(this)
		});
		requester.send(query);
	}
});

var ImageLightbox = new Class({
	options: {
		addCaption: false,
		closeText: 'close'
	},
	Extends: Lightbox,
	display: function(index) {
		var containerId = typeOf(this.options.containerId) === 'array' ? this.options.containerId[index]: this.options.containerId,
			container = this.overlay('div', containerId),
			elem = this.elems[index],
			alt, close, img, url;
		this.fireEvent('show', [container, this.options.elems, index]);
		if (this.content[index]) {
			container.innerHTML = this.content[index];
			img = container.getElement('img');
			this.showOverlay($(this.options.closeId));
		} else {
			url = elem.nodeName.toLowerCase() === 'img' ? elem.src : elem.href;
			alt = elem.nodeName.toLowerCase() === 'img' ? elem.alt : '';
			close = new Element('a', { id: this.options.closeId, html: this.options.closeText}).inject(container);
			img = new Element('img', {'src': url, 'alt': alt }).inject(container);
			if (alt && this.options.addCaption) container.innerHTML += '<p class="caption">' + alt + '</p>';
			if (this.options.cache) this.content[index] = container.innerHTML;
			img.addEvent('load', function() {
				this.showOverlay($(this.options.closeId));
			}.bind(this));
		}
	}
});

var Loader = new Class({
	setLoader: function(container, options) {
		var opts = {
				loaderType: 'text', // 'image' or 'text'
				loaderText: 'loading...',
				loaderSrc: false,
				styles: {}
			},
			pos = container.getPosition(),
			w = container.getSize().x,
			loaderImg, loaderPos;
		if (options) opts = Object.merge(opts, options);
		if (!this.requestCount) this.requestCount = 0;
		this.requestCount += 1;
		this.loader = opts.loaderType === 'text' ? $('textLoader') : $('loader');
		
		if (!this.loader) {
			if (opts.loaderType === 'text') {
				this.loader = new Element('p', {'id': 'textLoader'}).appendText(opts.loaderText);
			} else {
				this.loader = new Element('div', {'id': 'loader'});
				loaderImg = new Element('img', {'src': opts.loaderSrc}).inject(this.loader);
			}
		}
		
		this.loader.inject(container);
		if (typeOf(opts.styles['left']) !== 'number' && typeOf(opts.styles['right']) !== 'number') opts.styles['left'] = (w/2) - (this.loader.getSize().x/2) + 'px';
		opts.styles['position'] = 'absolute';
		opts.styles['display'] = 'block';
		this.loader.setStyles(opts.styles);
	},
	hideLoader: function() {
		if (this.requestCount <= 1) this.loader.setStyle('display', 'none');
		this.requestCount -= 1;
	}
});

var Accordion = new Class({
	Implements: [Options, Events],
	options: {
		// onCollapse: function(){},
		// onExpand: function(){},
		closedClass: 'collapsed',
		direction: 'vertical',
		duration: 'normal',
		fixedHeight: false,
		fixedWidth: false,
		forceWidth: null,
		foldClass: 'fold',
		multiOpen: false,
		opacity: true,
		openedClass: 'expanded',
		params: null, // should be an object
		togglerClass: 'toggler'
	},
	initialize: function(container, options) {
		this.setOptions(options);
		var opts = this.options,
			params = opts.params,
			fold, fx, i, key, l, w;
		this.container = $(container);
		this.togglers = container.getElements('.' + opts.togglerClass);
		this.folds = container.getElements('.' + opts.foldClass);
		
		if (!params) params = opts.params = {};
		this.d = opts.direction === 'horizonal' ? 'width': 'height';
		if (opts.opacity) params.opacity = 1;
		this.collapseParams = {};
		this.collapseParams[this.d] = 0;
		for (fx in params) this.collapseParams[fx] = typeOf(params[fx]) === 'array'? params[fx].reverse(): 0;
		
		l = this.folds.length;
		d = this.d;
		w = this.container.getStyle('width');
		this.folds.each(function(fold) {
			if (opts.forceWidth) fold.setStyle('width', fold.getParent(opts.forceWidth).getStyle('width'));
			if (fold.hasClass(opts.closedClass)) fold.setStyle(this.d, '0px');
			fold.set('morph', { duration: opts.duration, onComplete: function() {
				if (fold.retrieve('action') === 'collapse') fold.removeClass(opts.openedClass).addClass(opts.closedClass);
			}.bind(this)});
		}, this);
		
		this.attach();
	},
	attach: function() {
		this.container.addEvents({
			'click': function(event) {
				var elem = $(event.target);
				if (elem.hasClass(this.options.togglerClass)) {
					event.preventDefault();
					this.display(this.togglers.indexOf(elem));
				}
			}.bind(this)
		});
	},
	display: function(index) {
		var fold = this.folds[index],
			action = fold.hasClass(this.options.closedClass) ? 'expand': 'collapse';
		this[action](fold, index);
	},
	collapse: function(fold, index) {
		var opts = this.options;
		fold.store('action', 'collapse');
		this.fireEvent('collapse', [this.togglers, this.folds, index]);
		fold.morph(this.collapseParams);
	},
	expand: function(fold, index) {
		var i = 0,
			opts = this.options,
			dValue, j, l;
		
		this.fireEvent('expand', [this.togglers, this.folds, index]);
		fold.removeClass(opts.closedClass).addClass(opts.openedClass);
		if (fold.scrollHeight) {
			// opening up or out?
			if (this.d === 'width') {
				dValue = opts.fixedWidth? opts.fixedWidth: fold.offsetWidth;
			} else {
				dValue = opts.fixedHeight? opts.fixedHeight : fold.scrollHeight;
			}
			opts.params[this.d] = dValue;
			
			fold.store('action', 'expand');
			fold.morph(opts.params);
			
			if (!this.options.multiOpen) {
				l = this.folds.length;
				while (i < l) {
					if (i !== index) this.collapse(this.folds[i], i);
					i += 1;
				}
			}
		}
	}
});

/*
---
I took this out of more.js so that we didn't have to include the entire more library on every page.
script: Tips.js

name: Tips

description: Class for creating nice tips that follow the mouse cursor when hovering an element.

license: MIT-style license

authors:
  - Valerio Proietti
  - Christoph Pojer
  - Luis Merino

requires:
  - Core/Options
  - Core/Events
  - Core/Element.Event
  - Core/Element.Style
  - Core/Element.Dimensions
  - /MooTools.More

provides: [Tips]

...
*/

(function(){

var read = function(option, element){
	return (option) ? (typeOf(option) == 'function' ? option(element) : element.get(option)) : '';
};

this.Tips = new Class({

	Implements: [Events, Options],

	options: {/*
		onAttach: function(element){},
		onDetach: function(element){},
		onBound: function(coords){},*/
		onShow: function(){
			this.tip.setStyle('display', 'block');
		},
		onHide: function(){
			this.tip.setStyle('display', 'none');
		},
		title: 'title',
		text: function(element){
			return element.get('rel') || element.get('href');
		},
		showDelay: 100,
		hideDelay: 100,
		className: 'tip-wrap',
		offset: {x: 16, y: 16},
		windowPadding: {x:0, y:0},
		fixed: false
	},

	initialize: function(){
		var params = Array.link(arguments, {
			options: Type.isObject,
			elements: function(obj){
				return obj != null;
			}
		});
		this.setOptions(params.options);
		if (params.elements) this.attach(params.elements);
		this.container = new Element('div', {'class': 'tip'});
	},

	toElement: function(){
		if (this.tip) return this.tip;

		this.tip = new Element('div', {
			'class': this.options.className,
			styles: {
				position: 'absolute',
				top: 0,
				left: 0
			}
		}).adopt(
			new Element('div', {'class': 'tip-top'}),
			this.container,
			new Element('div', {'class': 'tip-bottom'})
		);

		return this.tip;
	},

	attach: function(elements){
		$$(elements).each(function(element){
			var title = read(this.options.title, element),
				text = read(this.options.text, element);

			element.set('title', '').store('tip:native', title).retrieve('tip:title', title);
			element.retrieve('tip:text', text);
			this.fireEvent('attach', [element]);

			var events = ['enter', 'leave'];
			if (!this.options.fixed) events.push('move');

			events.each(function(value){
				var event = element.retrieve('tip:' + value);
				if (!event) event = function(event){
					this['element' + value.capitalize()].apply(this, [event, element]);
				}.bind(this);

				element.store('tip:' + value, event).addEvent('mouse' + value, event);
			}, this);
		}, this);

		return this;
	},

	detach: function(elements){
		$$(elements).each(function(element){
			['enter', 'leave', 'move'].each(function(value){
				element.removeEvent('mouse' + value, element.retrieve('tip:' + value)).eliminate('tip:' + value);
			});

			this.fireEvent('detach', [element]);

			if (this.options.title == 'title'){ // This is necessary to check if we can revert the title
				var original = element.retrieve('tip:native');
				if (original) element.set('title', original);
			}
		}, this);

		return this;
	},

	elementEnter: function(event, element){
		this.container.empty();

		['title', 'text'].each(function(value){
			var content = element.retrieve('tip:' + value);
			if (content) this.fill(new Element('div', {'class': 'tip-' + value}).inject(this.container), content);
		}, this);

		clearTimeout(this.timer);
		this.timer = (function(){
			this.show(element);
			this.position((this.options.fixed) ? {page: element.getPosition()} : event);
		}).delay(this.options.showDelay, this);
	},

	elementLeave: function(event, element){
		clearTimeout(this.timer);
		this.timer = this.hide.delay(this.options.hideDelay, this, element);
		this.fireForParent(event, element);
	},

	fireForParent: function(event, element){
		element = element.getParent();
		if (!element || element == document.body) return;
		if (element.retrieve('tip:enter')) element.fireEvent('mouseenter', event);
		else this.fireForParent(event, element);
	},

	elementMove: function(event, element){
		this.position(event);
	},

	position: function(event){
		if (!this.tip) document.id(this);

		var size = window.getSize(), scroll = window.getScroll(),
			tip = {x: this.tip.offsetWidth, y: this.tip.offsetHeight},
			props = {x: 'left', y: 'top'},
			bounds = {y: false, x2: false, y2: false, x: false},
			obj = {};

		for (var z in props){
			obj[props[z]] = event.page[z] + this.options.offset[z];
			if (obj[props[z]] < 0) bounds[z] = true;
			if ((obj[props[z]] + tip[z] - scroll[z]) > size[z] - this.options.windowPadding[z]){
				obj[props[z]] = event.page[z] - this.options.offset[z] - tip[z];
				bounds[z+'2'] = true;
			}
		}

		this.fireEvent('bound', bounds);
		this.tip.setStyles(obj);
	},

	fill: function(element, contents){
		if (typeof contents == 'string') element.set('html', contents);
		else element.adopt(contents);
	},

	show: function(element){
		if (!this.tip) document.id(this);
		if (!this.tip.getParent()) this.tip.inject(document.body);
		this.fireEvent('show', [this.tip, element]);
	},

	hide: function(element){
		if (!this.tip) document.id(this);
		this.fireEvent('hide', [this.tip, element]);
	}

});

})();

var Search = new Class({
	Implements: [Options, Events, Loader],
	options: {
		// onSend: function(){},
		// onFinish: function(){},
		bustCache: false,
		cache: true,
		containerClass: false,
		elemClass: false,
		events: 'submit',
		loader: false,
		loaderOptions: {
			loaderSrc: false,
			loaderStyles: {'top': 0, 'right': 0},
			loaderType: 'image'
		},
		loaderParent: 'trigger', // can be 'trigger' or 'container'
		preventDefault: true,
		params: false, // should be an object
		query: 'id',
		url: null
	},
	initialize: function(elem, container, options) {
		this.setOptions(options);
		this.elems = this.options.elemClass? elem.getElements('.' + this.options.elemClass): elem;
		this.containers = container ? container: elem.getElements('.' + this.options.containerClass);
		this.attach(elem);
	},
	attach: function(elem) {
		var events = this.options.events;
		if (typeOf(events) === 'array') {
			events.each(function(e) {
				elem.addEvent(e, function(event) {
					var t = $(event.target),
						elem = t.hasClass(this.options.elemClass) ? t: elem;
					if (e === 'submit' || t.hasClass(this.options.elemClass)) this.getResults(elem, event);
				}.bind(this));
			}, this);
		} else {
			elem.addEvent(events, function(event) {
				var t = $(event.target),
					elem = t.hasClass(this.options.elemClass) ? t: elem;
				
				if (events === 'submit' || t.hasClass(this.options.elemClass)) this.getResults(elem, event);
			}.bind(this));
		}
	},
	getResults: function(elem, event) {
		var i = (typeOf(this.elems) === 'array' || typeOf(this.elems) === 'elements') ? this.elems.indexOf(elem): -1,
			container = (typeOf(this.containers) === 'array' || typeOf(this.containers) === 'elements') ? this.containers[i]: this.containers,
			opts = this.options.loaderOptions,
			params = this.options.params,
			url = this.options.url,
			loader, newQuery, query, requester, results;
		
		if (this.options.preventDefault) event.preventDefault();
		
		if (event.type === 'submit') {
			query = elem.toQueryString();
		} else {
			query = elem.nodeName === 'A' ? getQuery(elem.href): this.options.query + '=' + elem.get(this.options.query);
		}
		if (params) query += '&' + params.toQueryString();
		results = container.retrieve(query);
		
		newQuery = (this.options.bustCache) ? query + '&' + new Date().getTime() : query;
		
		if (this.options.loader) loader = !opts.loaderType ? this.options.loader : this.options.loaderParent === 'container' ? container: elem;
		
		if (results) {
			container.innerHTML = results;
			this.fireEvent('onFinish', [this.elems, this.containers, i]);
		} else {
			requester = new Request({
				url: url,
				method: 'get',
				onRequest: function() {
					this.fireEvent('onSend', [this.elems, this.containers, i]);
					if (this.options.loader) this.setLoader(loader, opts);
				}.bind(this),
				onSuccess: function(response) {
					container.innerHTML = response;
					if (this.options.cache) container.store(query, response);
					this.fireEvent('onFinish', [this.elems, this.containers, i]);
					if (this.options.loader) this.hideLoader();
				}.bind(this)
			});
			requester.send(newQuery);
		}
	}
});

var Autocomplete = new Class({
	Implements: [Options, Events],
	options: {
		// onBlur: function(){},
		// onHide: function(){},
		// onInit: function(){},
		// onInput: function(){},
		// onOver: function(){},
		// onSelect: function(){},
		// onShow: function(){},
		clickSubmit: true,
		containerElem: 'ul',
		containerId: 'autocomplete',
		minLength: 1,
		queryString: null,
		resultsElem: 'li',
		resultsClass: 'highlighted',
		width: 0,
		url: null,
		zIndex: 10
	},
	initialize: function(elem, options) {
		this.setOptions(options);
		this.len = 0;
		this.elem = $(elem);
		this.form = this.elem.getParent('form');
		this.container = $(this.options.containerId) || new Element(this.options.containerElem, {'id': this.options.containerId}).inject(document.body);
		this.container.setStyle('visibility', 'hidden');
		this.fireEvent('onInit', [this.elem, this.container]);
		this.attach();
	},
	attach: function() {
		this.elem.addEvents({
			'keyup': function(event) {
				this.container.store('form', this.form);
				if ((event.code === 38 || event.code === 40) && this.len > 0) {
					if (event.code === 38) {
						this.position = this.position <= 0 ? this.len - 1 : this.position - 1;
					} else {
						this.position = this.position === this.len - 1 ? 0 : this.position + 1;
					}
					this.updatePosition();
				} else {
					if (this.elem.value.length >= this.options.minLength) {
						this.fireEvent('onInput', [this.elem, this.container]);
						this.getResults();
					}
				}
			}.bind(this),
			'blur': function(event) {
				this.fireEvent('onBlur', [this.elem, this.container]);
				this.hide();
			}.bind(this)
		});
	},
	getResults: function() {
		var url = this.options.url,
			query = (this.options.queryString) ? this.options.queryString + this.elem.value : this.elem.getParent('form').toQueryString(),
			results = this.container.retrieve(query);
		if (this.requester) this.requester.cancel();
		this.requester = new Request({
			method: 'get',
			url: url,
			onSuccess: function(response) {
				this.container.innerHTML = response;
				this.container.store(query, response);
				this.show();
			}.bind(this)
		});
		if (results) {
			this.container.innerHTML = results;
			this.show();
		} else {
			console.log(query);
			this.requester.send(query);
		}
	},
	hide: function() {
		this.container.setStyle('visibility', 'hidden');
		this.fireEvent('onHide', [this.elem, this.container]);
	},
	show: function() {
		var d = this.elem.getSize(),
			t = this.elem.getPosition(),
			w = this.options.width > d.x ? this.options.width: d.x,
			z = this.options.zIndex;
		this.results = this.container.getElements(this.options.resultsElem);
		this.len = this.results.length;
		if (this.len > 0) {
			this.position = -1;
			this.container.setStyles({
				'visibility': 'visible',
				'top': d.y + t.y + 'px',
				'left': t.x + 'px',
				'width': w + 'px',
				'z-index': z
			});
			this.fireEvent('onShow', [this.elem, this.container]);
		}
		if (!this.container.retrieve('hasEvents')) this.attachContainerEvents();
	},
	attachContainerEvents: function() {
		this.container.store('hasEvents', true);
		this.container.addEvents({
			'mouseover': function(event) {
				if (event.target.nodeName.toLowerCase() === this.options.resultsElem) {
					this.position = this.results.indexOf(event.target);
					this.updatePosition();
					this.fireEvent('onOver', [this.elem, this.container, event]);
				}
			}.bind(this),
			'mousedown': function(event) {
				if (event.target.nodeName.toLowerCase() === this.options.resultsElem) {
					event.preventDefault();
					this.hide();
					if (this.options.clickSubmit) this.container.retrieve('form').submit();
				}
			}.bind(this)
		});
	},
	updatePosition: function() {
		var i, cur = this.results[this.position], child = cur.firstChild;
		for (i = 0; i < this.len; i += 1) this.results[i].removeClass(this.options.resultsClass);
		cur.addClass(this.options.resultsClass);
		while(child.nodeType !== 3) {
			child = child.firstChild;
		}
		this.elem.value = child.nodeValue;
		this.fireEvent('onSelect', [this.elem, this.container, cur]);
	}
});

// no ajax, assumes that containers.length === tabs.length
var Tabs = new Class({
	Implements: [Options, Events],
	options: {
		// onHide: function(){},
		// onInit: function(){},
		// onShow: function(){},
		forceHTML: false,
		hideClass: 'hideTab',
		showClass: 'showTab',
		start: 0
	},
	initialize: function(tabs, containers, options) {
		this.setOptions(options);
		this.tabs = $$(tabs);
		this.containers = $$(containers);
		this.now = this.options.start;
		this.fireEvent('init', [this.tabs, this.containers]);
		if (this.options.forceHTML && !this.tabs[this.now].hasClass(this.options.showClass)) this.show(this.tabs[this.now], this.now);
		this.tabs.each(function(tab, index) {
			if (!this.options.forceHTML & tab.hasClass(this.options.showClass)) this.now = index;
			this.attach(tab, index);
		}, this);
	},
	attach: function(tab, index) {
		tab.addEvents({
			'click': function(event) {
				event.preventDefault();
				this.show(tab, index);
			}.bind(this),
			'focus': function() {
				this.show(tab, index);
			}.bind(this)
		});
	},
	hideAll: function(index) {
		var i, l = this.containers.length;
		this.fireEvent('hide', [this.tabs, this.containers, index]);
		for (i = 0; i < l; i += 1) {
			this.tabs[i].removeClass(this.options.showClass);
			this.containers[i].removeClass(this.options.showClass).addClass(this.options.hideClass);
		}
	},
	show: function(tab, index) {
		if (this.now === index) return;
		this.now = index;
		this.hideAll(index);
		this.tabs[index].addClass(this.options.showClass);
		this.containers[index].removeClass(this.options.hideClass).addClass(this.options.showClass);
		this.fireEvent('show', [this.tabs, this.containers, index]);
	}
});

var AjaxTabs = new Class({
	Extends: Tabs,
	options: {
		cache: true,
		loader: false,
		loaderOptions: {
			'type': false,
			loaderSrc: null
		},
		query: false,
		queryValue: false,
		urls: null
	},
	show: function(tab, index) {
		var container = this.containers[0],
			l = this.tabs.length, content, i;	
		
		if (this.now === index) return;
		this.fireEvent('hide', [this.tabs, this.containers, index]);
		if (this.options.cache && !this.tabs[this.now].retrieve('content')) this.tabs[this.now].store('content', container.innerHTML);
		content = tab.retrieve('content');
		if (content) {
			this.tabs[this.now].removeClass(this.options.showClass);
			tab.addClass(this.options.showClass);
			this.now = index;
			container.innerHTML = content;
			this.fireEvent('show', [this.tabs, this.containers, index]);
		} else {
			this.getContent(tab, container, index);
		}
	},
	getContent: function(tab, container, index) {
		var loader = new Loader(),
			loaderParent = this.options.loaderParent === 'container' ? container: tab,
			urls = this.options.urls,
			query, requester, url;
		
		if (urls) {
			url = typeOf(urls) === 'array' ? urls[index]: urls;
		} else {
			url = tab.nodeName === 'A' ? stripQuery(tab.href) : stripQuery(tab.getChildren('a')[0].href);
		}
		
		if (this.options.query) {
			query = this.options.query + '=' + tab.get(this.options.queryValue);
		} else {
			query = tab.nodeName === 'A' ? getQuery(tab.href) : getQuery(tab.getChildren('a')[0].href);
		}
		
		requester = new Request({
			method: 'get',
			url: url,
			onRequest: function() {
				var opts = this.options.loaderOptions,
					loaderParent;
				if (this.options.loader) {
					loaderParent = !opts['type'] ? this.options.loader: opts['type'] === 'container' ? container: tab;
					loader.setLoader(loaderParent, opts);
				}
			}.bind(this),
			onSuccess: function(response) {
				container.innerHTML = response;
				if (this.options.loader) loader.hideLoader();
				this.tabs[this.now].removeClass(this.options.showClass);
				tab.addClass(this.options.showClass);
				this.now = index;
				this.fireEvent('show', [this.tabs, this.containers, index]);
			}.bind(this)
		});
		
		requester.send(query);
	}
});

var AjaxPaging = new Class({
	Implements: [Options, Events, Loader],
	options: {
		// onComplete: function(){},
		// onInit: function(){},
		// onRequest: function(){},
		// onShow: function(){},
		loader: true,
		loaderContainer: null,
		loaderOptions: {
			loaderType: 'image',
			loaderSrc: '/system/img/ajax-loader.gif'
		},
		trigger: 'click',
		url: null
	},
	initialize: function(elems, container, cacheTo, options) {
		this.setOptions(options);
		this.elems = $$(elems);
		this.container = $(container);
		this.cache = $(cacheTo).retrieve('pagingCache', {});
		this.query = window.location.search.replace('?', '');
		this.args = [this.elems, this.container];
		this.fireEvent('init', this.args);
		this.elems.each(function(elem, index) {
			this.attach(elem, container, index);
		}, this);
	},
	attach: function(elem, container, index) {
		var trigger = this.options.trigger;
		elem.addEvent(trigger, function(event) {
			var query = trigger === 'submit' ? elem.toQueryString() : getQuery(elem.href),
				cache = this.cache[query];
			event.preventDefault();
			this.args[2] = index;
			if (cache) {
				container.innerHTML = cache;
				this.fireEvent('show', this.args);
			} else {
				this.cache[this.query] = container.innerHTML;
				this.fetchContent(elem, container, index, query);
			}
		}.bind(this));
	},
	fetchContent: function(elem, container, index, query) {
		var url = this.options.url;
		var requester = new Request({
			url: url,
			method: 'get',
			onRequest: function() {
				if (this.options.loader) {
					var loaderContainer = this.options.loaderContainer || elem;
					this.setLoader(loaderContainer, this.options.loaderOptions);
				}
				this.fireEvent('request', [this.elems, container, index, query]);
			}.bind(this),
			onSuccess: function(response) {
				this.query = query;
				container.innerHTML = response;
				if (this.options.loader) this.hideLoader();
				this.fireEvent('show', this.args);
				this.fireEvent('complete', this.args);
			}.bind(this)
		});
		requester.send(query);
	}
});
var MultipleRequestPaging = new Class({
	Extends: AjaxPaging,
	requesters: [],
	attach: function(elem, containers, index) {
		var trigger = this.options.trigger;
		elem.addEvent(trigger, function(event) {
			var query = trigger === 'submit' ? elem.toQueryString() : getQuery(elem.href),
				cache = this.cache[query],
				currentCache = this.cache[this.query];
			event.preventDefault();
			if (this.requesters.length === 0) {
				if (currentCache) {
					currentCache.length = 0;
				} else {
					currentCache = this.cache[this.query] = [];
				}
				containers.each(function(container) {
					currentCache[currentCache.length - 1] = (typeOf(container) === 'array' || typeOf(container) === 'elements') ? container[0].innerHTML : container.innerHTML;
				});
				this.query = query;
				if (cache) {
					cache.each(function(result, i) {
						if (typeOf(containers[i]) === 'array' || typeOf(containers[i]) === 'elements') {
							containers[i].each(function(container) {
								container.innerHTML = result;
							});
						} else {
							containers[i].innerHTML = result;
						}
					});
					this.fireEvent('show', this.args);
				} else {
					this.fetchContent(elem, containers, index, query);
				}
			}
		}.bind(this));
	},
	fetchContent: function(elem, containers, index, query) {
		var sending = 0;
		this.options.url.each(function(url, i) {
			this.requesters[i] = new Request({
				method: 'get',
				url: url,
				onRequest: function() {
					if (sending === 0) this.fireEvent('request', [this.elems, containers, index, query]);
					if (this.options.loader) {
						var loaderContainer = this.options.loaderContainer || elem;
						this.setLoader(loaderContainer, this.options.loaderOptions);
					}
					sending += 1;
				}.bind(this),
				onSuccess: function(response) {
					var cache;
					sending -= 1;
					if (!this.cache[query]) this.cache[query] = [];
					this.cache[query][i] = response;
					if (sending === 0) {
						containers.each(function(container, i) {
							cache = this.cache[query][i];
							if (typeOf(container) === 'array' || typeOf(container) === 'elements') {
								container.each(function(c) {
									c.innerHTML = cache;
								});
							} else {
								container.innerHTML = cache;
							}
						}, this);
						if (this.options.loader) this.hideLoader();
						this.fireEvent('show', this.args);
					}
				}.bind(this)
			});
			this.requesters[i].send(query);
		}, this);
	}
});
var Slideshow = new Class({
	Implements: [Options, Events, Chain],
	options: {
		// onInit: function(){},
		// onHide: function(){},
		// onShow: function(){},
		start: 0,
		delay: 7000,
		duration: 500,
		hideClass: 'hideSlide',
		showClass: 'showSlide',
		opacity: true,
		progressButton: false,
		progressPanel: 'panelProgress',
		previous: null,
		pause: null,
		next: null
	},
	initialize: function(slides, options) {
		this.setOptions(options);
		this.slides = $$(slides);
		if (this.slides.length) {
			this.index = this.options.start;
			var progress = $(this.options.progressPanel), slide, images;
			if (this.options.opacity) {
				for (var i = 0, l = this.slides.length; i < l; i += 1) {
					slide = this.slides[i];
					if (this.options.progressButton) slide.store('button', new Element('a').inject(progress));
					if (i !== this.index) slide.setStyle('opacity', '0');
					slide.set('tween', {
						duration: this.options.duration,
						onComplete: function() {
							this.callChain();
						}.bind(this)
					});
					if (Browser.ie) {
						images = slide.retrieve('images', slide.getElements('img'));
						if (typeOf(images) === 'elements') {
							images.each(function(img) {
								img.set('tween', {
									duration: this.options.duration,
									onComplete: function() {
										this.callChain();
									}.bind(this)
								});
							}, this);
						}
					}
				}
			}
			this.timer = setInterval(function() {
				this.display(true);
			}.bind(this), this.options.delay);
			this.setControls($(this.options.previous), $(this.options.pause), $(this.options.next));
			this.fireEvent('onInit', [this.slides, this.index]);
		}
	},
	display: function(effects, show, pause) {
		this.hideSlide(this.slides[this.index], effects);
		if (typeOf(show) === 'number') {
			this.index = show;
		} else if (show === 'previous') {
			this.index = this.index === 0 ? this.slides.length - 1: this.index - 1;
		} else {
			this.index = this.index === this.slides.length - 1 ? 0: this.index + 1;
		}
		this.showSlide(this.slides[this.index], effects);
		if (pause) clearInterval(this.timer);
	},
	hideSlide: function(slide, effects) {
		this.chain(
			function() {
				if (effects) {
					slide.tween('opacity', '0');
					if (Browser.ie && typeOf(slide.retrieve('images') === 'elements')) {
						slide.retrieve('images').each(function(img) {
							img.tween('opacity', '0');
						});
					}
				} else {
					slide.setStyle('opacity', '1');
					if (Browser.ie && typeOf(slide.retrieve('images') === 'elements')) {
						slide.retrieve('images').each(function(img) {
							img.setStyle('opacity', '0');
						});
					}
					this.callChain();
				}
			},
			function() { slide.removeClass(this.options.showClass).addClass(this.options.hideClass); this.callChain(); },
			function() {
				this.fireEvent('onHide', [this.slides, this.index]);
				this.callChain();
			}
		);
	},
	showSlide: function(slide, effects) {
		this.chain(
			function() {
				this.fireEvent('onShow', [this.slides, this.index]);
				this.callChain();
			},
			function() { slide.removeClass(this.options.hideClass).addClass(this.options.showClass); this.callChain(); },
			function() {
				if (effects) {
					slide.tween('opacity', '1');
					if (Browser.ie && typeOf(slide.retrieve('images') === 'elements')) {
						slide.retrieve('images').each(function(img) {
							img.tween('opacity', '1');
						});
					}
				} else {
					slide.setStyle('opacity', '1');
					if (Browser.ie && typeOf(slide.retrieve('images') === 'elements')) {
						slide.retrieve('images').each(function(img) {
							img.setStyle('opacity', '1');
						});
					}
					this.callChain();
				}
			}
		);
		this.callChain();
	},
	setControls: function(prevLink, pauseLink, nextLink) {
		if (prevLink) {
			$(prevLink).addEvent('click', function(event) {
				event.preventDefault();
				this.display(false, 'previous', true);
			}.bind(this));
		}
		if (nextLink) {
			$(nextLink).addEvent('click', function(event) {
				event.preventDefault();
				this.display(false, 'next', true);
			}.bind(this));
		}
		if(pauseLink) {
			$(pauseLink).addEvent('click', function(event) { 
				event.preventDefault(); clearInterval(this.timer);
			}.bind(this));
		}
	}
});

var Slidereel = new Class({
	Implements: [Options, Events],
	options: {
		// onChange: function(){},
		slidesSelector: 'div',
		wrapper: false,
		wrapperStyles: {},
		prevLink: false,
		nextLink: false,
		start: 0,
		duration: 500,
		//itemElem: 'div',
		sameSize: true
	},
	initialize: function(container, options) {
		var w = container.getSize().x,
			//divs = container.getChildren(this.options.itemElem),
			divs = container.getChildren(this.options.slidesSelector),
			div = divs[0],
			wItem = div.getSize().x + div.getStyle('marginLeft').toInt() + div.getStyle('marginRight').toInt(),
			scrollW = this.options.sameSize ? divs.length * wItem : this.calculateWidth(divs);
		this.setOptions(options);
		this.now = this.options.start;
		this.container = container;
		//this.slides = this.container.getElements(this.options.slidesSelector);
		this.slides = divs;
		this.wrapper = this.options.wrapper || new Element('div').wraps(this.container);
		this.wrapper.setStyles(Object.merge(this.options.wrapperStyles, {
			width: w,
			position: 'relative',
			overflow: 'hidden'
		}));
		this.container.setStyles({
			'left': this.options.start,
			'width': scrollW,
			'overflow': 'visible'
		}).set('tween', {'duration': this.options.duration, 'onStart': function() {
			this.fireEvent('onChange', [this.wrapper, this.container, this.slides, this.now]);
		}.bind(this)});
		if (this.options.prevLink) this.setControls(this.options.prevLink, 'previous');
		if (this.options.nextLink) this.setControls(this.options.nextLink, 'next');
	},
	calculateWidth: function(elems) {
		var w = 0;
		elems.each(function(elem) {
			w += (elem.getSize().x + elem.getStyle('marginLeft').toInt() + elem.getStyle('marginRight').toInt());
		});
		return w;
	},
	setControls: function(elem, action) {
		elem.addEvent('click', function(event) {
			event.preventDefault();
			this.display(action);
		}.bind(this));
	},
	display: function(action) {
		var w = this.wrapper.getSize().x,
			scrollW = this.container.getScrollSize().x;
		if (action === 'previous') {
			scrollW = ((scrollW/w).isInt()) ? scrollW : (scrollW/w).toInt() * w;
			this.now = (this.now === 0) ? w - scrollW : this.now + w;
		} else {
			this.now = ((this.now - w) < (w - scrollW)) ? 0 : this.now - w;
		}
		this.container.tween('left', this.now);
	}
});

var InputClear = new Class({
	initialize: function(elems) {
		var elems = elems || 'input[type^=text]';
		$$(elems).each(function(elem) {
			if (elem.get('type') === 'password') elem.store('orig', elem.getStyle('background-image'));
			this.attach(elem);
		}, this);
	},
	attach: function(elem) {
		elem.addEvents({
			'focus': function() {
				if (elem.get('type') !== 'password') elem.store('orig', elem.get('value'));
				elem.set('value', '');
				if (elem.get('type') === 'password') elem.setStyle('background-image', 'none');
			},
			'blur': function() {
				if (elem.get('value') === '') {
					if (elem.get('type') === 'password') {
						elem.setStyle('background-image', elem.retrieve('orig'));
					} else {
						elem.set('value', elem.retrieve('orig'));
					}
				}
			}
		});
	}
});

(function() {
	var cur = null;
	var SaveItems = this.SaveItems = new Class({
		Implements: [Options, Events, Overlay, Loader],
		options: {
			// onSave: function() {},
			// onSaveTo: function() {},
			closeId: 'closeSavedBox',
			containerId: 'saveItemContainer',
			itemClass: 'saveItem',
			leftOffset: -12,
			lightboxId: 'saveLightbox',
			loader: true,
			loaderOptions: {
				loaderType: 'image',
				loaderSrc: '/system/img/ajax-loader.gif',
				styles: {
					'top': 5
				}
			},
			savedItemClass: 'savedItem',
			topOffset: 20,
			url: '/system/ajax/save.html'
		},
		initialize: function(elems, options) {
			var opts;
			this.setOptions(options);
			this.elems = $$(elems);
			if (this.elems) {
				this.setContainer();
				opts = this.options;
				this.elems.each(function(a, index) {
					a.addEvent('click', function(event) {
						var elem = $(event.target),
							par = elem.getParent();
						if (cur) cur.getParent().setStyle('z-index', cur.retrieve('z'));
						cur = (elem.hasClass(opts.itemClass) || elem.hasClass(opts.savedItemClass)) ? elem : (par.hasClass(opts.itemClass) || par.hasClass(opts.savedItemClass)) ? par : null;
						if (cur) {
							event.preventDefault();
							clearTimeout(this.container.retrieve('timer'));
							this.container.store('query', cur.href);
							this.container.store('timer', setTimeout(function() {
								this.hide();
							}.bind(this), 1500));
							this.display(cur);
						}
					}.bind(this));
				}, this);
			}
		},
		setContainer: function() {
			var flagged, newfolder, existing, createalert, bgdiv;
			this.container = $(this.options.containerId);
			if (!this.container) {
				this.container = new Element('div', {'id': this.options.containerId, 'style': 'display: none;'}).inject(document.body);
				flagged = new Element('a', {'href': '?saveto=flagged&save=true'}).appendText('save to \'My Flagged items\'').inject(this.container);
				newfolder = new Element('a', {'href': '?saveto=newfolder'}).appendText('save to new folder').inject(this.container);
				existing = new Element('a', {'href': '?saveto=existingfolder'}).appendText('save to existing folder').inject(this.container);
				createalert = new Element('a', {'class': 'createAlert', 'href': '?saveto=alert&save=true'}).appendText('create an alert').inject(this.container);
				bgdiv = new Element('div').inject(this.container);
				this.container.addEvents({
					'click': function(event) {
						event.preventDefault();
						if (event.target.nodeName === 'A') {
							if ($('overlay')) {
								$$('.lightbox')[0].destroy();
								$('overlay').destroy();
							}
							this.saveItem($(event.target));
						}
					}.bind(this),
					'mouseover': function(event) {
						var timer = this.container.retrieve('timer');
						clearTimeout(timer);
						this.keepOpen = true;
					}.bind(this),
					'mouseout': function(event) {
						this.keepOpen = false;
						this.container.retrieve('timer', setTimeout(function() {
							this.hide();
						}.bind(this), 800));
					}.bind(this)
				});
			}
		},
		hide: function() {
			if (!this.keepOpen) {
				this.container.setStyles({
					'z-index': 0,
					'display': 'none',
					'visibility': 'hidden'
				});
			}
		},
		display: function(elem) {
			var alertLink = this.container.getElement('.createAlert'),
				par = elem.getParent(),
				t = elem.getPosition().y + this.options.topOffset + 'px',
				l = elem.getPosition().x + this.options.leftOffset + 'px';
			par.store('z', elem.parentNode.getStyle('z-index'));
			par.setStyle('z-index', 9999999);
			this.container.setStyle('z-index', 9999999);
			if (elem.href.contains('type=author') || elem.href.contains('type=keyword') || elem.href.contains('type=scripture')) {
				alertLink.setStyle('display', '');
			} else {
				alertLink.setStyle('display', 'none');
			}
			this.container.inject(document.body).setStyles({
				'left': l,
				'top': t,
				'display': 'block',
				'visibility': 'visible'
			});
		},
		saveItem: function(a) {
			var query = getQuery(a.href) + '&' + getQuery(this.container.retrieve('query'));
				resultsBox = this.overlay('div', this.options.lightboxId),
				url = this.options.url,
				requester = new Request({
					method: 'get',
					url: url,
					onRequest: function() {
						if (this.options.loader) this.setLoader(a, this.options.loaderOptions);
					}.bind(this),
					onSuccess: function(response) {
						if (this.options.loader) this.hideLoader();
						this.keepOpen = false;
						this.hide();
						resultsBox.innerHTML = response;
						this.showOverlay($(this.options.closeId));
						this.saveTo(resultsBox);
						this.fireEvent('saveTo', [cur, a, this.container]);
					}.bind(this)
				});
			requester.send(query + '&' + new Date().getTime());
		},
		saveTo: function(elem) {
			var lightbox = elem.nodeName === 'FORM' ? elem : elem.getElement('form');
			if (lightbox) {
				lightbox.addEvent('submit', function(event) {
					var query = lightbox.toQueryString(),
						url = this.options.url;
					event.preventDefault();
					var requester = new Request({
						url: url,
						onRequest: function() {
							if (this.options.loader) this.setLoader(elem, this.options.loaderOptions);
						}.bind(this),
						onSuccess: function(response) {
							if (this.options.loader) this.hideLoader();
							elem.innerHTML = response;
							$(this.options.closeId).addEvent('click', function(event) {
								this.closeLightbox();
							}.bind(this));
							this.fireEvent('save', [cur, elem, this.container]);
						}.bind(this)
					});
					requester.send(query);
				}.bind(this));
			}
		}
	});
})();

var charCount = function charCount(what, maxCount, limitText)
{
	var what = (typeOf(what) === 'element') ? what : $(what),
		entry = what.get('value'),
		str = new String(entry),
		len = str.length,
		limitText = limitText || 'limitText',
		limitSpan = $(limitText);
	
	len = maxCount - len;
	
	if (len < 0) {
		what.set('value', entry.slice(0, maxCount));
	} else if (len > 1) {
		limitSpan.innerHTML = "<strong>" + len + "</strong> characters remaining";
	} else {
		limitSpan.innerHTML = "<strong>" + len + "</strong> character remaining";
	}
}
var suckerfish = function suckerfish(elems) {
	if (Browser.ie6) {
		var sfEls = $$(elems);
		for (var i = 0, l = sfEls.length; i < l; i += 1) {
			sfEls[i].onmouseover=function() {
				this.className += " sfhover";
			}
			sfEls[i].onmouseout = function() {
				this.className = this.className.replace(new RegExp(" sfhover\\b"), "");
			}
		}
	}
};
var externalLinks = function externalLinks(items) {
	var links = (items) ? $$(items): $$('a.external');
	links.each(function(a) {
		a.addEvent('click', function(e) {
			e.preventDefault();
			open(a.get('href'));
			return false;
		});
	});	
};
var printPage = function printPage(elems, width, height) {
	var elems = $$(elems),
		width = width || 790,
		height = height || 400;
	if (elems) {
		elems.each(function(elem) {
			elem.addEvent('click', function(event) {
				event.preventDefault();
				window.open(elem.get('href'), 'printWindow', 'width=' + width + ',height=' + height + ',toolbar=0,location=0,directories=0,status=0,menubar=1,scrollbars=1,resizable=1');
			});
		});
	}
};
var emailPage = function emailPage(elems, width, height) {
	var elems = $$(elems),
		width = width || 790,
		height = height || 400;
	if (elems) {
		elems.each(function(elem) {
			elem.addEvent('click', function(event) {
				event.preventDefault();
				window.open(elem.get('href'), 'emailWindow', 'width=' + width + ',height=' + height + ',toolbar=0,location=0,directories=0,status=0,menubar=1,scrollbars=1,resizable=1');
			});
		});
	}
};
var smallWindow = function smallWindow(elems, width, height) {
	$$(elems).each(function(elem) {
		elem.addEvent('click', function(event) {
			event.preventDefault();
			var w = (width) ? width: '520';
			var h = (height) ? height: '450';
			window.open(elem.get('href'), 'printWindow', 'width=' + w + ',height=' + h + ',toolbar=0,location=0,directories=0,status=0,menubar=1,scrollbars=1,resizable=1');
		});
	});	
};
// Hover Ads
var ctiHovers = {
	init: function() {
		var h = this.getSize().y,
			that = this,
			w = this.getSize().x,
			elems = [], elem, txt;
		
		this.closeLink = $('closeHoverAd');
		this.hover = $('hover');
		this.overlay = $('overlay');
		
		txt = this.hover.innerHTML.toLowerCase();
		if (this.hover && (txt.contains('empty hover ad') || txt.contains('http://content.aimatch.com/cti/black_default.gif') || this.hover.getChildren().length <= 1)) {
			this.closeHover();
		} else {
			this.hover.inject(document.body);
			this.hover.style.left = (w/2) - (this.hover.clientWidth/2) + 'px';
			this.hover.style.visibility = 'visible';
	   
			if (this.overlay) {
				this.overlay.inject(document.body);
				this.overlay.style.height = h + 'px';
				this.overlay.style.width = w + 'px';
			}
			
			this.timer = setTimeout(function() {
				that.closeHover();
			}, 15000);
			
			this.attach();
		}
	},
	attach: function() {
		var that = this,
			hoverForm = this.hover.getElementsByTagName('form')[0];
		
		if (hoverForm) {
			hoverForm.onsubmit = function() {
				that.hover.style.left = '-999em';
				setTimeout(function() {
					that.closeHover();
				}, 5000);
			};
		}
		this.hover.onclick = function(event) {
			var event = event || window.event,
				elem = event.target || event.srcElement;
			if (elem.nodeName === 'A' || elem.parentNode.nodeName === 'A' || elem.nodeName === 'OBJECT' || elem.nodeName === 'EMBED') {
				setTimeout(function() {
					that.closeHover();
				}, 500);
			}
		};
		/*this.hover.onmouseup = function() {
			var event = event || window.event,
				elem = event.target || event.srcElement;
			if (elem.nodeName === 'OBJECT' || elem.nodeName === 'EMBED') {
				setTimeout(function() {
					that.closeHover();
				}, 500);
			}
		};*/
		this.hover.onmouseover = function() {
			clearTimeout(that.timer);
		};
		this.closeLink.onfocus = function() {
			clearTimeout(that.timer);
		};
		this.closeLink.onclick = function() {
			that.closeHover();
			return false;
		};
		if (this.overlay) {
			this.overlay.onclick = function() {
				that.closeHover();
			};
		}
	},
	closeHover: function() {
		this.hover.destroy();
		if (this.overlay) this.overlay.destroy();
		clearTimeout(this.timer);
	},
	// getSize: based on MooTools method of the same name
	getSize: function() {
		var doc = (!document.compatMode || document.compatMode === 'CSS1Compat') ? document.getElementsByTagName('html')[0] : document.body,
			m = window.ActiveXObject ? 'min': 'max';
		return {x: Math[m](doc.scrollWidth, doc.offsetWidth), y: Math.max(doc.scrollHeight, doc.offsetHeight)};
	}
};
// This function relies on the IPInfoDB api: http://ipinfodb.com
var Geolocate = function Geolocate(objectVar, options) {
	var geodata;
	options = Object.merge({
		callback: function(){},
		cookieDuration: 365,
		timezone: false,
		cityPrecision: true
	}, options);

	this.initialize = function() {
		var cache = Cookie.read('ctiGeolocation');
		if (!cache) {
			this.getGeolocation();
		} else {
			geodata = JSON.decode(cache);
			options.callback(geodata);
		}
	};

	this.setGeoCookie = function(response) {
		if (response['Status'] === 'OK') {
			var JSONString = JSON.encode(response);
			Cookie.write('ctiGeolocation', JSONString, {
				duration: options.cookieDuration
			});
			geodata = response;
			options.callback(geodata);
		}
	};

	this.getGeolocation = function() {
		var timezone = (options.timezone) ? 'true' : 'false',
			api = (options.cityPrecision) ? 'ip_query.php' : 'ip_query_country.php',
			apiKey = '5ae3767203f9b8299534e63b00127854d99d8aec28024d92e6e33a7bffb1cf6a',
			url = "http://api.ipinfodb.com/v2/" + api + "?key=" + apiKey + "&output=json&timezone=" + timezone + "&callback=" + objectVar + ".setGeoCookie",
			script = new Element('script', {'src': url});
		script.inject(document.body);
	};
};
if (!cti) var cti = {};
if (typeof cti.reportComments !== 'function') {
	cti.reportComments = function() {
		var elems = $$('.reportComment');
		elems.each(function(elem) {
			elem.addEvent('click', function(event) {
				var pos = elem.getPosition(),
					comment = elem.id.replace('report', ''),
					container = $('whyReport'),
					createContainer, commentForm;
				event.preventDefault();
				
				createContainer = function() {
					var container = new Element('div', {'id': 'whyReport'}).inject(document.body);
					container.innerHTML = '<h3>I am reporting this comment because*: <span>(check all that apply)</span></h3><form method="get" action="/system/comments/report.html"><fieldset><div><input type="checkbox" id="spam" class="checkbox" name="reason" value="spam" /><label for="spam">It is spam or advertising</label></div><div><input type="checkbox" id="vulgarity" class="checkbox" name="reason" value="vulgarity" /><label for="vulgarity">It contains vulgarities</label></div><div><input type="checkbox" id="inflammatory" class="checkbox" name="reason" value="inflammatory" /><label for="inflammatory">It is inflammatory or attacks another person</label></div><div><input type="checkbox" id="offtopic" class="checkbox" name="reason" value="offtopic" /><label for="offtopic">It is completely off-topic</label></div><div><input type="hidden" id="reportedComment" name="id" value="" /><input type="submit" value="Submit" /><input type="button" id="cancelReport" value="Cancel" /></div></fieldset></form><p class="disclaimer">*We will only consider removing comments for the reasons listed above. Comments will not be removed because of disagreement of opinion.</p>';
					
					return container;
				};
				
				if (!container) {
					container = createContainer();
					$('cancelReport').addEvent('click', function(event) {
						container.style.cssText = 'position: absolute; top: 0; left: -999em; visibility: hidden;';
					});
					commentForm = container.getElement('form');
					commentForm.addEvent('submit', function(event) {
						var inputs = commentForm.getElements('input'),
							reason = '';
						event.stop();
						inputs.each(function(elem) {
							if (elem.name === 'reason' && elem.checked) reason += elem.value;
						});
						if (reason === '') {
							alert('Please specify why you are reporting this comment.');
						} else {
							commentForm.submit();
						}
					});
				}
	
				$('reportedComment').value = comment;
				container.style.cssText = 'position: absolute; top: ' + (pos.y + 20) + 'px; left: ' + pos.x + 'px; visibility: visible;';
			});
		});		
	};
}
window.addEvent('domready', function() {
	suckerfish('#globalheader li');
	cti.inputClear = new InputClear('.clearField');
	cti.reportComments();
	externalLinks();
	cti.tooltips = new Tips ('.tooltip', {
		className: 'tipContainer',
		text: null
	});
	if (window.showPromo) showPromo();
	if ($('hover') && !ctiHovers.notSystem) ctiHovers.init();
	var embedLightbox = new Lightbox({
		elems: $$('.embed'),
		containerId: 'embedVideo',
		closeId: 'closeEmbedVideo',
		url: '/system/ajax/embedvideo.html',
		onResponse: function(container) {
			var textarea = container.getElements('textarea')[0];
			textarea.addEvent('click', function(event) {
				textarea.focus();
				textarea.select();
			});
		}
	});
});
