/* --------------------------------------------------------------------

NET4VISIONS.COM IGALLERY - igallery.js 05-11-2009
Version: 1.1
Created by: net4visions.com
Last edited: 11-04-2009
Descriptions: Present images based on folder content - autoresize using phpThumb 
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
Requirements: mootools core 1.2.4.js || mootools more 1.2.4.2.js

-------------------------------------------------------------------- */

var IGallery = new Class({
	Implements: [Options, Events, Chain],
	
	options: {
		// onLoad: 			$empty,
		// onShow:			$empty,
		// onNext:			$empty,
		// onPrev:			$empty,	
		start:				false, // false to start with thumbnails OR index to start with image
		fadeTime: 			300,
		stayTime: 			2000,
		counter:			true,
		path:				'/projects/iGallery/pictures/',	// path to your pictures,
		pthumb:				{
			'path':			'/projects/scripts/pthumb/phpThumb.php/',
			'small':		'zc=1;q=95;wp=90;hp=67;wl=90;hl=67;90x67;',
			'large':		'far=0;bg=ffffff;q=95;wp=228;hp=228;wl=304;hl=228;304x228;'
		},
		ajaxRequest:		false
	},
	
	initialize: function(element, options) {
		this.setOptions(options);
		if (this.options.debug) dbug.enable();
		if (!$defined($(element))) { dbug.log('Error: container undefined'); return false };
		
		this.element 			= $(element);
		this.wrap 				= this.element.getElement('.wrap');
		this.layer 				= this.element.getElement('.layer');
		this.message 			= this.element.getElement('.message');
		this.pictureContainer 	= this.element.getElement('.picture');
		this.thumbsContainer  	= this.element.getElement('.thumbs');
		this.horzNav 			= this.element.getElement('.horz');
		this.vertNav 			= this.element.getElement('.vert');
		this.btnUp				= this.element.getElement('.btn-up');
		this.btnDown			= this.element.getElement('.btn-down');
		this.btnPrev			= this.element.getElement('.btn-prev');
		this.btnNext			= this.element.getElement('.btn-next');
		this.index 				= this.options.start;
		this.previousIndex 		= this.index;
		
		this.horzNav.hide();
		
		// request images
		this.request();
	},
	
	onPreload: function() {
		this.thumbsPerScroll = this._thumbsPerScroll();
		this.attach();
		
		this.fxScroll = this.fxScroll || new Fx.Scroll(this.thumbsContainer, {
			offset: { x: 0, y: 0 }
		}).toElement(this.thumbs[0]);

		this.layer.empty(); // remove loading image and counter
		this.handleButtons();
		
		if ($chk(this.options.start)) {
			this.show(this.options.start)
		} else {
			this.layer.fade('out');
			this.message.fade('hide');
		}
	},
	
	prepare: function(responseJSON) {
		if (!responseJSON.length) return false;

		this.prepareHTML();
		this.preparePictures(responseJSON);
	},
	
	preparePictures: function(els) {
		// thumbnails
		var ul = new Element('ul', { 'class': 'autoclear' });
		this.thumbs = els.map(function(file, index){
			return new Element('li', {
				events: {
					click: function(e) {
						e.stop();
						this.show(index);
					}.bind(this)
				}
			}).adopt(
				new Element('img', {
					src: this.options.pthumb.path + this.options.pthumb.small + file
				})
			).inject(ul);
		},this);
		this.thumbsContainer.empty();
		ul.inject(this.thumbsContainer);
		
		// preload thumbnails
		this._preload(els);
		
		// pictures
		this.loadedPictures = [];
		this.pictures = els.map(function(file, index){
			return new Element('img', {
				src: this.options.pthumb.path + this.options.pthumb.large + file,
				styles: { position: 'absolute' },
				events: {
					click: function(e) {
						e.stop();
						this.hidePicture();
					}.bind(this)
				},
				tween: { duration: this.options.stayTime }
			});
		},this);
	},
	
	prepareHTML: function() {
		// loader
		
		var path = './assets/site/images/ajax-loader.gif';
		this.loader = new Element ('img', {
			id:			'loader',
			src: 		path,
			'class':	'loader',
			styles: {
				position:	'absolute',
				top:		'50%',
				left:		'50%',
				margin:		'-12px 0 0 -12px',
				'z-index':	999
			}
		}).inject(this.layer);
		
		// load counter
		this.counter = new Element('p', { 'class': 'small' }).inject(this.layer);
		
		// image counter
		var counter = new Element('div', { 'class': 'slide-count small' }).inject(this.horzNav);
		if (!this.options.counter) counter.hide();
	},
	
	// get pictures - either AJAX or DOM
	request: function() {
		this.layer.fade(0.8);
		if (this.options.ajaxRequest) {
			var request = new Request.JSON({
				url: './assets/site/scripts/readdir.php',
				onComplete: function(responseJSON) {
					if (!$chk(responseJSON)) return false;
					this.pictureContainer.empty();
					this.prepare(responseJSON);
					this.fireEvent('onLoad');
				}.bind(this)
			}).get({ path: this.options.path });
		} else { // look for pictures in DOM element
			var responseJSON = this.pictureContainer.getElements('a').map(function(item, index){
				return item.get('href');
			})
	
			this.pictureContainer.empty();	
			this.prepare(responseJSON);
			this.fireEvent('onLoad');
		}
	},
	
	// attach button events
	attach: function() {
		this.btnUp.addEvent('click', function(e){
			e.stop();
			var index = this.move('up');
			index = index < 0 ? this.index : index;
			if (index != this.index) {
				this.index = index;
				this.fxScroll.toElement(this.thumbs[this.index]);
			}
			this.handleButtons();
		}.bind(this))
		
		this.btnDown.addEvent('click', function(e){
			e.stop();
			var index = this.move('down');
			index = index < this.thumbs.length ? index : this.index;
			if (index != this.index) {
				this.index = index;
				this.fxScroll.toElement(this.thumbs[this.index]);
			}
			this.handleButtons();
		}.bind(this))
		
		this.btnPrev.addEvent('click', function(e){
			e.stop();
			this.previous();
		}.bind(this))
		
		this.btnNext.addEvent('click', function(e){
			e.stop();
			this.next();
		}.bind(this))
	},
	
	reveal: function() {
		var ci = this.index;
		var pi = this.previousIndex;
		
		var file = this.pictures[ci].get('src');
		if (!this.loadedPictures.contains(file)) {
			new Asset.image(file, {
				onload: function() {
					this.loadedPictures.push(file);
					this.pictures[ci].fade('hide').inject(this.pictureContainer).fade('in');
				}.bind(this)
			});
		} else {
			this.pictures[ci].fade('hide').inject(this.pictureContainer).fade('in');
		}
		
		if (this.move('step') != -1) this.fxScroll.toElement(this.thumbs[this.move('step')]);
		
		this.horzNav.getElement('.slide-count').set('html', '<span class="red">' +(ci + 1)+ '</span>' + ' | ' + this.pictures.length);
		this.previousIndex = this.index;
		this.handleButtons();	
	},
	
	show: function(index) {
		var index  = index || 0;
		this.index = index - 1;
		this.vertNav.hide();
		this.horzNav.show().tween('margin-left', this._getButtonCenter());						
		this.showPicture();
		this.next();	
	},
	
	next: function() {
		this.index++;
		this.index = this.index > this.pictures.length-1 ? this.pictures.length-1 : this.index;
		this.reveal();
		this.fireEvent('onNext');	
	},
	
	previous: function() {
		this.index--;
		this.index = this.index < 0 ? 0 : this.index;
		this.reveal();
		this.fireEvent('onPrev');	
	},
	
	move: function(direction) {
		var count = Math.floor(this.index/this.thumbsPerScroll);
		switch(direction) {
			case 'up':
				return (count -1) * this.thumbsPerScroll;
				break;
			case 'down':
				return (count + 1) * this.thumbsPerScroll;
				break;
			case 'step':
				if ( count == Math.floor(this.previousIndex/this.thumbsPerScroll)) return -1; // no change
				return count * this.thumbsPerScroll;
			default:
				return false;
		}
	},
	
	handleButtons: function() {
		$$(this.btnPrev, this.btnNext, this.btnUp, this.btnDown).removeClass('disabled');
	
		// prev/next
		if (this.index == 0) this.btnPrev.addClass('disabled');
		if (this.index >= this.pictures.length-1) this.btnNext.addClass('disabled');
		
		// up/down
		var c = Math.floor(this.index/this.thumbsPerScroll);
		var m = Math.floor(this.pictures.length/this.thumbsPerScroll);
		
		if (c == 0) this.btnUp.addClass('disabled');
		if (c == m) this.btnDown.addClass('disabled');
	},
	
	showPicture: function() {
		this.layer.fade(0.8);
		this.message.fade(0.85);
		this.pictureContainer.getParent().fade('in').setStyle('z-index', 99);	
	},
	
	hidePicture: function() {
		this.layer.fade('out');
		this.message.fade('hide');
		this.pictureContainer.getParent().fade('out').setStyle('z-index', -1);	
		var fx = new Fx.Tween(this.horzNav, {
			onComplete: function() {
				this.horzNav.hide();
				this.vertNav.show();
			}.bind(this)
		}).start('margin-left', 0);
	},
	
	_preload: function(els) {
		// preload thumbnails
		new Asset.images( els.map(function(file){ return this.options.pthumb.path + this.options.pthumb.small + file; },this), {
			onProgress: function(counter, index) {
				this.counter.set('text', 'Please wait while loading... ' + ((counter + 1) * (100 / els.length)).toInt()  + '%');
			}.bind(this),
			onComplete: function() {
				this.onPreload();				
			}.bind(this)
		},this);	
	},
	
	_getButtonCenter: function() {
		if (this.buttonCenter) return this.buttonCenter;
		
		// get width of horz buttons to center
		var options = { computeSize: true, styles: ['margin', 'padding', 'border'] };
		this.buttonCenter = parseInt((this.horzNav.measure(function(){ return this.getDimensions(options); }).totalWidth -
		this.btnPrev.measure(function(){ return this.getDimensions(options); }).totalWidth -
		this.btnNext.measure(function(){ return this.getDimensions(options); }).totalWidth)/2);
		
		return this.buttonCenter;		
	},	
	
	// return the number of pictures fully visible in the container
	_thumbsPerScroll: function() {
		var tsize = this.thumbs[0].getDimensions({
			computeSize:	true,
			styles: 		['margin', 'padding', 'border']
		});
		var csize = this.thumbsContainer.getSize();
		
		// adjust container size
		var cwidth = tsize.totalWidth * (Math.floor(csize.x/tsize.totalWidth));
		this.thumbsContainer.getFirst().setStyle('width', cwidth);
		this.thumbsContainer.setStyle('width', cwidth - parseInt(this.thumbs[0].getStyle('margin-right')));

		// return no. of pictures fully visible in scrilling area
		return Math.floor(csize.y/tsize.totalHeight) * Math.floor(csize.x/tsize.totalWidth);
	}	
})