/*

 * MojoZoom 0.1.4 - JavaScript Image Zoom

 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/

 * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt]

 */



var MojoZoom = (function() {



	var $ = function(id) {return document.getElementById(id);};

	var dc = function(tag) {return document.createElement(tag);};



	var defaultWidth = 300;

	var defaultHeight = 300;



	function addEvent(element, ev, handler) 

	{

		var doHandler = function(e) {

			return handler(e||window.event);

		}

		if (element.addEventListener) { 

			element.addEventListener(ev, doHandler, false); 

		} else if (element.attachEvent) { 

			element.attachEvent("on" + ev, doHandler); 

		}

	}



	function getElementPos(element)

	{

		var x = element.offsetLeft;

		var y = element.offsetTop;

		var parent = element.offsetParent;

		while (parent) {

			x += parent.offsetLeft;

			y += parent.offsetTop;

			parent = parent.offsetParent;

		}

		return {

			x : x,

			y : y

		}

	}



	function getEventMousePos(element, e) {

		var scrollX = document.body.scrollLeft || document.documentElement.scrollLeft;

		var scrollY = document.body.scrollTop || document.documentElement.scrollTop;



		if (e.currentTarget) {

			var pos = getElementPos(element);

			return {

				x : e.clientX - pos.x + scrollX,

				y : e.clientY - pos.y + scrollY

			}

		}

		return {

			x : e.offsetX,

			y : e.offsetY

		}

	}



	function makeZoomable(img, zoomSrc, zoomImgCtr, zoomWidth, zoomHeight, alwaysShow) {

		// make sure the image is loaded, if not then add an onload event and return

		if (!img.complete && !img.__mojoZoomQueued) {

			addEvent(img, "load", function() {

				img.__mojoZoomQueued = true;

				setTimeout(function() {

				makeZoomable(img, zoomSrc, zoomImgCtr, zoomWidth, zoomHeight, alwaysShow);

				}, 1);

			});

			return;

		}



		img.__mojoZoomQueued = false;



		// Wrap everything in a timeout.

		// this fixes a problem where, if makeZoomable is called a second time after changing the src,

		// FF would not have figured out the new offsetHeight of the image yet. A small timeout helps though it's rather hackish.

		setTimeout(function(){



		// sorry

		var isIE = !!document.all && !!window.attachEvent && !window.opera;



		var w = img.offsetWidth;

		var h = img.offsetHeight;



		var oldParent = img.parentNode;

		if (oldParent.nodeName != "A") {

			var linkParent = dc("a");

			//linkParent.setAttribute("href", zoomSrc);

			//oldParent.replaceChild(linkParent, img);

			//linkParent.appendChild(img);

		} else {

			var linkParent = oldParent;

		}



		linkParent.style.position = "relative";

		linkParent.style.display = "block";

		linkParent.style.width = w+"px";

		linkParent.style.height = h+"px";



		var imgLeft = img.offsetLeft;

		var imgTop = img.offsetTop;



		var zoom = dc("div");

		zoom.className = "mojozoom_marker";



		var zoomImg = dc("img");

		zoomImg.className = "mojozoom_img";



		zoomImg.style.position = "absolute";

		zoomImg.style.left = "-9999px";

		zoomImg.style.top = "-9999px";



		document.body.appendChild(zoomImg);



		var parent = img.parentNode;



		var ctr = dc("div");

		with (ctr.style) {

			position = "absolute";

			left = imgLeft+"px";

			top = imgTop+"px";

			width = w+"px";

			height = h+"px";

			overflow = "hidden";

			display = "none";

		}



		ctr.appendChild(zoom);

		parent.appendChild(ctr);



		var zoomInput = parent;



		// clear old overlay

		if (img.__mojoZoomOverlay)

			parent.removeChild(img.__mojoZoomOverlay);

		img.__mojoZoomOverlay = ctr;



		// clear old high-res image

		if (img.__mojoZoomImage && img.__mojoZoomImage.parentNode)

			img.__mojoZoomImage.parentNode.removeChild(img.__mojoZoomImage);

		img.__mojoZoomImage = zoomImg;



		var useDefaultCtr = false;

		if (!zoomImgCtr) {

			zoomImgCtr = dc("div");

			zoomImgCtr.className = "mojozoom_imgctr";



			var imgPos = getElementPos(img);

			zoomImgCtr.style.left = w + imgPos.x + "px";

			zoomImgCtr.style.top = imgPos.y + "px";



			zoomImgCtr.style.width = (zoomWidth ? zoomWidth : defaultWidth) +"px";

			zoomImgCtr.style.height = (zoomHeight ? zoomHeight : defaultHeight) +"px";



			document.body.appendChild(zoomImgCtr);

			useDefaultCtr = true;

		}

		zoomImgCtr.style.overflow = "hidden";



		if (!alwaysShow) {

			zoomImgCtr.style.visibility = "hidden";

		}



		addEvent(zoomImg, "load", function() {



			// bail out if img has been removed from dom

			if (!zoomImg.parentNode) return;



			var zoomWidth = zoomImg.offsetWidth;

			var zoomHeight = zoomImg.offsetHeight;



			var ctrWidth = zoomImgCtr.offsetWidth;

			var ctrHeight = zoomImgCtr.offsetHeight;



			var ratioW = zoomWidth / w;

			var ratioH = zoomHeight / h;



			var markerWidth = Math.round(ctrWidth / ratioW);

			var markerHeight = Math.round(ctrHeight / ratioH);



			document.body.removeChild(zoomImg);

			zoomImgCtr.appendChild(zoomImg);



			var zoomFill = dc("div");

			zoomFill.className = "mojozoom_fill";

			zoom.appendChild(zoomFill);



			var zoomBorder = dc("div");

			zoomBorder.className = "mojozoom_border";

			zoom.appendChild(zoomBorder);



			zoom.style.width = markerWidth+"px";

			zoom.style.height = markerHeight+"px";





			if (alwaysShow) {

				zoom.style.left = "0px";

				zoom.style.top = "0px";

	

				zoomImg.style.left = "0px";

				zoomImg.style.top = "0px";

			}



			var isInImage = false;



			if (!alwaysShow) {

				addEvent(zoomInput, "mouseout", 

					function(e) {

						var target = e.target || e.srcElement;

						if (!target) return;

						if (target.nodeName != "DIV") return;

						var relTarget = e.relatedTarget || e.toElement;

						if (!relTarget) return;

						while (relTarget != target && relTarget.nodeName != "BODY" && relTarget.parentNode) {

							relTarget = relTarget.parentNode;

						}

						if (relTarget != target) {

							isInImage = false;

							ctr.style.display = "none";

							zoomImgCtr.style.visibility = "hidden";

						}

					}

				);

				// a bit of a hack, mouseout is sometimes not caught if moving mouse really fast

				addEvent(document.body, "mouseover", 

					function(e) {

						if (isInImage && !(e.toElement == zoomBorder || e.target == zoomBorder)) {

							ctr.style.display = "none";

							zoomImgCtr.style.visibility = "hidden";

							isInImage = false;

						}

					}

				);

			}



			addEvent(zoomInput, "mousemove", 

				function(e) {

					isInImage = true;



					var imgPos = getElementPos(img);



					if (useDefaultCtr) {

						zoomImgCtr.style.left = w + imgPos.x + "px";

						zoomImgCtr.style.top = imgPos.y + "px";

					}

					ctr.style.display = "block";

					zoomImgCtr.style.visibility = "visible";



					var pos = getEventMousePos(zoomInput, e);

					if (e.srcElement && isIE) {

						if (e.srcElement == zoom) return;

						if (e.srcElement != zoomInput) {

							var zoomImgPos = getElementPos(e.srcElement);

							pos.x -= (imgPos.x - zoomImgPos.x);

							pos.y -= (imgPos.y - zoomImgPos.y);

						}

					}

					var x = markerWidth/2;

					var y = markerHeight/2;



					if (!isIE) {

						pos.x -= imgLeft;

						pos.y -= imgTop;

					}



					if (pos.x < x) pos.x = x;

					if (pos.x > w-x) pos.x = w-x;

					if (pos.y < y) pos.y = y;

					if (pos.y > h-y) pos.y = h-y;



					var left = ((pos.x - x)|0);

					var top = ((pos.y - y)|0);



					zoom.style.left = left + "px";

					zoom.style.top = top + "px";



					zoomImg.style.left = -((pos.x*ratioW - ctrWidth/2)|0)+"px";

					zoomImg.style.top = -((pos.y*ratioH - ctrHeight/2)|0)+"px";
					
					//mh: set the left and top of the image to be in the top left corner if it has a small dimensions
					if(zoomImg.offsetLeft > zoomBorder.offsetLeft)
						zoomImg.style.left=zoomBorder.offsetLeft+"px";
					if(zoomImg.offsetTop > zoomBorder.offsetTop)
						zoomImg.style.top=zoomBorder.offsetTop+"px";
					

				}

			);

		});



		// I've no idea. Simply setting the src will make IE screw it self into a 100% CPU fest. In a timeout, it's ok.

		setTimeout(function() { 

			zoomImg.src = zoomSrc;

		}, 1);



		}, 1);

	}



	function init() {

		var images = document.getElementsByTagName("img");

		for (var i=0;i<images.length;i++) {

			var img = images[i];

			var zoomSrc = img.getAttribute("data-zoomsrc");

			if (zoomSrc) {

				makeZoomable(img, zoomSrc, document.getElementById(img.getAttribute("id") + "_zoom"), null, null, img.getAttribute("data-zoomalwaysshow")=="true");

			}

		}

	}



	return {

		addEvent : addEvent,

		init : init,

		makeZoomable : makeZoomable

	};



})();



MojoZoom.addEvent(window, "load", MojoZoom.init);

