/*
 * Slideshow
 * @ Anthor : YSD Kenny
 *
 */

;(function(win){
	if(typeof(Class.create)=='undefined'||typeof(Effect)=='undefined')throw 'prototype.js and scriptaculous required for Element Slideshow';
	
	var SlideShow=Class.create({
		initialize:function(elm,options){
			this.element=$(elm);
			this.elementId=Element.identify(this.element);
			this._Timer=null;
			// default options
			this.opt=Object.extend({
				ClassName:{
					Pool:'SlideShowPool',
					Node:'SlideShowNode',
					DotPool:'SlideShowDotPool',
					ButtonDot:'btnSlideShowDot',
					ButtonNext:'btnSlideShowNext',
					ButtonPrev:'btnSlideShowPrev'
				},
				isLoop:true,
				isAutoStart:true,
				EffectTrans:'appear',
				EffectDuration:.5,
				EffectDelay:5,
				EffectQueueName:'SlideShow-'+this.elementId,
				DotTemplate:''
			},options);

			this.PoolElement=this.element.select('.'+this.opt.ClassName.Pool).first();
			if(typeof(this.PoolElement)=='undefined')throw this.elementId+': No Element Pool for slide show';
			
			this.NodeElements=this.PoolElement.select('.'+this.opt.ClassName.Node);
			if(this.NodeElements.size()==0)throw this.elementId+': No node in Pool';

			this.CurrentElement=this.NodeElements.invoke('setStyle',{
				'position':'absolute'
			}).invoke('hide').first().observe('load',function(){
				var dim=Element.show(this).getDimensions();
				Element.up(this).setStyle({width:dim.width+'px',height:dim.height+'px'});
			}).show();

			this.DotPoolElement=this.element.select('.'+this.opt.ClassName.DotPool).first();
			if(this.DotPoolElement&&this.opt.DotTemplate.blank()){
				this.DotButton=this.element.select('.'+this.opt.ClassName.ButtonDot).first();
				if(typeof(this.DotButton)!='undefined'){
					this.DotButtonTemplate=Element.clone(this.DotButton,true);
					this.DotPoolElement.update('');
					this.NodeElements.each(function(e,i){
						var dot=Element.clone(this.DotButtonTemplate,true);
						Element.store(dot,'SlideShowIndex',i+1).SlideShowObj=this;
						dot.SlideShowRelatedObj=e;
						e.SlideShowRelatedObj=dot;
						this.DotPoolElement.insert({bottom:dot});
						
						Event.observe(dot,'click',function(){
							if(!Element.visible(this.SlideShowRelatedObj))this.SlideShowObj.goto(this.SlideShowRelatedObj);
							//console.log(this.SlideShowRelatedObj);
							//event.stop();
						});
					}.bind(this));
					Element.addClassName(this.getCurrent().SlideShowRelatedObj,'current');
				}
			}else{
				
			}

			if(this.opt.isLoop&&this.opt.isAutoStart)this.start();
		},
		goto:function(obj){
			return this.stop()._TransAppear(this.getCurrent(),$(obj)).start();
		},
		next:function(){
			return this._TransAppear(this.getCurrent(),this.getNext());
		},
		prev:function(){
			return this._TransAppear(this.getCurrent(),this.getPrev());
		},
		start:function(){
			if(this._Timer==null){
				this._Timer=new PeriodicalExecuter(this._OnTimerTick.bind(this),this.opt.EffectDelay);	
			}
			return this;
		},
		stop:function(){
			if(this._Timer!=null){
				this._Timer.stop();
				delete this._Timer;
				this._Timer=null;
			};
			return this;
		},
		getCurrent:function(){
			return this.CurrentElement;
		},
		getNext:function(){
			return this.CurrentElement==this.NodeElements.last()?this.NodeElements.first():this.CurrentElement.next('.'+this.opt.ClassName.Node);
		},
		getPrev:function(){
			return this.CurrentElement==this.NodeElements.first()?this.NodeElements.last():this.CurrentElement.previous('.'+this.opt.ClassName.Node);
		},
		setCurrent:function(obj){
			if(this.DotPoolElement&&this.getCurrent().SlideShowRelatedObj&&obj.SlideShowRelatedObj){
				Element.removeClassName(this.getCurrent().SlideShowRelatedObj,'current');
				Element.addClassName(obj.SlideShowRelatedObj,'current');
			}
			this.CurrentElement=obj;
		},
		_OnTimerTick:function(){
			return this.stop().next().start();
		},
		_PoolSizeFix:function(){
			
		},
		_TransAppear:function(current,next){
			new Effect.Parallel([new Effect.Fade(current,{sync:true}),new Effect.Appear(next,{sync:true})],{
				duration:this.opt.EffectDuration,
				queue:{position:'end',scope:this.opt.EffectQueueName,limit:2},
				afterFinish:function(){
					this.element.fire("slideshow:afterEffect");
				}.bind(this)
			});
			this.setCurrent(next);
			return this;
		}
	});
	
	win.SlideShow=SlideShow;
})(window);
