/**
* jQuery fancyzoom plugin.
* This is an adaptation of the fancyzoom effect as a jQuery plugin
*
* Author: Mathieu Vilaplana <mvilaplana@df-e.com>
* Date: March 2008
* rev 1.0
* rev: 1.1
* Add title if alt in the img
* rev 1.2
* Correction of the image dimension and close button on top right of the image
* rev 1.3
* now fancyzoom can be apply on an image, no need any more link wrapper
* rev 1.4 correct the bug for the overlay in ie6
* rev 1.6 (09/2009), lot of impovement, now image get out of its context.
*/
(function($) {

        $.fn.fancyzoom = function(userOptions) {
                //the var to the image box div
                 var oOverlay = $('<div>').css({
                        height: '100%',
                        width: '100%',
                           position:'fixed',
                           zIndex:100,
                        left: 0,
                        top: 0,
                        cursor:"wait"
                });

                function openZoomBox(imgSrc,o){
                        if(o.showoverlay) {
                                oOverlay
                                        .appendTo('body')
                                        .click(function(){closeZoomBox(o);});
                                if( $.browser.msie && $.browser.version < 7 ){
                                        oOverlay.css({position:'absolute',height:$(document).height(),width:$(document).width()});
                                }
                        }
                        var oImgZoomBox = o.oImgZoomBox;

            //calculate the start point of the animation, it start from the image of the element clicked
            pos=imgSrc.offset();
                        o=$.extend(o,{imgSrc:imgSrc,dimOri:{width:imgSrc.outerWidth(),height:imgSrc.outerHeight(),left:pos.left,top:pos.top,'opacity':1}});
                        if(!imgSrc.is('img')){
                                o.dimOri = $.extend(o.dimOri,{width:0,height:0});
                        }

                        //calculate the end point of the animaton
                        oImgZoomBox.css({'text-align':'center','border':'0px solid red'}).appendTo('body');
                        var iWidth = oImgZoomBox.outerWidth();
                        var iHeight = oImgZoomBox.outerHeight();

                        //the target is in the center without the extra margin du to close Image
                        dimBoxTarget=$.extend({},{width:iWidth,height:iHeight,'opacity':1}, __posCenter((iWidth),(iHeight+30)));

            //place the close button at the right of the zoomed Image
            o.oImgClose.css({left:(dimBoxTarget.left+dimBoxTarget.width-15),top:(dimBoxTarget.top-15)});

            var $fctEnd = function(){
                    //end of open, show the shadow
                    if($.fn.shadow && o.shadow && !$.browser.msie){ $('img:first',oImgZoomBox).shadow(o.shadowOpts);}
                                if(o.Speed>0 && !$.browser.msie) {o.oImgClose.fadeIn('slow');$('div',oImgZoomBox).fadeIn('slow');}
                                else {o.oImgClose.show();$('div',oImgZoomBox).show();}
            };


            $('div',oImgZoomBox).hide();//cache le titre
            //cache l'image source
            if(o.imgSrc.is('img')){o.imgSrc.css({'opacity':0});}
            var oImgDisplay = $('img:first', oImgZoomBox).css({'width':'100%','height':'auto'});
                          if(o.Speed > 0) {
                                  oImgZoomBox.css(o.dimOri).animate(dimBoxTarget,o.Speed,$fctEnd);
                          }
                          else {
                                  oImgZoomBox.css(dimBoxTarget);
                                  $fctEnd();
                          }
                  }//end openZoomBox

                   /**
                    * First hide the closeBtn, then remove the ZoomBox and the overlay
                    * Animate if Speed > 0
                    */
                   function closeZoomBox(o){
                           var oImgZoomBox = o.oImgZoomBox;
                          o.oImgClose.remove();
                          $('div',oImgZoomBox).remove();
                          var endClose = function(){
                                  oImgZoomBox.empty().remove();
                                  o.imgSrc.css('opacity',1);
                          };
                          if(o.Speed > 0){
                                  var pos = oImgZoomBox.offset();
                                  var iPercent = 0.15;
                                  var oDimPlus = {
                                          width:(oImgZoomBox.width()*(1+iPercent)),
                                          height:(oImgZoomBox.height()*(1+iPercent)),
                                          left:(pos.left-(oImgZoomBox.width()*(iPercent/2))),
                                          top:(pos.top-(oImgZoomBox.height()*(iPercent/2)))
                                  };
                                  oImgZoomBox.animate(oDimPlus,o.Speed*0.2,function(){
                                          oImgZoomBox.animate(o.dimOri,o.Speed,function(){endClose();});
                                        if(o.showoverlay) {oOverlay.animate({'opacity':0},o.Speed,function(){$(this).remove();});}
                                  });
                          }else {
                                 endClose();
                                if(o.showoverlay) {oOverlay.remove();}
                          }
                   }

                /**
                 * The plugin chain.
                 */
                   return this.each(function() {
                           var $this = $(this);
                           var imgTarget = $this.is('img')?$this:($('img:first',$this).length==0)?$this:$('img:first',$this);
                           var imgTargetSrc=null;
                           if($this.attr('href')) {imgTargetSrc = $this.attr('href');}
                         var oImgClose = $('<img class="jqfancyzoomclosebox">').css({position:'absolute',top:0,left:0,cursor:'pointer'});

                        // build main options before element iteration
                    var opts = $.extend({},$.fn.fancyzoom.defaultsOptions, userOptions||{},{dimOri:{},
                            oImgZoomBoxProp:{position:'absolute',left:0,top:0},
                            oImgClose:oImgClose
                    });

                        if(imgTarget.is('img')){
                            var oImgHover = $("<img src='"+opts.imgDir+"zoom.png'>").css({position:'absolute',top:0,left:0});
                                imgTarget.hover(function(){
                                        if(imgTarget.css('opacity') != 0){
                                                //oImgHover.appendTo(imgTarget.parent()).hide();
                                                var pos = imgTarget.position();
                                                var marginLeft = parseInt(imgTarget.css('margin-left').replace(/px/,''));
                                                var marginTop = parseInt(imgTarget.css('margin-top').replace(/px/,''));
                                                marginTop = (marginTop)?marginTop:0;
                                                marginLeft = (marginLeft)?marginLeft:0;
                                                //oImgHover.css({left:(pos.left+marginLeft-12),top:(pos.top+marginTop-12)}).show();
                                                if($.fn.ifixpng) {oImgHover.ifixpng(opts.imgDir+'blank.gif');}
                                        }
                                },function(){
                                        oImgHover.remove();
                                });
                        }

                           if($this.is('img')){
                                   imgTargetSrc = $this.css('cursor','pointer').attr('src');
                                   if(opts.imgResizeScript){
                                           if( imgTargetSrc.match(new RegExp("^"+opts.imgResizeScript,"g")) ){
                                                   imgTargetSrc=imgTargetSrc.replace(/.*img=([^&]*).*/gi,'$1');
                                           }
                                   }
                           }
                    oOverlay.css({
                                opacity: opts.overlay,
                                background:opts.overlayColor
                    });

                           //make action only on link that point to an image
                           if( !/\.jpg|\.jpeg|\.png|\.gif/i.test(imgTargetSrc) ){
                                   return true;
                           }

                           $this.click(function(){
                                   var zoomOpened = $('div.jqfancyzoombox');
                                   if( zoomOpened.length > 0  ){
                                           //if user click on an other image, cancel the previous loading
                                        if($('img:first',zoomOpened).attr('src') != imgTargetSrc){
                                                   if( oLoading && oLoading.is(':visible') ) {
                                                           __cancelLoading();
                                                   }
                                        }
                                           else {//solve the double click pb
                                                   return false;
                                           }
                                   }
                                   var o = $.extend({},opts,userOptions);
                                   var closeBtn = $("img.jqfancyzoomclosebox");
                                   if(closeBtn.length > 0){
                                           var imCurrent = $('img:first',zoomOpened);
                                           if(imgTargetSrc == imCurrent.attr('src')){
                                                //calculate the start point of the animation, it start from the image of the element clicked
                                                pos=imgTarget.offset();
                                                o=$.extend(
                                                                o,
                                                                {dimOri:{width:(imgTarget.outerWidth()),height:(imgTarget.outerHeight()),left:pos.left,top:(pos.top),'opacity':0}
                                                        });
                                                closeZoomBox(o);
                                                return false;
                                           }else {
                                                   //user click on an other image, close the first one
                                                   closeBtn.trigger('click');
                                                   //return false;
                                           }
                                   }

                                   //remove the overlay and Reset
                                  if(o.showoverlay && oOverlay) {oOverlay.empty().remove().css({'opacity':o.overlay});}
                                //reset the img close and fix png on it if plugin available
                                oImgClose.attr('src',o.imgDir+'closebox.png').appendTo('body').hide();
                                if($.fn.ifixpng) {$.ifixpng(o.imgDir+'blank.gif');oImgClose.ifixpng(o.imgDir+'blank.gif');}
                                oImgClose.unbind('click').click(function(){closeZoomBox(o);});

                                //reset zoom box prop and add image zoom with a margin top of 15px = imgclose height / 2
                                var oImgZoomBox=$('<div class="jqfancyzoombox"></div>').css(o.oImgZoomBoxProp);
                                o = $.extend(o,{oImgZoomBox:oImgZoomBox});

                                   var strTitle = imgTarget.attr('alt');
                                   if(strTitle){
                                           var oTitle = $('<div><center><table height=0 border="0" cellspacing=0 cellpadding=0><tr><td></td><td class="fancyTitle">'+strTitle+'</td><td></td></table></center></div>').css({marginTop:10,marginRight:15});

                                           var tdL = oTitle.find('td:first').css({'background':'url('+o.imgDir+'zoom-caption-l.png)',width:'13px',height:'26px'});
                                           var tdR = oTitle.find('td:last').css({'background':'url('+o.imgDir+'zoom-caption-r.png)',width:'13px',height:'26px'});
                                           var tdC = $('.fancyTitle',oTitle).css({'background':'url('+o.imgDir+'zoom-caption-fill.png)',
                                                           'padding':'0px 20px',
                                                           color:'#FFF',
                                                           'font-size':'14px'
                                                           });

                                           if($.fn.ifixpng){
                                                   tdL.ifixpng(o.imgDir+'blank.gif');
                                                   tdR.ifixpng(o.imgDir+'blank.gif');
                                                   tdC.ifixpng(o.imgDir+'blank.gif');
                                           }
                                           oTitle.appendTo(oImgZoomBox);
                                   }
                                   var oImgZoom=$('<img />').attr('src',imgTargetSrc).click(function(){closeZoomBox(o);}).prependTo(oImgZoomBox);
                                /** Manage zIndex **/
                                var imagezindex= opts.imagezindex;
                                oOverlay.css('zIndex', imagezindex-1);
                                oImgZoomBox.css('zIndex',imagezindex);
                                oImgClose.css('zIndex',(imagezindex+10));

                                //be shure that the image to display is loaded open the zoom box, if not display a loading Image.
                                   var imgPreload = new Image();
                                   imgPreload.src = imgTargetSrc;
                                   var $fctEndLoading = function(){
                                        if(bCancelLoading) {bCancelLoading=false;}
                                        else {
                                                if(__getFileName(imgPreload.src) == __getFileName($('img:first',oImgZoomBox).attr('src')) ){
                                                        fctCalculateImageSize(o.autoresize);
                                                        openZoomBox(imgTarget, o);
                                                        __stoploading();
                                                }
                                        }
                                   };
                                   var fctCalculateImageSize = function (autoresize) {
                                           //calcul de la taille de l'image
                                           if(autoresize){
                                                   var divCalculate = $('<div></div>').css({position:'absolute','top':0,'left':0,opacity:0,'border':'0px solid red'});
                                                   var bResize = false;
                                                   oImgZoom.appendTo(divCalculate);
                                                divCalculate.appendTo('body');
                                                imWidth = oImgZoom.width();
                                                imHeight = oImgZoom.height();
                                                maxWidth = $(window).width()*0.9;
                                                maxHeight = $(window).height()-100;
                                                if( maxHeight < imHeight ){
                                                        bResize = true;
                                                        oImgZoom.height(maxHeight);
                                                        imWidth= (imWidth*maxHeight)/imHeight;
                                                        oImgZoom.width(imWidth);
                                                        if( maxWidth < imWidth ){
                                                                oImgZoom.width(maxWidth);
                                                                oImgZoom.height(imHeight*maxWidth/imWidth);
                                                        }
                                                }else if( maxWidth < imWidth ){
                                                        bResize = true;
                                                        oImgZoom.width(maxWidth);
                                                        oImgZoom.height(imHeight*maxWidth/imWidth);
                                                }
                                                //because ie do not resize image correctly
                                                if( bResize && o.imgResizeScript /*&& $.browser.msie*/ ){
                                                        var tWidth = oImgZoom.width();
                                                        var tHeight = oImgZoom.height();
                                                        var finalWidth = tWidth;
                                                        var tabSizes = new Array(1440,1280,1024,800,640,480,360);
                                                        for(i=0;i<tabSizes.length;i++){
                                                                if(tWidth > tabSizes[i]){
                                                                        finalWidth = tabSizes[i];
                                                                        break;
                                                                }
                                                        }
                                                        oImgZoom.width(finalWidth);
                                                        oImgZoom.height(parseInt(tHeight*finalWidth/tWidth));

                                                        var args = "img="+encodeURI(oImgZoom.attr('src'));
                                                        args += "&width="+oImgZoom.width();
                                                        args += "&height="+oImgZoom.height();
                                                        oImgZoom.attr('src',o.imgResizeScript+"?"+args);
                                                }
                                                divCalculate.remove();
                                        }
                                           oImgZoom.prependTo(oImgZoomBox);
                                   };

                                   if(imgPreload.complete)        {
                                           fctCalculateImageSize(o.autoresize);
                                           openZoomBox(imgTarget, o);
                                           /*__displayLoading(imgPreload);
                                           setTimeout($fctEndLoading,4000);*/
                                   }
                                   else {
                                           __displayLoading(o);
                                           imgPreload.onload = function(){
                                                   //when loading is finish display the zoombox if user not click on cancel
                                                   $fctEndLoading();
                                           };
                                   }
                                   return false;
                           });
                   }
           );//end return this
    };//end Plugin


    //Default Options
    $.fn.fancyzoom.defaultsOptions = {
            overlayColor: '#000',
            overlay: 0.6,
            imagezindex:100,
            showoverlay:true,
            Speed:400,
            shadow:true,
            shadowOpts:{ color: "#000", offset: 4, opacity: 0.2 },
            imgDir:'ressources/',
            imgResizeScript:null,
            autoresize:true
          };

        function __posCenter(iWidth,iHeight){
                var iLeft = ($(window).width() - iWidth) / 2 + $(window).scrollLeft();
                var iTop = ($(window).height() - iHeight) / 2 + $(window).scrollTop();
                iLeft=(iLeft < 0)?0:iLeft;
                iTop=(iTop < 0)?0:iTop;
                          return {left:iLeft,top:iTop};
    }

    //
    // LOADING MANAGEMENT
    //
    var oLoading =null ;
        var bCancelLoading = false;
        var timerLoadingImg = null;
        function __displayLoading(o){
                if(!oLoading){
                        oLoading = $('<div></div>').css({width:50,height:50,position:'absolute','background':'transparent',
                        opacity:8/10,color:'#FFF',padding:'5px','font-size':'10px'});
                }
                oLoading.css(__posCenter(50,50)).html('<img src="'+o.imgDir+'blank.gif" />').click(function(){__cancelLoading();}).appendTo('body').show();
                timerLoadingImg=setTimeout(function(){__changeimageLoading(o);},400);
        }
        function __cancelLoading(){
                bCancelLoading=true;
                __stoploading();
        }
        function __stoploading(){
                oLoading.hide().remove();
                if(timerLoadingImg){
                        clearTimeout(timerLoadingImg);
                        timerLoadingImg=null;
                }
        }

        /**
         * Animate the png loading image.
         */
        function __changeimageLoading(o){
                if(oLoading && !oLoading.is(':visible')){
                        timerLoadingImg=null;
                        return;
                }

                var $im=$('img',oLoading);
                //First call im.src ="", set it to the fire png zoom spin
                if(!$im.attr('src') || /blank\.gif/.test($im.attr('src'))){
                        strImgSrc = o.imgDir+"zoom-spin-1.png";
                }
                //rotate the im src until 12
                else {
                        tab = $im.attr('src').split(/[- .]+/);
                        iImg = parseInt(tab[2]);
                        iImg = (iImg < 12)? (iImg+1):1;
                        strImgSrc= tab[0]+"-"+tab[1]+"-"+iImg+"."+tab[3];
                }
                var pLoad = new Image();
                pLoad.src=strImgSrc;
                var $fct = function (){

                        oLoading && oLoading.css(__posCenter(50,50));
                        $im.attr('src',strImgSrc);
                        timerLoadingImg = setTimeout(__changeimageLoading,100);
                };
                //to preserve bug if img not exist change it only if load complete.
                if(pLoad.complete){$fct();}
                else{pLoad.onload=$fct;}
        }

         function __getFileName(strPath){
                 if(!strPath) {return false;}
                var tabPath = strPath.split('/');
                return ((tabPath.length<1)?strPath:tabPath[(tabPath.length-1)]);
         }

})(jQuery);

$(function() {
        $.fn.fancyzoom.defaultsOptions.imgDir='/images/fancyzoom/'; //very important must finish with a /
        $('a.tozoom').fancyzoom({Speed:1000});
        //new rev > 1.2
        //apply fancyzoom effect on all image whose class is fancyzoom !!
        $('img.fancyzoom').fancyzoom();


});


