zoomImageConfigDefault = {
      delay: 0.5,
      triggerShow: 'mouseover',      
      triggerHide: 'mouseout',      
      pointerXOffset: 10,
      pointerYOffset: 10,
      preloader: 'image/loader.gif',
      template: 'zoom_image_template',
      templateResetStyle: {width: "50px", height: "50px"}
    }
    
    Element.addMethods('IMG', {   
    
      showImage: function(objSender, config)
      {                
        var template = config.template;        
        
        var tpl = $(template);        
        
        var imgContainer = tpl.select(".image_container")[0];
        var imgDescription = tpl.select(".image_description")[0];
        
        if (config.preloader != null)
        {
          imgContainer.setStyle(
          {
            background: "url('" + config.preloader + "') no-repeat center center"
          });
        }
                        
        var tag = '<img src="' + objSender.src +'" alt="" />';
        imgContainer.update(tag);
        imgDescription.update("");
        
        var img = new Element('img');
        img.src = config.image;
        
                
        new PeriodicalExecuter(function(pe){
          if (img.complete)
          {
            tpl.setStyle({zIndex: 100});
            tpl.show();
            imgContainer.update("");
            imgContainer.appendChild(img);
            objSender.writeAttribute("imgWidth", img.getWidth());
            
            var docWidth = document.viewport.getWidth();                            
            if (!docWidth && document.body) docWidth = document.body.clientWidth;
            var xOffset = Position.page(tpl)[0];
            
            var xCondition = xOffset + img.getWidth()  + config.pointerXOffset + 20;                            
            
            if (xCondition  > docWidth)
            {                           
              objSender.writeAttribute("imgOffset" , 1);
              var left = xOffset - img.getWidth() - 20;                            
              tpl.setStyle({
                left: left + "px"       
              })
            }
            
                        
            var w = img.getWidth() + "px";
            var h = img.getHeight() + imgDescription.getHeight() + "px";     
            tpl.setStyle({width: w});
            new Effect.Morph(tpl, {duration: 0.5, style: {height: h}});
                        
            pe.stop();
          }
        }, 0.1);
                    
            
        if (config.description && config.description!='')
        {
          imgDescription.show();
          imgDescription.update(config.description);
        }      
        else
        {
          imgDescription.hide();
        }
        
      },
      
      actionZoomImage: function(objSender, localConfig)
      {
        var config = zoomImageConfigDefault;                
                
        for(var x in localConfig) config[x] = localConfig[x];      
        
        var template = config.template;
      
        var tpl = $(template);
        
        var imageZoomDelayTimer = setTimeout(function()
        {
          objSender.showImage(config);            
        }, (config.delay * 1000).round());

        tpl.setStyle({position: 'absolute', overflow: 'hidden'});
        
        objSender.observe('mousemove', function(event)
        {                                       
             
            var x = event.pointerX();
            var y = event.pointerY();
                     
            var imgWidth = objSender.readAttribute("imgWidth");
            var addOffset = objSender.readAttribute("imgOffset");
                                                                    
            tpl.setStyle({                
              top: (y + config.pointerYOffset) + "px",
              left: (x + config.pointerXOffset) + "px"
            });
            
            if (addOffset)
            {
              tpl.setStyle({
                left: (x - config.pointerYOffset - imgWidth) + "px"                              
              });
            }
        });
        
        objSender.observe( config.triggerHide, function(event) 
        {          
          clearTimeout(objSender.readAttribute('timer'));
          $(config.template).hide(); 
          objSender.stopObserving('mousemove');
          var template = config.template;        
          var tpl = $(template).setStyle(config.templateResetStyle);          
        });
          
        objSender.writeAttribute('timer', imageZoomDelayTimer);        
      },
    
      showZoomImage: function(objSender, localConfig)
      {
        var config = zoomImageConfigDefault;                
        for(var x in localConfig) config[x] = localConfig[x];
              
        objSender.observe( config.triggerShow, function(ev)
        {
          objSender.actionZoomImage(localConfig);
        });        
      }
    });
