(function($){

   var psSlideshow = function(element, options)
   {
			var defaults = {
				slide_element: 'img',
				fadetime: 'fast',
				timeout: '3000',
				type: 'sequence',
				pausestate: 0,
				pan:false,
				pan_speed:10,
				pauselink: null,
				nextlink: null,
				prevlink: null,
				onPlay: null,
				onPause: null,
				onOver: null,
				onLeave:null,
				onClick:null,
				onImage:null,
				onChange:null
			};	
			var opts = jQuery.extend({}, defaults, options);
			//debug(opts);
			var	pauseState = opts.pausestate,
				current = 0,
				last = 0,
				timer = '',
				$this = $(element),
				slides = $this.find(opts.slide_element).get(),
				obj = this,
				dif = 0;   
				
      // PRIVATE METHODS			
			var setup = function(){			
				//debug($this);
				$this.css('position','relative');
				if(opts.pan) $this.css('overflow','hidden');			
				jQuery.each(slides, function(i){
					jQuery(slides[i]).css('zIndex', slides.length - i).css({position:'absolute',top:'0',left:'0'});	
				});					
				if ( opts.pauselink != null ) {	jQuery('#' + opts.pauselink).click(pause);	}			
				if ( opts.nextlink != null ) {	jQuery('#' + opts.nextlink).click(next);	}			
				if ( opts.prevlink != null ) {	jQuery('#' + opts.prevlink).click(prev);	}			
				showSlide();					
				//if(!opts.pausestate) obj.play();	
				//debug(slides.lenght);
				if( !pauseState ) obj.play();	
					
			}
			
			var showSlide = function(){
				//log('showSlide');
				for (var i = 0; i < slides.length; i++) {
					jQuery(slides[i]).css('display', 'none');
				}
				jQuery(slides[last]).css('zIndex', '0');
				
				//log(last);
				//log(current);
				//log(slides[current]);
				
				jQuery(slides[current]).css({zIndex:'1',left:'0',top:'0'}).fadeIn(opts.fadetime,function(){
					//debug(slides[current]);
					if ( opts.onImage != null ) 	opts.onImage.call(slides[current]);
					////////////////// PAN IMAGE
					if(opts.pan){
						//jQuery(slides[current]).fadeIn(opts.fadetime);						
						var iw = jQuery(slides[current]).width();
						var ih = jQuery(slides[current]).height();
						var giw =$this.width();
						var gih =$this.height();
						
						//log(ih +' > '+ gih);
						
						if(iw > giw){
							var dif = iw - giw;
							if(dif != 0){
								jQuery(slides[current]).animate({'left': '-'+dif+'px'}, dif * opts.pan_speed)
							}
						}
						if(ih > gih){						
							var dif = ih - gih;
							if(dif != 0){
								jQuery(slides[current]).animate({'top': '-'+dif+'px'}, dif * opts.pan_speed)
							}
						}
					}	// PAN IMAGE					
				});
			}
			
			var change = function () {
				//log('change');	 
				if ( pauseState == 0 ) {				
					if ( opts.type == 'sequence' ) {
						if ( ( current + 1 ) < slides.length ) {
							current = current + 1;
							last = current - 1;
						}
						else {
							current = 0;
							last = slides.length - 1;
						}
					}
					else if ( opts.type == 'random' ) {
						last = current;
						while (	current == last ) {
							current = Math.floor ( Math.random ( ) * ( slides.length ) );
						}
					}
					else {
						alert('type must either be \'sequence\' or \'random\'');
					}		
					/*
					for (var i = 0; i < slides.length; i++) {
						jQuery(slides[i]).css('display', 'none');
					}
					jQuery(slides[last]).css('zIndex', '0');
					*/
					showSlide();	
					
					timer = setTimeout(change, opts.timeout);
				}
				if ( opts.onChange != null ) 	opts.onChange.call($(obj));
				
				
			};			
			
			var next = function (){
				//log('next '+ current);
				
				$this.stop();
				
				if ( ( current + 1 ) < slides.length ) {
					current = current + 1;
					last = current - 1;
				}
				else {
					current = 0;
					last = slides.length - 1;
				}
				
				//log(current +' : '+ last);
				
				showSlide();
				
			}
			
			var prev = function (){
				//log('prev '+ current);
				
				$this.stop();
				
				if (  current == 0 ) {
					last = 0;
					current =  slides.length - 1;
					
				}
				else {
					last = current;
					current = current -1;
				}
				
				//log(current +' : '+ last);
				
				showSlide();
				
			}
			
			// PUBLIC METHODS		
			//var pause = function() {
			this.pause = function() {	
				if ( pauseState == 0 ) {
					pauseState = 1;
					clearTimeout(timer);
					if ( opts.playcallback != null ) {
						opts.pausecallback(jQuery('#' + opts.pauselink));
					}
				}
				else {
					pauseState = 0;
					change();
					if ( opts.playcallback != null ) {
						opts.playcallback(jQuery('#' + opts.pauselink));
					}
				}
				return false;
			};	
			
			this.play = function(){
			
			//debug(slides.length);
			//var play = function(){
			//	log('play');
				if(slides.length > 1){
					pauseState = 0;
					//console.log('play '+pauseState);
					if ( opts.type == 'sequence' ) {
						 timer = setTimeout(change, opts.timeout);
					}
					else if ( opts.type == 'random' ) {
						do {
							current = Math.floor ( Math.random ( ) * ( slides.length ) );
						} while ( current == 0 );
							timer = setTimeout(change, opts.timeout);
					}
					else {
						alert('type must either be \'sequence\' or \'random\'');
					}
					
				}
			};
			
			this.stop = function() {
				//log('stop');
				pauseState = 1;
				clearTimeout(timer);	
			};
			
			this.mouseover = function() {
				if ( opts.onOver != null ) 	opts.onOver.call($this);
			};
			
			this.mouseout = function() {
				if ( opts.onOut != null ) 	opts.onOut.call($this);
			};
			
			this.current = function (id){
				if(id){
					current = id;
				}else{
					return current;				
				}
			};
			
			this.gotoSlide = function(id){
				//log('gotoSlide '+id);
				current = id;	
				showSlide();
			};
			
			// SETUP			
			setup();	
   };

   $.fn.slideshow = function(options)
   {
		 return this.each(function()
		 {
			 var element = $(this);
			 
			 //debug(element);
			
			 // Return early if this element already has a plugin instance
			 if (element.data('slideshow')) return;

			 // pass options to plugin constructor
			 var slideshow = new psSlideshow(this, options);
				
			//	debug(slideshow);
			 
			 // Store plugin object in this element's data
			 element.data('slideshow', slideshow);
			});
   };
	 
	function log($s) {
    if (window.console && window.console.log)
     window.console.log($s);
  };
	
	
	function debug($obj) {
    if (window.console && window.console.debug)
     window.console.debug('debug: %o', $obj);
  };
	 
})(jQuery);

