/*!
 * 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: "loading...",  // 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
    }, 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'
            });
        }
		
        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.sW-42)+'px'
            });
        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);
        };
		
    });
	
};
