document.observe('dom:loaded', function() { 
	$$('.cycle').each(function(element) { new CycleImages(element); }); 	
});

var CycleImages = Class.create();

CycleImages.prototype = {
	
	initialize : function(element) {
		this.element = $(element);
		
		// get all the images and captions
		this.images      = this.element.select('.pics img');
		this.captions    = this.element.select('.captions p');
		this.next_links  = this.element.select('.next');
		this.previous    = this.element.down('.previous');
		this.currentId   = 0;

    if (this.images.size() == 0 || this.captions.size() == 0) return;

		// hide all the images and captions
		this.images.invoke('hide');
		this.captions.invoke('hide');		

		// show the first image and first caption
		this.images.first().show();
		this.captions.first().show();

		// attach the onclick events to the previous arrow
		Event.observe(this.previous, 'click', this._changeSlide.bindAsEventListener(this));
		
    // attach onclick the the image anchors and the next arrow
    this.next_links.each(function(link) {
  		Event.observe(link, 'click', this._changeSlide.bindAsEventListener(this));      
    }.bind(this));
		
    // boolean to indicate if the image is being changed
		this.working = false;
	},
	
	_changeSlide: function(event) {
	  if (this.working) {
	    return true;
	  } else {
	    this.working = true;
	  }
	  
		// work out which arrow was pressed based on the class name
		var direction = event.element().className;
		
		// increment or decrement the currentId based on the direction
		var previousId = this.currentId;
		if (direction == "next") {
			this.currentId = this.currentId + 1;		  
		}	else {
			this.currentId = this.currentId - 1;		  
		}
		
		// if the currentId is now outside the range of image we have set the currentId to the beginning or end
		if(this.currentId >= this.images.size()) this.currentId = 0;
		if(this.currentId < 0) this.currentId = this.images.size() - 1;			

    // create an array of the effects to execute
    var effects = []

		// show the new image and fade out the old image at the same time
		effects.push(new Effect.Appear(this.images[this.currentId]));
		effects.push(new Effect.Fade(this.images[previousId]));
		
		// show and hide the captions
    effects.push(new Effect.Appear(this.captions[this.currentId]));
    effects.push(new Effect.Fade(this.captions[previousId]));
		
		// execute the effect in parrallel
    new Effect.Parallel(effects, {
		  afterFinish: function() {
		    this.working = false;
		  }.bind(this)
    });
	}
	
}