/*
Script: gallery.js
		
License:
        MIT-style license.
		
Note:
		Don't forget to insert "<script language="Javascript" type="text/javascript" src="js/mootools.js"></script>" into the head page before this js file.

Example:
	<div id="item9880" class="gallerybox">
		<h4>Galerie photos>h4>
		<a href="/gallery-link" title="" ><img src="/img/icons/camera.gif" alt="Galerie photos" /></a>
		<ul class="imageslist" rel="School">
			<li><a href="/data/album/m/336.jpg" rev="/data/album/s/336.jpg">Afrique du sud</a></li>
			<li><a href="/data/album/m/332.jpg" rev="/data/album/s/332.jpg">Afrique du sud</a></li>
			<li><a href="/data/album/m/329.jpg" rev="/data/album/s/329.jpg">Afrique du sud</a></li>
			<li><a href="/data/album/m/334.jpg" rev="/data/album/s/334.jpg">Afrique du sud</a></li>
			<li><a href="/data/album/m/337.jpg" rev="/data/album/s/337.jpg">Afrique du sud</a></li>
			<li><a href="/data/album/m/346.jpg" rev="/data/album/s/346.jpg">Afrique du sud</a></li>
		</ul>
		<ul class="imageslist" rel="Classrooms">
			<li><a href="/data/album/m/338.jpg" rev="/data/album/s/338.jpg">EC Cap Town</a></li>
			<li><a href="/data/album/m/335.jpg" rev="/data/album/s/335.jpg">EC Cap Town</a></li>
			<li><a href="/data/album/m/331.jpg" rev="/data/album/s/331.jpg">EC Cap Town</a></li>
			<li><a href="/data/album/m/330.jpg" rev="/data/album/s/330.jpg">EC Cap Town</a></li>
			<li><a href="/data/album/m/333.jpg" rev="/data/album/s/333.jpg">EC Cap Town</a></li>
			<li><a href="/data/album/m/339.jpg" rev="/data/album/s/339.jpg">EC Cap Town</a></li>
		</ul>
	</div>

*/


var Gallery = new Class({
	
	Implements : Options,

	options: {
		selector : '.gallerybox',
		gallerySelector : 'ul.imageslist',
		opener : 'h4',
		unlinkedOpener : false,
		opacity : 0.4,
		playerSpeed : 3500,
		slideLength : 6,
		preloader : false,
		upscaling : false,
		imageSize : {
			width : 640,
			height : 480
		},
		thumbWidth : 106
	},
	
	initialize : function(options) {
		this.setOptions(options);
		
		this.initialized = false;
		
		//set behavior
		this.setBehavior();
	},
	
	build : function(){
		//add an overlay
		this.setOverlay();
		
		//open gallery
		this.openGallery();
		
		//recenter on resize
		window.addEvent('resize', function(e){
			this.setWrapperPosition();
		}.bind(this));
		
		if (Browser.Engine.trident == true && Browser.Engine.version == 4) {
			window.onscroll = function(){
				//set gallery position
				this.setWrapperPosition();
			}.bind(this);
		}
	},
	
	setOverlay : function(){
		//build the overlay
		this.overlay = new Element('div', {
			id : 'gallery-overlay'
		}).inject(document.body);
		
		//make an fx
		var fx = new Fx.Tween(this.overlay, {
			onComplete : function(){
				if (!this.overlay.getStyle('opacity')) {
					this.overlay.destroy();
				}
			}.bind(this)
		}).start('opacity', 0, this.options.opacity);
		
		//add click event to remove
		this.overlay.addEvent('click', function(){
			this.closeGallery(fx);
		}.bind(this));
	},
	
	openGallery : function(){
		//gallery alerady exist?
		if (this.initialized) {
			//set gallery position
			this.setWrapperPosition();
			
			//display gallery
			this.wrapper.setStyle('display', 'block');
			this.wrapperFx.start('opacity', 1);
		} else {
			//build it
			this.buildGallery();
			this.initialized = true;
		}
	},
	
	buildGallery : function(){
		//make a container
		this.wrapper = new Element('div', { id : 'gallery-wrapper'}).inject(document.body);
		this.wrapperFx = new Fx.Tween(this.wrapper, {
			onComplete : function(){
				if (!this.wrapper.getStyle('opacity')) this.wrapper.setStyle('display', 'none');
			}.bind(this)
		});
		
		//Determine wrapper size
		if (!this.buildSections()) {
			this.wrapper.addClass('small');
		}
		
		//define static size
		this.size = {
			gallery : this.wrapper.getSize(),
			window : window.getSize()
		};			
		
		this.setWrapperPosition();
		
		//Create elements
		new Element('div', { id : 'gallery-picture' }).inject(this.wrapper, 'top');
		new Element('div', { id : 'gallery-title' }).inject(this.wrapper, 'top');
		if (this.options.preloader) new Element('div', { id : 'gallery-preloader' }).inject(this.wrapper, 'top');
		var IEisshit = new Element('div').inject(this.wrapper, 'top');
		new Element('img', {
			id : 'gallery-close',
			src : '/img/gallery/closebox.png',
			events : {
				click : function(){
					this.overlay.fireEvent('click');
				}.bind(this)
			}
		}).inject(IEisshit);
		var bottom = new Element('div', { id : 'gallery-bottom' }).inject(this.wrapper);
		var slider = new Element('div', { id : 'gallery-slider' }).inject(bottom);
		new Element('ul', { id : 'gallery-thumbs' }).inject(slider);
		this.buildControls();
		
		//Load first gallery
		this.loadGallery(1, $('gallery-sections').getFirst());
		
	},
	
	setWrapperPosition : function(){
		this.size.window = window.getSize();
		var ieCorrection = (Browser.Engine.trident == true && Browser.Engine.version == 4) ? window.getScroll().y : 0;
		this.wrapper.setStyles({
			top : (this.size.window.y - this.size.gallery.y) / 2 + ieCorrection,
			left : (this.size.window.x - this.size.gallery.x) / 2
		});
	},
	
	buildSections : function(){
		var ul = new Element('ul', { id : 'gallery-sections' }).inject(this.wrapper);
		this.sections.each(function(section, i){
			var li = new Element('li', {
				html : section.getProperty('rel')
			}).inject(ul);
			
			//add event to load related gallery
			li.addEvent('click', function(){
				// load gallery
				this.loadGallery(i+1, li);
			}.bind(this));
		}, this);
		
		if (this.sections.length > 1) {
			return true;
		} else {
			ul.setStyle('display', 'none');
			this.options.slideLength -= 2;
			return false;
		}
	},
	
	buildControls : function(){
		new Element('div', { id : 'gallery-logo', 'class' : 'png' }).inject(this.wrapper);
		var wrapper = new Element('div', { id : 'gallery-controls' }).inject(this.wrapper);
		
		//add fx on thumbs list
		var fx = new Fx.Tween('gallery-slider');
		
		//buttons
		new Element('a', { id : 'gallery-controls-previous', 'class' : 'png' }).inject(wrapper);
		new Element('a', { id : 'gallery-controls-play' }).inject(wrapper);
		new Element('a', { id : 'gallery-controls-next', 'class' : 'png' }).inject(wrapper);		
		
		this.counterControls = 0;
		this.autoPlay = false;
		
		$('gallery-controls-next').addEvent('click', function(){
			var max = ($$('#gallery-thumbs li').length / this.options.slideLength ).ceil();
			if (this.counterControls < max - 1){
				fx.start('left', $('gallery-slider').getStyle('left').toInt() - this.options.thumbWidth * this.options.slideLength);
				this.counterControls++;
			}
		}.bind(this));
		
		$('gallery-controls-previous').addEvent('click', function(){
			if (this.counterControls > 0){
				fx.start('left', $('gallery-slider').getStyle('left').toInt() + this.options.thumbWidth * this.options.slideLength);
				this.counterControls--;
			}
		}.bind(this));
		
		$('gallery-controls-play').addEvent('click', function(){
			if (!this.autoPlay) {
				//start a periodical if not exist
				this.autoPlay = this.autoPlayer.periodical(this.options.playerSpeed, this, fx);
				//change image
				$('gallery-controls-play').addClass('p');
			} else {
				$('gallery-controls-play').removeClass('p');
				$clear(this.autoPlay);
				this.autoPlay = false;
			}
		
		}.bind(this));
	},
	
	autoPlayer : function(fx){
		this.activeThumb++
		
		if ($('gallery-thumb-' + this.activeThumb)) {
			$('gallery-thumb-' + this.activeThumb).fireEvent('click');
			//slide tous les 4
			if (this.activeThumb % this.options.slideLength == 0) $('gallery-controls-next').fireEvent('click');
		} else {
			this.activeThumb = 0;
			this.counterControls = 0;
			$('gallery-thumb-' + this.activeThumb).fireEvent('click');
			//slide au d�but
			fx.start('left', 0);
		}
	},
	
	killAutoPlayer : function(){
		//kill autoplay if needed
		if (this.autoPlay) {
			$('gallery-controls-play').removeClass('p');
			$clear(this.autoPlay);
			this.autoPlay = false;
		}
	},
	
	loadGallery : function(id, li){
		//Clean previous if exist
		$('gallery-thumbs').empty();
		
		//return to left
		this.activeThumb = 0;
		this.counterControls = 0;
		$('gallery-slider').setStyle('left', 0);
		
		//fill with new elements
		var size = this.options.imageSize;
		
		$('gallery-title').set('html', this.sections[id -1].getProperty('rel'))
		
		this.sections[id -1].getChildren().each(function(img, i){
			var infos = img.getFirst();
			var li = new Element('li').inject('gallery-thumbs');
			var thumb = new Element('img', {
				id: 'gallery-thumb-' + i,
				rel: i,
				styles : {
					opacity : 0
				},
				events : {
					load : function(){
						//setsize
						var ratio = this.height / this.width;
						if (ratio <= size.height / size.width) {
							//image is larger
							this.width = 96;
							this.height = 96 * ratio;
						} else {
							//image is heigher
							this.height = 72;
							this.width = 72 / ratio;
						}
						
						this.setStyle('marginTop', (72 - this.height) / 2);
						
						this.fade(0, 1);
					}
				},
				src: infos.getProperty('rev')
			}).inject(li);
			
			//add click event
			thumb.addEvent('click', function(){
				this.loadPicture(infos.getProperty('href'));
				this.setBorder(thumb);
				this.activeThumb = thumb.getProperty('rel');
			}.bind(this));
		}, this);
		
		//open first image
		$('gallery-thumbs').getElement('img').fireEvent('click', '', 500);
		
		//set gallery active
		if (this.activeGallery) this.activeGallery.removeClass('s');
		this.activeGallery = li.addClass('s');
		this.activeThumb = 0;
	},
	
	loadPicture : function(url) {
		$('gallery-picture').empty();
		var size = this.options.imageSize;
		var viewSize = {
			width : $('gallery-picture').getStyle('width').toInt(),
			height : $('gallery-picture').getStyle('height').toInt()
		}
		var upscaling = this.options.upscaling;
		new Element('img', {
			styles : { opacity : 0 },
			events : {
				load : function(){
					//determine width & height if not standard
					if ((upscaling && (this.width < size.width || this.height < size.height)) || this.width >= size.width || this.height >= size.height) {
						var ratio = this.height / this.width;
						if (ratio <= size.height / size.width) {
							//image is larger
							this.width = size.width;
							this.height = size.width * ratio;
						} else {
							//image is heigher
							this.height = size.height;
							this.width = size.height / ratio;
						}
					}
					var mLeft = Browser.Engine.trident ? 0 : (viewSize.width - this.width) / 2;
					this.setStyles({
						'marginTop' : (viewSize.height - this.height) / 2,
						'marginLeft': mLeft
					});
					
					//add the new image with a fade
					this.fade(1);
				}
			},
			src : url
		}).inject('gallery-picture');
	},
	
	setBorder : function(target){
		if (!this.follower) {
			this.follower = new Element('div', {
				id : 'gallery-follower'
			}).inject('gallery-slider');
			
			this.follower.fx = new Fx.Tween(this.follower);
		}
		
		var coord = target.getPosition('gallery-slider');
		
		this.follower.fx.start('left', coord.x-1);
	},
	
	closeGallery : function(fx){
		//remove overlay
		fx.start('opacity', 0);
		
		//hide gallery
		this.wrapperFx.start('opacity', 0);
		
		this.killAutoPlayer();
	},
	
	setBehavior : function(){
		
		//get some elements
		this.root = $$(this.options.selector);
		this.opener = this.options.unlinkedOpener ? $$(this.options.opener)[0] : this.root.getElement(this.options.opener);
		this.sections = this.root.getElements(this.options.gallerySelector)[0];
		
		//add event on opener
		this.opener.addEvent('click', function(e){
			new Event(e).stop();
			this.build();
		}.bind(this));
	}
});
