jQuery.fn.fancyZoom = function(options){
  
  options   = options || {};
  options.width   = options.width ? options.width : 620;
  var directory = options && options.directory ? options.directory : '/images';
  var zooming   = false;

  if (jQuery('#zoom').length == 0) {
    var ext = jQuery.browser.msie && jQuery.browser.version.substr(0,1) < 7 ? 'gif' : 'png';
    var html = '<div id="zoom" style="display:none;z-index:10000;"> \
                  <table id="zoom_table" style="border-collapse:collapse; width:100%; height:100%;"> \
                    <tbody> \
                      <tr> \
                        <td class="tl" style="background:url(' + directory + '/tl.' + ext + ') 0 0 no-repeat; width:20px; height:20px; overflow:hidden;" /> \
                        <td class="tm" style="background:url(' + directory + '/tm.' + ext + ') 0 0 repeat-x; height:20px; overflow:hidden;" /> \
                        <td class="tr" style="background:url(' + directory + '/tr.' + ext + ') 100% 0 no-repeat; width:20px; height:20px; overflow:hidden;" /> \
                      </tr> \
                      <tr> \
                        <td class="ml" style="background:url(' + directory + '/ml.' + ext + ') 0 0 repeat-y; width:20px; overflow:hidden;" /> \
                        <td class="mm" style="background:#fff; vertical-align:top; padding:10px;"> \
                          <div id="zoom_content"> \
                          </div> \
                        </td> \
                        <td class="mr" style="background:url(' + directory + '/mr.' + ext + ') 100% 0 repeat-y;  width:20px; overflow:hidden;" /> \
                      </tr> \
                      <tr> \
                        <td class="bl" style="background:url(' + directory + '/bl.' + ext + ') 0 100% no-repeat; width:20px; height:20px; overflow:hidden;" /> \
                        <td class="bm" style="background:url(' + directory + '/bm.' + ext + ') 0 100% repeat-x; height:20px; overflow:hidden;" /> \
                        <td class="br" style="background:url(' + directory + '/br.' + ext + ') 100% 100% no-repeat; width:20px; height:20px; overflow:hidden;" /> \
                      </tr> \
                    </tbody> \
                  </table> \
                  <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>';
                
    jQuery('body').append(html);
    
    jQuery('html').click(function(e){
      if(jQuery(e.target).parents('#zoom:visible').length == 0) hide();
    });
    jQuery(document).keyup(function(event){
      if (event.keyCode == 27 && jQuery('#zoom:visible').length > 0) hide();
    });
    
    jQuery('#zoom_close').click(hide);
  }
  
  var zoom          = jQuery('#zoom');
  var zoom_table    = jQuery('#zoom_table');
  var zoom_close    = jQuery('#zoom_close');
  var zoom_content  = jQuery('#zoom_content');
  var middle_row    = jQuery('td.ml,td.mm,td.mr');
  
  this.each(function(i) {
    jQuery(jQuery(this).attr('href')).hide();
    jQuery(this).click(show);
  });
  
  return this;
  
  function show(e) {
    if (zooming) return false;
    zooming         = true;
    var content_div = jQuery(this);
    var zoom_width  = options.width;
    var zoom_height = options.height > 0 ? options.height : jQuery(window).height() - 60;
		
    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
    }

    width              = (zoom_width || content_div.width()) + 60;
    height             = (zoom_height || content_div.height()) + 60;
    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);
    var newLeft            = (d.width/2) - (width/2);
    //var curTop             = e.pageY;
    //var curLeft            = e.pageX;
    var curTop             = y;
    var curLeft            = x;
		
    zoom_close.attr('curTop', curTop);
    zoom_close.attr('curLeft', curLeft);
		
    jQuery('#zoom').hide().css({
      position	: 'absolute',
      top				: curTop + 'px',
      left			: curLeft + 'px',
      width     : '1px',
      height    : '1px'
    });
    
    fixBackgroundsForIE();
    zoom_close.hide();
    
    if (options.closeOnClick) {
      jQuery('#zoom').click(hide);
    }
    
    zoom_content.html('');
    
    jQuery('#zoom').animate({
      top     : newTop + 'px',
      left    : newLeft + 'px',
      opacity : "show",
      width   : width,
      height  : height
    }, 500, null, function() {
      zoom_content.html(getContentHtml(content_div));
      unfixBackgroundsForIE();
      zoom_close.show();
      zooming = false;
    })
    return false;
  }
  
  function hide() {
    if (zooming) return false;
    zooming         = true;
    jQuery('#zoom').unbind('click');
    fixBackgroundsForIE();
    zoom_content.html('');
    zoom_close.hide();
    jQuery('#zoom').animate({
      top     : zoom_close.attr('curTop') + 'px',
      left    : zoom_close.attr('curLeft') + 'px',
      opacity : "hide",
      width   : '1px',
      height  : '1px'
    }, 500, null, function() {
      unfixBackgroundsForIE();
      zooming = false;
    });
    return false;
  }
  
  function switchBackgroundImagesTo(to) {
    jQuery('#zoom_table td').each(function(i) {
      var bg = jQuery(this).css('background-image').replace(/\.(png|gif|none)\"\)jQuery/, '.' + to + '")');
      jQuery(this).css('background-image', bg);
    });
    var close_img = zoom_close.children('img');
    var new_img = close_img.attr('src').replace(/\.(png|gif|none)jQuery/, '.' + to);
    close_img.attr('src', new_img);
  }
  
  function fixBackgroundsForIE() {
    if (jQuery.browser.msie && parseFloat(jQuery.browser.version) >= 7) {
      switchBackgroundImagesTo('gif'); 
    }
  }
  
  function unfixBackgroundsForIE() {
    if (jQuery.browser.msie && jQuery.browser.version >= 7) {
      switchBackgroundImagesTo('png'); 
    }
  }

  function getContentHtml(content) {
    var height = options.height > 0 ? options.height : jQuery(window).height() - 60;
    if(!options.height) {
      jQuery(window).resize(function() {
        jQuery('#frameContentFz').css('height', (jQuery(window).height() - 60) + 'px');
        jQuery('#zoom').css('height', (jQuery(window).height() - 30) + 'px');
      });
      jQuery(window).scroll(function() {
        jQuery('#zoom').css('top', (jQuery(window).scrollTop()) + 'px');
      });
    }
    var html = '<iframe id="frameContentFz" src="'+content.attr('href')+'" style="border:none; margin:0px; padding:0px; width:'+options.width+'px; height:'+height+'px" width="'+options.width+'" height="'+options.height+'" align="middle" frameborder="0" border="0">';
    html += '</iframe>';
    return html;
  }
}
