/*

 * MojoMagnify 0.1.4 - JavaScript Image Magnifier

 * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/

 * MIT License [http://www.opensource.org/licenses/mit-license.php]

 */





var MojoMagnify = (function() {



	var $ = function(id) {return document.getElementById(id);};

	var dc = function(tag) {return document.createElement(tag);};



	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 makeMagnifiable(img, zoomSrc) {

		// make sure the image is loaded, if not then add an onload event and return

		if (!img.complete && !img.__mojoMagnifyQueued) {

			addEvent(img, "load", function() {

				img.__mojoMagnifyQueued = true;

				setTimeout(function() {

				makeMagnifiable(img, zoomSrc);

				}, 1);

			});

			return;

		}



		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;

		}



		var isIE = !!document.all && !!window.attachEvent && !window.opera;



		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 = "mojomagnify_zoom";



		var zoomImg = dc("img");

		zoomImg.className = "mojomagnify_img";

		zoomImg.style.position = "absolute";



		var parent = img.parentNode;

		zoom.appendChild(zoomImg);



		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 zoomBorder = dc("div");

		zoomBorder.className = "mojomagnify_border";

		zoom.appendChild(zoomBorder);



		var zoomInput = parent;



		var isInImage = false;



		addEvent(zoomImg, "load", function() {



			var onMouseOut = 

				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";

					}

				};



			addEvent(ctr, "mouseout", onMouseOut);

			addEvent(ctr, "mouseleave", onMouseOut);

			if (isIE) {

				addEvent(document.body, "mouseover",

					function(e) {

						if (isInImage && e.toElement != zoomImg) {

							ctr.style.display = "none";

						}

					}

				);

			}



			addEvent(zoomInput, "mousemove", 

				function(e) {

					isInImage = true;



					ctr.style.display = "block";



					var pos = getEventMousePos(zoomInput, e);



					if (e.srcElement && isIE) {

						if (e.srcElement == zoom) return;

						if (e.srcElement != zoomInput) {

							var zoomImgPos = getElementPos(e.srcElement);

							var imgPos = getElementPos(img);

							pos.x -= (imgPos.x - zoomImgPos.x);

							pos.y -= (imgPos.y - zoomImgPos.y);

						}

					}



					var x = e.clientX - (getElementPos(img).x - (document.body.scrollLeft||document.documentElement.scrollLeft));

					var y = e.clientY - (getElementPos(img).y - (document.body.scrollTop||document.documentElement.scrollTop));



					var maskWidth = zoom.offsetWidth;

					var maskHeight = zoom.offsetHeight;



					var left = pos.x - maskWidth/2;

					var top = pos.y - maskHeight/2;



					if (!isIE) {

						left -= imgLeft;

						top -= imgTop;

					}



					zoom.style.left = left + "px";

					zoom.style.top = top + "px";



					var zoomXRatio = zoomImg.offsetWidth / w;

					var zoomYRatio = zoomImg.offsetHeight / h;



					var zoomX = Math.round(x * zoomXRatio);

					var zoomY = Math.round(y * zoomYRatio);



					zoomImg.style.left = -zoomX + maskWidth/2 + "px";

					zoomImg.style.top = -zoomY + maskWidth/2 + "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);

	}



	function init() {

		var images = document.getElementsByTagName("img");

		var imgList = [];

		for (var i=0;i<images.length;i++) {

			imgList.push(images[i]);

		}

		for (var i=0;i<imgList.length;i++) {

			var img = imgList[i];

			var zoomSrc = img.getAttribute("data-magnifysrc");

			if (zoomSrc) {

				makeMagnifiable(img, zoomSrc);

			}

		}

	}



	return {

		addEvent : addEvent,

		init : init,

		makeMagnifiable : makeMagnifiable

	};



})();



MojoMagnify.addEvent(window, "load", MojoMagnify.init);
