var ContentFetcher = new Class({
	Implements: Options,
	elements: [],
	animating: false,
	req: null,
	visible: false,
	content: null,
	container: null,
	imageload: {
		images: [],
		loaded: 0
	},
	options: {
		append: '',
		opacity: 0,
		duration: 250,
		timeout: 1000,
		adoptOnly: '',
		appendTo: null,
		onComplete: null,
		triggerActiveClass: 'on'
	},
	initialize: function (elements, container, options) {
		this.setOptions(options);
		this.elements = elements;
		this.container = $(container);
		
		if (!this.container) return;
		
		this.content = new Element('div');

		this.elements.each(function (el) {
			el.addEvent('click', this.clicked.bindWithEvent(this, el));
		}, this);
	},
	imageLoaded: function () {
		this.imageload.loaded++;
		if (this.imageload.loaded == this.imageload.images.length) {
			this.show();
		}
	},
	loaded: function (tree, elements, html) {
		var el = null;
		for (i = 0; i < tree.length; i++) {
			if (typeof $(tree[i]).getElements != 'undefined') {
				var el = $(tree[i]);
				if (this.options.adoptOnly) {
					var elements = el.getElements('div');
					for (j = 0; j < elements.length; j++) {
						if (elements[j].get('id') == this.options.adoptOnly) {
							el = elements[j];
							break;
						}
					}
				}
				break;
			}
		}
		
		var images = [];
		elements.each(function (e) {
			images.extend(e.getElements('img'));
		});

		// load images
		this.imageload = {
			images: images,
			loaded: 0
		};
		images.each(function (e) {
			e.addEvent('load', this.imageLoaded.bind(this));
		}, this);

		this.content.empty();
		el.injectInside(this.content);

		if (this.imageload.images.length == 0) {
			this.show();
		}
	},
	show: function () {
		this.content.injectInside(this.container);

		var closes = this.container.getElements('.close');
		closes.each(function (el) {
			el.addEvent('click', function (evt) {
				this.hide();
			}.bind(this));
		}, this);
		
		if (this.options.onComplete) {
			(this.options.onComplete)();
		}
	},
	hide: function () {
		this.visible = false;
		this.content.dispose();
		
		this.toggleTriggersClass(true);
	},
	clicked: function (evt, el) {
		if (evt) {
			evt.stop();
		}
		this.toggleTriggersClass();
		if (!this.visible) {
			if (el.get('href') == '#') {
				return;
			}
			var url = new String(el.href);
			if (this.options.append) {
				url += url.contains('?') ? '&' : '?';
				url += this.options.append;
			}
			this.load(url);
		}
		else {
			this.hide();
		}
	},
	load: function (url) {
		this.req = new Request.HTML({
			url: url,
			onSuccess: this.loaded.bind(this),
			onFailure: function () {
				alert('The page request failed, please refresh the page and try again.');
			},
			method: 'get'
		}).send();

		// show loading
		this.visible = true;
	},
	toggleTriggersClass: function(hide) {
		this.elements.each(function (el) {
			if (hide) {
				el.removeClass(this.options.triggerActiveClass);
			}
			else {
				el.addClass(this.options.triggerActiveClass);
			}
		}, this);
	}
});
