/*!
 * jquery.overlay 1.0.1. Overlay HTML with eyecandy.
 * 
 * Copyright (c) 2009 Tero Piirainen
 * http://flowplayer.org/tools/overlay.html
 *
 * Dual licensed under MIT and GPL 2+ licenses
 * http://www.opensource.org/licenses
 *
 * Launch  : March 2008
 * Version : 1.0.1 - Wed Feb 18 2009 05:18:24 GMT-0000 (GMT+00:00)
 */
( function($) {
	var instances = [];
	function fireEvent(opts, name, self, arg) {
		var fn = opts[name];
		if ($.isFunction(fn)) {
			try {
				return fn.call(self, arg);
			} catch (error) {
				if (opts.alert) {
					alert("Error calling overlay." + name + ": " + error);
				} else {
					throw error;
				}
				return false;
			}
		}
		return true;
	}
	function Overlay(el, opts) {
		var self = this;
		var trigger = null;
		var w = $(window);
		var jq = opts.target || el.attr("rel");
		var o = jq ? $(jq) : null;
		if (!o) {
			o = el;
		} else {
			trigger = el;
		}
		var bg = o.attr("overlay");
		if (!bg) {
			bg = o.css("backgroundImage");
			bg = bg.substring(bg.indexOf("(") + 1, bg.indexOf(")"));
			o.css("backgroundImage", "none");
			o.attr("overlay", bg);
		}
		if (!bg) {
			throw "background-image CSS property not set for overlay element: "
					+ jq;
		}
		bg = bg.replace(/\"/g, "");
		if (opts.preload) {
			$(window).load( function() {
				setTimeout( function() {
					var img = new Image();
					img.src = bg;
				}, 2000);
			});
		}
		var oWidth = o.outerWidth( {
			margin :true
		});
		var oHeight = o.outerHeight( {
			margin :true
		});
		var img = $('<img id="imgdiv" src="' + bg + '"/>');
		img.css( {
			border :0,
			position :'absolute'
		}).width(oWidth).hide();
		$('div.overlay').append(img);
		if (trigger) {
			trigger.bind("click.overlay", function(e) {
				self.load(e.pageY - w.scrollTop(), e.pageX - w.scrollLeft());
				return e.preventDefault();
			});
		}
		if (!opts.close || !o.find(opts.close).length) {
			o.prepend('<div class="close"></div>');
			opts.close = "div.close";
		}
		var closeButton = o.find(opts.close);
		$.extend(self, {
			load : function(top, left) {
				if (self.isOpened()) {
					return self;
				}
				if (opts.oneInstance) {
					$.each(instances, function() {
						this.close();
					});
				}
				if (fireEvent(opts, "onBeforeLoad", self) === false) {
					return self;
				}
				top = top || opts.start.top;
				left = left || opts.start.left;
				var toTop = opts.finish.top;
				var toLeft = opts.finish.left;
				if (toTop == 'center') {
					toTop = Math.max((w.height() - oHeight) / 2 - 30, 0);
				}
				if (toLeft == 'center') {
					toLeft = Math.max((w.width() - oWidth) / 2, 0);
				}
				if (!opts.start.absolute) {
					top += w.scrollTop();
					left += w.scrollLeft();
				}
				if (!opts.finish.absolute) {
					toTop += w.scrollTop();
					toLeft += w.scrollLeft();
				}
				img.css( {
					top :top,
					left :left,
					width :opts.start.width,
					zIndex :opts.zIndex
				}).show();
				img.animate( {
					top :toTop,
					left :toLeft,
					width :oWidth
				}, opts.speed, function() {
					o.css( {
						position :'absolute',
						top :toTop,
						left :toLeft
					});
					var z = img.css("zIndex");
					closeButton.add(o).css("zIndex", ++z);
					o.fadeIn(opts.fadeInSpeed, function() {
						fireEvent(opts, "onLoad", self);
					});
				});
				return self;
			},
			getBackgroundImage : function() {
				return img;
			},
			getContent : function() {
				return o;
			},
			getTrigger : function() {
				return trigger;
			},
			isOpened : function() {
				return o.is(":visible");
			},
			getConf : function() {
				return opts;
			},
			close : function() {
				if (!self.isOpened()) {
					return self;
				}
				if (fireEvent(opts, "onClose", self) === false) {
					return self;
				}
				if (img.is(":visible")) {
					img.hide();
					o.hide();
				}
				return self;
			},
			getVersion : function() {
				return [ 1, 0, 0 ];
			},
			expose : function() {
				img.expose();
			}
		});
		closeButton.bind("click.overlay", function() {
			self.close();
		});
		w.bind("keypress.overlay", function(evt) {
			if (evt.keyCode == 27) {
				self.close();
			}
		});
		if (opts.closeOnClick) {
			w.bind("click.overlay", function(evt) {
				if (!o.is(":visible, :animated")) {
					return;
				}
				var target = $(evt.target);
				if (target.attr("overlay")) {
					return;
				}
				if (target.parents("[overlay]").length) {
					return;
				}
				self.close();
			});
		}
	}
	jQuery.prototype.overlay = function(conf) {
		var api = this.eq(typeof conf == 'number' ? conf : 0).data("overlay");
		if (api) {
			return api;
		}
		var w = $(window);
		var opts = {
			start : {
				top :Math.round(w.height() / 2),
				left :Math.round(w.width() / 2),
				width :0,
				absolute :false
			},
			finish : {
				top :'center',
				left :'center',
				absolute :false
			},
			speed :'normal',
			fadeInSpeed :'fast',
			close :null,
			oneInstance :true,
			closeOnClick :true,
			preload :true,
			zIndex :9999,
			target :null,
			alert :true
		};
		if ($.isFunction(conf)) {
			conf = {
				onBeforeLoad :conf
			};
		}
		$.extend(true, opts, conf);
		this.each( function() {
			var instance = new Overlay($(this), opts);
			instances.push(instance);
			$(this).data("overlay", instance);
		});
		return this;
	};
})(jQuery);