


var BertaGallery = new Class({
	
	Implements: Options,
	
	options: {
		type: 'slideshow',
		engineRoot: null,
		engineABSRoot: null,
		playerType: 'JWPlayer'
	},
	
	type: 'slideshow',
	container: null,
	imageContainer: null,
	navContainer: null,
	rowClearElement: null,
	
	newObjectInjectWhere: null,
	newObjectInjectPosition: null,

	currentSrc: null,
	currentType: null,
	currentVideoPath: null,
	preload: null,
	phase: null,
	
	imageFadeOutFx: null,
	imageResizeFx: null,
	imageShowFx: null,
	
	numFinishedLoading: 0,
	
	initialize: function(container, options) {
		this.setOptions(options);
		this.attach(container);
		this.loadFirst();
	},
	
	
	attach: function(container) {
		this.container = container;
		this.type = this.container.getClassStoredValue('xGalleryType');
		//this.container.addClass('galleryType-' + this.type);
		
		this.imageContainer = this.container.getElement('div.xGallery');
		this.navContainer = this.container.getElement('ul.xGalleryNav');
		
		if(this.navContainer && this.navContainer.getElements('a').length > 0) {
			this.imageFadeOutFx = new Fx.Tween(this.imageContainer, { duration: 'short', transition: Fx.Transitions.Sine.easeInOut });
			this.imageShowFx = new Fx.Tween(this.imageContainer, { duration: 'normal', transition: Fx.Transitions.Sine.easeInOut });
			
			if(this.type == 'slideshow') {
				this.imageResizeFx = new Fx.Morph(this.imageContainer, { duration: 'short', transition: Fx.Transitions.Sine.easeInOut });
				this.nav_setEvents();
				
				this.newObjectInjectWhere = this.options.environment == 'site' ? this.imageContainer : this.imageContainer.getElement('.xGalleryEditButton');
				this.newObjectInjectPosition = this.options.environment == 'site' ? 'bottom' : 'before';
				
			} else {
				this.rowClearElement = new Element('br', { 'class': 'clear' }).inject(this.imageContainer);
				
				this.newObjectInjectWhere = this.options.environment == 'site' ? this.rowClearElement : this.imageContainer.getElement('.xGalleryEditButton');
				this.newObjectInjectPosition = 'before';
			}
		} else 
			this.navContainer = null;
	},
	detach: function() {
		if(this.navContainer) {
			this.navContainer.getElements('a').each(function(item) {
				item.removeEvents('click');
			});
		
			this.imageFadeOutFx.cancel();
			if(this.imageResizeFx) this.imageResizeFx.cancel(); 
			this.imageShowFx.cancel();
			this.imageFadeOutFx = this.imageResizeFx = this.imageShowFx = null;
		}
		this.container = this.imageContainer = this.navContainer = null;
		this.currentSrc = null;
	},
	
	
	

	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////| Loading  |////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	
	loadFirst: function() {
		
		if(this.navContainer) {
			var li = this.navContainer.getElement('li')
			this.nav_highlightItem(li);
			var aEl = this.navContainer.getElement('li a');
			var fistItemType = aEl.getClassStoredValue('xType');
			
			if(fistItemType != 'image') {
				// load only if not image, because if that's image, it's already written in the HTML
				this.load(aEl.get('href'), aEl.getClassStoredValue('xType'), aEl.getClassStoredValue('xW'), aEl.getClassStoredValue('xH'), aEl.getClassStoredValue('xVideoHref'), li.getElement('.xGalleryImageCaption').get('html'), true);
			} else {
				this.currentSrc = aEl.get('href');
				this.preload = this.imageContainer.getElement('div.xGalleryItem');
				if(this.getNext() && this.type == 'slideshow') {
					this.preload.setStyle('cursor', 'pointer');
					this.preload.addEvent('click', this.loadNext.bind(this));
				}
				if(this.type == 'row') {
					this.layout_update();
					this.loadNext();
				}
			}
		}
	},
	
	loadNext: function(bRotate) {
		if(this.navContainer) {
			var nextLi = this.getNext(bRotate);
			if(nextLi) {
				this.nav_highlightItem(nextLi);
				var aEl = nextLi.getElement('a');
				this.load(aEl.get('href'), aEl.getClassStoredValue('xType'), aEl.getClassStoredValue('xW'), aEl.getClassStoredValue('xH'), aEl.getClassStoredValue('xVideoHref'), nextLi.getElement('.xGalleryImageCaption').get('html'));
			} else {
				// end of the list reached, do nothing
			}
		}
	},
	
	getNext: function(bRotate) {
		if(this.navContainer) {
			var selectedLi = this.navContainer.getElement('li.selected');
			if(selectedLi) {
				var n = selectedLi.getNext();
				if(!n && bRotate) {
					n = this.navContainer.getElement('li');
				}
				return n;
			}	
		}
		return null;
	},
	
	
	
	
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////| Layout  |/////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	
	
	layout_update: function() {
		// implementable
		// in a template you can implement this function
		
		// this is a default implementation that assumes that "row" mode is horizontal
		if(this.type == 'row') {
			var totalWidth = 0, maxHeight = 0, itmSize, numImages = 0;
			this.imageContainer.getChildren('.xGalleryItem').each(function(item) {
				item.setStyle('height', 'auto');
				itmSize = item.getSize();
				totalWidth += itmSize.x;
				if(itmSize.y > maxHeight) maxHeight = itmSize.y;
				numImages++;
			});
			
			this.imageContainer.setStyle('width', (totalWidth + numImages /* for "em" discrepancy */) + 'px');
			//this.imageContainer.setStyle('height', maxHeight + 'px');
		}
	},
	
	layout_inject: function(bDeleteExisting, bDoFade) {
		//console.debug('inject ', this.preload, ' with bDeleteExisting = ', bDeleteExisting);
		if(bDeleteExisting) this.imageContainer.getChildren('.xGalleryItem').destroy();
		
		if(bDoFade) this.imageShowFx.set('opacity', 0).start('opacity', 1);
		this.preload.inject(this.newObjectInjectWhere, this.newObjectInjectPosition);
		this.layout_update();
	},
	
	layout_finisage: function(src, mType, mWidth, mHeight) {
		if(mType == 'image' && this.getNext(this.options.slideshowAutoRewind == 'yes')) {
			this.preload.setStyle('cursor', 'pointer');
			this.preload.addEvent('click', this.layout_onImageClick.bindWithEvent(this));
		}
	},
	
	layout_onImageClick: function(event) {
		this.loadNext(this.options.slideshowAutoRewind == 'yes');
	},
	
	
	
	
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////| Navigation  |/////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	
	nav_setEvents: function() {
		// implementable in the future
		this.navContainer.getElements('a').addEvent('click', this.nav_onItemClick.bindWithEvent(this));
	},
	
	nav_onItemClick: function(event) {
		// implementable in the future
		
		event.stop();
		var linkElement = $(event.target);
		var li = linkElement.getParent('li');
		this.nav_highlightItem(li);
		var caption = li.getElement('.xGalleryImageCaption').get('html');
		
		this.load(linkElement.get('href'), linkElement.getClassStoredValue('xType'), linkElement.getClassStoredValue('xW'), linkElement.getClassStoredValue('xH'), linkElement.getClassStoredValue('xVideoHref'), caption);
	},
	nav_highlightItem: function(liElement) {
		// implementable in the future
		this.navContainer.getElements('li').removeClass('selected');
		liElement.addClass('selected');
	},
	
	
	
	
	
	
	
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////| Loading engine  |/////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	
	// load: starts the actual loading of next image/video into the container
	
	load: function(src, mType, mWidth, mHeight, videoPath, caption, bDeleteExisting) {
		switch(this.phase) {
			case 'fadeout': this.imageFadeOutFx.cancel(); break;
			case 'fadein': this.imageResizeFx.cancel(); this.imageShowFx.cancel(); break;
		}
		
		if(this.currentSrc && this.type == 'slideshow') {
			this.currentSrc = null;
			this.phase = "fadeout";
			this.imageFadeOutFx.start('opacity', 0).chain(this.load_Render.bind(this, [ src, mType, mWidth, mHeight, videoPath, caption, bDeleteExisting ]));
			
		} else {
			this.currentSrc = null;
			this.load_Render(src, mType, mWidth, mHeight, videoPath, caption, bDeleteExisting);
		}
	},
	load_Render: function(src, mType, mWidth, mHeight, videoPath, caption, bDeleteExisting) {
		this.currentSrc = src;
		this.currentType = mType;
		this.currentVideoPath = videoPath;
		this.currentCaption = caption;
		
		if(this.type == 'slideshow') {
			var obj;
			if(obj = this.imageContainer.getElement('div.xGalleryItem')) obj.destroy();
		}
		
		switch(mType) {
			case 'image':
				this.phase = "preload";
				this.preload = new Asset.image(src, this.type == 'slideshow' ? {
					'onload': this.load_Finish.bind(this, [ src, mType, mWidth, mHeight, bDeleteExisting ])
				} : {});
				this.preload = new Element('div', { 'class': 'image' }).adopt(this.preload);
				if(this.type == 'row') {
					if(mWidth) this.preload.setStyle('width', mWidth + 'px');
					if(mHeight) this.preload.setStyle('height', mHeight + 'px');
				}
				
				this.preload = new Element('div', { 'class': 'xGalleryItem xGalleryItemType-image' }).adopt(this.preload);
				if(this.type == 'row') {
					if(mWidth) this.preload.setStyle('width', mWidth + 'px');
					if(mHeight) this.preload.setStyle('height', mHeight + 'px');
				}
				
				new Element('div', { 'class': 'xGalleryImageCaption' }).set('html', caption).inject(this.preload);
				
				if(this.type != 'slideshow') this.load_Finish(src, mType, mWidth, mHeight, bDeleteExisting);
				break;
			
			case 'video':
				this.preload = new Element('div', { 'class': 'xGalleryItem xGalleryItemType-video', 'style': { 'opacity': 0 } });
				//this.preload.setStyle('background-image', 'url(\'' + src + '\')');
				//this.preload.setStyle('background-repeat', 'no-repeat');
								
				if(mWidth) this.preload.setStyle('width', mWidth + 'px');
				this.layout_inject(bDeleteExisting, true);
				
				if(this.options.playerType == 'JWPlayer' || this.options.playerType == 'JWPlayer_Overlay') { 
					if(mHeight) mHeight = parseInt(mHeight) + 25;
					
					var vars = {
						'file': videoPath,
						'image': src,
						'stretching': 'fill'
						//'skin': '/' + this.options.engineRoot + 'jwplayer/bekle.swf'
					};
					if(this.options.playerType == 'JWPlayer_Overlay') {
						if(mHeight) mHeight = parseInt(mHeight) - 25;
						vars.skin = this.options.engineABSRoot + '_lib/jwplayer/bekle/bekle.xml';
						vars.controlbar = 'over';
					}
					
					if(mHeight) this.preload.setStyle('height', mHeight + 'px');
					
					new Swiff(this.options.engineABSRoot + '_lib/jwplayer/player.swf', {
						'container': this.preload,
						'width': mWidth,
						'height': mHeight,
						'params': {
							'allowFullScreen': true,
							'menu': false
						},
						'vars': vars
					});
				} 
				else {
					if(mHeight) {
						mHeight = parseInt(mHeight);
						this.preload.setStyle('height', mHeight + 'px');
					}
					new Swiff(this.options.engineABSRoot + '_lib/nonverblaster/NonverBlaster.swf', {
						container: this.preload,
						width: mWidth,
						height: mHeight,
						params: {
							'allowFullScreen': true,
							'menu': false,
							'allowScriptAccess': 'always'
						},
						vars: {
							'mediaURL': videoPath,
							'teaserURL': src,
							'allowSmoothing': 'true',
							'autoPlay': 'false',
							'controlColor': "0xffffff",
							'crop': "false",
							'scaleIfFullScreen': 'true',
							'showScalingButton': 'false'
						
						}
					});
				}
				
				new Element('img', { 'src': src, 'class' : 'xGalleryImageVideoBack', 'styles': {
					'width' : mWidth + 'px',
					'height' : mHeight + 'px'
				} }).inject(this.preload, 'top');
				
				new Element('div', { 'class': 'xGalleryImageCaption' }).set('html', caption).inject(this.preload);
				this.load_Finish(src, mType, mWidth, mHeight, bDeleteExisting);
				
				break;
		}
		
	},
	load_Finish: function(src, mType, mWidth, mHeight, bDeleteExisting) {
		
		// test if the loaded image's src is the last invoked image's src
		if(src == this.currentSrc) {
			if(this.type == 'slideshow') {
				this.phase = "fadein";
				this.imageResizeFx.start({
					'width': mWidth,
					'height': mHeight
				}).chain(function() {
					this.phase = "done";
					if(mType == 'image') this.layout_inject(bDeleteExisting, true);
					this.layout_finisage(src, mType, mWidth, mHeight);
				}.bind(this));
			} else {
				this.phase = "done";
				//console.debug(this.preload);
				if(mType == 'image') this.layout_inject(bDeleteExisting, true);
				//this.preload.inject(this.newObjectInjectWhere, this.newObjectInjectPosition);
				this.layout_update();
				
				//new Fx.Tween(this.preload, { duration: 'normal', transition: Fx.Transitions.Sine.easeInOut }).set('opacity', 0).start('opacity', 1);
				this.loadNext();
			}
		}
	}
	
	
	
});


