(function($){
$.fn.fancyZoom = function(options) {

  var options   = options || {};
  var directory = options && options.directory ? options.directory : 'images';
  var zooming  = false;
  var disabled_opacity = options.disabled_opacity || 0.3;
  var speed = options.speed || 250;
  var click_exit = options.click_exit || true;
  
  var zoom = '#zoom';
  var zoom_container = '#zoom-container';
  var zoom_close = '#zoom-close';
  var zoom_content = '#zoom-content';
  var zoom_cover = '#zoom-cover';

  if ($(zoom).length == 0) {
    var ext = $.browser.msie ? 'gif' : 'png';
    var html = '<div id="zoom-cover" style="display:none;position:absolute;width:100%;height:100%;left:0;top:0;background:#000;"></div> \
                     <div id="zoom" style="display:none;z-index:999;"> \
                       <div id="zoom-container"> \
                         <div class="top" style="background:url(' + directory + '/tm.' + ext + ') 0 0 repeat-x; height:20px;overflow:visible;margin:0 20px;clear:both;"> \
                           <div class="tl" style="background:url(' + directory + '/tl.' + ext + ') 0 0 no-repeat; width:20px; height:20px; overflow:hidden;float:left;margin-left:-20px;"></div> \
                           <div class="tr" style="background:url(' + directory + '/tr.' + ext + ') 100% 0 no-repeat; width:20px; height:20px; overflow:hidden;float:right;margin-right:-20px;"></div> \
                         </div> \
                         <div class="middle" style="background-color:#fff;vertical-align:top;overflow:visible;margin:0 20px;clear:both;"> \
                            <div class="ml" style="background:url(' + directory + '/ml.' + ext + ') 0 0 repeat-y; overflow:visible;margin-left:-20px;"> \
                              <div class="mr" style="background:url(' + directory + '/mr.' + ext + ') 100% 0 repeat-y; overflow:hidden;margin-right:-20px;"> \
                                <div id="zoom-content" style="margin:10px 30px;overflow:hidden;"> </div> \
                              </div> \
                            </div> \
                         </div> \
                         <div class="bottom" style="background:url(' + directory + '/bm.' + ext + ') 0 100% repeat-x; height:20px;overflow:visible;margin:0 20px;clear:both;"> \
                           <div class="bl" style="background:url(' + directory + '/bl.' + ext + ') 0 100% no-repeat; width:20px; height:20px; overflow:hidden;float:left;margin-left:-20px;"></div> \
                           <div class="br" style="background:url(' + directory + '/br.' + ext + ') 100% 100% no-repeat; width:20px; height:20px; overflow:hidden;float:right;margin-right:-20px;"></div> \
                         </div> \
                       </div> \
                  <a href="#" title="Close" id="zoom-close" style="position:absolute; top:0; left:0;"> \
                    <img src="' + directory + '/closebox.' + ext + '" alt="Close" style="border:none; margin:0; padding:0;" /> \
                  </a> \
                </div>';

    $('body').append(html);

    if (click_exit) {
      $('html').click(function(e) {
        if ($(e.target).parents(zoom+':visible').length == 0) {
          hide();
        }
      });
    }
    
    $(document).keyup(function(event){
        if (event.keyCode == 27 && $(zoom+':visible').length > 0) {
          hide();
        }
    });

    $(zoom_close).click(hide);
  }

  this.each(function(i) {
    $($(this).attr('href')).hide();
    $(this).click(show);
  });

  return this;

  function show(e) {
    if (zooming) {
      return false;
    }
    
    var zooming = true;
    var content_div = $($(this).attr('href'));
    var zoom_width  = options.width;
    var zoom_height = options.height;

    var width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
    var height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
    var x = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);
    var y = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);
    var window_size = {'width': width, 'height': height, 'x': x, 'y': y}
    
    var width = (zoom_width || content_div.width());
    var height = (zoom_height || content_div.height()+30);
    var d = window_size;
    
    // ensure that newTop is at least 0 so it doesn't hide close button
    var newTop = Math.max((d.height/2) - (height/2) + y, 0) - 30;
    var newLeft = (d.width/2) - (width/2);
    var curTop = e.pageY;
    var curLeft = e.pageX;
    
    $(zoom_close).attr('curTop', curTop);
    $(zoom_close).attr('curLeft', curLeft);
    $(zoom_close).attr('scaleImg', options.scaleImg ? 'true' : 'false');

    $(zoom).hide().css({
      position: 'absolute',
      top: curTop + 'px',
      left: curLeft + 'px',
      width: '1px'// for webkit
    });
    
    $(zoom_content).hide().css({
      width: '1px',
      height: '1px'
    });

    fixBackgroundsForIE();
    $(zoom_close).hide();

    if (options.closeOnClick) {
      $(zoom).click(hide);
    }

    if (options.scaleImg) {
      $(zoom_content).html(content_div.html());
      $(zoom_content+' img').css('width', '100%');
    } else {
      $(zoom_content).html('');
    }
	
    $(zoom).animate({
      top: newTop + 'px',
      left: newLeft + 'px',
      opacity: 'show',
      width: width,// for webkit
    }, speed, null, function() {
      if (options.scaleImg != true) {
        $(zoom_content).html(content_div.html());
      }
      unfixBackgroundsForIE();
      $(zoom_close).show();
      zooming = false;
    });
    
    $(zoom_content).animate({
      width: width-60,
      height: height-30,
      opacity: 'show'
    }, speed);
    
    if (options.disable_behind) {
      $(zoom_cover).css('opacity', 0);
      $(zoom_cover).show();
      $(zoom_cover).animate({opacity: disabled_opacity}, 300);
    }
    
    return false;
  }

  function hide() {
    if (zooming) {
      return false;
    }
    var zooming = true;
    $(zoom).unbind('click');
    fixBackgroundsForIE();
    if ($(zoom_close).attr('scaleImg') != 'true') {
      $(zoom_content).html('');
    }
    $(zoom_close).hide();
    $(zoom).animate({
      top: $(zoom_close).attr('curTop') + 'px',
      left: $(zoom_close).attr('curLeft') + 'px',
      width: '1px',// for webkit
      opacity: "hide"
    }, speed, null, function() {
      if ($(zoom_close).attr('scaleImg') == 'true') {
        $(zoom_content).html('');
      }
      unfixBackgroundsForIE();
      zooming = false;
    });
    $(zoom_content).animate({
      width: '1px',
      height: '1px',
      opacity: 'hide'
    }, speed);
    
    if (options.disable_behind) {
      $(zoom_cover).animate({opacity: 0}, 300, function() {
        $(zoom_cover).hide();
      });
    }
    
    return false;
  }

  function switchBackgroundImagesTo(to) {
    $(zoom_container+' div').each(function(i) {
      var bg = $(this).css('background-image').replace(/\.(png|gif|none)\"\)$/, '.' + to + '")');
      $(this).css('background-image', bg);
    });
    var close_img = $(zoom_close).children('img');
    var new_img = close_img.attr('src').replace(/\.(png|gif|none)$/, '.' + to);
    close_img.attr('src', new_img);
  }

  function fixBackgroundsForIE() {
    if ($.browser.msie && parseFloat($.browser.version) >= 7) {
      switchBackgroundImagesTo('gif');
    }
  }

  function unfixBackgroundsForIE() {
    if ($.browser.msie && $.browser.version >= 7) {
      switchBackgroundImagesTo('png');
    }
  }
}
})(jQuery);
