/*
 * MojoMagnify 0.1.7 - JavaScript Image Magnifier
 * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
 * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt]
 */


var MojoMagnify = (function() {

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

    var isIE = !!document.all && !!window.attachEvent && !window.opera;
    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.documentElement.scrollLeft || document.body.scrollLeft;
        var scrollY = document.documentElement.scrollTop || document.body.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 setZoomPos(img, x, y, pos) {
        var zoomImg = img.__mojoMagnifyImage;
        if (!zoomImg) {
            return;
        }
        img.__mojoMagnifyX = x;
        img.__mojoMagnifyY = y;
        img.__mojoMagnifyPos = pos;

        var zoom = img.__mojoMagnifyZoomer;

        var maskWidth = zoom.offsetWidth;
        var maskHeight = zoom.offsetHeight;

        maskWidth = 350;
        maskHeight = 350;

        var imgLeft = img.offsetLeft;
        var imgTop = img.offsetTop;
        var w = img.offsetWidth;
        var h = img.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);

        var zx = -zoomX + maskWidth/2;
        var zy = -zoomY + maskHeight/2;

        zoomImg.style.left = zx + 'px';
        zoomImg.style.top = zy + 'px';
    }


    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;
        }
        img.__src = zoomSrc;

        var w = img.offsetWidth;
        var h = img.offsetHeight;
        var oldParent = img.parentNode;
        if (oldParent.nodeName.toLowerCase() != 'span' && !$('mojomagnify_parent')) {
            var linkParent = dc('span');
            linkParent.id = 'mojomagnify_parent';
            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 parent  = img.parentNode;

        var zoom    = $('mojomagnify_zoom');
        var zoomImg = $('mojomagnify_img');
        var ctr     = $('mojomagnify-overlay');
        var icon    = $('mojomagnify_icon');

        if (!zoom) {
            var zoom = dc('div');
            zoom.id = 'mojomagnify_zoom';
            zoom.className = 'mojomagnify_zoom';
            zoom.style.left = '-9999px';
        }
        if (!ctr) {
            var ctr = dc('div');
            ctr.id = 'mojomagnify-overlay';
            with (ctr.style) {
                position = 'absolute';
                left = imgLeft+1+'px';
                top = imgTop+1+'px';
                width = w-2+'px';
                height = h-2+'px';
                overflow = 'hidden';
                display = 'block';
            }
            ctr.appendChild(zoom);
            parent.appendChild(ctr);
        }
        if (!icon) {
            var icon = dc('span');
            icon.id = 'mojomagnify_icon';
            icon.className = 'loading';
            parent.appendChild(icon);
        }

        if (!zoomSrc) {
            img.__onload = false;
            ctr.style.display = 'none';
            icon.style.display = 'none';
            // clear old high-res image
            if (img.__mojoMagnifyImage && img.__mojoMagnifyImage.parentNode) {
                img.__mojoMagnifyImage.parentNode.removeChild(img.__mojoMagnifyImage);
            }
            return;
        }
        if (!zoomBorder) {
            var zoomBorder = dc('div');
            zoomBorder.className = 'mojomagnify_border';
            zoomBorder.id        = 'mojomagnify_border';
            zoom.appendChild(zoomBorder);

        }
        var zoomInput = parent;

        if (!zoomImg) {
            var zoomImg = dc('img');
            zoomImg.className = 'mojomagnify_img';
            zoomImg.style.position = 'absolute';
            if (isIE) { 
                // IE won't let the mouse click pass through properly to the link,
                // so we clone the link and use it for the zoom image as well. Do for all browsers, perhaps?
                var zoomLink = dc('a');
    //            zoomLink.setAttribute('href', linkParent.getAttribute('href'));
                zoomLink.setAttribute('onclick', linkParent.getAttribute('onclick'));
                zoomLink.style.position = 'absolute';
                zoomLink.style.left = '0px';
                zoomLink.style.top = '0px';
                zoomLink.appendChild(zoomImg);
                zoom.appendChild(zoomLink);
            } else {
                zoom.appendChild(zoomImg);
            }
            addEvent(zoomImg, 'error', function() {
                zoom.style.display = 'none';
                icon.style.display = 'none';
                img.__onload = false;
                img.__src    = '';
            });
            addEvent(zoomImg, 'load', function() {
                if (!img.__src) {
                    icon.style.display = 'none';
                    img.__onload       = false;
                    return;
                }
                icon.className = '';
                img.__onload = true;
                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;
                        if (!img.__onload) {
                            return;
                        }
                        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.documentElement.scrollLeft||document.body.scrollLeft));
                        var y = e.clientY - (getElementPos(img).y - (document.documentElement.scrollTop||document.body.scrollTop));

                        setZoomPos(img, x, y, pos);
                    }
                );

                ctr.style.display = 'none';
            });

        }

        // clear old overlay
        if (img.__mojoMagnifyOverlay) {
            parent.removeChild(img.__mojoMagnifyOverlay);
        }
        img.__mojoMagnifyOverlay = ctr;

        // clear old high-res image
        if (img.__mojoMagnifyImage && img.__mojoMagnifyImage.parentNode) {
            img.__mojoMagnifyImage.parentNode.removeChild(img.__mojoMagnifyImage);
        }
        img.__mojoMagnifyImage = zoomImg;
        img.__mojoMagnifyZoomer = zoom;
        img.__mojoMagnifyBorder = zoomBorder;

        var isInImage = false;

        if (!isIE) {
            addEvent(linkParent, 'mouseover', function() { var z = $('mojomagnify_zoom'); if (z) {z.style.display = 'block';} });
            addEvent(zoom, 'mouseout', function() { var z = $('mojomagnify_zoom'); if (z) {z.style.display = 'none'; }});
            addEvent(img, 'mouseout', function() { var z = $('mojomagnify_zoom'); if (z) {z.style.display = 'none'; }});
        }

        // 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 setCoords(img, x, y) {
        if (!img.__mojoMagnifyOverlay) {
            return;
        }
        isInImage = true;
        img.__mojoMagnifyOverlay.style.display = 'block';
        setZoomPos(img, x, y, {x: x, y: y});
    }

    function init() {
        var img = document.getElementById('item-image');
        if (!img) {
            return;
        }
        var zoomSrc = img.getAttribute('data-magnifysrc');
        if (zoomSrc) {
            makeMagnifiable(img, zoomSrc);
        }
    }

    return {
        addEvent : addEvent,
        init : init,
        makeMagnifiable : makeMagnifiable,
        setCoords : setCoords
    };
})();

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