/* jquery.multibox.js
 * lightbox plugin that will handle multiple images of multiple sizes or a div
 * Usage:	single photo, one size, thumb shows on page, larger photo in multibox ---- DONE ----
 *				<a href="large.jpg" rel="multibox"><img src="thumb.jpg" /></a>
 *				$('a[rel*="multibox"]').multibox(); (on ready) 
 * 			single photo, multiple sizes, thumb shows on page, medium photo in multibox, large photo in multibox on click
 *				<a href="photo.jpg" rel="multibox"><img src="photo_thumb.jpg" /></a> 
 *				$('a[rel*="multibox"]').multibox({medSuffix: '_med'});
 *			single photo, multiple sizes, thumb shows on page, medium photo in multibox, magnifier shows large photo
 *				<a href="photo.jpg" rel="multibox"><img src="photo_thumb.jpg" /></a>
 *				$('a[rel*="multibox"]').multibox({medSuffix: '_med', magnifier: true});
 *			multiple photos, one size each, thumbs show on page, clicked-on photo in multibox + thumbs of other photos
 *				<div class="images multibox"><a href="photo1"><img src="photo1_thumb" /></a><a href="photo2"><img src="photo2_thumb" /></a>...</div>
 *				$('div.multibox').multibox();
 *			multiple photos, multiple sizes each as above
 *				<div class="images multibox"><a href="photo1"><img src="photo1_thumb" /></a><a href="photo2"><img src="photo2_thumb" /></a>...</div
 *				$('div.multibox).multibox({medSuffix: '_med'});
 *			multiple photos, multiple sizes with magnifier
 *				<div class="images multibox"><a href="photo1"><img src="photo1_thumb" /></a><a href="photo2"><img src="photo2_thumb" /></a>...</div 
 *				$('div.multibox).multibox({medSuffix: '_med', magnifier: true});
 *			show a div
 *				<a href="#" rel="multibox>Show div</a><div id="divToShow">Some html</div>
 *				$('a[rel="multibox"]').multibox('divToShow');
 *			pass html programmatically
 *				 var html = '<div>Some html</div>';
 *				 $.multibox(html); 
 *				 
 * SETTINGS:	overlay settings: 		overlay: boolean (default = true)  
 *										opacity: decimal value (default = .5)
 *										  
 *				multiple size images:	multiSize: boolean (default = false)
 *										thumbSuffix: string (default = '_thumb')
 *										mediumSuffix: string (default = '_med)
 *				   										
 *				magnifier settings:		magnify: boolean (default = false)
 *				(requires above)		magWidth: integer (default = 200)
 *										magHeight: integer (default = 200)  
 *										
 *										
 *				multiple images:		multiImage: boolean (default = false) 
 *				
 *				position settings:		top: integer (default = 0)
 *				
 *				callback settings:		beforeShow: string
 *										afterShow: string
 *										onClose: string      
 *										   
 *				        
 */

 				 
;(function($) {
$.fn.multibox = function(options) {

	/******************************* PRIVATE PROPERTIES **********************************/
	
	var imgobj = { // image and properties for each image
		width:		0,
		height:		0,
		thumbsrc:	'',
		medsrc:		'',
		lgsrc:		'',
		src:		''
	};
	var imgs = []; // imgobj holder		
	var info = {}; // document, window and calling object positions
	var sibs = []; // holder for non-clicked on images 
	
	var multiboxHtml = ''; // the html for multibox and overlay
	
	var divToShow;
	var href;	
	
	/******************************* PRIVATE METHODS **********************************/
	
	// the main controller, everything starts here
	function doMultibox() {
		// get info about window and document sizes
		getDocumentInfo();

		// write the html and append it to the body
		writeHtml();
		
		// append it
		$('body').append(multiboxHtml);	
		
		// image(s) or div?
		if (!options.div) {	// showing image(s)
			// get href of the clicked image
			href = $(this).attr('href');
			if (options.multiSize) {
				imgobj.medsrc = makeMediumSrc(href);
				imgobj.thumbsrc = makeThumbSrc(href);
				multiboxImage(imgobj.medsrc);
			} else {
				multiboxImage(href);
			}
		} else {
			multiboxDiv();
		}
		
		// stop default click action
		return false;
	}
		
	// write the html for the multibox using options
	function writeHtml() {
		multiboxHtml = '';
		// write it
		if (options.overlay) multiboxHtml += '<div id="multiboxoverlay"></div>';
		if (options.magnifier && !options.div) multiboxHtml += '<div id="magnifier"></div>';
		multiboxHtml += '<div id="multibox">';
		multiboxHtml += '<table><tbody>';
		multiboxHtml += '<tr><td class="tl"/><td class="bh"/><td class="tr"/></tr>';
		multiboxHtml += '<tr>';
		multiboxHtml += '<td class="bv"/>';
		multiboxHtml += '<td class="body">';
		multiboxHtml += '<div class="header">';
		multiboxHtml += '<a href="#" id="closeMultibox" title="Close the multibox">Close</a>';
		if (options.magnifier && !options.div) multiboxHtml += '<a href="#" id="magnify"></a>';
		multiboxHtml += '<span class="loading">&nbsp;</span>';
		multiboxHtml += '</div>';
		if (options.div) {
			multiboxHtml += '<div class="maincontent"></div>';
		} else {
			multiboxHtml += '<div class="mainimage"></div>';
		}
		if (options.multiImage && !options.div) multiboxHtml += '<div class="thumbs"></div>';
		multiboxHtml += '<div class="footer"></div>';
		multiboxHtml += '</td>';
		multiboxHtml += '<td class="bv"/>';
		multiboxHtml += '</tr>';
		multiboxHtml += '<tr><td class="bl"/><td class="bh"/><td class="br"/></tr>';
		multiboxHtml += '</tbody></table>';
		multiboxHtml += '</div>';
	}
	
	// show image(s)
	function multiboxImage(href) {
		imgobj.content = new Image();
		imgobj.content.src = href;
		getImageSize(loadMultibox);
		return false;	
	}

	// load the images
	function loadMultibox() {
		// size the .mainimage div
		$('#multibox .mainimage').css({
			width:		imgs[0].width,
			height:		imgs[0].height				
		});
		
		if (options.multiImage) {
			
		} else {
			showTheBox();
		}
		
		// size the additional images
		/* if (sibs.length > 0) {
			var addlWidth = Math.floor(imgs[0].width/(sibs.length+1)) - 13;
			//var addlWidth = Math.floor(500/(sibs.length+1)) - 13;
			$('#multibox .thumbs img').css({
				'width':	addlWidth	
			});
			// bind the change-image function to the thumbs
			changeThumb();	
		} */
		
		
	}
	
	// finally show
	function showTheBox() {
		// size the overlay
		var topPosition = info.st + options.top + 100;
		var multiboxHeight = imgs[0].height + 105; // + max height of thumbs
		var overlayHeight;
		if (info.dh > (topPosition + multiboxHeight)) {
			overlayHeight = info.dh;	
		} else {
			overlayHeight = topPosition + multiboxHeight +100;
		}
		
	 	
		// animate the transparent layer if default not changed
		if (options.overlay) {
			$('#multiboxoverlay')
				.css({'height': overlayHeight})
				.animate({opacity: options.opacity}, 400, 'linear');
		}

		
		// add the (main) image and show the multibox
		$('#multibox .mainimage').html('<img alt="" src="' + imgs[0].content.src + '" />');
		$('#multibox')
			.css({
				top:			info.st + options.top + 100,
				'left':			'50%',				
				'margin-top':	'-100px',
				'margin-left':	-((imgs[0].width+40)/2)
				
			})
			.animate({opacity: 1}, 400, 'linear');
		
		// bind the magnifier if needed
		if (options.magnifier) {
			bindMagnifier();
		}	
				
		// bind the close function
		removeMultibox();
		// bind the full-size image popup
//			showLargeImage();			
	}

	// show div
	function multiboxDiv() {			
		// add the div to show to the multibox and set it to visible (save for later)
		if (!divToShow) divToShow = $(div).clone(true).css({display: 'block'});
		
		$('#multibox .maincontent').append(divToShow);
		// get its width
		var contentWidth = $(div).width();
		// and show it
		$('#multibox').css({
			top:			info.st + settings.top,
			left:			'50%',
			marginLeft:		-((contentWidth+40)/2) //to position it in the middle
		}).animate({opacity: 1}, 400, 'linear');
		
		// bind the close function
		removeMultibox();
		return false;						
	}		
	
	// get all the thumbs
	function getThumbs() {
		/* // try to get the rest of the photos
		sibs = $('#maincontent a[href*=' + imgs[0].lgsrc + ']').siblings('a');
		if (sibs.length > 0) {
			// add a smaller copy of main photo, now imgs[0]
			$('#guitarbox .thumbs').append('<a href="' + imgs[0].lgsrc + '"><img class="img_current" src="'+imgs[0].medsrc+'" alt="" /></a>');				
			for (var i=0; i<sibs.length; i++) {
				// empty and refill the imgobj
				imgobj = {};
				imgobj.lgsrc = $(sibs[i]).attr('href');
				imgobj.thumbsrc = makeThumbSrc(imgobj.lgsrc);
				imgobj.medsrc = makeMediumSrc(imgobj.lgsrc);
				if (i !== sibs.length-1) {
					$('#guitarbox .thumbs').append('<a href="' + imgobj.lgsrc + '"><img src="'+imgobj.thumbsrc+'" alt="" /></a>');
				} else {
					$('#guitarbox .thumbs').append('<a href="' + imgobj.lgsrc + '"><img class="img_last" src="'+imgobj.thumbsrc+'" alt="" /></a>');
				}
				
				// preload the medium-size images in order to get their sizes when needed
				imgobj.content = new Image();
				imgobj.content.src = imgobj.medsrc;
				imgs.push(imgobj);															
			}
			loadGuitarbox();	
		} else {
			loadGuitarbox();
		}
		return false; */
	}
	
	// get the various sizes
	function getSizes() {
		
	}	
	function changeThumb() {
		$('#multibox .thumbs a').click(function(){
			// swap classes
			$('#gmultibox .thumbs img').removeClass('img_current');
			$(this).children('img').addClass('img_current');				
			// get the src and use it for the main image
			var href = $(this).attr('href');
			var newsrc = href.slice(0, href.lastIndexOf('.')-3) + options.mediumSuffix + href.slice(href.lastIndexOf('.'));
			$('#multibox .mainimage').html('<a href="' + href + '"><img src="' + newsrc + '"" alt="" /></a>');
			// hide the magnifier and wipe its background
			$('#magnifier').css({
				'display':			'none',
				'background-image':	'none'
			});
			$('#guitarbox a#magnify').removeClass('minify');
			bigimg = null;
			return false;	
		});
	}
	
	function bindMagnifier() {
		$('#multibox a#magnify').toggle(function(){
			// show the loading image
			$('#multibox span.loading').css('display', 'block');
			// switch to minify image
			$(this).addClass('minify');
			// preload the large version of the current main image
			var href = $('#multibox .mainimage a').attr('href');
			bigimg = new Image();
			bigimg.src = href;
			// preload the large version
			// get the size and bind the rest of the function as a callback
			getImageSize(makeMagnifier);
			return false;
		}, function(){
			// switch to magnifyimage
			$(this).removeClass('minify');
			// hide the magnifier and wipe its background
			$('#magnifier').css({
				'display':			'none',
				'background-image':	'none'
			});
		});
	}

	// create the magnifier
	function makeMagnifier() {
		// display the magnifier and put it in the general area
		$('#magnifier').css({
			'display':				'block',
			'left':					'50%',
			'top':					'50%',
			'width':				options.magWidth,
			'height':				options.magHeight,
			'margin-left':			'-100px',
			'margin-top':			'-140px',
			'background-repeat':	'no-repeat',
			'background-image':		'url(' + bigimg.src + ')',
			'background-position':	'50% 50%'
		});
		// bind the mouse events
		$('#magnifier').mousedown(function(e){
			// add the big image as a background-image
			$(this).css({'cursor': 'move'}); 	
			// get the original position of the magnifier
			var pmag = $(this).position();
			// now the mouse data
			var pmouse = e;	
			// get the position of the image for maximum move limits
			var imgpos = $('#multibox .mainimage').position();
			var gbpos = $('#multibox').position();
			var limits = {
				minX:	Math.floor(gbpos.left + imgpos.left),
				maxX:	Math.floor(gbpos.left + imgpos.left + $('#multibox .mainimage').width()),
				minY:	Math.floor(gbpos.top + imgpos.top),
				maxY:	Math.floor(gbpos.top + imgpos.top + $('#multibox .mainimage').height())
			};
			$(this).bind('mousemove', [pmag, pmouse, limits], drag);
		});
		$('#magnifier').mouseup(function(e){
			$(this).css({'cursor': 'default'});
			$(this).unbind('mousemove');
		});
	}
	
	// allow users to be able to close the lightbox
	function removeMultibox() {
		// by clicking the overlay
		$('#multiboxoverlay').click(function(){
			$('#multiboxoverlay').animate({'opacity':'0'}, 400, 'linear', function(){
				$('#multibox, #multiboxoverlay').remove();
				$('#multibox #magnifier').remove();						
			});
			if (options.onClose) options.onClose();
		});
		// by clicking the close image
		$('#closeMultibox').bind('click', function(e){
			$('#multiboxoverlay').animate({'opacity':'0'}, 400, 'linear', function(e){
				$('#multibox, #multiboxoverlay').remove();
				$('#multibox #magnifier').remove();
			});
			if (options.onClose) options.onClose();
			return false;
		});
		// by clicking the image itself
		$('#multibox .mainimage img').click(function(){
			$('#multiboxoverlay').animate({'opacity':'0'}, 400, 'linear', function(){
				$('#multibox, #multiboxoverlay').remove();
				$('#multibox #magnifier').remove();					
			});
			if (options.onClose) options.onClose();
			return false;
		});		
	}
	
	/************************************** HELPER FUNCTIONS *****************************************/
	
	// all the info about the window, document and calling element position (via scrollTop)
	function getDocumentInfo() {
		info.ww = $(window).width();
		info.wh = $(window).height();
		info.st = $(window).scrollTop();			
		info.dh = $(document).height();
	}
	
	// gets the image dimensions, recursive function calls passed callback on completion		
	function getImageSize(callback) {
		if (imgobj.content.complete) {
			imgobj.width = imgobj.content.width;
			imgobj.height = imgobj.content.height;
			imgs.push(imgobj);
			callback();
		} else {
			setTimeout(function(){getImageSize(callback);}, 100);
		}
	}
	
	// make the image src attributes using options.mediumSuffix and options.thumbSuffix and the large image href
	function makeMediumSrc(href) {
		return href.slice(0, href.lastIndexOf('.')-3) + options.mediumSuffix + href.slice(href.lastIndexOf('.'));	
	}
	
	function makeThumbSrc(href) {
		return href.slice(0, href.lastIndexOf('.')-3) + options.thumbSuffix + href.slice(href.lastIndexOf('.'));
	}
	
	
	
	
	// the dragging of the magnifier
	function drag(e) {
		// the magnifier original position
		var origX = e.data[0].left, origY = e.data[0].top;
		// the mouse original position
		var startX = e.data[1].clientX, startY = e.data[1].clientY;
		// the boundaries
		var minX = e.data[2].minX, maxX = e.data[2].maxX;
		var minY = e.data[2].minY, maxY = e.data[2].maxY;			
		// the change in position of the mouse
		var deltaX = startX - origX, deltaY = startY - origY;			
		// the position to go to
		var left = 	e.clientX - deltaX;
		var top = e.clientY - deltaY;			
		// the width of the visible image
		var sWidth = e.data[2].maxX - e.data[2].minX;
		var sHeight = e.data[2].maxY - e.data[2].minY;
		//var ratio = dimensions.width/sWidth;
		//var ratio = dimensions.width/300;
		var bl = ((left-sWidth-100) / sWidth) * 100;
		var bt = ((top-minY-100) / sHeight) * 100;
		$(this).css({
			'left':					left + 'px',
			'top':					top + 'px',				
			'background-position':	bl + '% ' + bt + '%'
		});				
	}
		
	// the clone function
	/* function clone(object) {
		function F() {};
		F.prototype = object;
		return new F;
	} */	
	
	/************************************** PUBLIC *****************************************/
	
	return this.each(function(){
		
		var defaults = {
			// overlay settings
			overlay:		true,
			opacity:		.5,
			
			// for a div
			div:			null,
			
			// multiple size images (thumb, medium, large)
			multiSize:		false,
			thumbSuffix:	'_thumb',
			mediumSuffix:	'_med',
			
			// magnifier settings for multiple size images
			magnifier:		false,
			magWidth:		200,
			magHeight:		200,
			
			// multiple images
			multiImage:		false,
			
			// position settings
			top:			100,
			
			// callbacks
			beforeShow:		null,
			afterShow:		null,
			onClose:		null
		};
		
		function extend(options) {
			for (var name in options) {
				//console.log('name: '+name+', old: '+defaults[name]+', new: '+options[name]);
				defaults[name] = options[name];
			}
			return defaults;
		}

//console.log('defaults.multiSize: '+defaults.multiSize)
			options = options ? extend(options) : defaults;
//console.log('options.multiSize: '+options.multiSize)		
		
		
			$(this).bind('click', options, doMultibox);
	
	
		
	});
	
				
}; // end plugin
})(jQuery);
