var ImgZoom = new Class({
	options: {
		className: 'fxzoom',
		//spinnerGif: 'http://www.ajaxload.info/cache/ff/ff/ff/23/40/88/25-0.gif',
		spinnerGif: 'imgtools/spinner.gif',
		warningGif: 'imgtools/warning.png',
		warningIE: 'imgtools/warning.gif', // default false, use only if warningGif is png
		offset: {x: 0, y: 0},
		transition: Fx.Transitions.Quad.easeOut,
		duration: 500,
		wheel: false,
		caption: false
	},
	
	initialize: function(options) {
		this.setOptions(options);
		this.gallery = $$('.' + this.options.className);
		this.size = {width: 0, height: 0};
		this.pos = {left: 0, height: 0};
		this.loading = false;
		this.image = null;
		this.wrapper = new Element('div', {
			'id': this.options.className + '-wrapper',
			'styles': {
				'position': 'absolute',
				'display': 'none'
			}
		}).inject(document.body);
		this.fxWrap = new Fx.Styles(this.wrapper, {
			transition: this.options.transition,
			duration: this.options.duration,
			wait: false
		});

		this.cacheIcons();
		this.image = new Image();
		this.gallery.each(function(img) {
			img.addEvent('click', this.addClick.bindWithEvent(this, img));
		}, this);
	},
	
	addClick: function(e, img) {
		var thumb = img.getChildren().filterByTag('img')[0];
		if (!thumb) return;
		
		e.stop();
		if ($chk(this.image.width)) {
			this.image.src = '';
			if (window.webkit || window.ie) {
				this.image.width = null;
				this.image.height = null;
			}
			else {
				this.image.removeProperty('width');
				this.image.removeProperty('height');
			}
		}
		this.wrapMove(thumb);
		this.imageLoad(img, thumb);
	},
	
	wrapMove: function(thumb) {
		var overflow, styles;
		var wrapper = this.wrapper, spinner = this.spinner;
		var thumbStyles = thumb.getStyles('margin', 'border-width', 'padding');
		var pos = thumb.getPosition();
		
		if ($('fxzoom-full')) $('fxzoom-full').remove();
		this.view('wrapper', 'show').view('spinner', 'show');
				
		overflow = {
			'left': pos.x + 1,
			'top': pos.y + 1,
			'width': thumb.width + this.styleToInt(thumbStyles, 'border-width', 'leftRight') + this.styleToInt(thumbStyles, 'padding', 'leftRight'),
			'height': thumb.height + this.styleToInt(thumbStyles, 'border-width', 'topBottom') + this.styleToInt(thumbStyles, 'padding', 'topBottom')
		}
		this.pos = {left: overflow.left, top: overflow.top};
		styles = $merge(overflow, {'position': 'absolute', 'opacity': 0.8, 'padding': 0});
		wrapper.setStyles(styles);
	},
	
	styleToInt: function (from, style, index) {
		var to = from[style].trim().split(' ');
		to.each(function(s, i) { to[i] = s.toInt(); });
		if (!index) return to;
		else {
			switch(index) {
				case 'top': return to[0];
				case 'right': return to[1];
				case 'bottom': return to[2];
				case 'left': return to[3];
				case 'leftRight': return to[3] + to[1];
				case 'topBottom': return to[0] + to[2];
			}
		}
	},
	
	imageLoad: function(img, thumb) {
		this.image.id = this.options.className + '-full';
		this.fxWrap.stop();
		if (this.fxImage) this.fxImage.stop();
		this.image.onload = function() {
			this.view('spinner', 'hide');
			this.size = {width: this.image.width, height: this.image.height};
			if (window.webkit419) this.image = new Element('img', {'src': this.image.src});
			else $(this.image)
			this.image.setProperties({'width': thumb.width, 'height': thumb.height});
			this.image.setStyles({
				'left': thumb.getStyle('borderLeft').toInt(),
				'top':	thumb.getStyle('borderTop').toInt(),
				'width': this.image.width,
				'height': this.image.height,
				'position': 'absolute'
			}).inject(this.wrapper, 'top');
			this.fxImage = new Fx.Styles(this.image, {
				transition: this.options.transition,
				duration: this.options.duration,
				onStep: function() {
					this.element.setProperties({'width': this.now.width.toInt(), 'height': this.now.height.toInt()});
					this.element.setStyles({'width': this.now.width.toInt(), 'height': this.now.height.toInt()})
				},
				
				onComplete: function() {
					this.element.setProperties({'width': this.now.width.toInt(), 'height': this.now.height.toInt()});
					this.element.setStyles({'width': this.now.width.toInt(), 'height': this.now.height.toInt()})
				},
				wait: false
			});
			this.view('image', 'show');
			this.wrapper.setStyle('opacity', 1);
			this.fxWrap.start({
				'left': [this.pos.left, window.getWidth() / 2 - this.size.width / 2],
				'top': [this.pos.top, window.getHeight() / 2 - this.size.height / 2], 
				'width': this.size.width,
				'height': this.size.height
			});
			this.fxImage.start({
				'width': this.size.width,
				'height': this.size.height
			});
		}.bind(this);
		this.image.onerror = function(e) {
			this.view('warning', 'show');
		}.bind(this);
		this.image.src = img.href;
	},
	
	view: function(element, type) {
		switch(element) {
			case 'spinner': 
				this.wrapper.setStyle('background', (type == 'show') ? '#000 url(' + this.spinner.getProperty('src') + ') 50% 50% no-repeat' : '');
				break;
			case 'warning': 
				this.wrapper.setStyle('background', (type == 'show') ? '#000 url(' + this.warning.getProperty('src') + ') 50% 50% no-repeat' : '');
				break;
			case 'image':
				this.image.setStyle('display', (type == 'show') ? '' : 'none'); 
				break; 
			case 'wrapper': 
				this.wrapper.setStyle('display', (type == 'show') ? '' : 'none'); 
				break;
		}
		return this;
	},
	
	cacheIcons: function() {
		var wrapper = this.wrapper;
		this.spinner = new Asset.image(this.options.spinnerGif, {
			'alt': '', 'styles': 'position: relative',
			'class': this.options.className + '-spinner',
			'onload': function() { 
				this.setProperties({'width': this.width, 'height': this.height});
			}
		});
		var warn = (this.options.warningIE && window.ie6) ? this.options.warningIE : this.options.warningGif;
		this.warning = new Asset.image(warn, {
			'alt': '', 'styles': 'position: relative',
			'class': this.options.className + '-warning',
			'onload': function() { 
				this.setProperties({'width': this.width, 'height': this.height});
			}
		});
	}
});
ImgZoom.implement(new Options);