
//***********************************************************************//
//      AUTHOR: Johnny Green
//    FILENAME: jquery.imagezoom.js
//        DATE: 03/09/2010 updated 01/09/2012
// DESCRIPTION: My first attempt at an image zoom module using jQuery.
//              Image zoom module / view port with zoom and drag.
//***********************************************************************//

$(function() {
	$.ajaxSetup({'cache': false});
	
	var zoomlevel = 0,
		initzoomlevel = 0,
		zoommax = -1,
		zoommin = 0,
		
		disablezoom = false,
		
		offset = 0,
		cur_view = 1,
		num_views = $(".view").length,
		
		initLeft = [],
		initTop = [],
		
		clicktype = "click",
		clickcount = 0,
		
		clicktimer,
		dblclicktimer,
		imagetimer,
		
		image_location = MZW.Product.image_location;
		
	var $viewport = $("#zoom .viewport"), 
	
		$zoom_control = $("#zoom .control"),
		$zoom_in = $(".zoom-in", $zoom_control),
		$zoom_out = $(".zoom-out", $zoom_control),
		
		$selector = $("#zoom .selector"),
		$views = $(".view", $selector),
		$left = $(".left", $selector),
		$right = $(".right", $selector),
		
		$loading_container = $("#zoom .loading-container"),
		$loading = $(".loading", $loading_container);
		
	
	$zoom_control.fadeTo("slow", 0.65).bind({"mouseenter": function() { $(this).fadeTo(1, 1.0); }, "mouseleave": function() { $(this).fadeTo(1, 0.5); } });
	$zoom_in.bind("click", zoomIn);
	$zoom_out.bind("click", reset);
	$loading_container.ajaxStart(function() { MZW.ajaxBusy = true; });
	$loading_container.ajaxStop(function() { MZW.ajaxBusy = false; });
	$left.bind("click", function() { $(".view").eq(cur_view - 2).click(); });
	$right.bind("click", function() { if(cur_view == num_views) { $(".view").eq(0).click(); } else { $(".view").eq(cur_view).click(); } });
	
	//INITIALIZE SINGLE IMAGE GRID
	function initialize(index) {
		index = index - offset;
		
		$(".imagegrid").eq(index).css({"width": $(".imagegrid").eq(index).width(), "height": $(".imagegrid").eq(index).height(), "margin-left": -$(".imagegrid").eq(index).width()/2, "margin-top": -$(".imagegrid").eq(index).height()/2}).hide();
		
		if(index == initzoomlevel) {
			var ratio = (($viewport.height()/$(".imagegrid").eq(initzoomlevel).height())/1.1).toFixed(1);
		
			$(".imagegrid").eq(initzoomlevel).css({"width": $(".imagegrid").eq(initzoomlevel).width()*ratio, "height": $(".imagegrid").eq(initzoomlevel).height()*ratio, "margin-left": -($(".imagegrid").eq(initzoomlevel).width()*ratio)/2, "margin-top": -($(".imagegrid").eq(initzoomlevel).height()*ratio)/2}).fadeTo("slow", 1.0);
			$(".imagegrid").eq(initzoomlevel).children().children("img").each(function() {
				$(this).css({"width": parseInt($(this).width()*ratio), "height": parseInt($(this).height()*ratio)});
			});
		}
		
		if(($(".imagegrid").eq(initzoomlevel).height() >= $(".imagegrid").eq(index).height() || ($(".imagegrid").eq(index).height() <= ($(".imagegrid").eq(initzoomlevel).height() + 200) && $(".imagegrid").eq(index).height() >= $(".imagegrid").eq(initzoomlevel).height())) && initzoomlevel != index) {
			$(".imagegrid").eq(index).remove();
			offset++;
		} else {
			initLeft[index] = $(".imagegrid").eq(index).css("left");
			initTop[index] = $(".imagegrid").eq(index).css("top");
			zoommax++;
		}
	}
	
	function zoomIn() {
		clickcount = 0;
		
		if(zoomlevel + 1 <= zoommax && !disablezoom) {
			zoomlevel++;
			$(".imagegrid").each(function() { $(this).fadeTo(1, 0.0).fadeOut(1); });
			$(".imagegrid").eq(zoomlevel).fadeTo(1, 1.0, function() { $(this).fadeIn("slow"); });
		}
	}
	
	function zoomOut() {
		clickcount = 0;
		
		if(zoomlevel - 1 >= zoommin && !disablezoom) {
			zoomlevel--;
			$(".imagegrid").each(function() { $(this).fadeTo(1, 0.0).fadeOut(1); });
			$(".imagegrid").eq(zoomlevel).fadeTo(1, 1.0, function() { $(this).fadeIn("slow"); });
		}
	}
	
	function reset() {
		clickcount = 0;
		zoomlevel = initzoomlevel;
		$(".imagegrid").each(function() { $(this).css({"left": initLeft[$(this).index()], "top": initTop[$(this).index()]}).fadeTo(1, 0.0).fadeOut(1); });
		$(".imagegrid").eq(zoomlevel).fadeTo(1, 1.0, function() { $(this).fadeIn("slow"); });
	}
	
	function setClickType() { clicktype = "drag"; }
	
	function checkLoading(imagequeue) {
		if(imagequeue.length > 0) {
			var counter = 0;
			$loading_container.fadeIn("slow");
			
			$.each(imagequeue, function(index, image) {
				if(image != "DONE") {
					$.each(image, function(i, piece) {
						if(piece && (piece.complete || piece.error)) {
							image.splice(i, 1);
							$loading.width($loading.width() + 2);
						}
					});
				}
				
				if(image.length == 0) {
					initialize(index);
					imagequeue[index] = "DONE";
					counter++;
				}
				
				if(image == "DONE") counter++;
				
				if(counter >= imagequeue.length) {
					clearInterval(imagetimer);
					$loading_container.fadeOut("slow");
					offset = 0;
				}
			});
		}
	}
	
	function setViewportCursor(state) { 
		switch(state) {
			case "dragging": $viewport.css({"cursor": ($.browser.mozilla) ? "-moz-grabbing" : "pointer"}); break;	
			case "zoom": $viewport.css({"cursor": ($.browser.mozilla) ? "-moz-zoom-in" : "url(/mzwshop/zoom_module/images/other/zoomin.cur), default"}); break;
			default: $viewport.css({"cursor": "default"});
		}
	}
	
	function loadView(view) {
		$viewport.load("/mzwshop/zoom_module/zoom_module.php", {'task': "changeView", 'view': view, 'dir': image_location}, function() {
			var imagequeue = [],
				imagecount = 0,
				piececount = 0,
				piececount_sum = 0;
			
			$(".imagegrid").fadeTo(0, 0.0);
			
			$(this).children().each(function() {
				imagequeue[imagecount] = [];
				
				$(this).children().children("img").each(function() {
					imagequeue[imagecount][piececount] = new Image();
					imagequeue[imagecount][piececount].src = $(this).attr("src");
					piececount++;
					piececount_sum++;
				});
				
				piececount = 0;
				imagecount++;
			});
			
			$loading_container.css({"width": piececount_sum*2});
			
			zoommax = -1;
			zoomlevel = initzoomlevel;
			imagetimer = setInterval(function() { checkLoading(imagequeue); }, 200);
		});
	}
	
	$views.click(function() {
		if(!MZW.ajaxBusy) {			
			var current = $(this);
			clearInterval(imagetimer);
			offset = 0;
			$loading_container.hide();
			$loading.width(0);
			
			$(".view.selected").removeClass("selected");
			$(this).addClass("selected");
			
			cur_view = $(this).text();
			disablezoom = false;
			$zoom_control.fadeIn("slow");
			setViewportCursor("zoom");
			
			if($(this).text() == "BODY") {
				cur_view = $(".view").length;
				disablezoom = true;
				$zoom_control.fadeOut("slow");
				setViewportCursor("default");
			}
			
			loadView($(this).text());
		}
	});
	
	$viewport.bind({
		"click": function(e) {
			e.preventDefault();
			
			if(clicktype == "click") {
				clickcount++;
				
				switch(clickcount) {
					case 1: dblclicktimer = setTimeout(function() { zoomIn(); }, 200); break;
					case 2: clearTimeout(dblclicktimer); break;
					default: clickcount = 0;
				}
			}
		},
		
		"dblclick": function() {
			clearTimeout(dblclicktimer);
			setTimeout(zoomOut, 200);
		},
		
		"mousedown": function(e) {
			e.preventDefault();
			
			if(!disablezoom) {
				setViewportCursor("dragging");
				clicktype = "click";
				clicktimer = window.setTimeout(setClickType, 150);
				
				var iCX = e.pageX,
					iCY = e.pageY, 
					vpX = $(this).offset().left,
					vpY = $(this).offset().top,
					iMX = iCX - vpX,
					iMY = iCY - vpY,
					iGX = iCX - $(".imagegrid").eq(zoomlevel).offset().left,
					iGY = iCY - $(".imagegrid").eq(zoomlevel).offset().top,
					iEL = [],
					iET = [];
				
				$(".imagegrid").each(function() {
					var ratio = $(this).width()/$(".imagegrid").eq(zoomlevel).width(),
						GX = e.pageX - vpX - iGX*ratio - parseInt($(this).css("margin-left")),
						GY = e.pageY - vpY - iGY*ratio - parseInt($(this).css("margin-top"));
					
					$(this).css({"left": GX + "px", "top": GY + "px"});
					
					iEL[$(this).index()] = parseInt($(this).css("left"));
					iET[$(this).index()] = parseInt($(this).css("top"));
				})
			
				$viewport.bind('mousemove', function(e) {
					e.preventDefault();
					
					x = e.pageX;
					y = e.pageY;
					
					$(".imagegrid").each(function() {
						$(this).css({"left": (iEL[$(this).index()] + x - iCX) + "px", "top": (iET[$(this).index()] + y - iCY) + "px"});
					});
				});
			}
		},
		
		"mouseup": function() {
			$viewport.unbind('mousemove');
			clearTimeout(clicktimer);
			if(!disablezoom) setViewportCursor("zoom");
		}
	});
	
	setViewportCursor("zoom");
	
	if($views.length) {
		$views.first().click();
	} else {
		loadView(1);	
	}
	
});

