var mooView = new Class({
	Implements: [Options, Events],

	options: {
		'rel': 'mooView',
		'allowSingleImage': false,
		'minWidth': 320,
		'minHeight': 240,
		'useKeyboard': true,
		'useMousewheel': false,
		'loopImages': false
	},

	initialize: function(options) {
		this.setOptions(options);

		// images groups
		this.images = new Hash;

		// grab links
		$$('a[rel^=' + this.options.rel + ']').each(function(link) {
			link.removeEvents('click').addEvent('click', this.click.bindWithEvent(this, link));

			// create group
			if(!this.images.has(link.rel)) {
				this.images.set(link.rel, new Array());
			}

			// push link in group
			var dual = link.title.split('::');
			if(dual.length > 1) {
				this.images[link.rel].push(new Array(link, dual[0]));
			}
			else {
				this.images[link.rel].push(new Array(link, link.title));
			}
		}, this);
	},

	keyboardListener: function(event) {
		switch (event.key){
			case 'esc': this.close(); break;
			case 'left': this.prev(); break;
			case 'right': this.next(); break;
		}
	},

	mouseListener: function(event) {
		event = new Event(event);
		if(event.wheel > 0) {
			this.prev();
		}
		else if(event.wheel < 0) {
			this.next();
		}
	},

	click: function(e, link) {
		e.stop();

    	if($defined($('mooViewOverlay'))) {
    		return false;
		}

		if(Browser.Engine.trident4) {
			$$('select').set('visibility', 'hidden');
		}

		if(this.options.useKeyboard) {
			document.addEvent('keydown', this.keyboardListener.bindWithEvent(this));
		}
		if(this.options.useMousewheel) {
			document.addEvent('mousewheel', this.mouseListener.bindWithEvent(this));
		}

		this.overlay = new Element('div', {
			'id': 'mooViewOverlay'
		}).inject(document.body, 'top').setStyle('height', document.getScrollSize().y).set('opacity', 0.5).addEvent('click', this.close.bind(this));

		this.center = new Element('div', {
			'id': 'mooViewCenter',
			'class': 'mooViewLoading',
			'styles': {
				'width': this.options.minWidth,
				'height': this.options.minHeight,
				'margin-left': -(this.options.minWidth * 0.5)
			}
		}).inject(this.overlay, 'after').setStyle('top', document.getScroll().y + 20 + 'px').set('morph', {
			'duration': 'short',
			'onComplete': function() {
				this.open();
			}.bind(this)
		});

		// next/prev on not single images
		if(!this.options.allowSingleImage || link.rel != this.options.rel) {
			this.prevLink = new Element('a', {
				'id': 'mooViewPrevLink',
				'href': 'javascript:void(0)'
			}).inject(this.center);

			this.nextLink = new Element('a', {
				'id': 'mooViewNextLink',
				'href': 'javascript:void(0)'
			}).inject(this.center);
		}

		this.image = new Element('div', {
			'id': 'mooViewImage'
		}).inject(this.center).set('morph', {
			'duration': 'short'
		}).set('opacity', 0);

		this.bottom = new Element('div', {
			'id': 'mooViewBottom'
		}).inject(this.center, 'after').set('morph', {
			'duration': 'short'
		});

		new Element('a', {
			'id': 'mooViewClose',
			'href': 'javascript:void(0)'
		}).inject(this.bottom).addEvent('click', this.close.bind(this));

		this.caption = new Element('div', {
			'id': 'mooViewCaption'
		}).inject(this.bottom);

		this.number = new Element('div', {
			'id': 'mooViewNumber'
		}).inject(this.bottom);

	 	new Element('div', {
			'styles': {
				'clear': 'both',
				'height': '1px',
				'line-height': '0'
			}
		}).inject(this.bottom);

		for(var i = 0; i < this.images[link.rel].length; i++) {
			if(this.images[link.rel][i][0].href == link.href) {
				this.activeImage = i;
				this.activeImageTitle = this.images[link.rel][i][1];
				this.activeImageRel = link.rel;
				this.preload = new Image();
				this.preload.onload = this.resize.bind(this);
				this.preload.src = this.images[link.rel][i][0].href;
				break;
			}
		}
		return false;
	},

	resize: function() {
		this.center.morph({
			'margin-left': -(Math.max(this.options.minWidth, this.preload.width) * 0.5),
			'width': Math.max(this.options.minWidth, this.preload.width),
			'height': Math.max(this.options.minHeight, this.preload.height),
			'top': document.getScroll().y + 20 + 'px'
		});
	},

	open: function() {
		this.center.removeClass('mooViewLoading');

		this.image.setStyles({
			'background-image': 'url(' + this.preload.src + ')',
			'width': Math.max(this.options.minWidth, this.preload.width) + 'px',
			'height': Math.max(this.options.minHeight, this.preload.height) + 'px'
		}).morph({
			'opacity': 1
		});

		this.caption.set('html', this.activeImageTitle || '').setStyle('display', this.activeImageTitle ? 'block' : 'none');

		// if not single image and more than 1 image in group
		if((!this.options.allowSingleImage || this.activeImageRel != this.options.rel) && this.images[this.activeImageRel].length > 1) {
			this.number.set('html', 'Изображение <b>' + (this.activeImage + 1) + '</b> из <b>' + this.images[this.activeImageRel].length + '</b>').setStyle('display', 'block');

			if(this.options.loopImages) {
				this.prevLink.setStyles({
					'height': Math.max(this.options.minHeight, this.preload.height),
					'display': 'block'
				}).addEvent('click', this.prev.bind(this));

				this.nextLink.setStyles({
					'height': Math.max(this.options.minHeight, this.preload.height),
					'display': 'block'
				}).addEvent('click', this.next.bind(this));
			}
			else {
				if(this.activeImage > 0) this.prevLink.setStyles({
					'height': Math.max(this.options.minHeight, this.preload.height),
					'display': 'block'
				}).addEvent('click', this.prev.bind(this));

				if(this.activeImage < this.images[this.activeImageRel].length - 1) this.nextLink.setStyles({
					'height': Math.max(this.options.minHeight, this.preload.height),
					'display': 'block'
				}).addEvent('click', this.next.bind(this));
			}
		}
		else this.number.setStyle('display', 'none');

		this.bottom.setStyles({
			'display': 'block',
			'top': this.center.getStyle('top').toInt() + this.center.getSize().y.toInt() + 'px',
			'width': this.center.getSize().x.toInt() + 'px',
			'margin-left': this.center.getStyle('margin-left')
		}).setStyle('margin-top', -this.bottom.getSize().y).morph({
			'margin-top': 0
		});

		this.preload = null;

		this.overlay.setStyle('height', document.getScrollSize().y);

		return false;
	},

	prev: function() {
		if(this.options.loopImages) {
			return (this.activeImage - 1 < 0) ? this.change(this.images[this.activeImageRel].length - 1) : this.change(this.activeImage - 1);
		}
		else {
			return this.change(this.activeImage - 1);
		}
	},

	next: function() {
		if(this.options.loopImages) {
			return (this.activeImage >= this.images[this.activeImageRel].length - 1) ? this.change(0) : this.change(this.activeImage + 1);
		}
		else {
			return this.change(this.activeImage + 1);
		}
	},

	change: function(imageNum) {
		if(imageNum < 0 || imageNum >= this.images[this.activeImageRel].length) {
			return false;
		}
		this.image.setStyle('background-image', '').set('opacity', 0);
		this.center.addClass('mooViewLoading');
		this.nextLink.removeEvents();
		this.prevLink.removeEvents();
		this.prevLink.style.display = this.nextLink.style.display = this.bottom.style.display = 'none';
		this.activeImage = imageNum;
		this.activeImageTitle = this.images[this.activeImageRel][imageNum][1];
		this.preload = new Image();
		this.preload.onload = this.resize.bind(this);
		this.preload.src = this.images[this.activeImageRel][imageNum][0].href;
		return false;
	},

	close: function() {
		this.overlay.destroy();
		document.removeEvents();
		if(Browser.Engine.trident4) {
			$$('select').setStyle('visibility', 'visible');
		}
		this.center.destroy();
		this.bottom.destroy();
		document.removeEvents('keydown');
		return false;
	} 

});

window.addEvent('domready', function() {
	new mooView();
});