
/**
* magnify tools.
*  @todo: option to set position on an other side of the img element(top, bottom, left, rigth.
*  @exemple:<img src="joelafrite" onload="new Magnify(this, 'big/pic/url');"/>
*/
Magnify = new Class({

    options: {
		viewer               : null,
		viewersize      : {'x': 200,'y': 200},
		
		bigPic               :null,
		bigSize: {'x': 536,'y': 640}
	},
	
    /**
    * @param String Container id where is the img to magnify.
    * @param String big-size img url
    * @param ArrayOptions overload default param. 
    */
    initialize: function(img, url, options){
        this.img = $(img);
        this.url = url;
        this.setOptions(options);
		
		// set mask element.
        this.viewer = this.getViewer();
        
		// set big img for viewer
		this.bigPic = this.getBigPic();
		
		
      
	    //setting the viewer apparition effect. 
        this.viewer.fx = new Fx.Styles(this.viewer, {
            wait: false,
            duration: 1000,
            transition: Fx.Transitions.Quad.easeInOut
        });
        
      // bind us on miniature mouse event
        this.img.addEvent('mousemove', this.render.bind(this) );
        this.img.addEvent('mouseleave', this.hide.bind(this) );
        this.img.addEvent('mouseenter', this.show.bind(this) );      
        
        var reg = new RegExp("[_]+", "g");
        var arr_prov = img.split(reg);

        this.e = $('image_label_zoom_' + arr_prov[2]);
        if(this.e)
        {
            this.e.addEvent('mousemove', this.render.bind(this));
            this.e.addEvent('mouseleave', this.hide.bind(this));
            this.e.addEvent('mouseenter', this.show.bind(this));
        }

        this.n = $('cache-new');
        if(this.n)
        {
            this.n.addEvent('mousemove', this.render.bind(this));
            this.n.addEvent('mouseleave', this.hide.bind(this));
            this.n.addEvent('mouseenter', this.show.bind(this));
        }

        this.setRatio();
    },
	
	/*
	 * setting the viewer
	 * @todo: check the overlay on setting viewer from scratch.
	 */
	getViewer: function(){
		if (this.options.viewer != null) {
			return $(this.options.viewer);
		}
		else {
			var viewer = new Element('div');
			viewer.injectAfter(this.img);
			viewer.setStyles({
				width: 0,
				height: this.options.viewersize.y,
				overflow: 'hidden',
				zindex: 1000,
				position: 'absolute',
				opacity: 0,
				left: this.img.width + this.findPos(this.img)
			});
			
			return viewer;
		}
	},
	
	/*
	 * Setting the big picture for the viewer (must be already set).
	 * @todo: ajax request to catch the img / size and avoid onload bug.
	 */
	getBigPic: function(){
		if (this.options.bigPic != null) 
            return $(this.options.bigPic)
        else {
            var bigPic = new Element('img', {'src' : this.url});
			bigPic.injectInside(this.viewer);
            bigPic.setStyles({top: 0,
                                             left: 0,
                                             position: 'absolute',
                                             height: this.options.bigSize.y,
                                             width: this.options.bigSize.x
                                            });
            return bigPic;
		}
	},
	
	setRatio: function(){
		 // the size ratio viewer / miniature .
        this.ratio = {
            'x': -this.bigPic.height / this.img.height,
            'y': -this.bigPic.width / this.img.width
        };
	},
    
    show: function(event){
        this.viewer.fx.start({'width': this.options.viewersize.x, 'opacity': 1});
		this.setRatio();
		if (window.ie6)
		  $each(this.elemToHide, function(val){
            $(val).setStyle('visibility', 'hidden');
		  });
    },
    
    hide: function(event){
        this.viewer.fx.start({'width': 0, 'opacity': 0});
		if (window.ie6)
          $each(this.elemToHide, function(val){
            $(val).setStyle('visibility', 'visible');
          });
    },
    
    render: function(event){
		//compatibility calc to fix offset position from a mouse event  (note that the result is aproximative)
        var coord = this.getFromMouse(event);
        var me=this.findPos(this.img);
		
        var x = coord[0] - me[0];
        var y = coord[1] - me[1];
        var top_pos = Math.round(y * this.ratio.y + (this.options.viewersize.y / 2));
        var left_pos = Math.round(x * this.ratio.x + (this.options.viewersize.x / 2));
        
        //outbound testing.
        if (top_pos > 0)
            top_pos = 0;
        else if (top_pos < -this.bigPic.height+ this.options.viewersize.y)
            top_pos = -this.bigPic.height + this.options.viewersize.y;

        if (left_pos > 0)
            left_pos = 0;
        else if (left_pos < -this.bigPic.width + this.options.viewersize.x)
            left_pos = -this.bigPic.width + this.options.viewersize.x;
                
        this.bigPic.setStyles({
                                            top: top_pos,
                                            left: left_pos
                                            });
    } ,
	
	//thanks to quirksmode
    getFromMouse: function(e){
        var posx = 0;
        var posy = 0;
        if (!e)
         var e = window.event;
        if (e.pageX || e.pageY)
        {
            posx = e.pageX;
            posy = e.pageY;
        }
        else if (e.clientX || e.clientY)
        {
            posx = e.clientX +document.documentElement.scrollLeft ;
            posy = e.clientY +document.documentElement.scrollTop;
        }
        return [posx, posy];

    },
    
    //quirksmode again
    findPos: function (obj){
        var curleft = curtop = 0;
	    if (obj.offsetParent) {
	        do {
	            curleft += obj.offsetLeft;
	            curtop += obj.offsetTop;
	        } while (obj = obj.offsetParent);
	    }
	    return [curleft,curtop];
	},
	
	/*ie6 my friend...
	 * reference the input elem that must be hide
	 * @param array of eleme id 
	 * @todo: scan page for input elem, comput there pos to know if we must hide them  for our best friend.
	 */  
	underViewerElements: function(els){
		if(window.ie6){
			this.elemToHide=els;
		}
	} 
	
});
Magnify.implement(new Options);

