var Lightbox = Class.create({
	initialize: function(box) {
		this._lb = box;
		this._lb.setStyle({zIndex:1000});
		this._animationTime = 0.3;

		this._overlay = new Element('div');
		this._overlay.addClassName('lb-overlay');
		this._lb.up().insertBefore(this._overlay, this._lb);
		this._overlay.setStyle({zIndex:999});
		this._overlay.hide();

		this._disabler = new Element('div');
		this._disabler.addClassName('lb-disabler');
		this._lb.up().insertBefore(this._disabler, this._lb);
		this._disabler.setStyle({zIndex:1001});
		this._disabler.hide();

		var closeBox = new Element('a');
		closeBox.addClassName('close-box');
		closeBox.innerHTML = '<span>Close</span>';
		this._lb.appendChild(closeBox);
		closeBox.onclick = function() {return false;};
		closeBox.observe('click', this._closeClicked.bind(this));

		this._content = new Element('div');
		this._content.addClassName('lb-content');
		this._lb.appendChild(this._content);

		Event.observe(window, 'resize', this._positionLightbox.bind(this));

		window.ourLightbox = this;

		if (this._lb.down('.lb-notice') || this._lb.down('.lb-msg')) {this.show();}
	},

	contains: function(element) {
		return element.descendantOf(this._lb);
	},

	load: function(url, meth) {
		new Lightbox.Updater(
			this._content, url, {
				method:meth,
				evalScripts:true,
				onComplete:this._gotResponse.bind(this)
			}
		);
	},

	submit: function(form, commit) {
		if (form) {
			var params = form.serialize();
			if (commit) {params += '&submit_action=' + commit;}
			new Lightbox.Updater(
				this._content, form.action, {
					parameters:params,
					evalScripts:true,
					onComplete:this._gotResponse.bind(this)
				}
			);
			this._disabler.show();
		}
	},

	_finishDismissWithReload: function() {
		this._overlay.hide();
		window.location.reload();
	},

	_finishDismiss: function() {
		this._overlay.hide();
	},

	dismiss: function(reload) {
		reload = reload ? this._finishDismissWithReload.bind(this) : this._finishDismiss.bind(this);
		this._disabler.hide();
		Effect.Fade(this._lb, {duration:this._animationTime, afterFinish:reload});
	},

	show: function() {
		this._instrumentForms();
		this._positionLightbox();
		this._disabler.hide();
		if (!this._lb.visible()) {
			this._overlay.show();
			Effect.Appear(this._lb, {duration:this._animationTime, afterFinish:this._activateDefaultField.bind(this)});
		}
	},

	_activateDefaultField: function() {
		var form = this._lb.down('form');
		if (form) {Framework.Form.activateDefaultField(form);}
	},

	_closeClicked: function() {
		this.dismiss();
	},

	_gotResponse: function(response) {
		switch (response.status) {
			case 200:
				document.fire('ourstage:ajaxLoaded');
				this.show();
				break;
			case 205:
				this.dismiss(true)
				break;
			default:
				this.dismiss();
				break;
		}
	},

	_formSubmitted: function(event) {
		var form = event.element();
		if (form) {this.submit(form);}
	},

	_instrumentForms: function() {
		this._lb.select('form').each(function(form) {
			form.onsubmit = function() {return false;}
			form.observe('submit', this._formSubmitted.bind(this));
		}.bind(this));
		this._lb.select('input[type=submit]').each(function(button) {
			button.onclick = this._submitClicked.bind(this);
		}.bind(this));
	},

	_submitClicked: function(event) {
		var button = event.element();
		var form = button.up('form');
		var commit = $F(button);
		if (form && commit) {this.submit(form, commit);}
		return false;
	},

	_positionLightbox: function() {
		var dims = this._lb.getDimensions();
		var wDims = document.viewport.getDimensions();
		var x = (wDims.width - dims.width) / 2;
		var y = (wDims.height - dims.height) / 3;
		this._lb.setStyle({
			position:'fixed',
			top:y + 'px',
			left:x + 'px'
		});
	}
});

Lightbox.Updater = Class.create(Ajax.Request, {
	initialize: function($super, container, url, options) {
		this.container = {
			success: (container.success || container),
			failure: (container.failure || (container.success ? null : container))
		};

		options = Object.clone(options);
		var onComplete = options.onComplete;
		options.onComplete = (function(response, json) {
			this.updateContent(response);
			if (Object.isFunction(onComplete)) onComplete(response, json);
		}).bind(this);

		$super(url, options);
	},

	updateContent: function(response) {
		var responseText = response.responseText;
		if (response.status == 200) {
			var receiver = this.container[this.success() ? 'success' : 'failure'];
			var options = this.options;

			if (!options.evalScripts) responseText = responseText.stripScripts();

			if (receiver = $(receiver)) {
				if (options.insertion) {
					if (Object.isString(options.insertion)) {
						var insertion = { }; insertion[options.insertion] = responseText;
						receiver.insert(insertion);
					}
					else options.insertion(receiver, responseText);
				}
				else receiver.update(responseText);
			}
		}
	}
});

Lightbox.contains = function(element) {return (window.ourLightbox) ? window.ourLightbox.contains(element) : false;};
Lightbox.load = function(url, method) {if (window.ourLightbox) {window.ourLightbox.load(url, method);}};
Lightbox.dismiss = function() {if (window.ourLightbox) {window.ourLightbox.dismiss();}};
Lightbox.submit = function(form, commit) {if (window.ourLightbox) {window.ourLightbox.submit(form, commit);}};
Lightbox.setup = function() {
	var box = $('our-lightbox');
	if (box) {new Lightbox(box);}
};
document.observe('dom:loaded', Lightbox.setup);

var Hoverbox = Class.create({
	initialize: function(box) {
		this._box = $(box);
		this._trigger = this._box.previous();
		var link = this._box.down('a.hb-link');
		if (link) {
			this._url = link.href;
			link.up().removeChild(link);
		}

		this._content = new Element('div');
		this._content.addClassName('content');
		this._arrow = new Element('div');
		this._arrow.addClassName('arrow');
		this._content.innerHTML = this._box.innerHTML;
		this._box.innerHTML = '';
		this._box.appendChild(this._arrow);
		this._box.appendChild(this._content);

		if (this._trigger) {
			this._trigger.observe('mouseover', this.show.bind(this));
			this._trigger.observe('mouseout', this.hide.bind(this));
			this._box.observe('mouseout', this.hide.bind(this));
		}
	},

	_presentBox: function() {
		this._url = null;
		this._box.show();
		this._box.clonePosition(this._trigger, {
			setHeight: false,
			setWidth: false,
			offsetTop: this._trigger.offsetHeight - 8,
			offsetLeft: -10
		});
		var arrowOff = 10 + Math.floor(this._trigger.getWidth() / 2) - 13;
		this._arrow.setStyle({
			backgroundPosition:arrowOff + 'px 0'
		});
	},

	show: function(event) {
		if (this._url) {
			new Ajax.Updater(
				this._content, this._url, {
					method:'get',
					onComplete:this._presentBox.bind(this)
				}
			);
		} else {
			this._presentBox();
		}
	},

	hide: function(event) {
		var hideIt = true;
		if (event) {
			var newElt = $(event.relatedTarget);
			if ((newElt == this._trigger) || (newElt == this._box) || newElt.descendantOf(this._trigger) || newElt.descendantOf(this._box)) {
				hideIt = false;
			}
		}
		if (hideIt) {this._box.hide();}
	}
});
document.observe('dom:loaded', function() {
	$$('.our-hoverbox').each(function(box) {
		new Hoverbox(box);
	});
});
