/*
 * SlideShow 
 * 
 * @auther : Sahbi KHALFALLAH <sa7booch@yahoo.fr>
 * @date : 24/02/2010
 * 
 */

Object.extend(Event, {
	wheel: function (event) {
		var delta = 0;
		if (!event) event = window.event;
		if (event.wheelDelta) {
			delta = event.wheelDelta/120; 
			if (window.opera) {
				delta = -delta;
			}
		} else if (event.detail) {
			delta = -event.detail/3;
		}
		return Math.round(delta);
	}
});

var SlideShow = Class.create({
	
	defaultOptions: {
		dataSourceMode: 'html', /* html ajax */
		dataSourceUrl: null, 
		sliderWidth: 600,
		sliderHeight: 300,
		containerWidth: 400,
		containerHeight: 300,
		thumbsWidth: 200,
		thumbsHeight: 300,
		thumbWidth: 200,
		thumbHeight: 100,
		thumbsPosition: 'after',
		thumbsDirection: 'vertical',
		showShortDescription: false,
		shortDescriptionLength: 25,
		showLongDescription: true,
		longDescriptionLength: 250,
		sliderDirection: 'horizontal',
		defaultIndex: 3,
		duration: 0.5,
		transition: Effect.Transitions.linear,
		descriptionWidth: 400,
		descriptionHeight: 80,
		descriptionTop: 220,
		descriptionLeft: 0,
		descriptionDirection: 'vertical',
		showDescriptionBox: true,
		closableDescription: true,
		closeButtonPosition: 'tr', /* tl : top-left / tr : top-right / bl : bottom-left / br : bottom-right */
		closeButtonMargin: 2
	},
	
	initialize: function(slideShowId, options) {
		
		this.setOptions(options);
		this.currentIndex = null;
		this.slideShowId = slideShowId;
		this.container = $(this.slideShowId);
		
		/* initializing items */
		this.items = [];
		
		if (this.options.dataSourceMode == 'html') {
			$$('#'+this.slideShowId+' div').each(function(div){
				var links = div.getElementsByTagName('a');
				var images = div.getElementsByTagName('img');
				var paragraphs = div.getElementsByTagName('p');
				this.items.push({
					title: links[0].innerHTML,
					link: links[0].href,
					thumb: images[0].src,
					description: paragraphs[0].innerHTML
				});
			}.bind(this));
			this.start();
		} else if (this.options.dataSourceMode == 'ajax') {
			new Ajax.Request(this.options.dataSourceUrl, {
				onSuccess: function(xhr){
					var json = xhr.responseText.evalJSON();
					if (json.items) {
						this.items = json.items;
						this.start();
					}
				}.bind(this)
			});
		}
	},
	
	setOptions: function(options) {
		this.options = Object.extend(Object.clone(this.defaultOptions), options || {});
	},

	start: function(){
		
		$(this.slideShowId).update();
		
		/* setting slide show style */
		$(this.slideShowId).setStyle({
			width: this.options.sliderWidth+'px',
			height: this.options.sliderHeight+'px',
			position: 'relative'
		});
		
		var slideshow_container = new Element('div', {
			'class': 'slideshow_container',
			id: 'slideshow_container_'+this.slideShowId
		});
		this.container.insert(slideshow_container);
		$('slideshow_container_'+this.slideShowId).setStyle({
			width: this.options.containerWidth+'px',
			height: this.options.containerHeight+'px',
			position: 'relative',
			float: 'left',
			overflow: 'hidden'
		});
		
		$('slideshow_container_'+this.slideShowId).insert(
			new Element('div', {
				'class': 'slideshow_mask',
				id: 'slideshow_mask_'+this.slideShowId
			})
		);

		$('slideshow_mask_'+this.slideShowId).absolutize();
		
		$('slideshow_mask_'+this.slideShowId).setStyle({
			width: this.options.containerWidth+'px',
			height: this.options.containerHeight+'px',
			zIndex: 999
		});
			
		var slideshow_slider = new Element('div', {
			'class': 'slideshow_slider',
			id: 'slideshow_slider_'+this.slideShowId
		});
		$('slideshow_container_'+this.slideShowId).insert(slideshow_slider);
		
		if (this.options.sliderDirection == 'horizontal') {
			var sliderWidth = this.options.containerWidth*this.items.length;
			var sliderHeight = this.options.containerHeight;
		} else if (this.options.sliderDirection == 'vertical') {
			var sliderWidth = this.options.containerWidth;
			var sliderHeight = this.options.containerHeight*this.items.length;
		}
		$('slideshow_slider_'+this.slideShowId).setStyle({
			width: sliderWidth+'px',
			height: sliderHeight+'px',
			position: 'absolute',
			top: 0,
			left: 0,
			zIndex: 0
		});
		
		if (this.options.thumbsDirection == 'horizontal') {
			this.showedThumbs = this.options.thumbsWidth / this.options.thumbWidth;
			this.thumbsContainerHeight = this.options.thumbsHeight;
			this.thumbsContainerWidth = this.options.thumbWidth*this.items.length;
		} else if (this.options.thumbsDirection == 'vertical') {
			this.showedThumbs = this.options.thumbsHeight / this.options.thumbHeight;
			this.thumbsContainerHeight = this.options.thumbHeight*this.items.length;
			this.thumbsContainerWidth = this.options.thumbsWidth;
		}
		
		var slideshow_thumbs =  new Element('div', {
			'class': 'slideshow_thumbs',
			id: 'slideshow_thumbs_'+this.slideShowId
		}).update(
			new Element('div', {
				id: 'slideshow_thumbs__'+this.slideShowId
			})
		);
		
		if (this.options.thumbsPosition == 'before') {
			this.container.insert({top:slideshow_thumbs});
		} else if (this.options.thumbsPosition == 'after') {
			this.container.insert({bottom:slideshow_thumbs});
		}
		$('slideshow_thumbs__'+this.slideShowId).setStyle({
			width: this.thumbsContainerWidth+'px',
			height: this.thumbsContainerHeight+'px',
			float: 'left',
			overflow: 'hidden',
			position: 'absolute',
			top: '0px',
			left: '0px'
		});

		$('slideshow_thumbs_'+this.slideShowId).setStyle({
			width:this.options.thumbsWidth+'px',
			height:this.options.thumbsHeight+'px',
			float: 'left',
			overflow: 'hidden',
			position: 'relative'
		});
		
		var id = 0;
		
		if (this.options.showDescriptionBox) {
			if (this.options.descriptionDirection == 'horizontal') {
				var descriptionTop = this.options.descriptionTop;
				if(this.options.descriptionLeft == 0) {
					var descriptionLeft = -this.options.containerWidth;
				} else {
					var descriptionLeft = this.options.containerWidth;
				}
			} else if (this.options.descriptionDirection == 'vertical') {
				if(this.options.descriptionTop == 0) {
					var descriptionTop = -this.options.containerHeight;
				} else {
					var descriptionTop = this.options.containerHeight;
				}
				var descriptionLeft = this.options.descriptionLeft;
			}
		}
		
		this.items.each(function(item){
			id++;
			
			/* creating thumbs */
			var itemThumbElement = new Element('div', {
				'class': 'slideshow_thumb',
				id: 'slideshow_thumb_'+id+'_'+this.slideShowId
			});
			$('slideshow_thumbs__'+this.slideShowId).insert(itemThumbElement);
			$('slideshow_thumb_'+id+'_'+this.slideShowId).setStyle({
				width:this.options.thumbWidth+'px',
				height:this.options.thumbHeight+'px',
				overflow: 'hidden',
				float: 'left'
			});
			$('slideshow_thumb_'+id+'_'+this.slideShowId).insert(
				new Element('a', {href: item.link}).update(item.title)
			);
			$('slideshow_thumb_'+id+'_'+this.slideShowId).insert(
				new Element('img', {src: item.thumb, id: 'slideshow_pic_'+id+'_'+this.slideShowId})
			);
			if (this.options.showShortDescription) {
				$('slideshow_thumb_'+id+'_'+this.slideShowId).insert(
					new Element('p').update(this.substring(item.description, this.options.shortDescriptionLength))
				);
			}
			
			/* creating descriptions */
			if (this.options.showDescriptionBox) {
				var itemDescriptionElement = new Element('div', {
					'class': 'slideshow_description',
					id: 'slideshow_description_'+id+'_'+this.slideShowId
				}).update(
					new Element('div', {
						id: 'slideshow_description__'+id+'_'+this.slideShowId
					})
				);
				$('slideshow_container_'+this.slideShowId).insert(itemDescriptionElement);
				$('slideshow_description_'+id+'_'+this.slideShowId).setStyle({
					width:this.options.descriptionWidth+'px',
					height:this.options.descriptionHeight+'px',
					top: descriptionTop+'px',
					left: descriptionLeft+'px',
					position: 'absolute',
					overflow: 'hidden',
					zIndex: 1000
				});
				$('slideshow_description__'+id+'_'+this.slideShowId).insert(
					new Element('a', {href: item.link}).update(item.title)
				);
				if (this.options.showLongDescription) {
					$('slideshow_description__'+id+'_'+this.slideShowId).insert(
						new Element('p').update(this.substring(item.description, this.options.longDescriptionLength))
					);
				}
				if (this.options.closableDescription) {
					
					switch (this.options.closeButtonPosition) {
						case 'tl':
							var style = {position: 'absolute', top: this.options.closeButtonMargin+'px', left: this.options.closeButtonMargin+'px'};  
						break;
						case 'tr':
							var style = {position: 'absolute', top: this.options.closeButtonMargin+'px', right: this.options.closeButtonMargin+'px'};  
						break;
						case 'bl':
							var style = {position: 'absolute', bottom: this.options.closeButtonMargin+'px', left: this.options.closeButtonMargin+'px'};  
						break;
						case 'br':
							var style = {position: 'absolute', bottom: this.options.closeButtonMargin+'px', right: this.options.closeButtonMargin+'px'};  
						break;
					}
					
					$('slideshow_description__'+id+'_'+this.slideShowId).insert(
						new Element('div', {
							'class': 'slideshow_close',
							id: 'slideshow_close_'+id+'_'+this.slideShowId
						}).setStyle(style)
					);
					
					Event.observe('slideshow_close_'+id+'_'+this.slideShowId, 'click', function(event){
						var index = event.findElement().id.replace('slideshow_close_', '').replace('_'+this.slideShowId, '');
						$('slideshow_description_'+index+'_'+this.slideShowId).hide();
					}.bind(this));
				}
			}
			
			/* creating  pics */
			var slideshow_slider_pic = new Element('img', {src: item.thumb}).setStyle({
				width:this.options.containerWidth+'px',
				height:this.options.containerHeight+'px',
				margin:0,
				padding:0
			});
			$('slideshow_slider_'+this.slideShowId).insert(slideshow_slider_pic);
			
			/* creating events */
			Event.observe('slideshow_pic_'+id+'_'+this.slideShowId, 'click', function(event){
				this.slideTo(event);
			}.bind(this));
			
		}.bind(this));

		$(this.slideShowId).show();
		
		Event.observe($(this.slideShowId), 'mousewheel', function(event) {
			this.scroll(event);
		}.bind(this), false);
		
		Event.observe($(this.slideShowId), 'DOMMouseScroll', function(event) {
			this.scroll(event);
		}.bind(this), false);
		
		this.slideTo(this.options.defaultIndex);
	},
	
	slideTo: function(event) {
		if (typeof event == 'number') {
			var index = event;
		} else {
			var index = event.findElement().id.replace('slideshow_pic_', '').replace('_'+this.slideShowId, '');
		}
		
		if (this.currentIndex != index) {
			
			if (this.options.showDescriptionBox) {
			
				if (this.options.descriptionDirection == 'horizontal') {
					
					var positonAttribute = 'left';
					
					if(this.options.descriptionLeft == 0) {
						var positionOld = -this.options.containerWidth;
					} else {
						var positionOld = this.options.containerWidth;
					}
					
					var positionNew = this.options.descriptionLeft;
					
				} else if (this.options.descriptionDirection == 'vertical') {
					
					var positonAttribute = 'top';
					
					if(this.options.descriptionTop == 0) {
						var positionOld = -this.options.containerHeight;
					} else {
						var positionOld = this.options.containerHeight;
					}
					
					var positionNew = this.options.descriptionTop;
					
				}
				
				if (this.currentIndex != null) {
					new Effect.Morph('slideshow_description_'+this.currentIndex+'_'+this.slideShowId, {
						style: positonAttribute+':'+positionOld+'px;',
						duration: this.options.duration,
						transition: this.options.transition
					});
				}
				
				$('slideshow_description_'+index+'_'+this.slideShowId).show();
				new Effect.Morph('slideshow_description_'+index+'_'+this.slideShowId, {
					style: positonAttribute+':'+positionNew+'px;',
					duration: this.options.duration,
					transition: this.options.transition
				});
			}
			
			if (this.currentIndex != null) {
				$('slideshow_thumb_'+this.currentIndex +'_'+this.slideShowId).removeClassName('active');
			}
			$('slideshow_thumb_'+index+'_'+this.slideShowId).addClassName('active');
			
			if (this.options.sliderDirection == 'horizontal') {
				var attribute = 'left';
				var positonAttribute = (index-1)*this.options.containerWidth;
			} else if (this.options.sliderDirection == 'vertical') {
				var attribute = 'top';
				var positonAttribute = (index-1)*this.options.containerHeight;
			}
			
			new Effect.Morph('slideshow_slider_'+this.slideShowId, {
				style: attribute+':-'+positonAttribute+'px;',
				duration: this.options.duration,
				transition: this.options.transition
			});
			
			if (index > 1 && (index < this.items.length || (this.options.defaultIndex == index && this.currentIndex == null))) {
				
				var step = 1;
				
				if (this.showedThumbs == 2 && this.currentIndex == index -1) {
					var step = 0;
				}

				if (this.showedThumbs != 2 && this.options.defaultIndex == this.items.length && this.currentIndex == null) {
					var step = 2;
				}
				
				var x = Math.floor(this.showedThumbs/2)-index+step;
				
				if (this.options.thumbsDirection == 'horizontal') {
					var attribute = 'left';
					var positonAttribute = x*this.options.thumbWidth;
				} else if (this.options.thumbsDirection == 'vertical') {
					var attribute = 'top';
					var positonAttribute = x*this.options.thumbHeight;
				}
				
				new Effect.Morph('slideshow_thumbs__'+this.slideShowId, {
					style: attribute+':'+positonAttribute+'px;',
					duration: this.options.duration,
					transition: this.options.transition
				});
				
			}
			
			this.currentIndex = index;
		}
	},
	
	substring: function(str, length) {
		var new_str = str.substring(0, length);
		if (str.length > length) {
			new_str += '&hellip;';
		}
		return new_str;
	},
	
	scroll: function(event) {
		var index = this.currentIndex + Event.wheel(event);
		if (index < 1) {
			index = 1;
		} else if (index > this.items.length) {
			index = this.items.length;
		}
		this.slideTo(index);
	}
	
});

