/*!
 * jQuery gzoom 0.1
 * 2009 Giovanni Battista Lenoci <gianiaz@gianiaz.net>
 * 
 * Based on minizoomPan plugin of Gian Carlo Mingati Version: 1.0 (18-JUNE-2009) http://www.gcmingati.net/wordpress/wp-content/lab/jquery/minizoompan/
 * Inspiration from jquery lightbox plugin http://leandrovieira.com/projects/jquery/lightbox/
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Requires:
 * jQuery v1.3.2 or later
 * jQuery ui.core.js v.1.7.1
 * jQuery ui.slider.js v.1.7.1
 * 
 */
jQuery.fn.gzoom = function(settings) {
    settings = jQuery.extend({
        sW: 10, // small image width
        sH: 10, // small image height
        lW: 20, // large image width
        lH: 20, // large image height
        step: 5,
        frameColor: "#cecece",
        frameWidth: 1,
        re: /thumbs\//,
        replace: '',
        debug: false,
        overlayBgColor: '#000',
        overlayOpacity: 0.8,
        containerBorderSize: 10,
        containerResizeSpeed: 400,
        loaderContent: "",  // plain text or an image tag eg.: "<img src='yoursite.com/spinner.gif' />"
        lightbox: false,
        zoomIcon: "", // icon url, if not empty shown on the right-top corner of the image
        sliderWidth: 0
    }, settings);

    return this.each(function() {

        var swapped = false;

        var $div = jQuery(this).css({ width: settings.sW, height: settings.sH, border: settings.frameWidth + "px solid " + settings.frameColor, overflow: 'hidden' }).addClass("minizoompan");
        $div.wrap('<div class="gzoomwrap"></div>').css({ width: settings.sW });
        var ig = $div.children().css({ position: "relative" });

        jQuery(window).bind("load", function() {
            ig.width(settings.sW);
            ig.height(settings.sH);
        });


        jQuery("<span class='loader'>" + settings.loaderContent + "<\/span>").insertBefore(ig);
        if (settings.zoomIcon != '' && settings.lightbox) {
            var $zoom = jQuery('<img class="zoomIcon" src="' + settings.zoomIcon + '" alt="view larger" />').insertBefore(ig);
            $zoom.load(function() {
                $zoom.css({ 'left': (settings.sW - $zoom.width()) + 'px' }).show();
            });
            $zoom.click(function() {
                drawIface();
            });
        } else if (settings.lightbox) {
            $div.click(function() {
                drawIface();
            });
            $div.css({ 'cursor': 'pointer' });
        }

        if (settings.sliderWidth === 0)
            settings.sliderWidth = settings.sW - 42;
        var $plus = jQuery('<div class="ui-icon ui-icon-circle-plus gzoombutton">&nbsp;</div>').insertAfter($div);
        var $slider = jQuery('<div class="gzoomSlider"></div>').insertAfter($div).css({ width: settings.sliderWidth + 'px', 'z-index': 100});
        var $minus = jQuery('<div class="ui-icon ui-icon-circle-minus gzoombutton">&nbsp;</div>').insertAfter($div);

        $plus.click(function() {
            valore = parseInt($slider.slider('value')) + settings.step;
            $slider.slider('value', valore);
        });

        $minus.click(function() {
            valore = parseInt($slider.slider('value')) - settings.step;
            $slider.slider('value', valore);
        });

        $slider.slider({ value: 0,
            min: 0,
            max: 100,
            step: settings.step,
            change: function(event, ui) {

                if (!swapped) {
                    var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
                    swapImage(ig, hiSrc);
                    $div.children("span.loader").fadeIn(250);
                    swapped = true;
                }

                val = ui.value;

                newWidth = settings.sW + ((settings.lW - settings.sW) * val) / 100;
                newHeight = settings.sH + ((settings.lH - settings.sH) * val) / 100;
                ig_pos = ig.position();

                if (settings.debug && typeof (console) != 'undefined') {
                    console.log('new dimensions:' + newWidth + 'x' + newHeight);
                }

                deltaWidth = ig.width() - settings.sW;
                leftPos = Math.abs(ig_pos.left);
                leftFactor = leftPos / deltaWidth;
                newDeltaWidth = newWidth - settings.sW;
                newLeft = (leftFactor * newDeltaWidth) * -1;

                deltaHeight = ig.height() - settings.sH;
                topPos = Math.abs(ig_pos.top);
                topFactor = topPos / deltaHeight;
                newDeltaHeight = newHeight - settings.sH;
                newTop = (topFactor * newDeltaHeight) * -1;
                ig.css({ width: newWidth, height: newHeight, left: newLeft, top: newTop });
            }
        });
        $('<br style="clear:both" />').insertAfter($plus);

        function swapImage(param, uri) {
            param.load(function() {
                $div.children("span.loader").fadeOut(250);
            }).error(function() {
                alert("Image does not exist or its SRC is not correct.");
            }).attr('src', uri);
        }

        $div.mousemove(function(e) {
            var divWidth = $div.width();
            var divHeight = $div.height();
            var igW = ig.width();
            var igH = ig.height();
            var dOs = $div.offset();
            var leftPan = (e.pageX - dOs.left) * (divWidth - igW) / (divWidth + settings.frameWidth * 2);
            var topPan = (e.pageY - dOs.top) * (divHeight - igH) / (divHeight + settings.frameWidth * 2);

            if (settings.debug && typeof (console) != 'undefined') {
                console.log('left:' + leftPan + '|Top:' + topPan);
            }

            ig.css({ left: leftPan, top: topPan });
        });

        if (typeof ($.event.special.mousewheel) != 'undefined') {
            ig.mousewheel(function(event, delta) {
                if (delta > 0) {
                    valore = parseInt($slider.slider('value')) + settings.step;
                    $slider.slider('value', valore);
                } else if (delta < 0) {
                    valore = parseInt($slider.slider('value')) - settings.step;
                    $slider.slider('value', valore);
                }
                return false; // prevent default
            });
        }

        function resize_fx(intImageWidth, intImageHeight) {

            if (settings.debug && typeof (console) != 'undefined') {
                console.log('resize_fx(' + intImageWidth + ',' + intImageHeight + ')');
            }

            if (intImageWidth > ($(window).width() * 80 / 100)) {
                imgWidth = $(window).width() * 80 / 100;
                intImageHeight = (imgWidth / intImageWidth) * intImageHeight;
                $('#zoomedimage').css({ 'width': imgWidth + 'px', 'height': intImageHeight });
                if (settings.debug && typeof (console) != 'undefined') {
                    console.log('Img dimensions 80% horizontal:' + imgWidth + 'x' + intImageHeight);
                }
            } else {
                imgWidth = intImageWidth;
            }

            if (intImageHeight > $(window).height() * 80 / 100) {
                imgHeight = $(window).height() * 80 / 100;
                imgWidth = (imgHeight / intImageHeight) * imgWidth;
                $('#zoomedimage').css({ 'width': imgWidth + 'px', 'height': imgHeight });
                if (settings.debug && typeof (console) != 'undefined') {
                    console.log('Img dimensions 80% vertical:' + imgWidth + 'x' + imgHeight);
                }
            } else {
                imgHeight = intImageHeight;
            }

            if (settings.debug && typeof (console) != 'undefined') {
                console.log('Img dimensions:' + imgWidth + 'x' + imgHeight);
            }

            // Get current width and height
            var intCurrentWidth = $('#imagebox').width();
            var intCurrentHeight = $('#imagebox').height();
            // Get the width and height of the selected image plus the padding
            var intWidth = (imgWidth + (settings.containerBorderSize * 2)); // Plus the imageŽs width and the left and right padding value
            var intHeight = (imgHeight + (settings.containerBorderSize * 2)); // Plus the imageŽs height and the left and right padding value



            // Diferences
            var intDiffW = intCurrentWidth - intWidth;
            var intDiffH = intCurrentHeight - intHeight;
            // Perfomance the effect
            $('#imagebox').animate({ width: intWidth, height: intHeight }, settings.containerResizeSpeed, function() { _show_image(); });
            if ((intDiffW == 0) && (intDiffH == 0)) {
                if ($.browser.msie) {
                    ___pause(250);
                } else {
                    ___pause(100);
                }
            }
            $('#lboximgdatacontainer').css({ width: imgWidth });
        };

        function drawIface() {

            $('body').append('<div id="gzoomoverlay"></div><div id="gzoomlbox"><div id="imagebox"><div id="gzoom-cont-img"><img id="zoomedimage"><div id="gzoomloading"><a href="#" id="gzoomloadinglink"><img src="images/loading.gif"></a></div></div></div><div id="gzoomlbox-con-imgdata"><div id="lboximgdatacontainer"><div id="gzoomlbox-image-details"><span id="gzoom-image-caption"></span></div></div></div></div>');

            $('#gzoomoverlay').css({
                backgroundColor: settings.overlayBgColor,
                opacity: settings.overlayOpacity,
                width: $(window).width(),
                height: $(document).height()
            }).fadeIn();

            // Calculate top and left offset for the gzoomlbox div object and show it
            $('#gzoomlbox').css({
                top: $(window).scrollTop() + ($(window).height() / 10),
                left: $(window).scrollLeft()
            }).show();

            $('#gzoomoverlay,#gzoomlbox').click(function() {
                close();
            });
            // If window was resized, calculate the new overlay dimensions
            $(window).resize(function() {
                $('#gzoomoverlay').css({
                    width: $(window).width(),
                    height: $(window).height()
                });
                // Calculate top and left offset for the jquery-lightbox div object and show it
                $('#gzoomlbox').css({
                    top: $(window).scrollTop() + ($(window).height() / 10),
                    left: $(window).scrollLeft()
                });
            });

            _set_image_to_view();
        }

        function _set_image_to_view() { // show the loading
            // Show the loading
            $('#gzoomlbox-con-imgdata').hide();
            $('#zoomedimage').hide();
            $('#gzoomloading').show();
            // Image preload process
            var objImagePreloader = new Image();
            if (!swapped) {
                var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
            } else {
                var hiSrc = ig.attr("src").replace(settings.re, settings.replace);
            }
            objImagePreloader.onload = function() {
                $('#zoomedimage').attr('src', hiSrc);
                resize_fx(objImagePreloader.width, objImagePreloader.height);
            };
            objImagePreloader.src = hiSrc;
        };

        function _show_image() {
            $('#gzoomloading').hide();
            $('#zoomedimage').fadeIn(function() {
                _show_image_data();
            });
        };

        /**
        * Show the image information
        *
        */
        function _show_image_data() {
            $('#lightbox-loading').hide();
            $('#gzoom-image-caption').html(ig.attr('title'));
            $('#gzoomlbox-con-imgdata').slideDown('fast');
        }

        function close() {
            $('#gzoomlbox').remove();
            $('#gzoomoverlay').fadeOut(function() { $('#gzoomoverlay').remove(); });
            $('embed, object, select').css({ 'visibility': 'visible' });
        }

        function ___pause(ms) {
            var date = new Date();
            curDate = null;
            do { var curDate = new Date(); }
            while (curDate - date < ms);
        };

    });

};
