//////////////////////////////////////////////////////////////////////////////////

// SLIDESHOW CLASS (for use with homepage slideshow widget)

if (!Slide_show) var Slide_show = {};
SLIDE_SHOWS = new Hash(); // global hash is an associative array of lightbox objects, indexed by content_src

Slide_show = Class.create({
	initialize: function(widget_id, options) {
		var SS = this;
		this.id = widget_id;
		//this.photos = new Hash(); // associative array of photos, indexed by slide number
		
		// use default options as base and overwrite as desired with options param
		this.options = Object.extend(Object.extend({ },this.default_options), options || { });
		
		this.play_status = false; // boolean for if slide show is playing or not.
		this.play_timer = false; // used to store the periodical executer function for play
		
		this.container = $(widget_id);
		
		// attach behaviors to the slideshow buttons
		this.btn_play = this.container.down('img.play');
		this.btn_play.observe("click", function() {
			SS.play();
		});
		this.btn_pause = this.container.down('img.pause');
		this.btn_pause.observe('click', function() {
			SS.pause();
		});
		this.btn_back = this.container.down('img.back');
		this.btn_back.observe('click', function() {
			SS.go_back();
		});
		this.btn_next = this.container.down('img.next');
		this.btn_next.observe('click', function() {
			SS.go_forward();
		});
		
		this.total_slides = this.container.down('span.total').innerHTML;
		this.current_slide = this.container.select('img.slide_show_photo').size(); // attribute of slide show object that tracks current slide - start with the last slide and go to the first one
		this.counter = this.container.down('span.current'); // element that reflects the current slide number
		
		// if there is more than one slide (if there is only one, the controls are hidden in the template)
		if (this.total_slides > 1) {
			
			// run the png fix on the images to support IE6 alpha opacity
			this.container.select('img.play, img.pause, img.back, img.next').invoke('pngFix');
			
			// add the slide_show object to the global array (object)
			SLIDE_SHOWS.set(this.id, SS);
			
			if (this.options.default_status) {
				this.play(); // start the slideshow (after a delay?)
			}
		}
	},
	
	// default options: any of these can be passed in as parameters to override the defaults
	default_options: {
		width:            400, // integer values in pixels - width and height of the photo frame
		height:           300,
		default_status:  true, // boolean for if slide show is playing by default
		delay:             10, // integer for how long to wait (in seconds) before moving to the next slide
		transitions:     true, // boolean: a fade effect when switching from one photo to another
		effects:         true, // boolean: pan and zoom randomly while viewing photos.
		effects_percent:   25 // integer greater than 0. Controls how dramatic the movements are
	},
	
	play: function() {
		var SS = this;
		this.status = true;
		this.btn_play.hide();
		this.btn_pause.show();
		
		// on play start go to the next photo
		SS.go_forward(true);
		
		// start the periodical executer call to go_forward()
		this.play_timer = new PeriodicalExecuter( function() {
			SS.go_forward(true);
		}, SS.options.delay);
	},
	
	pause: function() {
		this.status = false;
		this.btn_play.show();
		this.btn_pause.hide();
		this.play_timer.stop();	
	},
	
	go_forward: function(auto) {
		// if this is a manual request (and slideshow is playing), reset the counter so the new slide time doesn't get cut short
		var SS = this;
		if (!auto && this.status) {
			this.play_timer.stop();
			this.play_timer = new PeriodicalExecuter( function() {
				SS.go_forward(true);
			}, SS.options.delay);
		}
		
		var cs = this.current_slide;
		if (cs != this.total_slides) { cs++; } else { cs = 1; }
		this.go_to_slide(cs);
	},
	
	go_back: function() {
		// if playing, pause it
		if (this.status) {
			this.pause();
		}
		var cs = this.current_slide;
		if (cs != 1) { cs--; } else { cs = this.total_slides; }
		this.go_to_slide(cs);
	},
	
	// called by both go_forward() and go_back()
	// allows you to jump to any slide
	go_to_slide: function(slide_number) {
		 SS = this;
		// check that the slide number is legit
		if (1 <= slide_number <= this.total_slides) {
			
			// hide the old photo and info and show the new photo and info
			var old_photo = this.container.down(".photo_" + this.current_slide);
			var old_info = this.container.down(".info_" + this.current_slide);
			var new_photo = this.container.down(".photo_" + slide_number);
			var new_info = this.container.down(".info_" + slide_number);
			
			SS.current_slide = slide_number;
			SS.counter.update(SS.current_slide);
			
			// if there are effects during individual slide view
			// (don't show effects if paused and iterating through)
			if ( (this.options.effects == true) && this.status) {
				// randomly choose either pan or zoom
				if (this.random_b()) { 
					this.pan(new_photo);
				} else {
					this.zoom(new_photo); // zooming looks bad on lower res monitors... disable it based on screen res of user agent??
				}
			}
			
			// use fade for transitions: put the old photo on top and then fade it out
			if (this.options.transitions) {
				old_photo.setStyle({
					zIndex: 3
				});
				new_photo.setStyle({
					zIndex: 2,
					display: "block"
				});
				old_photo.fade({
					duration: 1.5,
					from: 1,
					to: 0
				});
				if (old_info && new_info) {
					old_info.fade({
						duration: 0.75,
						from: 1,
						to: 0
					});
					new_info.appear({
						duration: 0.75,
						from: 0,
						to: 1,
						delay: 0.75
					});
				}
			// no effects during transitions, just a regular photo/info swap
			} else {
				old_photo.hide();
				old_info.hide();
				if (old_photo && new_photo) {
					new_photo.show();
					new_info.show();
				}
			}
		} else {
			alert("trying to go to a slide number that doesn't exist");
		}
	},
	
	// returns a random boolean integer: 0 or 1
	random_b: function() {
		return Math.round(Math.random());
	},
	
	// returns a random integer between 0 and the given integer value
	random_coord: function(int_val) {
		return Math.round( Math.random() * int_val );
	},
	
	// method for preloading
  
  	// method(s) to handle effects
	pan: function(photo) {
		var SS = this;
		
		// calculate min and max values for top and left coordinates
		var top_min = -( Math.round(this.options.effects_percent/100 * this.options.height) );
		var top_max = 0;
		var left_min = -( Math.round(this.options.effects_percent/100 * this.options.width) );
		var left_max = 0;
		
		// declare vars to hold the starting and ending coordinates of the photo
		var top_start = 0;
		var top_end = 0;
		var left_start = 0;
		var left_end = 0;
		
		// first choose a dimension to be fixed. Then polarize to a specific edge. The photo will travel the full range in this dimension
		// then get a random position for the other dimension along the selected edge
		var vert_fixed = this.random_b();
		
		if (vert_fixed) {
			top_start = (this.random_b()) ? top_min : top_max;
			top_end = (top_start != top_min) ? top_min : top_max;
			//left_start = this.random_coord(left_min);
			//left_end = this.random_coord(left_min);
			left_start = Math.round(left_min/2);
			left_end = left_start;
		} else { // else horiz_fixed
			left_start = (this.random_b()) ? left_min : left_max;
			left_end = (left_start != left_min) ? left_min : left_max;
			//top_start = this.random_coord(top_min);
			//top_end = this.random_coord(top_min);
			top_start = Math.round(top_min/2);
			top_end = top_start;
		}
		// set starting style
		photo.setStyle({
			top: top_start + 'px',
			left: left_start + 'px',
			width: (SS.options.width - left_min) + 'px',
			height: (SS.options.height - top_min) + 'px'
		});
		// morph to ending style
		new Effect.Morph( photo, {
			style: {
				top: top_end + 'px',
				left: left_end + 'px'
			},
			duration: SS.options.delay,
			transition: Effect.Transitions.sinoidal
		});
	},
	
	zoom: function(photo) {
		var SS = this;
		
		// vars initialized for zooming in
		var width_start = this.options.width;
		var height_start = this.options.height;
		var scale_from = 100;
		var scale_to = 100 + this.options.effects_percent;
		
		// always zoom in - it is more engaging for the user
		
		// randomly zoom in or out
		//var zoom_in = this.random_b();
		//if (!zoom_in) { // if zooming out
		//	width_start = this.options.width + (this.options.width * this.options.effects_percent/100);
		//	height_start = this.options.height + (this.options.height * this.options.effects_percent/100);
		//	scale_from = 100 + this.options.effects_percent;
		//	scale_to = 100;
		//}
		
		// pick one of the 4 corners at random to be fixed while zooming
		var top = this.random_b() ? '0px' : 'auto';
		var bottom = (top != '0px') ? '0px' : 'auto';
		var left = this.random_b() ? '0px' : 'auto';
		var right = (left != '0px') ? '0px' : 'auto';
		
		photo.setStyle({
			top: top,
			left: left, 
			bottom: bottom,
			right: right
		});
		new Effect.Scale( photo, scale_to, {
			scaleContent: false,
			//scaleFromCenter: true,
			scaleMode: {originalWidth: width_start, originalHeight: height_start},
			scaleFrom: scale_from,
			duration: SS.options.delay,
			transition: Effect.Transitions.sinoidal
		});
	}
	
});




// on page load events
Event.observe(window, 'load', function() {
	
	// initialize a slideshow object for each slideshow on the page
	$$(".slide_show_frame").each( function(ss_widget) {
		new Slide_show(ss_widget.id, {effects: homepage_slideshow_effects_on});
	});
	
	
	
});


