/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		Class: SimpleSlideShow
		Makes a very, very simple slideshow gallery with a collection of dom elements and previous and next buttons.

		Author:
		Aaron Newton
		
		Dependencies:
		mootools - 	<Moo.js>, <Utility.js>, <Common.js>, <Function.js>, <Array.js>, <String.js>, <Element.js>, <Fx.Base.js>, <Dom.js>, <Cookie.js>
		cnet - <element.cnet.js>
		
		Arguments:
		options - an object with key/value settings.
		
		Options:
		startIndex - (integer) the first image to show
		slides - (array) a collection of elements already in the dom.
		currentSlideClass - (string; optional) class to assign the currently visible slide; defaults to "currentSlide"
		currentIndexContainer - (dom element or id) container to display the the currently shown slide index
			(i.e. "showing *2* of 3"); optional
		maxContainer - (dom element or id) container to display the maximum number of slides available; optional
		nextImg - (dom element or id) image to capture clicks to show the next image; optional, but if 
			not supplied you'll have to execute <cycleForward> yourself.
		prevImg - (dom element or id) image to capture clicks to show the next image; optional, but if 
			not supplied you'll have to execute <cycleBack> yourself.
		wrap - (boolean) when the user clicks next at the end of a set, go back to the start 
			(and if they click prev at the begining, go to the end); defaults to true
		disabledClass - (string) class to add to next/prev links when there are no next or prev slides;
			defaults to "disabled"
		onNext - (function) callback for when the user clicks next; optional
		onPrev - (function) callback for when the user clicks prev; optional
		onSlideClick - (function) callback for when the user clicks a slide, this function will 
			be passed the slide clicked and the index of the slide. optional
		crossFadeOptions - (object) options object to be passed to the opacity effects.
		
		Example:
(start code)
new SimpleSlideShow({
  startIndex: 0,
	slides: $$('.slide'),
  currentIndexContainer: 'slideNow', //an element or it's id
  maxContainer: 'slideMax',
  nextLink: 'nextImg',
  prevLink: 'prevImg'
});
(end)
	*/
	
	var SimpleSlideShow = new Class({

	
	/*	This class makes use of the Options class. Down below you'll see a line:
	
			SimpleSlideShow.implement(new Options)
	
			The Options class handles merging default options with those the user
			passes in. This lets your class have a default "out of the box" behavior
			but also allows it to be flexible so that users can change what they need
			to.
		*/

		options: {
			startIndex: 0, //what image to start on; zero is the first
			slides: [], //by defining this array here, I don't have to worry about
									 //it being undefined below. it's either empty or it has
									 //values, but it's not undefined.
			currentIndexContainer: false, //these next two hold the number of slides and
																		//what number is visible
			maxContainer: false,
			nextLink: false, //here are two links or images to be used to cycle to the next
											//slide and previous slidee
			prevLink: false,
			wrap: true, //an option to let the user go 1,2,3 and then back to 1 
									//when there are no more slides
			disabledLinkClass: 'disabled', //if wrap isn't true, we have to do something to 
									//tell the user they've reached the end and can't go any futher
									//so I give the button a class when that happens
									
			/*	Down below you'll also see 
			SimpleSlideShow.implement(new Events)
			
			together with new Options, I can have events in my class that fire when things
			happen. Here I have 3 defined: onNext, onPrev, and onSlideClick
			
			This lets someone create a new gallery and then do something else when the user
			clicks next, previous, or clicks a slide. By adding these kinds of events, the
			gallery class can become much more robust when it needs to be because you can
			attach more functionality to it.
			
			Class.create() is basically an empty function. So these events will fire no matter
			what, it's just by default they don't do anything.
				*/
			onNext: Class.create(),
			onPrev: Class.create(),
			onSlideClick: Class.create(),
			/*	This class will use Fx.Style to crossfade between slides if Fx.Style is defined.
					
					This object is just a placeholder for options to pass to Fx.Style
				*/
			crossFadeOptions: {}
		},
		
		initialize: function(options){
			/*	the Options class has the function setOptions.
					this will merge the options passed in with the options I define above
					and also set up the events to fire later
				*/
			this.setOptions(options);
			/*	I save the slides passed in in an array	*/
			this.slides = this.options.slides;
			/*	set up each slide	*/
			this.makeSlides();
			/*	insert the counter values	*/
			this.setCounters();
			/*	set up the prev/next buttons	*/
			this.setUpNav();
		},
		/*	this function just updates the placeholders for the numbers of the images. i.e.:
				viewing 3 of 7
			*/
		setCounters: function(){
			if($(this.options.currentIndexContainer))$(this.options.currentIndexContainer).setHTML(this.now+1);
			if($(this.options.maxContainer))$(this.options.maxContainer).setHTML(this.slides.length);
		},
		/*	this function makes all the slides in the options	*/
		makeSlides: function(){
			/*	$pick returns the first argument if it's not undefined or null, 
					else the second argument is returned	*/
			this.now = $pick(this.now, this.options.startIndex);
			//hide them all
			this.slides.each(function(slide, index){
				if(index != this.now) slide.setStyle('display', 'none');
				else slide.setStyle('display', 'block');
				/*	set up the click event	*/
				this.makeSlide(slide);
			}, this);
		},
		/*	this is it's own function so it can be used at any time, not just on startup	*/
		makeSlide: function(slide){
			slide.addEvent('click', function(){ this.fireEvent('onSlideClick'); }.bind(this));
		},
		/*	here I set up the click events for the prev and next buttons	*/
		setUpNav: function(){	
			/*	next calls .cycleForward	*/
			if($(this.options.nextLink)) $(this.options.nextLink).addEvent('click', function(){
					this.cycleForward();
				}.bind(this));
			/*	prev calls .cycleBack	*/
			if($(this.options.prevLink)) $(this.options.prevLink).addEvent('click', function(){
					this.cycleBack();
				}.bind(this));
		},
/*	Property: cycleForward
		Shows the next slide.
	*/
		cycleForward: function(){
			/*	I keep track of which slide is visible so I know which one is "next"
				so, if this.now is defined and it's less than the length of the slides
				available, show the next slide
				*/
			if($type(this.now) && this.now < this.slides.length-1) this.showSlide(this.now+1);
			/*	if this.now is defined and we're ok to wrap around, then show the first one	*/
			else if($type(this.now) && this.options.wrap) this.showSlide(0);
			/*	otherwise this.now isn't defined, which means this is the first time we've called
			cycle, so show the default first slide	*/
			else this.showSlide(this.options.startIndex);
			/*	fire the event "onNext"; this function is in the Events class	*/
			this.fireEvent('onNext');
			/*	if this.now is at the end of the slide links and we're not wrapping	*/
			if(this.now == this.slides.length && !this.options.wrap && $(this.options.nextLink))
				/*	disable the next button	*/
				$(this.options.nextLink).addClass(this.options.disabledLinkClass);
			/*	otherwise remove that classname because we aren't at the end or we're wrapping	*/
			else if ($(this.options.nextLink)) $(this.options.nextLink).removeClass(this.options.disabledLinkClass);
		},
/*	Property: cycleBack
		Shows the prev slide.
	*/
		cycleBack: function(){
			/*	this is a lot like the above function; I'll let you figure it out.	*/
			if(this.now > 0) this.showSlide(this.now-1);
			else if(this.options.wrap) this.showSlide(this.slides.length-1);
			this.fireEvent('onPrev');
			if(this.now == 0 && !this.options.wrap && $(this.options.prevSlide))
				$(this.options.prevSlide).addClass(this.options.disabledLinkClass);
			else if ($(this.options.prevSlide)) 
				$(this.options.prevSlide).removeClass(this.options.disabledLinkClass);
		},
/*	Property: showSlide
		Shows a specific slide.
		
		Arguments:
		iToShow - (integer) index of the slide to show.
	*/
		showSlide: function(iToShow){
			/*	let's keep track of what slide we were on before we started	*/
			var now = this.now;
			/*	if there's an slide for the index we've been passed	*/
			if(this.slides[iToShow]) {
			
			/*************/
			var elSlide = this.slides[iToShow];
			var textLayer = elSlide.getParent().getParent().getPrevious();
			var titleSlide = elSlide.getProperty('title');
			var subtitleSlide = elSlide.getProperty('alt');
			var linkSlide = elSlide.getParent().getProperty('href');
			/***********************/
			
				/*	and we're not already showing that slide	*/
				if($type(this.now) && this.now != iToShow){
					/*	fade the current slide out
							this.slides is an array of slides. this.slides[this.now] is the current slide
							.effect creates a new Fx.Style, in this case opacity
							.start(0) will fade it to zero
							.chain will execute that function when the fade out is complete
						*/
						
						
					/***************/
					textLayer.effect('opacity', this.options.crossFadeOptions).start(0)
					/******************/
						
					this.slides[this.now].effect('opacity', this.options.crossFadeOptions).start(0).chain(function(){
						/*	we have to set the display to none so the next slide can be in the same place	*/
						//this.slides[now].hide();
						/*	now we show the slide that we're showing next
								set it to block so it's in place
								but set it's opacity to zero so it's invisible
							*/
						//this.slides[now].hide();
						
						
						
						/******************/
						textLayer.getElement('h3').setHTML("<a href='"+ linkSlide + "' title='" + titleSlide + "'>"+ titleSlide +"</a>");
						textLayer.getElement('p').setHTML(subtitleSlide);
						textLayer.setStyles({'display':'block','opacity':0}).effect('opacity', this.options.crossFadeOptions).start(1);
						/******************/
				
				
				
						
						this.slides[iToShow].addClass(this.options.currentSlideClass).setStyles({
							'display':'block',
							'opacity':0
							/*	then use .effect to fade it in	*/
						}).effect('opacity', this.options.crossFadeOptions).start(1);
					}.bind(this)); /*	gotta bind that "this"	*/
				/*	else we're showing an slide for the first time so we don't have to fade
						anything out first. */
				} else this.slides[iToShow].setStyles({
							'display':'block',
							'opacity':0
						}).effect('opacity', this.options.crossFadeOptions).start(1);
				/*	update the "now" index	*/
				this.now = iToShow;
				/*	update the counters	*/
				this.setCounters();
			}
		},
		/*	this handles the slide click. I could have not made this a function
				of its own, but this way it allows future functionality to be implemented
				into this section.	*/
		slideClick: function(){
			this.fireEvent('onSlideClick', [this.slides[this.now], this.now]);
		}
	});

/*	Finally, I add the functionality of the Events and Options classes	*/
SimpleSlideShow.implement(new Events);
SimpleSlideShow.implement(new Options);

/*	Now we have a slideshow, but I want to make one specific to images, so I'm going to extend
		the class above to add some more specific functionality to it.	*/
		
/*	Class: SimpleImageSlideShow
		Extends <SimpleSlideShow> to make a slideshow of images.
		
		Arguments:
		options - a key/value options object; inherits options from <SimpleSlideShow>.
		
		Options:
		imgUrls - (array; optional) an array of image urls to add to the dom and to the slideshow
		imgClass - (string; optional) a class to add to the images that get created on the fly
		container - (element; optional) if you are adding images to the dom either using <addImg> or
			the imgUrls array above, then "container" is required to know where to put them.
	*/
	
	/*	Here I extend SimpleSlideShow	*/
	var SimpleImageSlideShow = SimpleSlideShow.extend({
		/*	Options here get merged with the options from the parent; that's how .extend works	*/
		options: {
			imgUrls: [],
			imgClass: 'screenshot',
			container: false
		},
		/*	initialize has the same name as a function in the parent class (SimpleSlideShow),
				so it overwrites it	*/
		initialize: function(options){
			/*	but I can call the .initialize function in the parent class by calling this.parent().
					note how I pass the options along, because the parent class expects these options.	*/
			this.parent(options);
			/*	this next line is executed after whatever happens in this.parent() (which is
					SimpleSlideShow.initialize()
					
					Here I add new images to the slideshow using the urls passed in.
					Even if the user didn't pass any in, this.options.imgUrls is still
					an array, because that's the default. If it's empty, .each just won't
					iterate.
						*/
			this.options.imgUrls.each(function(url){
				this.addImg(url);
			}, this); /*	note the binding	*/
			/*	and here I show the first slide (because addImg adds images and hides each one	*/
			this.showSlide(this.options.startIndex);
			
		},
/*	Property: addImg
		Adds a new image to the group
	*/
		addImg: function(url){
			/*	the container has to be defined in the options or else I don't know where to
					put the image	*/
			if($(this.options.container)) {
				/*	I create a new image...	*/
				var img = new Element('img').setProperties({
							'src': url,
							'id': this.options.imgClass+this.slides.length
							}).addClass(this.options.imgClass).setStyle(
							'display', 'none').injectInside($(this.options.container)).addEvent(
							'click', this.slideClick.bind(this));
				/*	let's break this chunk above down a bit:
				var img = new Element('img') //new image
				
				.setProperties({
							'src': url,
							'id': this.options.imgClass+this.slides.length
							}). //set the srce and id properties
							
				.addClass(this.options.imgClass) //add a class
				
				.setStyle('display', 'none') //hide it
				
				.injectInside($(this.options.container)) //put it in the container
				
				.addEvent('click', this.slideClick.bind(this)); //add a click event
					*/			

				/*	add this image to the array of slides	*/
				this.slides.push(img);
				/*	set up the slide	*/
				this.makeSlide(img);
				/*	update the counters	*/
				this.setCounters();
			}
		}
	});
/*	Now I have two classes, but I don't duplicate my effort. If I fix a bug in SimpleSlideShow I automatically fix it in any class that extends it.	*/




var guide = {


	makeSlideShows: function(num) {
		new SimpleImageSlideShow({
		  startIndex: 0,
		  /*imgUrls: imatges,*/ /* array de les urls de les imatges */
		  slides: $$('#screenShotImgs'+num+' img'), 
		  container: 'screenShotImgs'+num, /*id on es mostren les ampliacions*/
		  currentIndexContainer: 'imgNow'+num,/*id on es mostra numero imatge que es mostra*/
		  maxContainer: 'imgMax'+num, /*id on es mostra nombre total d'imatges*/
		  nextLink: 'nextImg'+num, /*id boto next*/
		  prevLink: 'prevImg'+num/*id boto prev*/
		});
	},
	init: function(){
		var list = $$('div.screenshot');
		
		
		list.each(function(element,count) {
					element.id="screenShotImgs"+count;
					
					var elSlide = element.getElementsByTagName('img')[0];
					
					var titleSlide = elSlide.title;
					var subtitleSlide = elSlide.alt;
					var linkSlide = elSlide.parentNode.href;
					var textLayer = elSlide.parentNode.parentNode.getPrevious();
					textLayer.getElement('h3').setHTML("<a href='"+ linkSlide + "' title='" + titleSlide + "'>"+ titleSlide +"</a>");
					textLayer.getElement('p').setHTML(subtitleSlide);
					
					element.getPrevious().getElement('.imgNow').id='imgNow'+count;
					element.getPrevious().getElement('.imgMax').id='imgMax'+count;
					element.getPrevious().getElement('.nextImg').id='nextImg'+count;
					element.getPrevious().getElement('.prevImg').id='prevImg'+count;
					

					guide.makeSlideShows(count);
			});		
	}
};

		  