
(function(){

  
   window.Application = {

			

  };
  



}());

(function(){
	
	

	var application = window.Application,
	    proto = window.proto,
		object = proto.object,
		array  = proto.array;
       
	

 var Slideshow =  (function(){
	 

	 function render(){
		 
		 if(this.isRendered){
		
			 return this;
		 }
		 
		 var cssClasses        = this.cssClasses,
		     container         = this.container.addClass( cssClasses.sldieshowContainer ),
		     slidesPanel       = this.slidesPanel.addClass( cssClasses.sldieshowPanel ),
			 controlsContainer = this.controlsContainer,
			 controls          = this.controls,
			 that              = this,
			 currentSlideIndex = this.currentSlideIndex  = this.defaultSlideIndex,
			 slide,
			 control;
/*			 
 proto.object.defineProperty( this ,"slideshowPanelWidth", { value        : slidesPanel.innerWidth() 
                                                            ,writable     : false
															,configurable : false   
															,enumerable   : true } );*/
															
																
						this.slideshowPanelWidth = slidesPanel.innerWidth();
						this.slideshowPanelHeight = slidesPanel.innerHeight();									
																	 
			 
			array.forEach( this.slides , function( slide , index ){
		
				that.appendSlide( slide );
			
				slidesPanel.append( slide.container );
			
					
				
			});
			
		
			
			if(this.slides.length > 1){
				
				if( that.renderControls ){
								
				array.forEach( this.slides , function( slide , index ){
		
					controlsContainer.append( controls[index] );
				
	
				index === that.currentSlideIndex ? controls[index].addClass( cssClasses.currentControl  ) : "";
			});
				
				
				}
				
			}
				
				
				if( this.slides[ this.currentSlideIndex] ){
					
					var curr = this.currentSlideIndex - 1;
				
                    this.slides[ this.currentSlideIndex ].container.addClass( "current-slide" ).css( { left : 0 , top : 0, display : "block" , zIndex : 9 } );
						  
				    while( curr >= 0 ){
						
					if( this.orientation === "x"  || this.orientation !== "y" ){
							  
					this.slides[ curr ].container.css( { left : ( "-" + this.slideshowPanelWidth ) });
					
						}
						
					if( this.orientation === "y"   ){
						
						this.slides[ curr ].container.css( { top : ( "-" + this.slideshowPanelHeight ) });
					}
							
						 curr -= 1;
						 
						  }
				}
				
		/*	  
	proto.object.defineProperty( this ,"isRendered", 
	                                                 { value : true, 
													   writable : false,  
													   configurable  : false,   
													   enumerable : true } );*/
							this.isRendered = true;						   
													   
	
				
			
	   	if( that.renderControls ){	

		attachControlsBehaviour.call( this );
		
		}
		
					if( proto.isFunction( this.onRender ) ){
				
				this.onRender.apply(this , [ slide , this.slides.length - 1 ] );
				
			}
		
		
		return true;
		 
	 }
	 
 
	 function animateToSlide(index , prevIndex ,callback){
		 
		 if( this.isTransitioning ){
			 
			 return;
			 
		 }

var    prevSlideContainer =  this.slides[ prevIndex ].container,
	   slideContainer     =  this.slides[ index ].container,
	   left      =  index > prevIndex  ? "-" + this.slideshowPanelWidth  :  this.slideshowPanelWidth,
	   that = this,
	   leftf =  this.slides[ index ]._left,
	   leftf =  index > prevIndex && leftf < 0  ? Math.abs(leftf)  : "-" + leftf; 

		prevSlideContainer.css("zIndex", 8);
		slideContainer.css({"zIndex" : 9 , left : leftf}  )
		               .show();
		
		this.isTransitioning = true;

			slideContainer.animate({left : 0 , top : 0},this.transitionSpeed );
			 
			 		 prevSlideContainer.animate({left : left},this.transitionSpeed ,function(){
							
			         that.slides[ index ]._left = left;
					  
					 prevSlideContainer.hide();
					 
					 callback.call(null);

					that.isTransitioning = false;
	
			 }); 
			 
			 

	
	 }
	 
	 
	 

		 
	function  buildSlide(){
		 
		 return  $("<div class='" + this.cssClasses.slideContainer + "'></div>");
		 
	 }
	 

	function buildControl(){
			
			return $("<button class='" + this.cssClasses.control  + "'></button>");
			
		}
		
		

	function appendSlide( slide ){
		
		if( !slide.container ){
			
			 this.slides.push( slide );
		}
		

			
			var builtSlide = slide.container = this.buildSlide();
			                        builtSlide.append( slide.html )
											  .css( { position : "absolute", 
											          left     :  this.slideshowPanelWidth,
													  zIndex   : 8, 
													  display  : "none"} );
							 slide._left =  this.slideshowPanelWidth;
							 slide._top  =  this.slideshowPanelHeight; 
							 
			if( this.isRendered ){
				
			this.slidesPanel.append( slide.container );
			

			
			}
	

			if( this.renderControls ){
		
			 var control = this.buildControl().data( "index" , this.slides.length - 1 );
			 
			this.controls.push( control ); 
			
			if( this.isRendered ){
				
			this.controlsContainer.append( control );
			
			}
			
	 		
			}
			
			if( proto.isFunction( this.onaAddSlide ) ){
				
				this.onAddSlide.apply(this , [ slide , this.slides.length - 1 ] );
				
			}
			
			

		
		  
		 
		 return this;
		 
		 }
		 
		 
		 function appendSlides( slides ){
			 
			 var that = this;
			 
			 proto.array.forEach( slides , function( slide ){
				 
				 that.appendSlide( slide );
				 
				 
			 });
			 
			 return this;
		 }
		 
	
		 
		 function removeSlides(){
			 
			 var slides  = [].concat( this.slides );
			 
			 this.slides = [];
			 
	         this.slidesPanel.empty();
			 this.controlsContainer.empty();
			 this.currentSlideIndex = 0
			 
			 		 return slides;
		 }
		 
		 function removeSlide( index ){
			 
			 var slide =  this.slides[index],
			     button =  this.controls[index];

			 if( slide ){
				 
				 slide.container.remove();
				 button.remove();
				 
				 this.slides.splice( index , index + 1);
				  this.controls.splice( index , index + 1);
				 
				if( proto.isFunction( this.onRemoveSlide ) ){
				
				this.onAddSlide.call( this ,  slide  );
				
			}
				 
				 
			 }
			 
			 return this;
			 
		 }
		 
		 
		 
		 
		 
		 
		 
	function getSlide(index , animation){
	
			if(index ==  this.slides.length){
				 
				index = 0;
			
			 }
		
			 
			 
			 var that  = this,
			 prevIndex = prevIndex == this.currentSlideIndex ? -1 : this.currentSlideIndex  ;
	
	

         this.currentSlideIndex = index;
		 



		var prevSlide =  ( prevIndex != -1 ? this.slides[ prevIndex ].html.removeClass( this.cssClasses.currentSlide ) : "");

		 this.slides[ this.currentSlideIndex ].html.addClass( this.cssClasses.currentSlide );
		
		 if( this.renderControls ){
		 
		( prevIndex != -1 ? that.controls[ prevIndex ].removeClass( that.cssClasses.currentControl ) : "" );	
		that.controls[ that.currentSlideIndex ].addClass( that.cssClasses.currentControl );
		
		 }

		 if(animation){
			
			this.slides[ index ].container.css({left : 0 , top : 0 ,  display : "block" });
			 return;
		 }
		 
		 
        this.animateToSlide( index , prevIndex , function(){
			
			if( proto.isFunction( that.onSlideChange ) ){
				
				that.onSlideChange.apply( that , [ that.slides[that.currentSlideIndex],that.currentSlideIndex ] );
				
			}
				
			
			
		      
				 
        });
		
		return this;
		 
		 }
		 
		 
		 function nextSlide(){
			 
			 
			 this.getSlide(this.currentSlideIndex  + 1);
			 
			 return this;
			 
		 }
		 
		 	function previousSlide(){
			 
			 
			 this.getSlide(this.currentSlideIndex  -1);
			 
			 return this;
			 
		    }
		 
		 
		 
		 
		 
		 
		 
     function attachControlsBehaviour(){
		 
		 
	   
	   var slideshow = this;
	   
	      	   
      this.controlsContainer.delegate("button","click",function(e){
		  
		  if( slideshow.isTransitioning ){
			  
			  return;
		  }
		  
		  slideshow.stop();
		  slideshow.play();
	   

	   
	   if($(this).hasClass(slideshow.cssClasses.currentControl )){
		
		   return;
	   }
	   
	   
	 
	 var index = $(this).data("index");

	     slideshow.getSlide( index  );
		
	 

 });
 
   
   }
   
     function play(){
		 
		 if(this.slides.length === 1){
			 
			 return;
		 }
		  
		  var 
		      timerId  = null,
			  that     = this;
		

		  timerID = setTimeout( function(){
			  
			  
			  var index = that.currentSlideIndex + 1;
		

			  that.isPlaying = true;
			  
			  that.getSlide( index );
			  
			  that.play();
			  
			  that.isPlaying = false;
			  
		  } , this.delay );
		  
		this.timerID = timerID;
		  
		  
	  }
	  
	  function stop(){
		  
		  
		  clearTimeout( this.timerID );
		  
	  }
	  

	 
	 return {
	 
	 container                   : null,
	 slidesPanel                 : null,
	 controlsContainer           : null,
	 slides                      : [],
	 controls                    : [],
	 nextControl                 : null,
	 prevControl                 : null,
	 showAllSlidesOnTransition   : true,
	 isTransitioning             : false,
	 renderNextPrevControls      : false,
	 renderControls              : true,
	 orientation                 : "x",/*
	 _renderCallbacksDeferred       :  proto.deferred(),
	 _addSlideCallbacksDeferred     :  proto.deferred(),
	 _slideChangeCallbacksDeferred  :  proto.deferred(),
	 _removeSlidesCallbacksDeferred :  proto.deferred(),*/
	 
	 cssClasses                  :  { currentSlide                   : "current-slide" , 
	                                           sldieshowContainer    : "sldieshow-container" ,
											   sldieshowPanel        : "slideshow-panel",
											   slideContainer        : "slideshow-slide-container",
											   control               : "slideshow-button",
											   currentControl        : "slideshow-button-current"
											   }  ,                     
	 direction                   : "ltr",
	 delay                       : 4000,	  
     autoPlay                    : false,
	 isPlaying                   : false,
	 play                        : play,
	 stop                        : stop,
	 currentSlideIndex           : 0,
	 defaultSlideIndex           : 0,
	 disableAnimation            : false, 
	 transitionSpeed             : 1000,
	 isRendered                  : false ,
	 animateToSlide              : animateToSlide,
	 buildControl                : buildControl,
	 appendSlide                 : appendSlide,
	 appendSlides                : appendSlides ,
	 buildSlide                  : buildSlide ,
	 render                      : render ,
	 getSlide                    : getSlide,
	 nextSlide                   : nextSlide ,
	 removeSlides                : removeSlides ,
	 clearSlides                 : removeSlides ,
	 removeSlide                 : removeSlide,
	 previousSlide               : previousSlide,
	 onSlideChange               : function(){},
	 onRender                    : function(){},
	 onAddSlide                  : function(){},
	 onRemoveSlide               : function(){},
	 onClearSlides               : function(){}

	 }}());
 

  //  object.preventExtensions(Slideshow);
	
  
Application.Slideshow  = Slideshow;




}());
