
/**
 * Foldable Snippet
 */
var FoldableList = Class.create({
	initialize: function(rootNode) {
		this.rootNode = rootNode;
		
		var items = $A(this.rootNode.getElementsByTagName("li"));
		items.each(function(item) {
			var item = $(item);
			if (item.getElementsByTagName("ul").length) {
				item.addClassName("closed");
				
				if (this.rootNode.hasClassName("childcount")) {
					item.down("span").insert({
						bottom: "\u00A0("+(item.select("ul > li").length - item.select("ul").length + 1)+")"
					});
				}
				
				item.observe("click", function(event) {
					var target = Event.element(event);
					if (
						target.tagName.toLowerCase() == "span" &&
						(target.parentNode.hasClassName("closed") || target.parentNode.hasClassName("opened"))
					) {
						target.parentNode.toggleClassName("opened");
						target.parentNode.toggleClassName("closed");
						Event.stop(event);
					}
				});
			}
		}.bind(this));
		
		this.rootNode.addClassName("active");
	}
});


document.observe("dom:loaded", function(event) {
	$$("ul.foldable").each(function(rootNode) {
		new FoldableList(rootNode);
	});
});



/**
 * Resize Snippet
 */
window.afterResize = function(event) {
	if ($("header").select(".viewport").first().getWidth() < 1150)
		$("top").addClassName("noSidebar");
	else
		$("top").removeClassName("noSidebar");
	
	if (Prototype.Browser.WebKit) // redraw
		$("navigation").update($("navigation").innerHTML);
};
Event.observe(document, "dom:loaded", window.afterResize);
Event.observe(window, "resize", window.afterResize);






/**
 * Countdown Widget
 */
var Countdown = Class.create({
  initialize: function(element, date, options) {
    this.element = $(element);
    this.date = date;
    this.options = Object.extend({
      format: "#{weeks}w #{days}d #{hours}:#{minutes}:#{seconds}",
      interval: 1000,
      autostart: true
    }, options ? options : {});
    
    if (!Object.isFunction(this.options.format))
      this.options.format = new Template(this.options.format);
    
    if (this.options.autostart)
      this.start();
    
    this.update();
  },
  
  start: function() {
    this.stop();
    this.interval = window.setInterval(this.update.bindAsEventListener(this), this.options.interval);
  },
  
  stop: function() {
    if (this.interval)
      this.interval = window.clearInterval(this.interval);
  },
  
  update: function() {
    interval = Math.round((this.date.getTime() - (new Date()).getTime()) / 1000);
    
    this.element.update(this.options.format.evaluate(
      this.partition(interval)
    ));
  },
  
  partition: function(interval) {
    parts = {};
    
    if (this.options.format.template.include("#{weeks}")) {
      parts.weeks = Math.floor(interval / (3600*24*7)).toString();
      interval %= 3600*24*7;
    }
    
    if (this.options.format.template.include("#{days}")) {
      parts.days = Math.floor(interval / (3600*24)).toString();
      interval %= 3600*24;
    }
    
    if (this.options.format.template.include("#{hours}")) {
      parts.hours = Math.floor(interval / 3600).toString();
      interval %= 3600;
    }
    
    if (this.options.format.template.include("#{minutes}")) {
      parts.minutes = Math.floor(interval / 60).toString();
      interval %= 60;
    }
    
    if (this.options.format.template.include("#{seconds}")) {
      parts.seconds = interval.toString();
    }
    
    return parts;
  }
});





/**
 * Slideshow Widget
 */
var Slideshow = Class.create({
	initialize: function(element, sources, options) {
		this.element = $(element).update(null);
		
		this.options = Object.extend({
			images: [],
			playlist: null,
			randomize: true,
			transition: { duration: 2 },
			interval: 7,
			autoStart: true
		}, options);
		
		this.images = this.options.images;
		sources.each(this.addImage.bind(this));
		
		if (this.options.playlist) {
			this._load(this.options.playlist);
		} else {
			this._init();
		}
	},
	
	_createImage: function(source) {
		return $(document.createElement("img")).writeAttribute("src", source);
	},
	
	addImage: function(image) {
		if (Object.isString(image))
			image = this._createImage(image);
		else
			image.removeAttribute("alt");
		
		this.images.push(image);
		return this;
	},
	
	_init: function() {
		Object.extend(this.options.transition, {
			afterFinish: function() {
				this.element.removeChild(this.previousImage);
			}.bind(this)
		});
		
		this.currentIndex = this.options.randomize ? this._getNextIndex() : 0;
		this.currentImage = this.element.appendChild(this.images[this.currentIndex]);
		this.currentImage.forceRerendering()
		
		this.element.observe("mouseover", this.stop.bindAsEventListener(this));
		this.element.observe("mouseout", this.start.bindAsEventListener(this));
		
		if (this.options.autoStart) 
			this.start();
	},
	
	start: function() {
		if (this.interval) this.stop();
		this.interval = new PeriodicalExecuter(this.next.bind(this), this.options.interval);
	},
	
	stop: function() {
		if (this.interval) {
			this.interval.stop();
			this.interval = null;
		}
	},
	
	_getNextIndex: function() {
		if (this.options.randomize) {
			do {
				var next = Math.round(Math.random()*(this.images.length-1));
			} while(next == this.currentIndex);



			return next;
		} else
			return (this.currentIndex >= (this.images.length-1)) ? 0 : (this.currentIndex + 1);
	},


	

	next: function() {
		if (this.images.length == 0) return;
		
		var nextIndex = this._getNextIndex();
		var nextImage = this.element.appendChild(
			this.images[nextIndex].setStyle({ zIndex: 1 }).show()
		);
		
		this.previousImage = this.currentImage.setStyle({ zIndex: 2 }).fade(this.options.transition);
		
		this.currentIndex = nextIndex;
		this.currentImage = nextImage;
	},
	
	_load: function(playlist) {
		new Ajax.Request(playlist, {
			method: 'get',
			onSuccess: function(transport) {
				transport.responseText.strip().split(String.fromCharCode(10)).invoke("strip").each(this.addImage.bind(this));
				this.options.autoStart = true;
				this._init();
			}.bind(this),
			onFailure: this._init.bind(this),
			onException: this._init.bind(this)
		});
	}
});
