jQuery.fn.fancyZoom = function(o){
    
    var zooming   = false
        , o   = o || {}
        directory = o && o.directory ? o.directory : 'images';
        
//    o.width  = 600;
//    o.height = 300;
    o.closeOnClick = true;        

    if (jQuery('#zoom').length == 0) {
        var html = '<div id="zoom"> \
                    <table id="zoom_table"><tbody> \
                        <tr><td class="tl"/><td class="tm"/><td class="tr"/></tr> \
                        <tr><td class="ml"/><td class="mm"> \
                            <div id="zoom_content"></div> \
                        </td><td class="mr"/></tr> \
                        <tr><td class="bl"/><td class="bm"/><td class="br"/></tr> \
                    </tbody></table> \
                  <a href="#" title="Close" id="zoom_close">&#160;</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')
       ,zoom_table    = jQuery('#zoom_table')
       ,zoom_close    = jQuery('#zoom_close')
       ,zoom_content  = jQuery('#zoom_content')
       ,middle_row    = jQuery('td.ml,td.mm,td.mr')
       ;
  
    this.each(function(i) {
        jQuery(jQuery(this).attr("href").replace(/[\/:.]/g, '')).hide();
        jQuery(this).click(show);
    });
  
    return this;
  
    function show(e) {
        if (zooming) return false;
        zooming = true;
        
        var itemId = jQuery(this).attr("href").replace(/[\/:.]/g, '')
            , content_div = jQuery('#' + itemId)
            , zoom_width  = o.width ? o.width : content_div.width()
            , zoom_height = o.height ? o.height : content_div.height();

        var width   = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth)
            , height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight)
            , x      = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft)
            , 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
            , height = zoom_height
            , d      = window_size;
            
        zoom_content.css({height: height})
            
        // 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)
            , newLeft = (d.width/2) - (width/2)
            , curTop  = e.pageY
            , curLeft = e.pageX;
        
        zoom_close.attr('curTop', curTop);
        zoom_close.attr('curLeft', curLeft);
        zoom_close.attr('scaleImg', o.scaleImg ? 'true' : 'false');
        
        jQuery('#zoom').hide().css({
            position : 'absolute',
            top      : curTop + 'px',
            left     : curLeft + 'px',
            width    : '1px',
            height   : '1px'
        });
    
        fixBackgroundsForIE();
        zoom_close.hide();
    
        if (o.closeOnClick) {
            jQuery('#zoom').click(hide);
        }
        
        if (o.scaleImg) {
            zoom_content.html(content_div.html());
            jQuery('#zoom_content img').css('width', '100%');
        } else {
            zoom_content.html('');
        }
    
        jQuery('#zoom').animate({
            top     : newTop + 'px',
            left    : newLeft + 'px',
            opacity : "show",
            width   : width,
            height  : height
        }, 500, null, function() {
            if (o.scaleImg != true) {
                zoom_content.html(content_div.html());
            }
            unfixBackgroundsForIE();
            zoom_close.show();
            zooming = false;
        })
        return false;
    }
  
    function hide() {
        if (zooming) return false;
        zooming = true;
        
        jQuery('#zoom').unbind('click');
        fixBackgroundsForIE();
        if (zoom_close.attr('scaleImg') != 'true') {
            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() {
            if (zoom_close.attr('scaleImg') == 'true') {
                zoom_content.html('');
            }
            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');

        if (close_img.attr('src')) {
        	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'); 
        }
    }
}