var RokZoom = new Abstract({
	options: {
		imageDir: 'images/',
		resizeFX: {
			duration: 2000,
			transition: Fx.Transitions.Expo.easeOut,
			wait: false
		},
		opacityFX: {
			wait: false
		},
		shadowFX: {
			duration: 350,
			wait: false
		},
		onClick: Function.empty,
		onClose: Function.empty
	},
	init: function (a) {
		this.setOptions(a);
		this.getLinks();
		this.createElements();
		this.fx = {
			resize: this.center.effects(this.options.resizeFX),
			bottom: this.bottom.effect('top', this.options.captionFx),
			shadow: this.shadow.effect('opacity', this.options.shadowFx)
		}
	},
	getLinks: function () {
		this.anchors = [];
		$$(document.links).each(function (a) {
			if (a.rel && a.rel.test(/^RokZoom/i)) {
				a.onclick = this.click.bind(this);
				this.anchors.push(a)
			}
		},
		this)
	},
	createElements: function () {
		$(document.body).adopt(new Element('div', {
			'id': 'rbCenter'
		}), new Element('div', {
			'id': 'rbLinks'
		}).adopt(new Element('div', {
			'id': 'rbPrevLink',
			'events': {
				'click': this.previous.bind(this)
			}
		}).adopt(new Element('img', {
			'src': this.options.imageDir + 'spacer.gif',
			'styles': {
				'width': '100%',
				'height': '100%'
			},
			'events': {
				'mouseenter': function () {
					this.parentNode.addClass('hover')
				},
				'mouseleave': function () {
					this.parentNode.removeClass('hover')
				}
			}
		})), new Element('div', {
			'id': 'rbNextLink',
			'events': {
				'click': this.next.bind(this)
			}
		}).adopt(new Element('img', {
			'src': this.options.imageDir + 'spacer.gif',
			'styles': {
				'width': '100%',
				'height': '100%'
			},
			'events': {
				'mouseenter': function () {
					this.parentNode.addClass('hover')
				},
				'mouseleave': function () {
					this.parentNode.removeClass('hover')
				}
			}
		}))), new Element('div', {
			'id': 'rbBottom'
		}).adopt(new Element('div', {
			'id': 'rbCloseLink',
			'events': {
				'click': this.close.bind(this)
			}
		}), new Element('div', {
			'id': 'rbCaption'
		}), new Element('div', {
			'id': 'rbNumber'
		}), new Element('div', {
			'styles': {
				'clear': 'both'
			}
		})));
		['center', 'links', 'prevLink', 'nextLink', 'bottom', 'caption', 'number'].each(function (a) {
			this[a] = $('rb' + a.capitalize());
			if (! (/caption|number|/).test(a)) this[a].setStyle('display', 'none')
		},
		this);
		if (!Client.Engine.ie6) this.createShadows();
		else this.shadow = new Element('div', {
			'id': 'rbShadow'
		}).injectInside(document.body)
	},
	createShadows: function () {
		this.shadow = new Element('div', {
			'id': 'rbShadow',
			'styles': {
				'display': 'none'
			}
		}).adopt(new Element('table', {
			'styles': {
				'width': '100%',
				'height': '100%',
				'border-collapse': 'collapse'
			},
			'cellspacing': 0,
			'cellpadding': 0,
			'border': 0
		}));
		if (Client.Engine.ie) this.shadow.getElement('table').adopt(new Element('tbody'));
		var a = new Element('img', {
			'width': 1,
			'height': 1,
			'styles': {
				'display': 'block'
			}
		});
		var b = [],
		col,
		l = 1;
		for (var i = 0; i < 3; i++) {
			b[i] = new Element('tr', {
				'styles': {
					'height': (i == 0) ? 25 : (i == 2) ? 26 : ''
				}
			});
			for (var j = 1; j <= 3; j++, l++) {
				col = j == 1 || j == 3;
				if (i == 1) col = !col;
				if (i == 1 && j == 2) l--;
				b[i].adopt(new Element('td', {
					'styles': {
						'width': (col) ? (i == 2) ? 26 : 27 : '',
						'background': 'center center transparent url(' + ((!col) ? this.options.imageDir + 'zoom-shadow' + l + '.png': '') + ')',
						'padding': 0,
						'margin': 0
					}
				}).adopt(a.clone().setProperties({
					'width': (col) ? 27 : 1,
					'height': (col) ? i == 2 ? 26 : 25 : 1,
					'src': this.options.imageDir + ((col) ? 'zoom-shadow' + l + '.png': 'spacer.gif')
				})))
			}
		}
		b[1].getElements('td')[1].set({
			'styles': {
				'width': '',
				'background': '#fff'
			},
			'bgcolor': '#fff',
			'height': '100%',
			'width': '100%'
		}).empty().adopt(a.clone().set({
			'width': 1,
			'height': 1,
			'src': this.options.imageDir + 'spacer.gif'
		}));
		this.shadow.getElement(Client.Engine.ie ? 'tbody': 'table').adopt(b);
		$(document.body).adopt(this.shadow)
	},
	click: function (e) {
		e = new Event(e).stop();
		this.fireEvent('onClick', [e]);
		this.called = false;
		this.origin = $(e.target);
		var b = e.target.parentNode;
		if (b.rel.length == 7) this.show(b.href, b.title);
		else {
			var j, imageNum, images = [];
			this.anchors.each(function (a) {
				if (a.rel == b.rel) {
					for (j = 0; j < images.length; j++) if (images[j][0] == a.href) break;
					if (j == images.length) {
						images.push([a.href, a.title]);
						if (a.href == b.href) imageNum = j
					}
				}
			},
			this);
			this.open(images, imageNum)
		}
	},
	show: function (a, b) {
		this.open([[a, b]], 0)
	},
	open: function (a, b) {
		this.images = a;
		this.setup(true);
		this.changeImage(b)
	},
	setup: function (b) {
		$$('object').extend(Client.Engine.ie ? $$('select') : []).each(function (a) {
			a.setStyle('visibility', b ? 'hidden': 'visible')
		});
		document[b ? 'addEvent': 'removeEvent']('keyup', this.keyboardListener.bind(this))
	},
	keyboardListener: function (a) {
		switch (a.code) {
		case 27:
		case 88:
		case 67:
			this.close();
			break;
		case 37:
		case 80:
			this.previous();
			break;
		case 39:
		case 78:
			this.next()
		}
	},
	previous: function () {
		if (this.activeImage < 0 || this.activeImage >= this.images.length) return;
		this.origin = this.anchors[this.anchors.indexOf(this.origin.getParent()) - 1].getElement('img');
		this.changeImage(this.activeImage - 1)
	},
	next: function () {
		if (this.activeImage < 0 || this.activeImage >= this.images.length) return;
		this.origin = this.anchors[this.anchors.indexOf(this.origin.getParent()) + 1].getElement('img');
		this.changeImage(this.activeImage + 1)
	},
	changeImage: function (a) {
		this.activeImage = a;
		this.turnOff();
		this.coord = this.origin.getCoordinates();
		this.center.empty().set({
			'class': 'rbLoading',
			'styles': $merge(this.coord, {
				'display': 'block',
				'opacity': 1
			})
		});
		if (this.preload) {
			this.preload.onload = Class.empty;
			this.preload = null
		}
		this.preload = new Asset.image(this.images[a][0], {
			onload: this.startEffect.bind(this)
		})
	},
	startEffect: function () {
		if (this.called) return;
		this.called = true;
		this.image = this.preload.inject(this.center);
		this.size = {
			'height': this.image.height,
			'width': this.image.width
		};
		this.image.set({
			'id': 'rbImage',
			'width': this.coord.width,
			'height': this.coord.height
		});
		this.bottom.setStyle('width', this.size.width);
		$$([this.prevLink, this.nextLink]).setStyle('height', this.size.height);
		this.caption.setHTML(this.images[this.activeImage][1] || '&nbsp;');
		this.number.setHTML((this.images.length == 1) ? '': 'Image ' + (this.activeImage + 1) + ' of ' + this.images.length);
		this.fx = $merge(this.fx, {
			width: new Fx.Property(this.image, 'width', this.options.resizeFX),
			height: new Fx.Property(this.image, 'height', this.options.resizeFX),
			opac: new Fx.Style(this.center, 'opacity', this.options.opacityFX)
		});
		if (this.group) this.group.removeEvent('onComplete');
		this.group = new Group(this.fx.width, this.fx.height, this.fx.resize, this.fx.opac).addEvent('onComplete', this.openFX.bind(this));
		this.center.set({
			'class': '',
			'styles': {
				'opacity': 0,
				'width': this.size.width,
				'height': this.size.height,
				'top': this.coord.top - this.image.getStyle('padding-top').toInt(),
				'left': this.coord.left - this.image.getStyle('padding-left').toInt()
			}
		});
		this.bottom.setStyles({
			'opacity': 0,
			'display': 'block'
		});
		this.fx.width.start(this.coord.width, this.size.width);
		this.fx.height.start(this.coord.height, this.size.height);
		this.fx.opac.start(1);
		this.fx.resize.start({
			'top': [this.coord.top, Math.round(0.5 * (Client.getHeight() - (this.size.height + this.bottom.offsetHeight)) + Client.getScrollTop())],
			'left': [this.coord.left, Math.round(0.5 * (Client.getWidth() - this.size.width) + Client.getScrollLeft())]
		})
	},
	openFX: function () {
		this.called = false;
		var a = this.image.getCoordinates();
		this.bottom.setStyles({
			'top': a.top + a.height,
			'left': a.left,
			'opacity': 1
		});
		this.links.setStyles(a);
		this.fx.bottom.set(this.bottom.offsetTop - this.bottom.offsetHeight).start(this.bottom.offsetTop + this.bottom.offsetHeight).chain(function () {
			this.links.setStyle('display', 'block');
			if (this.activeImage) this.prevLink.setStyle('display', 'block');
			if (this.activeImage != (this.images.length - 1)) this.nextLink.setStyle('display', 'block');
			this.shadow.setStyles({
				'width': a.width + 26,
				'height': a.height + this.bottom.offsetHeight + 26,
				'left': a.left - 13,
				'top': a.top - 8,
				'opacity': 0,
				'display': 'block'
			});
			if (Client.Engine.ie7) this.shadow.getElement('table').setStyle('height', this.shadow.offsetHeight - 51);
			this.fx.shadow[!Client.Engine.ie ? 'start': 'set'](1)
		}.bind(this))
	},
	close: function (e) {
		this.fireEvent('onClose', [e.stop()]);
		if (Client.Engine.ie) this.fx.shadow.set(0);
		this.fx.shadow.stop().start(0).chain(function () {
			this.fx.bottom.start(this.center.offsetTop + this.center.offsetHeight - this.bottom.offsetHeight).chain(function () {
				this.turnOff();
				this.coord = this.origin.getCoordinates();
				this.group.removeEvent('onComplete');
				this.group = new Group(this.fx.width, this.fx.height, this.fx.resize, this.fx.opac);
				this.group.addEvent('onComplete', function () {
					this.center.setStyles({
						'display': 'none',
						'width': this.coord.width,
						'height': this.coord.height
					});
					this.group.removeEvent('onComplete')
				}.bind(this));
				this.fx.opac.start(0);
				this.fx.width.start(this.fx.width.now, this.coord.width);
				this.fx.height.start(this.fx.height.now, this.coord.height);
				this.fx.resize.start({
					'top': this.coord.top - this.image.getStyle('padding-top').toInt(),
					'left': this.coord.left - this.image.getStyle('padding-left').toInt()
				})
			}.bind(this))
		}.bind(this));
		this.setup(false)
	},
	turnOff: function () {
		this.els = this.els || $$([this.shadow, this.bottom, this.links, this.prevLink, this.nextLink]);
		this.els.setStyle('display', 'none')
	}
});
RokZoom.extend(new Events);
RokZoom.extend(new Options);
Group.implement({
	removeEvent: function (b) {
		this.instances.each(function (a, i) {
			if (a.$events[b]) a.$events[b] = []
		},
		this);
		return this
	}
});
Fx.Property = Fx.Base.extend({
	initialize: function (a, b, c) {
		this.property = b;
		this.parent(a, c);
		this.element = $(a)
	},
	increase: function () {
		$try(function () {
			this.element.setProperty(this.property, Math.round(this.now) + 'px');
			this.element.setStyle(this.property, Math.round(this.now) + 'px')
		},
		this)
	}
});
