var Overlay = Class.create( {
	current_options : null,
	holder : null,
	background : null,
	holder_shown : false,
	bckg_shown : false,
	hiding_in_progress : false,
	hide_timer : null,
	click_event_handler : null,
	window_events_handler : null,
	content_parent_element : null,
	content_element : null,
	init : function() {
		if (this.holder) {
			return
		}
		this.holder = this.init_holder();
		this.background = this.init_background();
		Element.extend(document);
		Element.extend(document.documentElement)
	},
	init_holder : function() {
		var b = document.createElement("div");
		Element.extend(b);
		b.identify();
		b.style.position = "absolute";
		var a = this.option("opacity");
		if (a) {
			b.setOpacity(a)
		}
		b.hide();
		document.body.appendChild(b);
		return b
	},
	position_holder : function(d) {
		var c = this.holder;
		var b = c.getDimensions();
		if (Prototype.Browser.Opera) {
			var f = {
				width : window.innerWidth,
				height : window.innerHeight
			}
		} else {
			var f = document.viewport.getDimensions()
		}
		var e = document.viewport.getScrollOffsets();
		var a = this.option("position");
		c.style.left = (f.width - b.width) / 2 + e.left + "px";
		if (this.option("auto_reposition") || d) {
			if (a == "center") {
				c.style.top = (f.height - b.height) / 2 + e.top + "px"
			} else {
				if (a == "top") {
					c.style.top = e.top + "px"
				} else {
					if (a == "bottom") {
						c.style.top = f.height - b.height + e.top + "px"
					} else {
						throw "Unsupported position: " + a
					}
				}
			}
		} else {
			if (a == "center") {
				c.style.top = (f.height - b.height) / 2 + "px"
			} else {
				if (a == "top") {
					c.style.top = "0px"
				} else {
					if (a == "bottom") {
						c.style.top = f.height - b.height + "px"
					} else {
						throw "Unsupported position: " + a
					}
				}
			}
		}
	},
	init_background : function() {
		var b = document.createElement("div");
		Element.extend(b);
		b.style.position = "absolute";
		b.style.left = 0;
		b.style.top = 0;
		b.style.backgroundColor = "#000";
		var a = this.option("bckg_opacity");
		if (a) {
			b.setOpacity(a)
		}
		b.hide();
		document.body.appendChild(b);
		return b
	},
	position_and_size_background : function() {
		var e = document.documentElement.getDimensions();
		var b = document.documentElement.cumulativeOffset();
		var f = document.viewport.getDimensions();
		var d = document.viewport.getScrollOffsets();
		var c = Math.max(e.width + b.left, f.width + d.left);
		var a = Math.max(e.height + b.top, f.height + d.top);
		this.background.style.width = c + "px";
		this.background.style.height = a + "px";
		this.background.style.left = 0;
		this.background.style.top = 0
	},
	update : function(a) {
		this.holder.className = this.option("cls");
		this.holder.style.zIndex = this.option("z-index");
		this.background.style.zIndex = this.option("z-index") - 1;
		this.restore_content_element();
		if (typeof a == typeof "") {
			this.holder.update(a)
		} else {
			this.content_element = a;
			this.content_parent_element = a.parentNode;
			this.holder.update(null);
			this.holder.appendChild(a)
		}
		this.position_holder(true);
		if (this.option("modal")) {
			this.background.className = this.option("bckg_cls");
			this.position_and_size_background()
		}
	},
	show : function(d, b) {
		Overlay.instances.push(this);
		this.current_options = b;
		this.clear_hide_timer();
		$$("select").each(function(h) {
			h.setStyle( {
				visibility : "hidden"
			})
		});
		this.init();
		this.update(d);
		this.start_handling_window_events();
		$$("#" + this.holder.id + " select").each(function(h) {
			h.setStyle( {
				visibility : "visible"
			})
		});
		var a = this.option("beforeshow");
		if (a) {
			a(this)
		}
		if (this.option("animate")) {
			var g = this.option("animation_duration");
			var e = this.show_animation_options(false);
			if (this.holder_shown) {
				new Effect.Opacity(this.holder, e)
			} else {
				this.holder.appear(e)
			}
			if (this.option("modal")) {
				var f = this.show_animation_options(true);
				if (this.bckg_shown) {
					new Effect.Opacity(this.background, f)
				} else {
					this.background.appear(f)
				}
			} else {
				this.background.fade(this.hide_animation_options(true))
			}
			var c = this;
			setTimeout(function() {
				c.complete_show()
			}, g)
		} else {
			this.holder.show();
			this.option("modal") ? this.background.show() : this.background
					.hide();
			this.complete_show()
		}
		this.holder_shown = true;
		this.bckg_shown = Boolean(this.option("modal"))
	},
	complete_show : function() {
		var a = this.option("aftershow");
		if (a) {
			a(this)
		}
		this.set_hide_timer();
		this.start_handling_click_events()
	},
	hide : function() {
		if (this.hiding_in_progress) {
			return
		}
		this.hiding_in_progress = true;
		this.clear_hide_timer();
		this.stop_handling_click_events();
		if (this.option("animate")) {
			var b = this.option("animation_duration");
			this.holder.fade(this.hide_animation_options(false));
			if (this.option("modal")) {
				this.background.fade(this.hide_animation_options(true))
			}
			var a = this;
			setTimeout(function() {
				a.complete_hide()
			}, b)
		} else {
			this.holder.hide();
			this.background.hide();
			this.complete_hide()
		}
		this.holder_shown = false;
		this.bckg_shown = false
	},
	complete_hide : function() {
		Overlay.instances = Overlay.instances.without(this);
		this.stop_handling_window_events();
		if (Overlay.instances.length == 0) {
			$$("select").each(function(b) {
				b.setStyle( {
					visibility : "visible"
				})
			})
		} else {
			$$("#" + Overlay.instances.last().holder.id + " select").each(
					function(b) {
						b.setStyle( {
							visibility : "visible"
						})
					})
		}
		this.clear_hide_timer();
		this.restore_content_element();
		var a = this.option("afterhide");
		if (a) {
			a(this)
		}
		this.hiding_in_progress = false
	},
	start_handling_click_events : function() {
		if (!this.option("click_hide")) {
			this.stop_handling_click_events();
			return
		}
		if (!this.click_event_handler) {
			var a = this;
			this.click_event_handler = function() {
				a.hide()
			}
		}
		Event.observe(this.holder, "click", this.click_event_handler);
		Event.observe(this.background, "click", this.click_event_handler)
	},
	stop_handling_click_events : function() {
		Event.stopObserving(this.holder, "click", this.click_event_handler);
		Event.stopObserving(this.background, "click", this.click_event_handler)
	},
	start_handling_window_events : function() {
		var a = this;
		if (this.option("modal")) {
			this.window_events_handler = function() {
				a.position_holder();
				a.position_and_size_background()
			}
		} else {
			this.window_events_handler = function() {
				a.position_holder()
			}
		}
		Event.observe(window, "resize", this.window_events_handler);
		Event.observe(window, "scroll", this.window_events_handler)
	},
	stop_handling_window_events : function() {
		Event.stopObserving(window, "resize", this.window_events_handler);
		Event.stopObserving(window, "scroll", this.window_events_handler)
	},
	set_hide_timer : function() {
		var a = this.option("auto_hide");
		var c = this.option("duration");
		if (a && c) {
			var b = this;
			this.hide_timer = setTimeout(function() {
				b.hide()
			}, c)
		}
	},
	clear_hide_timer : function() {
		if (this.hide_timer) {
			clearTimeout(this.hide_timer);
			this.hide_timer = null
		}
	},
	option : function(a) {
		if (this.current_options && this.current_options[a] !== undefined) {
			return this.current_options[a]
		}
		if (Overlay.default_options[a] !== undefined) {
			return Overlay.default_options[a]
		}
		return null
	},
	show_animation_options : function(a) {
		return {
			duration : this.option("animation_duration") / 1000,
			to : this.option(a ? "bckg_opacity" : "opacity")
		}
	},
	hide_animation_options : function(a) {
		return {
			duration : this.option("animation_duration") / 1000,
			from : this.option(a ? "bckg_opacity" : "opacity")
		}
	},
	restore_content_element : function() {
		if (this.content_element && this.content_parent_element) {
			this.content_parent_element.appendChild(this.content_element)
		}
		this.content_element = null;
		this.content_parent_element = null
	}
});
Object.extend(Overlay, {
	instances : [],
	valid_options : [ "cls", "bckg_cls", "opacity", "bckg_opacity", "position",
			"z-index", "click_hide", "auto_hide", "auto_reposition",
			"duration", "modal", "animate", "animation_duration", "beforeshow",
			"aftershow", "afterhide" ],
	default_options : {
		"z-index" : 9999,
		position : "center",
		click_hide : true,
		auto_hide : true,
		auto_reposition : true,
		duration : 5000,
		animate : true,
		animation_duration : 500,
		opacity : 0.9,
		bckg_opacity : 0.6
	},
	defaults : function(a) {
		for (name in a) {
			Overlay.default_options[name] = a[name]
		}
	},
	hide : function(c) {
		for ( var a = 0, b = Overlay.instances.length; a < b; a++) {
			if (Element.descendantOf(c, Overlay.instances[a].holder)) {
				Overlay.instances[a].hide();
				break
			}
		}
	}
});
