/*
  Simple slideshow using prototype and scriptaculous.
  
  Usage:
  
    <script src="prototype.js"></script>
    <script src="effects.js"></script>
    <script src="slideshow.js"></script>
    <div id="slideshow_foobar">
      <div class="slide_navigation"><!-- this class name is hardcoded, one level under the slideshow DOM object -->
        <div class="left_arrow">go left</div><!-- class name passed in constructor, must be one level under .slide_navigation -->
        <h3>description</h3><!-- tag name passed in constructor -->
        <div class="right_arrow">go right</div><!-- see left_arrow -->
      </div>
      <div class="slide"><img src="slide1.jpg"></div>
      <div class="slide"><img src="slide2.jpg"></div>
      <div class="slide"><img src="slide3.jpg"></div>
    </div>
    <script type="text/javascript">new SlideshowSmall('slideshow_foobar', 3000, 'left_arrow','right_arrow','h3');</script>
  
  See also: http://blog.remvee.net/post/17
  
  Copyright (c) 2006 - R.W. van 't Veer
  Heavily modified in 2010 by Jan "Piskvor" Martinec, it's practically a completely new script
*/

function SlideshowSmall(slideshow, timeout, slide_left, slide_right, headerTag) {
  var t = this;
  this.slides = [];
  this.maxSize = 0;
  this.timeoutHandle = null;
  Element.makePositioned(slideshow);
  var size;
  this.headingHeight = null;
  var nl = $(slideshow).getElementsByTagName('div');
  if (nl.length > 0) {
	  for (var i = 0; i < nl.length; i++) {
		if (Element.hasClassName(nl[i], 'slide')) {
		  this.slides.push(nl[i]);
		  nl[i].style.position='absolute';
		  size = Element.getDimensions(nl[i]);
		  if (size.height > this.maxSize) {
		  	this.maxSize = size.height;
		  }
		  Element.hide(nl[i]);
		} else if ((slide_left != null || slide_right != null) && Element.hasClassName(nl[i], "slide_navigation")) {
			nname = nl[i].getElementsByTagName(headerTag);
			if (nname.length > 0) {
				  this.headingHeight = Element.getDimensions(nname[0]).height;
			}
			els = nl[i].getElementsByTagName('a');
			for (var j = els.length - 1; j >= 0; j--) {
				if (slide_left != null && Element.hasClassName(els[j],slide_left)) {
					Element.observe(els[j],'click',function(e){t.prevPage();e.stop()});
				} else if (slide_right != null && Element.hasClassName(els[j],slide_right)) {
					Element.observe(els[j],'click',function(e){t.nextPage();e.stop()});
				}
			}

		}
	  }
	  this.container = slideshow;
	  $(slideshow).style.height = (this.headingHeight + this.maxSize) + 'px';
	  this.containerSize = Element.getDimensions(slideshow);
	  this.timeout = timeout;
	  this.timeoutPage = 3 * this.timeout;
	  this.current = 0;


	  for (var i = this.slides.length - 1; i >=0; i--) {
	  	var dim = Element.getDimensions(this.slides[i]);
	  	var halfSize = (this.maxSize - dim.height) / 2;
		this.slides[i].style.top = this.headingHeight + halfSize +'px'; // vertically centered
		this.slides[i].style.left = ((this.containerSize.width - dim.width) / 2) + 'px'; // horizontally centered
	  }
	  Element.show(this.slides[0]);

	  t.timeoutHandle = setTimeout((function(){this.next(t,1,true);}).bind(this), this.timeout + 850);
	}
}
SlideshowSmall.prototype = {
  next: function(t,direction,auto) {
  	if (t.timeoutHandle != null) {
		clearTimeout(t.timeoutHandle);
		t.timeoutHandle = null;
  	}
	var old = t.current;
  	t.current = (t.current + direction + t.slides.length) % t.slides.length;
  	Effect.Fade(t.slides[old]);
  	Effect.Appear(t.slides[t.current]);
  	if (auto != null && auto) {
		t.timeoutHandle = setTimeout((function(){t.next(t,direction,auto);}).bind(t), t.timeout + 850);
	}
  },

  prevPage: function() {
    this.next(this,-1,false);
 	this.timeoutHandle = setTimeout((function(){this.next(this,1,true);}).bind(this), this.timeoutPage + 850);
  },
  nextPage: function() {
    this.next(this,1,false);
 	this.timeoutHandle = setTimeout((function(){this.next(this,1,true);}).bind(this), this.timeoutPage + 850);
  }
}

function Slideshow(id,timeout_ms) {

	this.element = $(id);
	this.element.removeClassName('js_not_activated_yet'); // used for clipping without JS
	this.height = this.element.getHeight() + 'px';
	this.width = this.element.getWidth() + 'px';
	var img = this.element.getElementsByTagName('img');
	this.img = img[0];
	this.img.style.clip = 'rect(0px, ' + this.width + ', ' + this.height + ', 0px)';
	this.moveStep = 100;
	this.moveTime = 100;
	this.moveMax = this.element.getHeight();
	this.isMoving = false;
	this.otherImg = new Element('img'); // for crossfading
	this.otherImg.id = id + '_swap';
	this.otherImg.setStyle('display:none');
	this.otherImg.style.clip = 'rect(0px, ' + this.width + ', ' + this.height + ', 0px)';
	this.originalClip = 'rect(0px, ' + this.width + ', ' + this.height + ', 0px)';
	this.element.insert({top:this.otherImg});
	this.otherInit = false;
	var els = this.element.getElementsByTagName('*');
	var paging = null;
	this.description = null;
	for (var i = 0; i < els.length; i++) {
		if (els[i].hasClassName('teaser_paging')) {
			paging = els[i];
		} else if (els[i].hasClassName('teaser_description')) {
			this.description = els[i]; // later populated from "title" attribute
		}
	}
	if (paging == null) { // no pages defined, punt.
		return;
	}
	this.imgs = new Array();
	var lis = paging.getElementsByTagName('li');
	var item;
	var t = this;
	var count = 0;
	for (var i = 0; i < lis.length; i++) {
		if (lis[i].hasClassName('slideshow_image')) { // part of the slideshow
			count++;
			item = this.getInfo(lis[i],count);
			this.imgs.push(item);
			item.textPosition.innerHTML = ' ' + count + ' ';
			item.textPosition.ss_id = count;
			$(item.textPosition).observe('click',function(evt) {
				evt.stop();
				t.gotoImage(t,evt.element().ss_id);

			});
		} else if (lis[i].hasClassName('r')) { // "previous" arrow
			Event.observe(lis[i],'click',function(event){
				event.stop();
				t.gotoImage(t,(t.imgs.length + t.currentSlide) % t.imgs.length);
			});
		} else if (lis[i].hasClassName('f')) { // "next" arrow
			Event.observe(lis[i],'click',function(event){
				event.stop();
				t.gotoImage(t,(t.imgs.length + t.currentSlide + 2) % t.imgs.length);
			});
		}
	}
	this.countdownlatch = this.imgs.length + 1;
	if (this.imgs.length > 1) {
		paging.style.display='block';
	}
	this.slideDelay = timeout_ms;
	this.startTimer(t,this.slideDelay);
	window.setTimeout(function(){t.preloadimgs(t)},1000);
	this.img.moved = 0;
	if (this.img.getHeight() > this.element.getHeight()) {
		var t = this;
		this.countdownlatch++;
		window.setTimeout(function(){
			t.isMoving = true;
			t.moveClip(t);
		},3000);
	}
	
	this.currentSlide = this.prevSlide = 0;
	this.timer = null;
	Element.addClassName(this.imgs[this.currentSlide].textPosition.up(),'slideshow_active');
	this.description.innerHTML = this.imgs[this.currentSlide].title;
	this.hideTO = null;
	this.hideTOdelay = 3000;
	this.element.observe('mouseover',function(){
		window.clearTimeout(t.hideTO);
		Effect.Appear(t.description.up(),{duration:0.5});
	});
	this.element.observe('mouseout',function(){
		window.clearTimeout(t.hideTO);
		t.hideTO = window.setTimeout(function(){
			Effect.Fade(t.description.up(),{duration:0.5});
		},t.hideTOdelay);
	});
	this.description.up().observe('mouseover',function(){
		window.clearTimeout(t.hideTO);
	});
	this.description.up().observe('mouseout',function(){
		window.clearTimeout(t.hideTO);
		t.hideTO = window.setTimeout(function(){
			Effect.Fade(t.description.up(),{duration:0.5});
		},t.hideTOdelay);
	});

}

Slideshow.prototype = {
	getInfo: function(elm,count) {
		var item = new Object();
		var a = elm.getElementsByTagName('a');
		if (a.length == 0) {
			return item;
		}
		item.textPosition = a[0];
		item.title = a[0].title;
		item.src = a[0].href;
		item.position = count+0;
		return item;
	},

	_next: function (t,direction,time,auto) {
		window.clearTimeout(t.timer);
		t.currentSlide = (t.currentSlide + direction + t.imgs.length) % t.imgs.length;
		t.setSlide(t.currentSlide);
		if (auto) {
			t.timer = window.setTimeout(function(){
				t._next(t,direction,time,auto);
			},time);
		}
	},

	setSlide: function(num) {
		if (!this.otherInit) {
			var offset = Element.cumulativeOffset(this.img);
			this.otherImg.setStyle('position: absolute; left:0px; z-index: 2');
			this.otherInit = true;
		}
		this.otherImg.style.top = this.img.style.top;
		this.otherImg.style.clip = this.img.style.clip;
		this.otherImg.setStyle('display: block; opacity: 0.999');
		this.otherImg.src = this.imgs[this.prevSlide].src;
		this.img.src = this.imgs[num].src;
		this.img.style.clip = this.originalClip;
		this.img.style.top = '0px';

		Effect.Fade(this.otherImg);
		this.description.innerHTML = this.imgs[num].title;
		Element.removeClassName(this.imgs[this.prevSlide].textPosition.up(),'slideshow_active');
		Element.addClassName(this.imgs[num].textPosition.up(),'slideshow_active');
		this.prevSlide = num;
		this.img.moved = 0;
		if (this.img.getHeight() > this.element.getHeight()) {
			var t = this;
			window.setTimeout(function(){
				t.isMoving = true;
				t.moveClip(t);
			},3000);
		}
	},

	moveClip: function(t) {
		t.moveStep = 2;
		t.moveTime = 70;
		t.img.moved += t.moveStep;
		if (t.img.height < (t.img.moved+t.moveMax)) {
			t.isMoving = false;
			window.setTimeout(function(){
				t.latchDecrement(t);
			},1000);
			return;
		}
		t.isMoving = true;
		t.img.style.top = (0 - t.img.moved) + 'px';
		var clipCSS = 'rect(' + t.img.moved + 'px,' + t.width + ', ' + (t.img.moved + t.moveMax) + 'px, 0px)';
		t.img.style.clip = clipCSS;
		window.setTimeout(function(){
			if (t.isMoving) {
				t.moveClip(t);
			}
		}, t.moveTime);
	},

	gotoImage: function(t,id) {
		window.clearTimeout(t.timer);
		t.currentSlide = id - 1;
		t._next(t,0,0,false);
		t.countdownlatch = 1;
		window.clearTimeout(t.timer);
		t.timer = window.setTimeout(function(){
			t.latchDecrement(t);
		},t.slideDelay * 3);
	},

	startTimer: function(t,delay) {
		window.setTimeout(function(){t.latchDecrement(t)}, delay);
	},

	preloadimgs: function (t) {
		for (var i = 0; i < t.imgs.length; i++) {
			t.imgs[i].img = new Image();
			t.imgs[i].img.onload = t.latchDecrement(t);
			t.imgs[i].img.src = t.imgs[i].src;
		}
	},

	latchDecrement: function(t) {
		t.countdownlatch -= 1;
		if (t.countdownlatch == 0) {
			t.startSlides(t);
		}
	},

	startSlides: function(t) {
		t._next(t,1,t.slideDelay,true);
	}
}
