(function($){
  
$.fn.identify = function(prefix) {
    var i = 0;
    return this.each(function() {
        if($(this).attr('id')) return;
        do { 
            i++;
            var id = prefix + '_' + i;
        } while(document.getElementById(id) != null);            
        $(this).attr('id', id);            
    });
};

$.fn.enlarge = function(options){
  var options = $.extend({}, $.fn.enlarge.defaults, options);
  var directory = options && options.directory ? options.directory : 'images';
  var zooming = false;
  
  if ($('#zoom').length == 0) {
    setupWrapper();
  }

  var zoom          = $('#zoom');
  var zoom_table    = $('#zoom_table');
  var zoom_close    = $('#zoom_close');
  var zoom_content  = $('#zoom_content');
  var middle_row    = $('td.ml,td.mm,td.mr');
  
  this.each(function() {
    $(this).load(imageLoaded);
    if ($.browser.msie) {
      $(this).trigger('load');
    }
    
    if (options.rotate) {
      initRotation(this);
    }
    
    $(this).hover(grow, shrink);
    
    if (options.clickToEnlarge) {
      $(this).click(show);
    }
  });
  
  return this;
  
  function initRotation(el) {
    var rot = $(el).attr('class').match(/rotate([-]*\d+)/);
    if (rot) {
      rot = rot[1];
    } else {
      rot = 0;
    }
    $(el).data('oRot', rot);
    $(el).transform({rotate: rot+'deg'});
  }
  
  function imageLoaded(e) {
    var w = $(this).width();
    var h = $(this).height();
    $(this).data('w', w);
    $(this).data('h', h);
    $(this).data('pos', $(this).position());
    $(this).css({position:'absolute'});
    if ($(this).hasClass('extra')) {
      $(this).hide().css({visibility:'visible'}); // hack
    }
  }
  
  function grow(e) {
    if ($('#zoom').is(':visible')) return;
    
    var w = $(this).data('w'), h = $(this).data('h');
    var size = options.size;

    var pos = $(this).data('pos');
    var newleft = pos.left - size;
    var newtop = pos.top - size;
    var growStyles = {
      left: newleft + 'px',
      top: newtop + 'px',
      width: w + (2 * size) + 'px',
      height: h + (2 * size)  + 'px'
    }

    if (options.rotate) {
      growStyles['rotate'] = 0;
    }
    
    $(this).stop(true, true).animate(growStyles, 500, null, function() { 
      if ($.fn.dumbCrossFade) {
        
      }
    }).parent().css({'z-index':options.zIndex});

  }
  
  function shrink(e) {
    if ($(this).is(':visible')) {
      $.fx.off = false;
      var pos = $(this).data('pos');
      var shrinkStyles = {
        top: pos.top,
        left: pos.left,
        width: $(this).data('w')+'px',
        height: $(this).data('h')+'px'
      }
      if (options.rotate) {
        shrinkStyles['rotate'] = $(this).data('oRot');
      }
      $(this).stop(true, true).animate(shrinkStyles, 500).parent().css({'z-index':(options.zIndex-1)});
    }
  }
  
  function show(e) {
    if ($('#zoom').is(':visible')) return;
    if (zooming) return false;
		zooming         = true;
		var img         = $(this);
  	var zoom_width  = options.width;
		var zoom_height = options.height;

		var w_width     = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
  	var w_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':w_width, 'height':w_height, 'x':x, 'y':y}

    var ratio       = (img.data('w') / img.data('h'));

    if (zoom_width) {
      var width     = (zoom_width) + 60;
      var height    = (zoom_width / ratio) + 60;
    } else if (zoom_height) {
      var height    = (zoom_height) + 60;
      var width     = (ratio * zoom_height) + 60;
    }
  
		var d           = window_size;
		var newTop      = Math.max((d.height/2) - (height/2) + y, 0); // no less than 0
		var newLeft     = (d.width/2) - (width/2);
		                
		var pos         = img.offset();

		var curTop      = pos.top;//e.pageY;
		var curLeft     = pos.left;//e.pageX;
		
		zoom_close.data('curTop', curTop);
		zoom_close.data('curLeft', curLeft);
		
    // set up zoom to the right size and get ready to display
    $('#zoom').hide().css({
			position	: 'absolute',
			top				: (curTop - 30) + 'px',
			left			: (curLeft - 30) + 'px',
			width     : img.width() + 60,
			height    : img.height() + 60,
			'z-index' : options.zIndex
		});
		
		if (options.rotate && !$.browser.msie) {
		  $('#zoom').transform({'rotate':0});
		}

    if (!$(this).attr('id')) {
      $(this).identify('zoomSrc');
    }
    
    zoom_close.data('sourceImg', $(this).attr('id'));

    fixBackgroundsForIE();
    zoom_close.hide();

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

    zoom_content.html('');
  	$(this).clone(false).removeClass('enlarge').css({top:0,left:0, position:'relative'}).appendTo(zoom_content);
  	
		$('#zoom_content img').transform({scale:1}).css({ width: '100%', 'height':'auto'});		
		
		$('#zoom').show();
		
    $('#zoom').animate({
      top     : newTop + 'px',
      left    : newLeft + 'px',
      width   : width,
      height  : height
    }, 500, null, function() {
			zoom_close.show();
			zooming = false;
    })
    
    hideSelectedSourceImage(img);
        
    return false;
  }

  function hide() {    
    if (zooming) return false;
		zooming         = true;
	  $('#zoom').unbind('click');
		fixBackgroundsForIE();
		zoom_close.hide();
		
		var id = '#'+zoom_close.data('sourceImg');

    var origin = {
      top     : zoom_close.data('curTop') - 30 + options.size + 'px',
      left    : zoom_close.data('curLeft') - 30 + options.size + 'px',
      width   : $(id).data('w')+60+'px',
      height  : $(id).data('h')+60+'px'
    };
    
    
		if (options.rotate && !$.browser.msie) {
      origin['rotate'] = $(id).data('oRot');
		}
    
		$('#zoom').animate(origin, 500, null, function() {
      showPreviouslySelectedSource();
      $('td.mm').css({'background-color':'transparent'});
      $('#zoom').animate({opacity:'hide'},500,null,function() {
        zoom_content.html('');
        $('td.mm').css({'background-color':'#fff'});
      });
      unfixBackgroundsForIE();
			zooming = false;
    });

    
    return false;
  }
  
  function hideSelectedSourceImage(img) {
    img.stop().hide();
  }
  
  function showPreviouslySelectedSource() {
    var id = '#'+zoom_close.data('sourceImg');

    $(id).css({
      top     : $(id).data('pos').top,
      left    : $(id).data('pos').left,
      width   : $(id).data('w')+'px',
      height  : $(id).data('h')+'px',
    });
          
    if (options.rotate) {
      $(id).transform({
        rotate  : $(id).data('oRot')
      });
    }
    
    $(id).show();
  }
  
  function switchBackgroundImagesTo(to) {
    $('#zoom_table td').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');
    }
	}
	
	function setupWrapper()
  {
    var ext = $.browser.msie ? 'gif' : 'png';
    var html = '<div id="zoom" style="display:none;"> \
                  <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>';

    $('body').append(html);
    $('html').click(function(e) {
      if ($('#zoom:visible').length > 0) {
        hide();
      }
    });
    
    $(document).keyup(function(event){
        if (event.keyCode == 27 && $('#zoom:visible').length > 0) hide();
    });

    $('#zoom_close').click(hide);
  }
  
  
}

$.fn.enlarge.defaults = { clickToEnlarge: true, rotate: false, size: 10, zIndex: 100 };

})(jQuery);

/*
jQuery(function($)
{	
	
	var zindexnr = 1;
	var focusedElement = false;
	var isMoving = false;
	
	$("img.enlarge").each(function() {
	  var rot = $(this).attr('class').match(/rotate([-]*\d+)/)[1];
	  $(this).data('oRot', rot);
    $(this).data('oPos', $(this).position());
    $(this).transform({rotate: rot});

    var oWidth = $(this).width();
    var oHeight = $(this).height();
    //var mpx = (oWidth / oHeight);

    var mpx = 1.5;
    var centerAdjust = ((oWidth * mpx) - oWidth) / 2;
    
    $(this).hover(function(){
      if (focusedElement || $(this).data('isFocused')) return;
      zindexnr++;
      $(this).stop().animate({
        scale: mpx,
        rotate: '0',
        marginLeft: '-' + centerAdjust + 'px'
      },1000).css({'z-index':zindexnr});
    },
    function(){
      if (isMoving || $(this).data('isFocused')) return;
      $(this).stop().animate({
        scale: 1,
        marginLeft: 0,
        rotate: $(this).data('oRot')
      },1000);
    });
    
    $(this).click(function() {
      if (isMoving) return;
      if (focusedElement) {
        returnToHome(focusedElement);
        if (focusedElement == this) {
          return;
        }
      }
      isMoving = true;
      $(this).data('isFocused', true);
      $(this).stop().animate({
        top: '150px',
        left: '50%',
        rotate: 0,
        scale: 2,
        marginLeft: '-' + ((oWidth * mpx) / 2) + 'px',
      }, 1000, function() {
        isMoving = false, 
        focusedElement = $(this);
        $(this).data('isFocused', true);
      });
    });
	});
	
	function returnToHome(element) {
	  var oPos = element.data('oPos');
	  var oRot = element.data('oRot');
	  element.animate({
	    top: oPos.top,
	    left: oPos.left,
	    rotate: oRot,
	    scale: 1
	  }, 1000, function() { 
	    element.data('isFocused', false), focusedElement = false
	  });
	}
	
	$('body').click(function() {
	  if (focusedElement) {
	    returnToHome(focusedElement);
	  }
	})
});*/
