


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

// LISTING SLIDESHOW CLASS

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


Listing_slide_show = Class.create({
	initialize: function(id, options) {
		var SS = this;
		
		this.id = id;
		
		// 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 = $("ListingDetails_" + this.id);
		
		// attach behaviors to the slideshow buttons
		this.btn_play = this.container.down('img.ss_play');
		this.btn_play.observe("click", function() {
			SS.play();
		});
		this.btn_pause = this.container.down('img.ss_pause');
		this.btn_pause.observe('click', function() {
			SS.pause();
		});
		this.btn_back = this.container.down('img.ss_back');
		this.btn_back.observe('click', function() {
			SS.go_back();
		});
		this.btn_next = this.container.down('img.ss_next');
		this.btn_next.observe('click', function() {
			SS.go_forward();
		});
		this.container.select('#Thumbs a').each( function(thumb) {
			thumb.observe("click", function(event) {
				Event.stop(event);
				SS.pause();
				var slide_number = thumb.id.replace(/Thumb_/,'');
				SS.go_to_slide(slide_number);
				thumb.blur();
			});
		});
		
		this.current_slide = this.container.select('#Thumbs img').size(); // attribute of slide show object that tracks current slide - start with the last slide and go to the first one
		this.total_slides = this.container.down('span.ss_total').innerHTML;
		this.counter = this.container.down('span.ss_current'); // element that reflects the current slide number
		
		
		// run the png fix on the images to support IE6 alpha opacity
		this.container.select('img.ss_play, img.ss_pause, img.ss_back, img.ss_next').invoke('pngFix');
		
		LISTING_SLIDE_SHOW.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 = $("Photo_" + this.current_slide);
			var old_thumb = $("Thumb_" + this.current_slide);
			var new_photo = $("Photo_" + slide_number);
			var new_thumb = $("Thumb_" + 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,
					afterSetup: function() {
						$$('#Thumbs a').invoke('removeClassName', 'selected');
						$(new_thumb).className = "selected";
					}
				});
				
			// no effects during transitions, just a regular photo/info swap
			} else {
				old_photo.hide();
				if (old_photo && new_photo) {
					new_photo.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
		});
	}
	
});


// global var
var TOTAL_PHOTOS = 0;


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
// 	ATTACH EVENTS
//	On page load, this attaches all the necessary events to elements on the page
//
//	*** Note: Before attaching the event, we need to check for the existence of the element
//	This is done so the file won't produce errors if included on a page that doesn't have those elements
//	In particular, the map search page starts without these elements existing - but will use ajax to dynamically
//	write them to the page. In that case, it will run the attach events function again
//	after creating the elements.
//
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 


function attachListingDetailEvents() {
	
	
	// on page load events
	
	// initialize a slideshow if there are 2 or more photos
	
	// pause and then destroy any older slideshows - because their html will also be destroyed.
	LISTING_SLIDE_SHOW.each(function(ss) {
		LISTING_SLIDE_SHOW.unset(ss.key).pause();
	});
	
	
	// wait a second before setting up the new slideshow
	window.setTimeout(function() {
		TOTAL_PHOTOS = parseInt($$('img.photo').size());
		if (TOTAL_PHOTOS > 1) {
			
			var listing_id = "";
			
			// featured listings pages use a regular listing id
			if ($("LISTING_ID")) {
				listing_id = $("LISTING_ID").value;
			// whereas IDX listings use mls id plus mls no.
			} else {
				listing_id = $("MLS_ID").value + "_" + $("MLS_NO").value;
			}
			
			// for map search page we need to possibly have multiple instances of the listing slideshow class.
			// if the slideshow doesn't exist yet, create it now.
			if (!LISTING_SLIDE_SHOW.get(listing_id)) {
				new Listing_slide_show(listing_id, {effects: listing_slideshow_effects_on});
			}
			
		}
	}, 750);
	
	
	
	// TOOLS/ICONS BUTTONS
	
	// Tools & Resources links that open in popup windows
	$$('#BtnRequestMoreInfo, #BtnScheduleAShowing, #BtnCalculators, #BtnTellAFriend').each( function(s) {
		$(s).observe('click', function(event) {
			popWindow(s);
			Event.stop(event); // prevent the regular link from firing
		});
	});
	
	
	
	// save listing not yet logged in
	if ($("BtnSaveListingNeedLogin")) {
		$("BtnSaveListingNeedLogin").observe('click', function(event) {
			alert("You must login/register before you can save listings");
			Event.stop(event); // prevent the regular link from firing
		});
	}
	
	
	
	// back to map button (only used when detail is loaded within the context of the map search page)
	if ($("BackToMap")) {
		$("BackToMap").observe('click', function(event) {
			Event.stop(event);
			toggleFrame("Map");
		});
	}
	
}



Event.observe(window, 'load', function() {
	attachListingDetailEvents();
});




