////////////////////////////////////////////////////////////////////////////////
// FoldBar was written by Mikael Roos
// Copyright 2008 Nodeta Oy
// Requires Prototype (tested with 1.6)
////////////////////////////////////////////////////////////////////////////////

FoldBar = Class.create();
FoldBar.prototype = {
	initialize: function(barElement, growAmount, frameRate){
		this.barElement = $(barElement);
		this.frameRate = frameRate || 100;
		this.growAmount = growAmount || 100;
		this.cachedFactor = this.growAmount/this.frameRate;
		this.initialBarHeight = this.barElement.getHeight();
		this.cachedMaxHeight = this.initialBarHeight+this.growAmount;
		this.folded = true;
		this.latestTimeouts = [];
		this.barElement.observe('mouseover', this.unfold.bindAsEventListener(this));
		document.observe('mouseover', this.fold.bindAsEventListener(this));
		document.observe('mouseout', this.fold.bindAsEventListener(this));
	},
	// TODO: DRY these out
	unfold: function(event) {

		if (!this.folded) return;
		var startPoint = this.barElement.getHeight()-this.initialBarHeight;		
		this.latestTimeouts.each(function(to) { window.clearTimeout(to) }); // Clumsy syntax for IE compatibility
		// Let's create the frames
		for (var i = startPoint, fr = this.frameRate; i < fr; i++ ) {
			// Current offset
			var frameOffset = i-startPoint; // Maybe add a little pause when folding mid-animation?
			// Add the next frame to the correct point in time
			this.latestTimeouts[this.frameRate-i] = setTimeout(function(sizeOffset) {
				this.barElement.setStyle({height: (sizeOffset+this.initialBarHeight)+'px'});
			}.curry(parseInt(i*this.cachedFactor)).bind(this), this.animationTimer(frameOffset));
		 }
		this.folded = false;
		Event.stop(event); // Prevent the event from bubbling all the way to the document
	},
	fold: function(event) {
		if (this.folded) return;
		if (event.element().up('#'+this.barElement.id)!=null) return;
		var startPoint = this.cachedMaxHeight-this.barElement.getHeight();
		this.latestTimeouts.each(function(to) { window.clearTimeout(to) }); // Clumsy syntax for IE compatibility
		for (var i = startPoint; i < this.frameRate; i++ ) {
			// Current offset
			var frameOffset = i-startPoint; // Maybe add a little pause when folding mid-animation?
			// Add the next frame to the correct point in time
			this.latestTimeouts[this.frameRate-i] = setTimeout(function(sizeOffset) {
				this.barElement.setStyle({height: (this.cachedMaxHeight-sizeOffset)+'px'});
			}.curry(parseInt(i*this.cachedFactor)).bind(this), this.animationTimer(frameOffset));
		 }	
		this.folded = true;
	},
	animationTimer: function(frameOffset) {
		return frameOffset * ( (frameOffset/20) + 4 );
	}
		
}
