/**
 * tools.overlay 1.0.4 - Overlay HTML with eye candy.
 *
 * 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
 * Date: 2009-06-12 11:02:45 +0000 (Fri, 12 Jun 2009)
 * Revision: 1911
 */
(function($) {

	// static constructs
	$.tools = $.tools || {version: {}};

	$.tools.version.overlay = '1.0.4';


	var instances = [];


	function Overlay(el, opts) {

		// private variables
		var self = this, w = $(window), closeButton, img, oWidth, oHeight, trigger, bg, exposeApi;
		var expose = opts.expose && $.tools.version.expose;

		// generic binding function
		function bind(name, fn) {
			$(self).bind(name, function(e, args)  {
				if (fn && fn.call(this) === false && args) {
					args.proceed = false;
				}
			});
			return self;
		}

		// bind all callbacks from configuration
		$.each(opts, function(name, fn) {
			if ($.isFunction(fn)) { bind(name, fn); }
		});


		// get trigger and overlayed element
		var jq = opts.target || el.attr("rel");
		var o = jq ? $(jq) : null;

		if (!o) { o = el; }
		else { trigger = el; }


		// external CSS properties are accessible only on window.onLoad (safari / chrome)
		w.load(function() {

			// get growing image
			bg = o.attr("overlay");

			// growing image is required (on this version)
			if (!bg) {
				bg = o.css("backgroundImage");

				if (!bg) {
					throw "background-image CSS property not set for overlay element: " + jq;
				}

				// url("bg.jpg") --> bg.jpg
				bg = bg.substring(bg.indexOf("(") + 1, bg.indexOf(")")).replace(/\"/g, "");
				o.css("backgroundImage", "none");
				o.attr("overlay", bg);
			}

			// set initial growing image properties
			oWidth = o.outerWidth({margin:true});
			oHeight = o.outerHeight({margin:true});

			// setup growing image
			img = $('<img class="overlimage" src="' + bg + '"/>');
			img.css({border:0,position:'absolute',display:'none'}).width(oWidth).attr("overlay", true);
			$('body').append(img);


			// if trigger is given - assign it's click event
			if (trigger) {
				trigger.bind("click.overlay", function(e) {
					self.load(e.pageY - w.scrollTop(), e.pageX - w.scrollLeft());
					return e.preventDefault();
				});
			}

			// close button
			opts.close = opts.close || ".close";

			if (!o.find(opts.close).length) {
				o.prepend('<div class="close"></div>');
			}

			closeButton = o.find(opts.close);

			closeButton.bind("click.overlay", function() {
				self.close();
			});

			// automatic preloading of the image
			if (opts.preload) {
				setTimeout(function() {
					var img = new Image();
					img.src = bg;
				}, 2000);
			}

		});


		// API methods
		$.extend(self, {

			load: function(top, left) {

				// lazy loading if things are not setup yet
				if (!img) {
					w.load(function()  {
						self.load(top, left);
					});
					return self;
				}

				// one instance visible at once
				if (self.isOpened()) {
					return self;
				}

				if (opts.oneInstance) {
					$.each(instances, function() {
						this.close();
					});
				}

				// onBeforeLoad
				var p = {proceed: true};
				$(self).trigger("onBeforeLoad", p);
				if (!p.proceed) { return self; }

				// exposing effect
				if (expose) {
					img.expose(opts.expose);
					exposeApi = img.expose().load();
				}

				// start position
				top = top   || opts.start.top;
				left = left || opts.start.left;

				// finish position
				var toTop = opts.finish.top;
				var toLeft = opts.finish.left;

				if (toTop == 'center') { toTop = Math.max((w.height() - oHeight) / 2, 0); }
				if (toLeft == 'center') { toLeft = Math.max((w.width() - oWidth) / 2, 0); }

				if (toLeft == 'left') toLeft =left;
				if (toLeft == 'right') toLeft =left-500;

				// adjust positioning relative to scrolling position
				if (!opts.start.absolute)  {
					top += w.scrollTop();
					left += w.scrollLeft();
				}

				if (!opts.finish.absolute)  {
					toTop += w.scrollTop();
					toLeft += w.scrollLeft();
				}

				// initialize background image
				img.css({top:top, left:left, width: opts.start.width, zIndex: opts.zIndex}).show();


				// begin growing
				img.animate({top:toTop, left:toLeft, width: oWidth}, opts.speed, function() {

					// set content on top of the image
					o.css({position:'absolute', top:toTop, left:toLeft});


					var z = img.css("zIndex");
					closeButton.add(o).css("zIndex", ++z);

					o.fadeIn(opts.fadeInSpeed, function() {
						$(self).trigger("onLoad");
					});

				});

				return self;
			},

			close: function() {

				if (!self.isOpened()) { return self; }

				var p = {proceed: true};
				$(self).trigger("onBeforeClose", p);
				if (!p.proceed) { return self; }

				// close exposing effect
				if (exposeApi) { exposeApi.close(); }

				if (img.is(":visible")) {

					// hide overlayed content
					o.hide();

					// calculate triggers position
					var top = opts.start.top;
					var left = opts.start.left;

					if (trigger) {
						p = trigger.offset();
						top = p.top + trigger.height() / 2;
						left = p.left + trigger.width() / 2;
					}

					// shrink image
					img.animate({top: top, left: left, width:0 }, opts.closeSpeed, function()  {
						$(self).trigger("onClose", p);
					});
				}

				return self;
			},


			getBackgroundImage: function() {
				return img;
			},

			getContent: function() {
				return o;
			},

			getTrigger: function() {
				return trigger;
			},

			isOpened: function()  {
				return o.is(":visible")	;
			},

			// manipulate start, finish and speeds
			getConf: function() {
				return opts;
			},

			// callback functions
			onBeforeLoad: function(fn) {
				return bind("onBeforeLoad", fn);
			},

			onLoad: function(fn) {
				return bind("onLoad", fn);
			},

			onBeforeClose: function(fn) {
				return bind("onBeforeClose", fn);
			},

			onClose: function(fn) {
				return bind("onClose", fn);
			}

		});


		// keyboard::escape
		$(document).keydown(function(evt) {
			if (evt.keyCode == 27) {
				self.close();
			}
		});


		// when window is clicked outside overlay, we close
		if (opts.closeOnClick) {
			$(document).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 plugin initialization
	$.fn.overlay = function(conf) {

		// already constructed --> return API
		var el = this.eq(typeof conf == 'number' ? conf : 0).data("overlay");
		if (el) { return el; }

		var w = $(window);

		var opts = {

			/*
			 - onBeforeLoad
			 - onLoad
			 - onBeforeClose
			 - onClose
			*/

			start: {
				// by default: button position || window center
				top: Math.round(w.height() / 2),
				left: Math.round(w.width() / 2),
				width: 0,
				absolute: false
			},

			finish: {
				top: 80,
				left: 'center',
				absolute: false
			},

			speed: 'normal',
			fadeInSpeed: 'fast',
			closeSpeed: 'fast',

			close: null,
			oneInstance: true,
			closeOnClick: true,
			preload: true,
			zIndex: 9999,
			api: false,
			expose: null,

			// target element to be overlayed. by default taken from [rel]
			target: null
		};

		if ($.isFunction(conf)) {
			conf = {onBeforeLoad: conf};
		}

		$.extend(true, opts, conf);


		this.each(function() {
			el = new Overlay($(this), opts);
			instances.push(el);
			$(this).data("overlay", el);
		});

		return opts.api ? el: this;
	};

})(jQuery);
(function($) {

	// static constructs
	$.tools = $.tools || {version: {}};

	$.tools.version.expose = '1.0.3';

	function getWidth() {

		var w = $(window).width();

		if ($.browser.mozilla) { return w; }

		var x;

		if (window.innerHeight && window.scrollMaxY) {
			x = window.innerWidth + window.scrollMaxX;

		// all but Explorer Mac
		} else if (document.body.scrollHeight > document.body.offsetHeight) {
			x = document.body.scrollWidth;

		} else {
			x = document.body.offsetWidth;
		}

		return x < w ? x + 20 : w;
	}

	function Expose(els, opts) {

		// private variables
		var self = this, mask = null, loaded = false, origIndex = 0;

		// generic binding function
		function bind(name, fn) {
			$(self).bind(name, function(e, args) {
				if (fn && fn.call(this) === false && args) {
					args.proceed = false;
				}
			});
			return self;
		}

		// bind all callbacks from configuration
		$.each(opts, function(name, fn) {
			if ($.isFunction(fn)) { bind(name, fn); }
		});


		// adjust mask size when window is resized (or firebug is toggled)
		$(window).bind("resize.expose", function() {
			if (mask) {
				mask.css({ width: getWidth(), height: $(document).height()});
			}
		});


		// public methods
		$.extend(this, {

			getMask: function() {
				return mask;
			},

			getExposed: function() {
				return els;
			},

			getConf: function() {
				return opts;
			},

			isLoaded: function() {
				return loaded;
			},

			load: function() {

				// already loaded ?
				if (loaded) { return self;	}

				origIndex = els.eq(0).css("zIndex");

				// find existing mask
				if (opts.maskId) { mask = $("#" + opts.maskId);	}

				if (!mask || !mask.length) {

					mask = $('<div/>').css({
						position:'absolute',
						top:0,
						left:0,
						width: getWidth(),
						height: $(document).height(),
						display:'none',
						opacity: 0,
						zIndex:opts.zIndex
					});

					// id
					if (opts.maskId) { mask.attr("id", opts.maskId); }

					$("body").append(mask);


					// background color
					var bg = mask.css("backgroundColor");

					if (!bg || bg == 'transparent' || bg == 'rgba(0, 0, 0, 0)') {
						mask.css("backgroundColor", opts.color);
					}

					// esc button
					if (opts.closeOnEsc) {
						$(document).bind("keydown.unexpose", function(evt) {
							if (evt.keyCode == 27) {
								self.close();
							}
						});
					}

					// mask click closes
					if (opts.closeOnClick) {
						mask.bind("click.unexpose", function()  {
							self.close();
						});
					}
				}

				// possibility to cancel click action
				var p = {proceed: true};
				$(self).trigger("onBeforeLoad", p);
				if (!p.proceed) { return self; }


				// make sure element is positioned absolutely or relatively
				$.each(els, function() {
					var el = $(this);
					if (!/relative|absolute|fixed/i.test(el.css("position"))) {
						el.css("position", "relative");
					}
				});

				// make elements sit on top of the mask
				els.css({zIndex:opts.zIndex + 1});


				// reveal mask
				var h = mask.height();

				if (!this.isLoaded()) {
					mask.css({opacity: 0, display: 'block'}).fadeTo(opts.loadSpeed, opts.opacity, function() {

						// sometimes IE6 misses the height property on fadeTo method
						if (mask.height() != h) { mask.css("height", h); }
						$(self).trigger("onLoad");
					});
				}

				loaded = true;
				return self;
			},


			close: function() {

				if (!loaded) { return self; }

				var p = {proceed: true};
				$(self).trigger("onBeforeClose", p);
				if (p.proceed === false) { return self; }

				mask.fadeOut(opts.closeSpeed, function() {
					$(self).trigger("onClose");
					els.css({zIndex: $.browser.msie ? origIndex : null});
				});

				loaded = false;
				return self;
			},


			onBeforeLoad: function(fn) {
				return bind("onBeforeLoad", fn);
			},

			onLoad: function(fn) {
				return bind("onLoad", fn);
			},

			onBeforeClose: function(fn) {
				return bind("onBeforeClose", fn);
			},

			onClose: function(fn) {
				return bind("onClose", fn);
			}

		});

	}


	// jQuery plugin implementation
	$.fn.expose = function(conf) {

		var el = this.eq(typeof conf == 'number' ? conf : 0).data("expose");
		if (el) { return el; }

		var opts = {
			/*
			 - onBeforeLoad
			 - onLoad
			 - onBeforeClose
			 - onClose
			*/

			// mask settings
			maskId: null,
			loadSpeed: 'slow',
			closeSpeed: 'fast',
			closeOnClick: true,
			closeOnEsc: true,

			// css settings
			zIndex: 9998,
			opacity: 0.8,
			color: '#456',
			api: false
		};

		if (typeof conf == 'string') {
			conf = {color: conf};
		}

		$.extend(opts, conf);

		// construct exposes
		this.each(function() {
			el = new Expose($(this), opts);
			$(this).data("expose", el);
		});

		return opts.api ? el: this;
	};


})(jQuery);
