/** Image zoomer
 *	@author : Partikule studio 2009
 *	
 *	Options :
 *
 *		zoomer:			ID of the thumb container (small version of the picture)
 *		container:		ID of the big image container.                 
 *		zoomSize:		Size of the big container. Could be a number or an object
 *						number : the big container size will be the thumbnail size * number
 *						object : {x:300, y:400} : the big container size will be fixed to the x and y values, in pixels.
 *
 */

var ImageZoom = new Class({

	Implements: Options,

	options: {
		zoomSize:	1.8,
		size:		false,
		divToHide:	false
	},

					   
	initialize: function(options)
	{

		this.name = "Image Zoomer by Partikule";
		
		this.setOptions(options);

		this.zoomer = 		$(this.options.zoomer);			// Thumb image container
		this.container = 	$(this.options.container);		// Big image container
		
		this.zoomSize = 	this.options.zoomSize; 								// xX the size of the thumbnail
		
		this.thumb_url = 	this.zoomer.getElement('a');
		this.thumb_image = 	this.thumb_url.getElement('img');
		
		this.thumbnail = new Asset.image( this.thumb_image.get('src'),{
			onload: function(){
				this.zoomer.empty();
				this.thumbnail.inject(this.zoomer);
				this.generateZoomer( new Hash({ x:this.thumbnail.width , y:this.thumbnail.height }) );
			}.bind(this)
		});
	},
	
	generateZoomer: function( thumb_size )
	{
		this.thumb_size = thumb_size;
		
		// Thumb dimensions
		this.setDimensions(this.zoomer,thumb_size.x,thumb_size.y);
		
		if ($type(this.zoomSize) == 'object')
		{
			this.zoomSize.x = this.zoomSize.x / this.thumb_size.x;
			this.zoomSize.y = this.zoomSize.y / this.thumb_size.y;
		}
		else
		{
			this.zoomSize = {x:this.zoomSize, y:this.zoomSize};
		}

		this.setDimensions(this.container, thumb_size.x*this.zoomSize.x, thumb_size.y*this.zoomSize.y);

		this.bigImage = new Asset.image( this.thumb_url.get('href'), 
		{
			'class':'zoomer_image',
			onload: function()
			{
				this.bigImage.inject(this.container);
				
				// determine the proportions between the thumbnail and the zoomed image
				this.ratioX = this.bigImage.width/thumb_size.x;
				this.ratioY = this.bigImage.height/thumb_size.y;
				
				// set the size of the zoomed area on thumbnail
				var regionWidth = (thumb_size.x/this.ratioX).toInt() * this.zoomSize.x;
				var regionHeight = (thumb_size.y/this.ratioY).toInt() * this.zoomSize.y;				
				
				// Creates the zoomer region
				this.zoomer_region = new Element('div', {
					'class': 'zoomer_region',
					styles: {
						'width': regionWidth,
						'height': regionHeight,
						'opacity': .5,
						'display': 'none'
					}
				}).injectInside(this.zoomer);
				
			
				// Mover
				this.mover = new Fx.Move(this.bigImage, {
    								relativeTo: $(this.container),
									duration:100,
									transition:Fx.Transitions.linear,
    								position: 'upperLeft',
    								edge: 'upperLeft'
				});

				// Mouse position
				this.zoomer.addEvent('mousemove', function(e){
					this.zoomer_region.setStyle('display', 'block');
					this.container.setStyle('display', 'block');
					// Hides the first hild of the parent container
					if (this.options.divToHide)
						$(this.options.divToHide).setStyle('display', 'none');
//						this.container.getParent().getFirst().setStyle('display', 'none');
					this.evalNewPos(e);
				}.bind(this));
				
				this.zoomer.addEvent('mouseleave', function(e){
					this.zoomer_region.setStyle('display', 'none');
					this.container.setStyle('display', 'none');
					if (this.options.divToHide)
						$(this.options.divToHide).setStyle('display', 'block');
//					this.container.getParent().getFirst().setStyle('display', 'block');
				}.bind(this));

				// drag directly on the zoomed image. Also updates the zoomed region on the thumbnail
				// Not fully tested
				this.DragBig = new Drag(this.bigImage,{
					modifiers: {x:'left',y:'top'},
					grid:1,
					onDrag: function(elem){
						this.zoomer_region.setStyle('display', 'block');
						var pos = elem.getPosition(this.container);
						var left = pos.x;
						var top = pos.y;
						// if the zoomed image is dragged outside boundaries, set the correct position
						if(	pos.x>0 || pos.y>0 || -pos.x > this.bigImage.width-(thumb_size.x*this.zoomSize.x) || -pos.y > this.bigImage.height-(thumb_size.y*this.zoomSize.y)){							
							if(pos.x > 0) left = 0;
							if(pos.y > 0) top = 0;
							if ( -pos.x > this.bigImage.width-(thumb_size.x*this.zoomSize.x) ) left = -1*(this.bigImage.width-(thumb_size.x*this.zoomSize.x));
							if( -pos.y > this.bigImage.height-(thumb_size.y*this.zoomSize.y) ) top = -1*(this.bigImage.height-(thumb_size.y*this.zoomSize.y));
							
							this.setPosition(this.bigImage,left,top);					
						};
						// moves the zoomed region on thumbnail according to the position of the zoomed image
						this.setPosition(this.zoomer_region,-(left/this.ratioX),-(top/this.ratioY));						
					}.bind(this)
				})
							
			}.bind(this)
		});		
	},
	
	setDimensions: function(element,width,height){
		$(element).setStyles({
			'width':width,
			'height':height
		});
	},
	
	setPosition: function(element,left,top){
		$(element).set({
			styles:{
				'left': left,
				'top':top
			}
		})
	},
	
	evalNewPos: function(e)
	{
		var viewZoom = false;	
		var ztPos = this.zoomer.getPosition();
		var zrPos = this.zoomer_region.getPosition();
		var zrDim = this.zoomer_region.getSize();
		var ztDim = this.zoomer.getSize();
		
		var zr = this.zoomer_region;
		
		// New pos to reach
		var posX = e.client.x - ztPos.x;
		var posY = e.client.y - ztPos.y;
		
		posX -= zr.getStyle('width').toInt()/2;
		posY -= zr.getStyle('height').toInt()/2;

		// Left limit
		if (posX >= 0 && (posX + zrDim.x) < ztDim.x) {
			zr.setStyle('left', posX);
			viewZoom = true;	
		}
		if (posX < 0)
			zr.setStyle('left',0);

		// Top limit
		if (posY >= 0) {
			zr.setStyle('top', posY);
			viewZoom = true;	
		}
		if(posY < 0)
			zr.setStyle('top',0);
			
		// Right limit
		if((posX+zrDim.x) > ztDim.x)
			zr.setStyle('left', ztDim.x-zrDim.x);
		
		// Bottom limit
		if((posY+zrDim.y) > ztDim.y)
			zr.setStyle('top', ztDim.y-zrDim.y);
			
		if (viewZoom == true)
		{
			var pos = zr.getPosition(this.zoomer);
			var calcLeft = -(pos.x*this.ratioX);
			var calcTop = -(pos.y*this.ratioY);
		
			var bigImgLeft = this.bigImage.width - (this.thumb_size.x*this.zoomSize.x);
			var bigImgTop = this.bigImage.height - (this.thumb_size.y*this.zoomSize.y);						
			var left = (-calcLeft) > bigImgLeft ? -bigImgLeft : calcLeft;
			var top = (-calcTop) > bigImgTop ? -bigImgTop : calcTop;
			
			this.setPosition(this.bigImage,left.toInt(),top.toInt());
		
		}
		
	}
	
})
