/*
---
 
name: Zoomer
description: Class to show zoomed image inside original
license: MIT-Style License (http://mifjs.net/license.txt)
copyright: Anton Samoylov (http://mifjs.net)
authors: Anton Samoylov (http://mifjs.net)
requires: [Core/Class.Extras, Core/Element.Style, Core/Element.Dimensions, Core/Element.Event, Core/Fx.Tween]
provides: Zoomer
 
...
*/

var Zoomer = new Class({
	
	version: '1.9.3',
	
	Implements: [Options],
	
	options: {
		smooth: 6
	},
	
	initialize: function(element, options) {
		this.setOptions(options);
		this.small = document.id(element);
		if(!this.small.complete) {
			this.small.addEvent('load', function() {
				this.prepareSmall();
			}.bind(this));
		} else {
			this.prepareSmall();
		}
		var src = this.options.big || this.small.get('big');
		
		var styles = {
			position: 'absolute',
			top: 0,
			left: 0,
			opacity: 0,
			cursor: 'move'
		};
				
		if (typeof src == 'string') {
			this.big = new Element('img', {
				src: src,
				styles: styles
			});
		} else {
			this.big = src;
			this.big.setStyles(styles);
		}
		
		if(!this.big.complete) {
			this.big.addEvent('load', function() {
				this.prepareBig();
			}.bind(this));
		} else {
			this.prepareBig();
		}
	},
	
	prepareSmall: function() {
		// fix image size
		this.small.setStyle('width', this.small.getSize().x);
		
		this.wrapper = new Element('div', {'class': 'zoomer-wrapper'}).wraps(this.small);
		['margin', 'left', 'top', 'bottom', 'right', 'float', 'clear', 'border', 'padding'].each(function(p) {
			var style = this.small.getStyle(p);
			var dflt = 'auto';
			if(['float', 'clear', 'border'].contains(p)) dflt = 'none';
			if(p == 'padding') dflt = '0';
			if(p == 'margin') style = '0 auto';
			try {
				this.small.setStyle(p, dflt);
				this.wrapper.setStyle(p, style);
			} catch(e) {};
		}, this);
		this.wrapper.setStyles({
			width: this.small.offsetWidth,
			height: this.small.offsetHeight,
			position: 'relative',
			overflow: 'hidden'
		});
		this.smallSize = {
			width: this.small.width,
			height: this.small.height
		};
		
		if(this.bigPrepared) {
			this.ready();
		} else {
			this.smallPrepared = true;
		}
	},
	
	prepareBig: function() {
		this.bigSize = {
			width: this.big.width,
			height: this.big.height
		};
		if(this.smallPrepared) {
			this.ready();
		} else {
			this.bigPrepared = true;
		}
	},
	
	ready: function() {
		this.big.inject(this.wrapper);
		this.bigWrapper = new Element('div', {
			'class': 'zoomer-wrapper-big',
			styles: {
				position: 'absolute',
				overflow: 'hidden',
				top: this.small.getPosition().y - this.wrapper.getPosition().y - this.wrapper.getStyle('border-top-width').toInt(),
				left: this.small.getPosition().x - this.wrapper.getPosition().x - this.wrapper.getStyle('border-left-width').toInt(),
				width: this.small.offsetWidth,
				height: this.small.offsetHeight,
				//background: 'url("' + this.small.getAttribute('src') + '")',
				zIndex: (this.small.getStyle('zIndex').toInt() || 0) + 1
			},
			events: {
				mouseenter: this.startZoom.bind(this),
				mouseleave: this.stopZoom.bind(this),
				mousemove: this.move.bind(this)
			}
		}).wraps(this.big);
	},
	
	move: function(event) {
		this.dstPos = event.page;
	},
	
	startZoom: function() {
		this.position = this.small.getPosition();
		
		this.ratio = {
			x: 1 - this.bigSize.width / this.smallSize.width,
			y: 1 - this.bigSize.height / this.smallSize.height
		};
		
		this.current = {
			left: this.big.getStyle('left').toInt(),
			top: this.big.getStyle('top').toInt()
		};
		
		this.timer = this.zoom.periodical(10, this);
		this.big.fade('in');
	},
	
	stopZoom: function() {
		clearTimeout(this.timer);
		this.big.fade('out');
	},
	
	zoom: function() {
		if(!this.dstPos) return;
		
		var steps = this.options.smooth;
		var dst = {
			left: parseInt((this.dstPos.x - this.position.x) * this.ratio.x, 10),
			top: parseInt((this.dstPos.y - this.position.y) * this.ratio.y, 10)
		};
		this.current.left -= (this.current.left - dst.left) / steps;
		this.current.top -= (this.current.top - dst.top) / steps;
		
		this.big.setStyles(this.current);
	}
	
});
