//////////////////////////////////////////////////////////////////////////////////
// Some fixes with 'inside' position and others
//////////////////////////////////////////////////////////////////////////////////
// Cloud Zoom V1.0.2
// (c) 2010 by R Cecco. <http://www.professorcloud.com>
// MIT License
//
// Please retain this copyright header in all versions of the software
//////////////////////////////////////////////////////////////////////////////////
(function ($) {
  
  $(document).ready(function () {
    $('.cloud-zoom, .cloud-zoom-gallery').CloudZoom();
  });

  function format(str) {
    for (var i = 1; i < arguments.length; i++) {
      str = str.replace('%' + (i - 1), arguments[i]);
    }
    return str;
  }

  function CloudZoom(jWin, opts) {
    var sImg = $('img', jWin);
    var	img1;
    var	img2;
    var zoomDiv = null;
    var	$mouseTrap = null;
    var	lens = null;
    var	$tint = null;
    var	softFocus = null;
    var	$ie6Fix = null;
    var	zoomImage;
    var controlTimer = 0;      
    var cw, ch;
    var destU = 0;
    var	destV = 0;
    var currV = 0;
    var currU = 0;      
    var mx,
        my; 
    var ctx = this, zw;
    
    var ie6FixRemove = function () {
      if ($ie6Fix !== null) {
        $ie6Fix.remove();
        $ie6Fix = null;
      }
    };

    // Removes cursor, tint layer, blur layer etc.
    this.removeBits = function () {
      //$mouseTrap.unbind();
      if (lens) {
        lens.remove();
        lens = null;             
      }
      if ($tint) {
        $tint.remove();
        $tint = null;
      }
      if (softFocus) {
        softFocus.remove();
        softFocus = null;
      }
      ie6FixRemove();
      $('.cloud-zoom-loading', jWin.parent()).remove();
    };

    this.destroy = function () {
      jWin.data('zoom', null);
      if ($mouseTrap) {
        $mouseTrap.unbind();
        $mouseTrap.remove();
        $mouseTrap = null;
      }
      if (zoomDiv) {
        zoomDiv.remove();
        zoomDiv = null;
      }
      //ie6FixRemove();
      this.removeBits();
      // DON'T FORGET TO REMOVE JQUERY 'DATA' VALUES
    };

    // This is called when the zoom window has faded out so it can be removed.
    this.fadedOut = function () {
      if (zoomDiv) {
        zoomDiv.remove();
        zoomDiv = null;
      }
      this.removeBits();
      //ie6FixRemove();
    };

    this.controlLoop = function () {
      if (lens) {
        var x = (mx - sImg.offset().left - (cw * 0.5)) >> 0;
        var y = (my - sImg.offset().top - (ch * 0.5)) >> 0;

        if (x < 0) {
          x = 0;
        } else if (x > (sImg.outerWidth() - cw)) {
          x = (sImg.outerWidth() - cw);
        }
        if (y < 0) {
          y = 0;
        } else if (y > (sImg.outerHeight() - ch)) {
          y = (sImg.outerHeight() - ch);
        }
        lens.css({
          left: x,
          top: y
        });
        lens.css('background-position', (-x) + 'px ' + (-y) + 'px');

        destU = (((x) / sImg.outerWidth()) * ctx.zoomImage.width) >> 0;
        destV = (((y) / sImg.outerHeight()) * ctx.zoomImage.height) >> 0;
        currU += opts.zoomWidth != 'auto' && ctx.zoomImage.width > opts.zoomWidth ? (destU - currU) / opts.smoothMove : 0;
        currV += opts.zoomHeight != 'auto' && ctx.zoomImage.height > opts.zoomHeight ? (destV - currV) / opts.smoothMove : 0;

        top_left = opts.zoomWidth != 'auto' && ctx.zoomImage.width > opts.zoomWidth ? (-(currU >> 0) + 'px ') : 'center ';
        bottom_right = opts.zoomHeight != 'auto' && ctx.zoomImage.height > opts.zoomHeight ? (-(currV >> 0) + 'px') : ' center';

        ctx.zoomDiv.css('background-position', top_left + bottom_right);              
        ctx.zoomDiv.css('background-repeat', 'no-repeat');
      }
      controlTimer = setTimeout(function () {
        ctx.controlLoop();
      }, 30);
    };

    this.init2 = function (img, id) {
      if (id === 1) {
        zoomImage = img;
        this.init();
      }
    };

    // Init function start.
    this.init = function () {
      // Add a box (mouseTrap) over the small image to trap mouse events.
      // It has priority over zoom window to avoid issues with inner zoom.
      // We need the dummy background image as IE does not trap mouse events on
      // transparent parts of a div.
      $mouseTrap = jWin.parent().append(format("<div class='mousetrap' style='background-image:url(\".\");z-index:999;position:absolute;width:%0px;height:%1px;left:%2px;top:%3px;\'></div>", 620, 450, 0, 0)).find(':last');
      $mouseTrap.css('cursor', "url(/cursors/zoomin.cur),url(/cursors/zoomin.cur),default");
      //////////////////////////////////////////////////////////////////////			
      /* Do as little as possible in mousemove event to prevent slowdown. */
      $mouseTrap.bind('mousemove', this, function (event) {
        // Just update the mouse position
        mx = event.pageX;
        my = event.pageY;
      });
      //////////////////////////////////////////////////////////////////////					
      $mouseTrap.bind('mouseleave', this, function (event) {
        clearTimeout(controlTimer);
        //event.data.removeBits();                
        if(lens) { lens.fadeOut(299); }
        if($tint) { $tint.fadeOut(299); }
        if(softFocus) { softFocus.fadeOut(299); }
        ctx.zoomDiv.fadeOut(300, function () {
          ctx.fadedOut();
          $("#cloud-zoom-big").remove();
        });
        $mouseTrap.css('cursor', "url(/cursors/zoomin.cur),url(/cursors/zoomin.cur),default");
        return false;
      });
      //////////////////////////////////////////////////////////////////////
      $mouseTrap.bind('mouseenter', this, function (event) {
        if (sImg.outerWidth() < opts.zoomWidth && sImg.outerHeight() < opts.zoomHeight) { $mouseTrap.css('cursor', "default"); }
      });
      //////////////////////////////////////////////////////////////////////			
      $mouseTrap.bind('mousedown', this, function (event) {
        
        
        if($(".cloud-zoom-lens").length == 0){
          
          img2 = new Image();
          $(img2).load(function () {
            ctx.zoomImage = this;
            //ctx.init2(this, 1);
            // Remove loading message (if present);
            ctx.zoomDiv = appendTo.append(format('<div id="cloud-zoom-big" class="cloud-zoom-big" style="display:none;position:absolute;left:%0px;top:%1px;width:%2px;height:%3px;background-image:url(\'%4\');z-index:99;"></div>', xPos, yPos, w, h, ctx.zoomImage.src)).find(':last');
            // Add the title from title tag.
            if (sImg.attr('title') && ctx.opts.showTitle) {
              ctx.zoomDiv.append(format('<div class="cloud-zoom-title">%0</div>', sImg.attr('title'))).find(':last').css('opacity', ctx.opts.titleOpacity);
            }
    
            // Fix ie6 select elements wrong z-index bug. Placing an iFrame over the select element solves the issue...		
            if ($.browser.msie && $.browser.version < 7) {
              $ie6Fix = $('<iframe frameborder="0" src="#"></iframe>').css({
                position: "absolute",
                left: xPos,
                top: yPos,
                zIndex: 99,
                width: w,
                height: h
              }).insertBefore(ctx.zoomDiv);
            }
    
            ctx.zoomDiv.fadeIn(500);
            
            cw = (sImg.outerWidth() / ctx.zoomImage.width) * ctx.zoomDiv.width();
            ch = (sImg.outerHeight() / ctx.zoomImage.height) * ctx.zoomDiv.height();
    
            // Attach mouse, initially invisible to prevent first frame glitch
            lens = jWin.append(format("<div class = 'cloud-zoom-lens' style='display:none;z-index:98;position:absolute;width:%0px;height:%1px;'></div>", cw, ch)).find(':last');
            $mouseTrap.css('cursor', lens.css('cursor'));
            if (!noTrans) { lens.css('opacity', opts.lensOpacity); }
            if (opts.position !== 'inside') { lens.fadeIn(500); }
            
            $('.cloud-zoom-loading', jWin.parent()).remove();
            // zoomImage = this;
          });
          
          if (sImg.outerWidth() < opts.zoomWidth && sImg.outerHeight() < opts.zoomHeight) { return false; }
          img2.src = jWin.attr('big');
          
          var w = jWin.width();
          jWin.parent().append(format('<div style="width:%0px;position:absolute;top:75%;left:%1px;text-align:center" class="cloud-zoom-loading" >Carregando...</div>', w / 3, (w / 2) - (w / 6))).find(':last').css('opacity', 0.5);
          
          mx = event.pageX;
          my = event.pageY;
          zw = event.data;
          if (zoomDiv) {
            zoomDiv.stop(true, false);
            zoomDiv.remove();
          }
  
          var xPos = opts.adjustX,
          yPos = opts.adjustY;
  
          var siw = sImg.outerWidth();
          var sih = sImg.outerHeight();
  
          var w = opts.zoomWidth;
          var h = opts.zoomHeight;
          if (opts.zoomWidth == 'auto') { w = siw; }
          if (opts.zoomHeight == 'auto') { h = sih; }
          //console.info( xPos + ' ' + yPos + ' ' + siw + ' ' + sih + ' ' + w + ' ' + h );
          var appendTo = jWin.parent(); // attach to the wrapper			
          switch (opts.position) {
            case 'top':
              yPos -= h; // + opts.adjustY;
              break;
            case 'right':
              xPos += siw; // + opts.adjustX;					
              break;
            case 'bottom':
              yPos += sih; // + opts.adjustY;
              break;
            case 'left':
              xPos -= w; // + opts.adjustX;					
              break;
            case 'inside':
              break;
              // All other values, try and find an id in the dom to attach to.
            default:
              appendTo = $('#' + opts.position);
              // If dom element doesn't exit, just use 'right' position as default.
              if (!appendTo.length) {
                appendTo = jWin;
                xPos += siw; //+ opts.adjustX;
                yPos += sih; // + opts.adjustY;	
              } else {
                w = appendTo.innerWidth();
                h = appendTo.innerHeight();
              }
          }
  
          if (lens) {
            lens.remove();
            lens = null;
          } // Work out size of cursor
  
          var noTrans = false;
  
          // Init tint layer if needed. (Not relevant if using inside mode)			
          if (opts.tint) {
            lens.css('background', 'url("' + sImg.attr('src') + '")');
            $tint = jWin.append(format('<div style="display:none;position:absolute; left:0px; top:0px; width:%0px; height:%1px; background-color:%2;" />', sImg.outerWidth(), sImg.outerHeight(), opts.tint)).find(':last');
            $tint.css('opacity', opts.tintOpacity);                    
            noTrans = true;
            $tint.fadeIn(500);
          }
          if (opts.softFocus) {
            lens.css('background', 'url("' + sImg.attr('src') + '")');
            softFocus = jWin.append(format('<div style="position:absolute;display:none;top:2px; left:2px; width:%0px; height:%1px;" />', sImg.outerWidth() - 2, sImg.outerHeight() - 2, opts.tint)).find(':last');
            softFocus.css('background', 'url("' + sImg.attr('src') + '")');
            softFocus.css('opacity', 0.5);
            noTrans = true;
            softFocus.fadeIn(500);
          }
          // Start processing. 
          zw.controlLoop();
          return; // Don't return false here otherwise opera will not detect change of the mouse pointer type.
        }
      });
    };

    img1 = new Image();
    $(img1).load(function () {
      ctx.init();
    });
    img1.src = sImg.attr('src');
  }

  $.fn.CloudZoom = function (options) {
    // IE6 background image flicker fix
    try {
      document.execCommand("BackgroundImageCache", false, true);
    } catch (e) {}
    this.each(function () {
      var relOpts, opts;
      // Hmm...eval...slap on wrist.
      eval('var	a = {' + $(this).attr('rel') + '}');
      relOpts = a;
      if ($(this).is('.cloud-zoom')) {
        $(this).css({
          'position': 'relative'
        });
        $('img', $(this)).css({
          'display': 'inline-block'
        });
        // Wrap an outer div around the link so we can attach things without them becoming part of the link.
        // But not if wrap already exists.
        if ($(this).parent().attr('id') != 'wrap') {
          $(this).wrap('<div id="wrap" style="top:0px;z-index:9999;position:relative;"></div>');
        }
        opts = $.extend({}, $.fn.CloudZoom.defaults, options);
        opts = $.extend({}, opts, relOpts);
        $(this).data('zoom', new CloudZoom($(this), opts));
      } else if ($(this).is('.cloud-zoom-gallery')) {
        opts = $.extend({}, relOpts, options);
        $(this).data('relOpts', opts);
        $(this).bind('click', $(this), function (event) {
          var data = event.data.data('relOpts');
          // Destroy the previous zoom
          $('#' + data.useZoom).data('zoom').destroy();
          // Change the biglink to point to the new big image.
          $('#' + data.useZoom).attr('href', event.data.attr('href'));
          // Change the small image to point to the new small image.
          $('#' + data.useZoom + ' img').attr('src', event.data.data('relOpts').smallImage);
          // Init a new zoom with the new images.				
          $('#' + event.data.data('relOpts').useZoom).CloudZoom();
          return false;
        });
      }
    });
    return this;
  };

  $.fn.CloudZoom.defaults = {
    zoomWidth: 'auto',
    zoomHeight: 'auto',
    position: 'right',
    tint: false,
    tintOpacity: 0.5,
    lensOpacity: 0.5,
    softFocus: false,
    smoothMove: 3,
    showTitle: true,
    titleOpacity: 0.5,
    adjustX: 0,
    adjustY: 0
  };

})(jQuery);

