(function($, jQuery){

  // Konstruktor
  var _PanZoom = function (target, options){          
    this.target = target;         
    this.options = options;
        
    this.isInZoom = false;        
    this.closeHint = this.createCloseHint();
    this.image = this.createImage();
    this.imageContainerInner = this.createImageContainerInner();
    this.imageContainer = this.createImageContainer();
    this.overlayContainer = this.createOverlayContainer();
    this.attachToTarget();
  }
  
  // Methoden
  _PanZoom.prototype = {
       
    attachToTarget: function(){
                   
      this.target.bind('click.panzoom', jQuery.proxy(function(e){              
        this.zoomClickPageX = e.pageX;
        this.zoomClickPageY = e.pageY;
        this.execute();        
        e.preventDefault();   
        
      }, this));
      
      this.overlayContainer.bind('click', jQuery.proxy(function(e){                       
        this.detachPanZoom();
      }, this));
                  
      
    },
        
    execute: function(){
      this.overlayContainer.show();      
      this.attachPanZoom();
      this.loadImage();
      
    },
    
    loadImage: function(){
     if(this.options.onGetImageSrc)
       this.image.attr('src', this.options.onGetImageSrc);  
     else
       this.image.attr('src', this.target.attr('href')); 
    },
    
    attachPanZoom: function(){
      this.image.bind('load', jQuery.proxy(function(e){        
        this.imageContainer.show(); 
        this.closeHint.show(); 
        this.isInZoom = true;        
        this.beginPan();        
        
        $(window).bind('resize.panzoom', jQuery.proxy(function(e){                    
          if(this.isInZoom){
            this.image.unbind('mousemove'); 
            this.imageContainerInner.css({'top':'0', 'left':'0'});	
            this.beginPan();           
          }                     
        }, this));
        
      }, this)); 
    },
    
    detachPanZoom: function(){    
      this.closeHint.hide();
      this.overlayContainer.hide();       
      $(window).unbind('resize.panzoom');
      this.image.unbind('load');             
      this.image.attr('src', '');
    },
    
    
    beginPan : function(){      
      var margin_top = (this.imageContainer.height() - this.image.height()) / 2,
          margin_left = (this.imageContainer.width() - this.image.width()) / 2;
          
      this.image.css({
        'margin-top': margin_top + 'px',
        'margin-left': margin_left + 'px'
      });
      
      this.containerWidth = this.imageContainer.width();
      this.containerHeight = this.imageContainer.height();
	
      this.totalContentW = this.image.width();
      this.totalContentH = this.image.height();
	
      this.imageContainerInner.css({
        'width': this.totalContentW, 
        'height': this.totalContentH
      });
                       

      this.image.bind('mousemove', jQuery.proxy(function(e){
        this.mouseMove(e.pageX, e.pageY);									   
      }, this));
                              	      
      this.mouseMove(this.zoomClickPageX, this.zoomClickPageY);      
    },
    
    mouseMove: function(pageX, pageY){         
      var mouseCoordsX = (pageX - this.imageContainer.offset().left),
          mouseCoordsY =(pageY - this.imageContainer.offset().top),
          mousePercentX = mouseCoordsX / this.containerWidth,        
          mousePercentY = mouseCoordsY / this.containerHeight,

          destX =- (((this.totalContentW - (this.containerWidth)) - this.containerWidth) * (mousePercentX)),
          destY =- (((this.totalContentH - (this.containerHeight)) - this.containerHeight) * (mousePercentY)),
          thePosA = mouseCoordsX - destX,
          thePosB = destX - mouseCoordsX,
          thePosC = mouseCoordsY - destY,
          thePosD = destY - mouseCoordsY,

          marginL = this.image.css('marginLeft').replace('px', ''),
          marginT = this.image.css('marginTop').replace('px', '');
       
      if(mouseCoordsX > destX || mouseCoordsY > destY){
        // TODO: Jason
        this.imageContainerInner.css('left', -thePosA -marginL); 
        this.imageContainerInner.css('top', -thePosC -marginT); 		  
      } 
      else if(mouseCoordsX < destX || mouseCoordsY < destY){
       // TODO: Jason
        this.imageContainerInner.css('left', thePosB - marginL); 
        this.imageContainerInner.css('top', thePosD - marginT); 		  	
      } 
      else{
        this.imageContainerInner.stop();
      }           

      this.closeHint.css('left', pageX + 10 + 'px');
      this.closeHint.css('top', pageY + 10 + 'px');	        
    },
    
    createImage: function(){
      var container = $('<img />', {
            'class': 'panzoom-image'            
          });
      return container;    
    },
    
    createImageContainerInner: function(){
      var containerCss = {
            'position':'relative', 
            'left':'0'
          },
          container = $('<div />', {
            'class': 'panzoom-image-container-inner',
            'css': containerCss
          });
      
      container.append(this.image);
      return container; 
    },
    
    createImageContainer: function(){
      var containerCss = {
            'position':'absolute', 'left':'0', 'top':'0',
            'overflow':'hidden', 'height':'100%', 'width':'100%',
            'cursor': this.options.cursor 
          },
          container = $('<div />', {
            'class': 'panzoom-image-container',
            'css': containerCss
          });
         
      container.hide();   
      container.append(this.imageContainerInner);
      return container;
    },
    
    createOverlayContainer: function(){
       var targetPosition = this.target.offset(),
           uniqueId = [targetPosition.top, targetPosition.left].join('-'),           
           containerCss = {
             'position':'fixed', 'left':'0', 'top':'0',
             'height':'100%', 'width':'100%', 'overflow':'hidden', 
             'background': 'url("' + this.options.loader_img + '") '  
                + this.options.bgcolor + ' no-repeat scroll 50% 50%',
             'cursor': this.options.cursor,
             'z-index': '100'
           },           
           container = $('<div />', {
             'id': 'panzoom-container-' + uniqueId,
             'class': 'panzoom-container',
             'css':containerCss
           });
           
       container.hide();
       container.append(this.imageContainer);
       
       container.appendTo($("body"));       
       return container;       
    },
    
    createCloseHint: function(){
      var containerCss = {
            'position':'absolute',
            'z-index':'101',
            'font-size':'12px',
            'font-family':'arial',
            'color':'#777777'
          },
          container = $('<span />', {
            'class': 'panzoom-closehint',
            'css': containerCss
          }) 
      
      container.hide();
      container.text(this.options.close_hint)
      container.appendTo($('body'));       
      return container;
    }
    
    
    
    
  }
  
  
  jQuery.fn.panzoom = function(options){
  
    options = $.extend({}, jQuery.fn.panzoom.defaults, options);
    
    return this.each(function(){
    
      var pz = new _PanZoom($(this), options);                    
        
    });
    
  
  };
  
  

  // Standard-Optionen
  jQuery.fn.panzoom.defaults = {    
    bgcolor: "#fff",
    cursor: 'crosshair',
    loader_img: 'jquery.panzoom/images/loader.gif',
    close_hint: 'Klicken zum Schliessen'    
  }
  
  

})(jQuery, jQuery);

