var Slideshow = Class.create();
Slideshow.prototype = {
	webroot: '',
	distanceBetweenThumbs: 103,
	maxVisibleThumbs: 7,
	startingPosition: 309,
	startingSlot: 3,
	slideDuration: 5,
	timeoutId: false,
	initialize: function(webroot) {
		Slideshow.webroot = webroot;
		this.slides = [];
		this.lastIndex = -1;
		this.currentIndex = -1;
		this.started = false;
		this.paused = true;
		this.makeContinuous = false;
		$('thumbnails').insert('<ul></ul>');
		this.playlist = $('thumbnails').down('ul');
		$('slideshow').insert('<div id="slideshow_overlay"></div><div id="slideshow_label"></div><div id="slideshow_left"></div><div id="slideshow_right"></div><div id="slideshow_controls_wrap"><ul id="slideshow_controls"><!--<li id="prev">Previous</li>--><li id="pause">Pause/Play</li><!--<li id="next">Next</li>--></ul></div>', { position: 'after' } );
		Event.observe($('slideshow_left'), 'mouseover', function(e) { e.target.addClassName('over'); });
		Event.observe($('slideshow_left'), 'mouseout', function(e) { e.target.removeClassName('over'); });
		Event.observe($('slideshow_right'), 'mouseover', function(e) { e.target.addClassName('over'); });
		Event.observe($('slideshow_right'), 'mouseout', function(e) { e.target.removeClassName('over'); });
		Event.observe($('slideshow_left'), 'click', function(e) { this.moveBy(-1); }.bindAsEventListener(this));
		Event.observe($('slideshow_right'), 'click', function(e) { this.moveBy(1); }.bindAsEventListener(this));
		Event.observe($('pause'), 'click', function(e) { this.togglePlay(); }.bindAsEventListener(this));
	},
	add: function(slide) {
		var l = this.slides.length;
		var slideAdded = false;
		slide.drawSlide();
		slide.addToPlaylist(this.playlist);
		slide.moveTo(l, this);
		if (l == 0) {
			this.currentIndex = 0;
			this.drawBrackets();
			slide.fadeIn();
		} else if (l == (this.maxVisibleThumbs - 1)) {
			this.makeContinuous = true;
			this.slides.push(slide);
			slideAdded = true;
			this.updatePlaylist();
		} else if (l >= this.maxVisibleThumbs) {
			// add the slide just before the third from last slot
			var slideParts = this.slides.partition(function(el, i){ return i < (this.slides.length - this.startingSlot) }.bind(this));
			this.slides = [].concat(slideParts[0], [slide], slideParts[1]);
			slide.moveTo(slideParts[0].length, this);
			slideAdded = true;
		} else if (!this.started) {
			this.start();
		}
		if (!slideAdded) this.slides.push(slide);
	},
	remove: function(slide) {
		this.slides = this.slides.reject(function(s){
			return s == slide;
		});
	},
	drawBrackets: function() {
		$('slideshow').insert('<div id="slideshowBrackets"></div>');
	},
	start: function() {
		this.started = true;
		this.timeoutId = this.moveBy.bind(this).delay(this.slideDuration, 1);
		this.paused = false;
	},
	moveBy: function(dir) {
		if (this.timeoutId) window.clearTimeout(this.timeoutId);
		if (!this.makeContinuous && ((this.currentIndex + dir >= this.slides.length) || (this.currentIndex + dir <= 0))) {
			dir = ((dir + this.currentIndex + this.slides.length) % this.slides.length) - this.currentIndex;
		}
		this.lastIndex = this.currentIndex;
		this.currentIndex = (this.currentIndex + dir + this.slides.length) % this.slides.length;
		for (var i=0; i<this.slides.length; i++) {
			this.slides[i].animate(i, this, dir);
		}
		this.slides[this.lastIndex].fadeOut();
		this.slides[this.currentIndex].fadeIn();
		if (!this.paused) this.timeoutId = this.moveBy.bind(this).delay(this.slideDuration, 1);
	},
	togglePlay: function(e) {
		(this.paused) ? this.play() : this.pause();
	},
  pause: function() {
    Element.addClassName("pause", "play");
    this.paused = true; 
    clearTimeout(this.timeoutId);
    this.timeoutId = 0;
  },
  play: function() {
    Element.removeClassName("pause", "play");
    this.paused = false;
    this.moveBy(1);
  },
	updatePlaylist: function() {
		if (this.makeContinuous) {
			this.slides.each(function(s, i){
				s.moveTo(i-this.currentIndex, this);
			}.bind(this));
		}
	}
};

var Slide = Class.create();
Slide.prototype = {
	initialize: function(slideshow, id, thumb, slide, address, price) {
		this.id = id;
		this.thumb = new Image();
		this.slide = new Image();
		this.address = address;
		this.price = price;
		this.added = false;
		this.thumbComplete = false;
		this.slideComplete = false;
		this.thumb.onload = function(e){
			this.thumbComplete = true;
			this.checkComplete();
		}.bindAsEventListener(this);
		this.thumb.src = thumb;
		this.slide.onload = function(e){
			this.slideComplete = true;
			this.checkComplete();
		}.bindAsEventListener(this);
		this.slide.src = slide;
	},
	checkComplete: function() {
		if (!this.added && this.thumbComplete && this.slideComplete) {
			slideshow.add(this);
			this.added = true;
		}
	},
	getLink: function(size) {
		var sizeStr = (size == 'thumb') ? 'width:101px; height:55px;' : 'width:531px; height:270px;';
		return '<a href="' + Slideshow.webroot + 'property/' + this.id + '" title="' + this.address + '   ' + this.price + '"><img src="' + eval("this." + size + ".src") + '" alt="' + this.address + '   ' + this.price + '" style="' + sizeStr + '" /></a>';
	},
	getLabel: function() {
		return '<a href="' + Slideshow.webroot + 'property/' + this.id + '" title="' + this.address + '   ' + this.price + '">' + this.address + '   ' + this.price + '</a>';
	},
	getLeft:function(pos) {
		if ( slideshow.makeContinuous ) {
			if ((slideshow.slides.length - pos) <= slideshow.startingSlot) pos -= slideshow.slides.length;
			else if ((0 - pos) > slideshow.startingSlot) pos += slideshow.slides.length;
		}
		return slideshow.startingPosition + Math.max((0 - slideshow.startingSlot), Math.min(pos, slideshow.startingSlot + 1)) * slideshow.distanceBetweenThumbs;
	},
	moveTo:function(pos, slideshow) {
		var left = this.getLeft(pos);
		$('slideshowThumb' + this.id).style.left = left + "px";
	},
	animate:function(my_idx, slideshow, dir) {
		var pos = my_idx-slideshow.currentIndex;
		var originalLeft = this.getLeft(my_idx-slideshow.lastIndex);
		var newLeft = this.getLeft(pos);
		if ( ((originalLeft < newLeft) && (dir > 0)) || ((originalLeft > newLeft) && (dir < 0)) ) {
			$('slideshowThumb' + this.id).style.display = "none";
			$('slideshowThumb' + this.id).style.left = newLeft + "px";
			Effect.Appear.delay(0.5, $('slideshowThumb' + this.id), { duration:0.5, afterFinish: slideshow.updatePlaylist.bind(slideshow) });
		} else if (originalLeft == newLeft) {
			$('slideshowThumb' + this.id).style.left = newLeft + "px";
		} else {
			new Effect.Move($('slideshowThumb' + this.id), { x: newLeft, y:0, duration:0.5, mode: 'absolute' });
		}
	},
	drawSlide: function() {
		$('main_slide_image').insert('<div id="slideshowSlide' + this.id + '" class="slide_wrap" style="display:none;">' + this.getLink('slide') + '</div>');
	},
	addToPlaylist: function(obj) {
		obj.insert('<li id="slideshowThumb' + this.id + '" style="left:0px;">' + this.getLink('thumb') + '</li>');
	},
	fadeIn: function() {
		Effect.Appear('slideshowSlide' + this.id);
		$('slideshow_label').update(this.getLabel());
		$('slideshow_overlay').clonePosition($('slideshow_label'), { setLeft:false, setTop:false });
	},
	fadeOut: function() {
		Effect.Fade('slideshowSlide' + this.id);
	}
}
