/* ===============================
| JQUERY.LIGHTBOXLIB.JS
| Copyright, Andy Croxall (mitya@mitya.co.uk)
| For documentation and demo see http://www.mitya.co.uk/scripts/Lightbox-and-lightbox-dialog-99
|
| USAGE
| This script may be used, distributed and modified freely but this header must remain in tact.
| For usage info and demo, including info on args and params, see www.mitya.co.uk/scripts
=============================== */


/* -------------------
 | CONFIG
 ------------------- */
var lightboxConfig = {
	lbOpacity:	.6,
	lbBackground: '444',
	lbdialog_defaultHeight: 105, //default height of lightbox replcement dialog box (i.e. alert/confirm)
	lbdialog_allowCloseByClickingLightbox: false, //see notes at top
	lbdialog_css: {
		borderRadius: 10,
		width: 300,
		boxShadow: '0 0 32px #26a1ce',
		background: '#CDC5BF'
	}
};


/* -------------------
 | PREP. Log whether IE6 and declare func used by lbdialog to allow closure via escsape key (need to declare as non-anonymouse
 | func so it can be unbound when lbdialog closes
 ------------------- */

var ie6 = navigator.appVersion.match(/MSIE 6\.0/);
var closeLBDialogOnEscapePress = function(e) { if (e.keyCode == 27) hidelightbox(); };


/*$(function() {*/
jQuery(document).ready(function($){

	/* -------------------
	| MAIN LIGHTBOX FUNC
	------------------- */

	jQuery.fn.lightbox = function(noFade, autoDisappear, noLightbox, noClose) {


			//prep

			var ac = arguments.callee;
			$(this).addClass('lightbox_centralElement');
			var centralElement = this.get(0);
			$(centralElement).children().hide();
			if (noLightbox) $('#lightbox').css({opacity: 0, filter: 'alpha(opacity=0)'})
		if (noClose) $('#lightbox').addClass('noClose');


			//utility functions

			ac.doHide = function(noFade, callback) { //called on hide request
					if (!noFade) {
							var numChildren;
						if ((numChildren = $(ac.centralElement).children().length) > 0) {
									var childrenFaded = 0;
							$(ac.centralElement).children().fadeOut('', function() {
											childrenFaded++;
											if (childrenFaded == numChildren) $(ac.centralElement).slideUp('fast', function() {
												reinsertCentralElement();
												$('#lightbox').fadeOut('fast', callback ? callback() : null);
											});
									});
							} else
					$(ac.centralElement).slideUp('fast', function() { $('#lightbox').fadeOut('fast', callback ? callback() : null); reinsertCentralElement(); });
					} else {
							$(ac.centralElement).hide();
							$('#lightbox').hide();
							if (callback) callback();
							reinsertCentralElement();
					}

		};


			//request to show

			if (centralElement.id != 'lightbox') {


					//force central element to be child of body (lift it out of the DOM and re-insert). This ensures centering relative to body. After, put back where it was.

			var node_holder = $(centralElement).clone(true);
			var markerNodeForReinsertion = document.createElement('em');
			$(centralElement).before($(markerNodeForReinsertion));
			markerNodeForReinsertion.id = 'markerNodeForReinsertion';
			$(centralElement).remove();
			centralElement = document.body.insertBefore(node_holder.get(0), document.body.childNodes[0]);


			//assuming noClose not passed, close lighbox if any <button> or element with .close inside central element is clicked
			if (!noClose) $(centralElement).find('button, .close').not('.noLBClose, [rel=noLBClose]').click(function(e) { $('#lightbox').lightbox(); });


					//force position absolute and z-index 10001 if not set

					if ($(centralElement).css('position') != 'absolute') $(centralElement).css('position', 'absolute');
					if ($(centralElement).css('zIndex') != 10001) $(centralElement).css('zIndex', 10001);


					//remember the central element so we can kill it on hide request
					ac.centralElement = centralElement


					//centre it and ensure that, if user scrolls while LB open, central element moves with it
					$(centralElement).centreElement();
			$(window).scroll(function() { $(centralElement).centreElement(); });

			}


		//toggle show/hide lightbox

			if ($('#lightbox').is(":hidden")) { //hidden - so show pos as necessary)

			var callback = function() { $(centralElement).slideDown('fast', function() { $(centralElement).children(':not(:visible)').fadeIn(); }); };
			if (!noFade) $('#lightbox').fadeIn('fast', callback); else { $('#lightbox').show(); callback(); }
			if (autoDisappear) setTimeout(hidelightbox, autoDisappear * 1000)

			} else //showing - so hide
					ac.doHide();

	}



	/* -------------------
	| UTILITY: centre central element
	------------------- */

	jQuery.fn.centreElement = function(horiz, vert, justReturnValues) {

			//prep
			if (horiz == undefined) horiz = true;
			if (vert == undefined) vert = true;
			var scrollX = (document.documentElement.scrollLeft || document.body.scrollLeft || 0) || window.pageXOffset;
			var scrollY = (document.documentElement.scrollTop || document.body.scrollTop || 0) || window.pageYOffset;
			if (scrollX == undefined) scrollX = 0;
			if (scrollY == undefined) scrollY = 0;
			var el = this.get(0);

			//calculate
			var temp_elWidth = parseInt(el.currentStyle ? el.currentStyle.width : getComputedStyle(el, null).width);
			if (isNaN(temp_elWidth)) { $(el).css('width', '300px'); temp_elWidth = 300; } //force default width if none set
			var left = (self.innerWidth || (document.documentElement.clientWidth || document.body.clientWidth)) / 2 - (temp_elWidth / 2) + scrollX;

			var temp_elHeight = parseInt(el.currentStyle ? el.currentStyle.height : getComputedStyle(el, null).height);
			if (isNaN(temp_elHeight)) { $(el).css('height', '500px'); temp_elHeight = 500; } // " " "
			var top = (self.innerHeight || (document.documentElement.clientHeight || document.body.clientHeight)) / 2 - (temp_elHeight / 2) + scrollY;

			//account for padding
			top -= parseInt(el.currentStyle ? el.currentStyle.paddingTop : getComputedStyle(el, null).paddingTop);
			left -= parseInt(el.currentStyle ? el.currentStyle.paddingLeft : getComputedStyle(el, null).paddingLeft);

			//return/effect
			if (!justReturnValues) {
					if (horiz) el.style.left = left+"px";
					if (vert) el.style.top = top+"px";
			} else {
					if ((!horiz || horiz) && (!vert || vert))
							return [left, top];
					else if (!horiz || horiz)
							return left;
					else if (!vert || vert)
							return vert;
			}

	}


	/* -------------------
	| BUILD LIGHTBOX ONLOAD
	------------------- */

		//build
		var lightboxDiv = document.createElement('div');
		lightboxDiv.id = 'lightbox';
		$(lightboxDiv).click(function() {
			if (
			!$(this).hasClass('noClose')
			&&
			(
				jQuery.fn.lightbox.centralElement.id != 'lightboxdialog'
				||
				lightboxConfig.lbdialog_allowCloseByClickingLightbox
			)
			)
				$(this).lightbox();
		});
		$(document.body).prepend(lightboxDiv);

		//style it (doing it here means the script is portable, don't need to tell users to add rules to their CSS sheets)
		$('#lightbox').css({
			opacity: lightboxConfig.lbOpacity,
			filter: 'alpha(opacity='+(lightboxConfig.lbOpacity * 100)+')',
			width: $(document).width(),
			height: $(document).height(),
			background: '#'+lightboxConfig.lbBackground,
			position: 'fixed',
			left: 0,
			top: 0,
			zIndex: 10000,
			display: 'none'
		});

});



/* -------------------
| UTILITY FUNC: supporting func - on lightbox close, reinsert central element into DOM at its original position
------------------- */

reinsertCentralElement = function() {
		var ce = jQuery.fn.lightbox.centralElement;
		try {
				markerNodeForReinsertion = $('#markerNodeForReinsertion').get(0);
				if (markerNodeForReinsertion.parentNode.tagName.toLowerCase() != "body") {
						var ceHolder = ce;
						ce.parentNode.removeChild(ce);
						markerNodeForReinsertion.parentNode.insertBefore(ceHolder, markerNodeForReinsertion);
						markerNodeForReinsertion.parentNode.removeChild(markerNodeForReinsertion);
				}
		} catch(e) {}
}



/* -------------------
| UTILITY FUNC: lightbox-utilising replacement for in-built alert/confirm methods. See usage notes at top of page.
------------------- */

lbdialog = function(params) {


		//checktype passed args before continuing

		if (
				typeof params.content != 'string'
				||
						(params.okButton &&
								(typeof params.okButton.callback != 'function' && params.okButton.callback)
						)
				||
						(params.cancelButton &&
								(typeof params.cancelButton.callback != 'function' && params.cancelButton.callback)
						)
				)
				return false;


		//clean up from any previous alert

		if (jQuery('#lightboxdialog').length != 0) jQuery('#lightboxdialog').remove();


		//create, style (with necessary CSS, params-passed CSS and config CSS at top of file) and append dialog box

		var box = document.createElement('div');
		with (jQuery(box)) {
			attr('id', 'lightboxdialog');
			css({background: '#fff', position: 'absolute', padding: 15, width: 320, height: lightboxConfig.lbdialog_defaultHeight, display: 'none', textAlign: 'left'});
			if (typeof params.css == 'object') jQuery(box).css(params.css);
			if (lightboxConfig.lbdialog_css) css(lightboxConfig.lbdialog_css);
		}
		jQuery('body').prepend(box);


		//add content

		var fs = lightboxConfig.lbdialog_css.fontSize+'';
		if (!fs.match(/^\d$/)) fs += 'px';
		var header;
		if (params.error) header = ['ERROR', 'b00'];
	else if (params.success) header = ['SUCCESS', '0b0'];
	var header = header == undefined ? '' : "<h4 style='margin: 0 0 10px 0; color: #"+header[1]+"'>"+header[0]+"</h4>";
		jQuery(box).html(header+'<p'+(fs ? " style='margin-bottom: 10px; font-size: "+fs+"'" : '')+'>'+params.content+"</p<div style='clear: both'></div>");


		//add buttons, unless params stipulate the dialog should close itself after X seconds. right button will always be put out,
		//whereas left button is only put out if params.cancelButton object is passed, i.e. is confirm, not alert. onclick, along
		//with effecting any callbacks passed, they will also close the lightbox unless  you pass 'noLBClose' in their object

		if (!params.autoDisappear) {
			var buttons = ['OK', 'cancel'];
			for(var e in buttons) {
					if (buttons[e] == 'OK' || params.cancelButton) {
							var but = document.createElement('button');
							but.setAttribute("class", "button" + e);
							jQuery(but).css({'float': buttons[e] == 'OK' ? 'right' : 'left'});
							if (params[buttons[e]+'Button']) {
									if (params[buttons[e]+'Button'].noLBClose) jQuery(but).addClass('noLBClose');
									var butText = params[buttons[e]+'Button'].text ? params[buttons[e]+'Button'].text : buttons[e];
									if (params[buttons[e]+'Button'].callback) jQuery(but).click(params[buttons[e]+'Button'].callback);
							} else
									var butText = buttons[e];
							jQuery(but).text(butText);
							box.appendChild(but);
					}
			}
		}


		//centre and show
		jQuery(box).lightbox(true, params.autoDisappear ? params.autoDisappear : null, params.noLightbox ? true : null);

		//lastly, close on keypress to <escape>
		jQuery(document).bind('keypress', closeLBDialogOnEscapePress);

};


/* -------------------
| UTILITY FUNC: close lightbox and remove keypress bind to escape key
------------------- */

hidelightbox = function(noFade, callback) {
	jQuery.fn.lightbox.doHide(noFade, callback);
	jQuery(document).unbind('keypress', closeLBDialogOnEscapePress);
};
