
var windowResizeFunctions = [];
var windowScrollFunctions = [];

var windowResizeMinDelay = -1;
var windowResizeLastExecution = 0;
var resizeTimeoutID = -1;

window.onresize = windowResize;
window.onscroll = windowScroll;

function windowResize(e) {
	var curTime = $time();
	if (windowResizeMinDelay > 0) {
		var delaySinceLast = curTime - windowResizeLastExecution;
		if (delaySinceLast < windowResizeMinDelay) {
			if (resizeTimeoutID == -1) {
				resizeTimeoutID = window.setTimeout("windowResize(null)", windowResizeMinDelay - delaySinceLast);
			}
			return;
		}
	}

	if (resizeTimeoutID != -1) {
		window.clearTimeout(resizeTimeoutID);
		resizeTimeoutID = -1;
	}

	var origWidth = window.getWidth();
	var origHeight = window.getHeight();
	var origOnifinWidth = window.getOnifinWidth();
	var origOnifinHeight = window.getOnifinHeight();

	windowResizeFunctions.each(function(fn, i) {
		fn.call(null, e);
	});

	var newWidth = window.getWidth();
	var newHeight = window.getHeight();
	var newOnifinWidth = window.getOnifinWidth();
	var newOnifinHeight = window.getOnifinHeight();

	if (origWidth != newWidth || origHeight != newHeight
		|| origOnifinWidth != newOnifinWidth || origOnifinHeight != newOnifinHeight) {

		// Let's give it a second try.
		windowResizeFunctions.each(function(fn, i) {
			fn.call(null, e);
		});
	}

	if (mustSendDimsToServer == true) {
		sendDimsToServer(newOnifinWidth, newOnifinHeight);
	}

	windowResizeLastExecution = $time();
}
function windowScroll(e) {
	windowScrollFunctions.each(function(fn, i) {
		fn.call(null, e);
	});
}

Element.Events.windowResized = {
	add: function(fn){
		windowResizeFunctions.include(fn);
	}
};
Element.Events.windowScrolled = {
	add: function(fn){
		windowScrollFunctions.include(fn);
	}
};

function forceWindowResizeEvent() {
	windowResize(null);
}


var mustSendDimsToServer = false;
var dimsServerAddr = null;
var delayDimsToServer = -1;
var dimsToServerTimeoutId = -1;
var lastWidthSentToServer = null;
var lastHeightSentToServer = null;
function sendDimsToServer(width, height) {
	if ($type(delayDimsToServer) != 'number' || delayDimsToServer <= 0) {
		realSendDimsToServer(width, height);
		return;
	}

	if (dimsToServerTimeoutId != -1) {
		window.clearTimeout(dimsToServerTimeoutId);
		dimsToServerTimeoutId = -1;
	}

	dimsToServerTimeoutId = window.setTimeout("realSendDimsToServer("+width+", "+height+")", delayDimsToServer);
}
function realSendDimsToServer(width, height) {
	if (mustSendDimsToServer != true) {
		return;
	}
	if ($type(dimsServerAddr) != 'string') {
		return;
	}
	if (width == lastWidthSentToServer && height == lastHeightSentToServer) {
		return;
	}
	//alert('send');
	var myAjax = new Ajax(dimsServerAddr, {method: 'post', data: {
		width : width,
		height: height
	}, onComplete: function(result) {
		//alert(result);
		lastWidthSentToServer = width;
		lastHeightSentToServer = height;
	} }).request();
}

// LOGGER
var window_logger = null;

function log(txt) {
	return;
	if (window_logger == null) {
		window_logger = window.open();
	}
	window_logger.document.body.innerHTML = window_logger.document.body.innerHTML+txt+"<br/>";
}


window.extend({

	/*
	Property: getOnifinWidth
		Returns an integer representing the width of the browser window (without the scrollbar).
	*/

	getOnifinWidth: function(){
		if (window.ie) {
			return window.getWidth();
		}
		if (typeof( window.innerWidth ) != "undefined" && window.innerWidth != null && window.innerWidth > 0) {
			return window.innerWidth;
		} else if (typeof( document.body.clientWidth ) != "undefined" && document.body.clientWidth != null && document.body.clientWidth > 0) {
			return document.body.clientWidth;
		} else if (typeof( document.documentElement.scrollWidth ) != "undefined" && document.documentElement.scrollWidth != null && document.documentElement.scrollWidth > 0) {
			return document.documentElement.scrollWidth - 25;
		}
		return window.getWidth();
	},

	/*
	Property: getOnifinHeight
		Returns an integer representing the height of the browser window (without the scrollbar).
	*/

	getOnifinHeight: function(){
		if (window.ie) {
			return window.getHeight();
		}
		if (typeof( window.innerHeight ) != "undefined" && window.innerHeight != null && window.innerHeight > 0) {
			return window.innerHeight;
		} else if (typeof( document.body.offsetHeight ) != "undefined" && document.body.offsetHeight != null && document.body.offsetHeight > 0) {
			return document.body.offsetHeight;
		} else if (typeof( document.body.clientHeight ) != "undefined" && document.body.clientHeight != null && document.body.clientHeight > 0) {
			return document.body.clientHeight;
		} else if (typeof( document.documentElement.scrollHeight ) != "undefined" && document.documentElement.scrollHeight != null && document.documentElement.scrollHeight > 0) {
			return document.documentElement.scrollHeight - 25;
		}
		return window.getHeight();
	}

});

Element.extend({
	getScrollSize: function(){
		res_width = -1;
		res_height = -1;
		if (window.ie) {
			res_width = this.offsetWidth;
			res_height = this.offsetHeight;
		} else if (window.gecko) {
			children = this.getChildren();
			max_width = this.getSize().scrollSize.x;
			max_height = this.getSize().scrollSize.y;
			children.each(function(child) {
				coords = child.getCoordinates();

				positionLeft = child.offsetLeft;
				positionTop = child.offsetTop;

				tmpWidth = coords.width;
				tmpHeight = coords.height;

				if (positionLeft + tmpWidth > max_width) {
					max_width = positionLeft + tmpWidth;
				}
				if (positionTop + tmpHeight > max_height) {
					max_height = positionTop + tmpHeight;
				}
			});
			res_width = max_width;
			res_height = max_height;
		} else {
			res_width = this.getSize().scrollSize.x;
			res_height = this.getSize().scrollSize.y;
		}
		return {'scrollWidth': res_width, 'scrollHeight': res_height};
	}
});

Class.prototype['oniExtend'] = function(properties){
	var proto = new this(null);
	var parentProto = new this(null);

	var funcArray = [];

	for (var property in properties){
		var pp = proto[property];
		proto[property] = Class.OniMerge(pp, properties[property]);
		/*if ($type(pp) == 'function') {
			funcArray.push(pp);
		}*/
	}

	for (var key in parentProto) {
		if ($type(parentProto[key]) == 'function') {
			funcArray.push(parentProto[key]);
		}
	}
	parentProto['funcArray'] = funcArray;
	proto['parentProto'] = parentProto;
	if ($type(parentProto.oniExtendNum) == 'number') {
		proto['oniExtendNum'] = parentProto.oniExtendNum + 1;
	} else {
		proto['oniExtendNum'] = 1;
	}

	proto['getCurrentOniClass'] = function() {
		if ($type(arguments[0]) != 'function') {
			return null;
		}

		/*log('');
		log('arguments[0] : '+arguments[0]);
		log('');
		log('this : '+this);*/

		if (!$defined(this.parentProto)) {
			return this;
		}

		var tmpProto = this;
		var listProtos = [];
		while ($defined(tmpProto)) {
			listProtos.push(tmpProto);
			tmpProto = tmpProto.parentProto;
		}

		//alert('arg : '+arguments[0]);
		for (var i = listProtos.length - 1; i >= 1; i--) {
			tmpProto = listProtos[i];
			var currentNum = 0;
			if ($type(tmpProto.oniExtendNum) == 'number') {
				currentNum = tmpProto.oniExtendNum;
			}

			if ($defined(tmpProto.funcArray) && tmpProto.funcArray.contains(arguments[0])) {
				//alert('found : '+currentNum);
				return tmpProto;
			}

			/*for (key in tmpProto) {
				var elem = tmpProto[key];
				log('');
				log('test'+currentNum+' : '+key+" : "+elem);
				if ($type(elem) != 'function') {
					continue;
				}
				if (elem === arguments[0]) {
					// We found it !.
					log('foundCurrent : '+currentNum);
					return tmpProto;
				}
			}*/
			/*tmpProto = tmpProto.parentProto;*/
		}
		return this;
	}

	return new Class(proto);
};


Class.OniMerge = function(previous, current){
	if (previous && previous != current){
		var type = $type(current);
		if (type != $type(previous)) return current;
		switch(type){
			case 'function': return current;
			case 'object': return $merge(previous, current);
		}
	}
	return current;
};


Fx.StyleWithTransitionEvent = Fx.Style.extend({
	initialise: function() {
		this.element = $(el);
		this.property = property;
		this.setOptions(options);
		if (this.options.initialize) this.options.initialize.call(this);
	},

	increase: function(){
		this.increase.parent.bind(this)();
		//this.getCurrentOniClass(arguments.callee).parentProto.increase.bind(this)();
		if (this.options.onTransition) {
			this.fireEvent('onTransition', this.now);
		}
	}
});





// BlockElement : Basic functions.

var BlockElement = new Class({
	initialize: function(el) {
		this.element = el;

		this.previousMarginLeft = parseInt(this.element.getStyle('padding-left'));
		this.previousMarginRight = parseInt(this.element.getStyle('padding-right'));
		this.previousMarginTop = parseInt(this.element.getStyle('padding-top'));
		this.previousMarginBottom = parseInt(this.element.getStyle('padding-bottom'));

		//alert('left : '+this.previousMarginLeft+'\nright : '+this.previousMarginRight+'\ntop : '+this.previousMarginTop+'\nbottom : '+this.previousMarginBottom);

		this.previousWidth = this.element.getScrollSize().scrollWidth;
		this.previousHeight = this.element.getScrollSize().scrollHeight;
	},

	getElement: function() {
		return this.element;
	},

	setWidth: function(width) {
		this.previousWidth = width;

		log(((this.getElement())?this.getElement().id:'undefined')+'::setWidth('+width+')');
		//this.element.setStyle('width', width+'px');

		var realWidth = width - this.getMarginLeft() - this.getMarginRight();
		this.element.setStyle('width', realWidth+'px');
	},

	getWidth: function() {
		log(((this.getElement())?this.getElement().id:'undefined')+'::getWidth() : '+this.previousWidth);
		//alert(this.element.getSize().size.x);
		//return this.element.getSize().size.x;
		return this.previousWidth;
	},

	setHeight: function(height) {
		log(((this.getElement())?this.getElement().id:'undefined')+'::setHeight('+height+')');
		this.previousHeight = height;

		var realHeight = height - this.getMarginTop() - this.getMarginBottom();

		this.element.setStyle('height', realHeight+'px');
	},

	getHeight: function() {
		log(((this.getElement())?this.getElement().id:'undefined')+'::getHeight() : '+this.previousHeight);
		//return this.element.getSize().size.y;
		return this.previousHeight;
	},

	setMarginLeft: function(marginLeft) {
		this.previousMarginLeft = marginLeft;
		this.element.setStyle('width', this.getWidth() - marginLeft - this.getMarginRight());
		this.element.setStyle('margin-left', marginLeft+'px');
	},
	getMarginLeft: function() {
		return this.previousMarginLeft;
	},

	setMarginTop: function(marginTop) {
		this.previousMarginTop = marginTop;
		this.element.setStyle('height', this.getHeight() - marginTop - this.getMarginBottom());
		this.element.setStyle('margin-top', marginTop+'px');
	},
	getMarginTop: function() {
		return this.previousMarginTop;
	},

	setMarginRight: function(marginRight) {
		this.previousMarginRight = marginRight;
		this.element.setStyle('width', this.getWidth() - marginRight - this.getMarginLeft());
		this.element.setStyle('margin-right', marginRight+'px');
	},
	getMarginRight: function() {
		return this.previousMarginRight;
	},

	setMarginBottom: function(marginBottom) {
		this.previousMarginBottom = marginBottom;
		this.element.setStyle('height', this.getHeight() - marginBottom - this.getMarginTop());
		this.element.setStyle('margin-bottom', marginBottom+'px');
	},
	getMarginBottom: function() {
		return this.previousMarginBottom;
	},

	setName: function(nom) {
		this.nom = nom;
	},
	getName: function() {
		if ($defined(this.nom)) {
			return this.nom;
		}
		return null;
	}
});

var LinkedBlockElement = BlockElement.oniExtend({

	initialize: function(el) {
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el);

		this.parentResizeMinDelay = -1;
		this.parentResizeLastExecution = 0;
		this.parentResizeTimeoutID = -1;

		this.father = null;
		this.children = [];

		this.calcDimsFromParent = null;
		this.calcDimsOnChildChange = null;
		this.calcDimsFromChildren = null;

		this.calcWidthFromHeight = null;
		this.calcHeightFromWidth = null;

		this.methodRecursionLimit = -1;
		this.mustCallFather = true;
		this.childrenNotToCall = [];

		window.addEvent('windowResized', this.onWindowChanged.bind(this));
	},

	setParent: function(parent) {
		/*
		 * In this method we add the father before colling its 'addChild' method
		 * in order to avoid loop.
		 */
		if (this.father != null) {
			if (this.father == parent) {
				// Avoid loop
				return;
			} else {
				// Seems like we change the father.
				this.removeParent();
			}
		}
		this.father = parent;
		if (this.father != 'WINDOW') {
			this.father.addChild(this);
		}
	},

	removeParent: function() {
		/*
		 * In this method we remove the father before colling its 'removeChild' method
		 * in order to avoid loop.
		 */
		if (this.father == null) {
			return;
		}
		oldFather = this.father;
		this.father = null;
		if (oldFather != 'WINDOW') {
			oldFather.removeChild(this);
		}
	},

	getParent: function() {
		return this.father;
	},

	setChildren: function(children) {
		this.children = children;
		this.children.each(function(child) {child.setParent(this);}, this);
	},

	addChild: function(child) {
		/*
		 * In this method we add the child before colling its 'setParent' method
		 * in order to avoid loop.
		 */
		if (this.children.contains(child)) {
			return;
		}
		this.children.push(child);
		child.setParent(this);
	},

	removeChild: function(child) {
		/*
		 * In this method we remove the child before colling its 'removeParent' method
		 * in order to avoid loop.
		 */
		if (this.children.contains(child)) {
			this.children.remove(child);
			child.removeParent();
		}
	},

	getChildren: function() {
		return this.children;
	},

	setParentResizeMinDelay: function(delay) {
		this.parentResizeMinDelay = delay;
	},

	setDims: function(width, height) {
		changeWidth = true;
		changeHeight = true;
		if (width < 0) {
			changeWidth = false;
		}
		if (height < 0) {
			changeHeight = false;
		}

		if ($defined(this.currentlyChangingWidth) && this.currentlyChangingWidth == true) {
			changeWidth = false;
		}
		if ($defined(this.currentlyChangingHeight) && this.currentlyChangingHeight == true) {
			changeHeight = false;
		}

		if (changeWidth == false && changeHeight == false) {
			return;
		} else if (changeWidth == false && this.getHeight() == height) {
			return;
		} else if (changeHeight == false && this.getWidth() == width) {
			return;
		} else if (this.getWidth() == width && this.getHeight == height) {
			return;
		}

		if (changeWidth == true) {
			this.currentlyChangingWidth = true;
		}
		if (changeHeight == true) {
			this.currentlyChangingHeight = true;
		}

		var marginTop = 0;
		var marginLeft = 0;

		if (! $defined(this.setDimsMethodCounter)) {
			this.setDimsMethodCounter = 0;
		}
		if (this.methodRecursionLimit > 0 && this.setDimsMethodCounter >= this.methodRecursionLimit) {
			return;
		}
		this.setDimsMethodCounter = this.setDimsMethodCounter + 1;

		log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::setDims('+width+', '+height+') '+this.setDimsMethodCounter+' BEGIN');
		if (((!$defined(this.currentlyChangingHeight)) || this.currentlyChangingHeight == false) && height < 0 && $defined(this.calcHeightFromWidth) && this.calcHeightFromWidth != null) {
			var newHeight = -1;
			if ($type(this.calcHeightFromWidth) == 'function') {
				newHeight = this.calcHeightFromWidth(this, width);
			} else if ($type(this.calcHeightFromWidth.getDim) == 'function') {
				newHeight = this.calcHeightFromWidth.getDim(this, width);
			}
			if ($type(newHeight) == 'number') {
				if (newHeight > 0) {
					height = newHeight;
				}
			} else {
				if ($type(newHeight[0]) == 'number' && newHeight[0] > 0) {
					height = newHeight[0];
				}
				if (newHeight[1] >= 0) {
					marginLeft = newHeight[1];
				}
			}
		}

		if (((!$defined(this.currentlyChangingWidth)) || this.currentlyChangingWidth == false) && width < 0 && $defined(this.calcWidthFromHeight) && this.calcWidthFromHeight != null) {
			var newWidth = -1;
			if ($type(this.calcWidthFromHeight) == 'function') {
				newWidth = this.calcWidthFromHeight(this, height);
			} else if ($type(this.calcWidthFromHeight.getDim) == 'function') {
				newWidth = this.calcWidthFromHeight.getDim(this, height);
			}
			if ($type(newWidth) == 'number') {
				if (newWidth > 0) {
					width = newWidth;
				}
			} else {
				if ($type(newWidth[0]) == 'number' && newWidth[0] > 0) {
					width = newWidth[0];
				}
				if (newWidth[1] >= 0) {
					marginTop = newWidth[1];
				}
			}
		}

		log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::setDims('+width+', '+height+') '+this.setDimsMethodCounter+' INTERMEDIERE');
		if (width != this.getWidth() && width > 0) {
			log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::setDims('+width+', '+height+') '+this.setDimsMethodCounter+' TEST1');
			this.getCurrentOniClass(arguments.callee).parentProto.setWidth.bind(this)(Math.round(width));
			this.setMarginLeft(Math.round(marginLeft));
		}
		if (height != this.getHeight() && height > 0) {
			this.getCurrentOniClass(arguments.callee).parentProto.setHeight.bind(this)(Math.round(height));
			this.setMarginTop(Math.round(marginTop));
		}

		log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::setDims('+width+', '+height+') '+this.setDimsMethodCounter+' TEST2');
		//alert("apres : "+this.getWidth()+" / "+this.previousWidth);
		this.setAllMyChildrenToCallMe(false);
		this.callChildren();
		this.checkChildren();
		this.setAllMyChildrenToCallMe(true);
		log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::setDims('+width+', '+height+') '+this.setDimsMethodCounter+' TEST3');
		this.setMyFatherToCallMe(false);
		this.callParent();
		this.checkParent();
		this.setMyFatherToCallMe(true);
		log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::setDims('+width+', '+height+') '+this.setDimsMethodCounter+' TEST4');


		log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::setDims('+width+', '+height+') '+this.setDimsMethodCounter+' END');
		this.setDimsMethodCounter = this.setDimsMethodCounter - 1;
		this.currentlyChangingWidth = false;
		this.currentlyChangingHeight = false;
	},

	setWidth: function(width) {
		this.setDims(width, -1);
	},

	getWidth: function() {
		return this.getCurrentOniClass(arguments.callee).parentProto.getWidth.bind(this)();
	},

	setHeight: function(height) {
		this.setDims(-1, height);
	},

	getHeight: function() {
		return this.getCurrentOniClass(arguments.callee).parentProto.getHeight.bind(this)();
	},

	onParentChanged: function(pWidth, pHeight) {
		if ($defined(this.calcDimsFromParent) && this.calcDimsFromParent != null) {
			log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::onParentChanged('+pWidth+', '+pHeight+')');
			var curTime = $time();
			if (this.parentResizeMinDelay > 0) {
				var delaySinceLast = curTime - this.parentResizeLastExecution;
				if (delaySinceLast < this.parentResizeMinDelay) {
					if (this.parentResizeTimeoutID != -1) {
						window.clearTimeout(this.parentResizeTimeoutID);
						this.parentResizeTimeoutID = -1;
					}

					var timeOutFunc = function() {
						/*alert('test : '+pWidth+"x"+pHeight);
						alert(this.onParentChanged);*/
						this.onParentChanged(pWidth, pHeight);
					}
					this.parentResizeTimeoutID = window.setTimeout(timeOutFunc.bind(this), this.parentResizeMinDelay - delaySinceLast);
					return;
				}
			}

			if (this.parentResizeTimeoutID != -1) {
				window.clearTimeout(this.parentResizeTimeoutID);
				this.parentResizeTimeoutID = -1;
			}

			var newDims = [-1, -1];
			if ($type(this.calcDimsFromParent) == 'function') {
				newDims = this.calcDimsFromParent(this, pWidth, pHeight);
			} else if ($type(this.calcDimsFromParent.getDims) == 'function') {
				newDims = this.calcDimsFromParent.getDims(this, pWidth, pHeight);
			}

			log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::onParentChanged : newDims('+Math.round(newDims[0])+', '+Math.round(newDims[1])+')');

			if ($type(newDims[0]) == 'number' && $type(newDims[1]) == 'number') {
				this.setDims(Math.round(newDims[0]), Math.round(newDims[1]));
			}

			this.parentResizeLastExecution = $time();
		}
	},

	onChildChanged: function(child, cWidth, cHeight) {
		var newDims = [-1, -1];
		if ($defined(this.calcDimsOnChildChange) && this.calcDimsOnChildChange != null) {
			if ($type(this.calcDimsOnChildChange) == 'function') {
				newDims = this.calcDimsOnChildChange(this, child, cWidth, cHeight);
			} else if ($type(this.calcDimsOnChildChange.getDims) == 'function') {
				newDims = this.calcDimsOnChildChange.getDims(this, child, cWidth, cHeight);
			}
		} else if ($defined(this.calcDimsFromChildren) && this.calcDimsFromChildren != null) {
			if ($type(this.calcDimsFromChildren) == 'function') {
				newDims = this.calcDimsFromChildren(this, this.getChildren(), cWidth, cHeight);
			} else if ($type(this.calcDimsFromChildren.getDims) == 'function') {
				newDims = this.calcDimsFromChildren.getDims(this, this.getChildren(), cWidth, cHeight);
			}
		}

		if ($type(newDims[0]) == 'number' && $type(newDims[1]) == 'number') {
			this.setDims(Math.round(newDims[0]), Math.round(newDims[1]));
		}
	},

	checkChildren: function() {
		var newDims = [-1, -1];
		if ($defined(this.calcDimsFromChildren) && this.calcDimsFromChildren != null) {
			if ($type(this.calcDimsFromChildren) == 'function') {
				newDims = this.calcDimsFromChildren(this, this.getChildren(), -1, -1);
			} else if ($type(this.calcDimsFromChildren.getDims) == 'function') {
				newDims = this.calcDimsFromChildren.getDims(this, this.getChildren(), -1, -1);
			}
		}

		if ($type(newDims[0]) == 'number' && $type(newDims[1]) == 'number') {
			this.setDims(Math.round(newDims[0]), Math.round(newDims[1]));
		}
	},

	checkParent: function() {
		if (this.father == null) {
			return;
		}
		if (this.father == 'WINDOW') {
			//this.onParentChanged(window.getOnifinWidth(), window.getOnifinHeight());
			//this.onParentChanged(window.getWidth(), window.getHeight());
			this.onParentChanged(window.getWidth(), window.getOnifinHeight());
			return;
		}
		if (this.getMustCallFather() == true) {
			log(((this.getElement())?this.getElement().id:'undefined')+'::checkParent()');
			this.onParentChanged(this.father.getWidth(), this.father.getHeight());
		}
	},

	onWindowChanged: function() {
		if (this.father != 'WINDOW') {
			return;
		}
		//var tmpTime = $time();
		//this.onParentChanged(window.getOnifinWidth(), window.getOnifinHeight());
		//this.onParentChanged(window.getWidth(), window.getHeight());
		var newWidth = window.getWidth();
		var newHeight = window.getOnifinHeight();
		this.onParentChanged(newWidth, newHeight);
		//alert('Time elapsed : '+($time() - tmpTime));

		// Let's give it an other try.
		/*if (window.getWidth() != newWidth || window.getOnifinHeight() != newHeight) {
			this.onParentChanged(window.getWidth(), window.getOnifinHeight());
		}*/
	},

	callChildren: function() {
		var thisWidth = this.getWidth();
		var thisHeight = this.getHeight();
		this.children.each(function(child) {
				if ($type(child.onParentChanged) == 'function') {
					if (this.getMustCallChild(child) == true) {
						child.onParentChanged(thisWidth, thisHeight);
					}
				}
			}.bind(this));
	},

	callParent: function() {
		if (this.father == 'WINDOW' || this.father == null) {
			return;
		}
		var thisWidth = this.getWidth();
		var thisHeight = this.getHeight();
		if (this.getMustCallFather() == true) {
			log(((this.getElement())?this.getElement().id:'undefined')+'::LinkedBlockElement::callParent');
			this.father.onChildChanged(this, this.getWidth(), this.getHeight());
		}
	},

	setMustCallFather: function(mcf) {
		this.mustCallFather = mcf;
	},

	getMustCallFather: function() {
		return this.mustCallFather;
	},

	setMustCallChild: function(child, mcc) {
		if (this.childrenNotToCall.contains(child)) {
			if (mcc == false) {
				return;
			}
			this.childrenNotToCall.remove(child);
		} else {
			if (mcc == true) {
				return;
			}
			this.childrenNotToCall.push(child);
		}
	},

	getMustCallChild: function(child) {
		if (this.childrenNotToCall.contains(child)) {
			return false;
		}
		return true;
	},

	setAllMyChildrenToCallMe: function(doTheyCall) {
		this.children.each(function(child) {child.setMustCallFather(doTheyCall);});
	},

	setMyFatherToCallMe: function(doesHeCall) {
		log(((this.getElement())?this.getElement().id:'undefined')+'::setMyFatherToCallMe('+doesHeCall+')');
		if (this.father != null && this.father != 'WINDOW') {
			this.father.setMustCallChild(this, doesHeCall);
		}
	}
});



var SingleDimCalculator = new Class({
	initialize: function(method) {
		this.getCurrentOniClass(arguments.callee);

		this.calcMethod = method;
	},

	getDim: function(caller, origDim) {
		if ($type(this.calcMethod) == 'function') {
			return this.calcMethod(caller, origDim);
		}
		return -1;
	}
});

var ListBasedSingleDimCalculator = SingleDimCalculator.oniExtend({
	initialize: function(nbElems, elWidth, elHeight, minNumElemsByLine) {
		//this.parent(this.calcWidthFromHeight.bind(this));
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(this.calcWidthFromHeight.bind(this));

		this.nbElems = nbElems;
		this.elemWidth = elWidth;
		this.elemHeight = elHeight;
		this.minNumElemsByLine = minNumElemsByLine;
	},

	calcWidthFromHeight: function(caller, height) {
		if (height == 0) {
			return [-1, 0];
		}
		nb_lignes = Math.floor(height / this.elemHeight);
		nb_prod_par_ligne = Math.ceil(this.nbElems / nb_lignes);

		if ($defined(this.minNumElemsByLine) && this.minNumElemsByLine > nb_prod_par_ligne) {
			nb_prod_par_ligne = this.minNumElemsByLine;
		}

		new_width = nb_prod_par_ligne * this.elemWidth;

		real_height = (Math.ceil(this.nbElems / nb_prod_par_ligne)) * this.elemHeight;
		margin = Math.floor((height - real_height) / 2);

		//alert(height+" => "+new_width);
		return [new_width, margin];
		//return new_width;
	}
});

var ParentDimCalculator = new Class({
	initialize: function(method) {
		this.calcMethod = method;
	},

	getDims: function(caller, width, height) {
		if ($type(this.calcMethod) == 'function') {
			return this.calcMethod(caller, width, height);
		}
		return -1;
	}
});

var HeightParentDimCalculator = ParentDimCalculator.oniExtend({
	options: {
		percentMinus: 0,
		valMinus: 0,
		elemsMinus: [],
		minHeight: 0,
		order: 0
			/*
			 * Possible orders :
			 *
			 * 0: percent, val, elems
			 * 1: percent, elems, val
			 * 2: val, percent, elems
			 * 3: val, elems, percent
			 * 4: elems, percent, val
			 * 5: elems, val, percent
			 *
			 */
	},

	initialize: function(options) {
		//this.parent(this.calcMethod.bind(this));
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(this.calcMethod.bind(this));
		this.setOptions(options);
	},

	calcMethod: function(caller, width, height) {
		// We don't care aboute width here.
		newHeight = height;
		if (this.options.order == 0) {
			newHeight -= newHeight * this.options.percentMinus / 100;
			newHeight -= this.options.valMinus;
		} else if (this.options.order == 1) {
			newHeight -= newHeight * this.options.percentMinus / 100;
			newHeight -= this.options.valMinus;
		} else if (this.options.order == 2) {
			newHeight -= this.options.valMinus;
			newHeight -= newHeight * this.options.percentMinus / 100;
		} else if (this.options.order == 3) {
			newHeight -= this.options.valMinus;
			newHeight -= newHeight * this.options.percentMinus / 100;
		} else if (this.options.order == 4) {
			newHeight -= newHeight * this.options.percentMinus / 100;
			newHeight -= this.options.valMinus;
		} else if (this.options.order == 5) {
			newHeight -= this.options.valMinus;
			newHeight -= newHeight * this.options.percentMinus / 100;
		}

		if (newHeight < this.options.minHeight) {
			newHeight = this.options.minHeight;
		}

		return [-1, newHeight];
	}
});
HeightParentDimCalculator.implement(new Options);

var WidthParentDimCalculator = ParentDimCalculator.oniExtend({
	options: {
		percentMinus: 0,
		valMinus: 0,
		elemsMinus: [],
		minWidth: 0,
		order: 0
			/*
			 * Possible orders :
			 *
			 * 0: percent, val, elems
			 * 1: percent, elems, val
			 * 2: val, percent, elems
			 * 3: val, elems, percent
			 * 4: elems, percent, val
			 * 5: elems, val, percent
			 *
			 */
	},

	initialize: function(options) {
		//this.parent(this.calcMethod.bind(this));
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(this.calcMethod.bind(this));
		this.setOptions(options);
	},

	calcMethod: function(caller, width, height) {
		// We don't care aboute height here.
		newWidth = width;
		if (this.options.order == 0) {
			newWidth -= newWidth * this.options.percentMinus / 100;
			newWidth -= this.options.valMinus;
		} else if (this.options.order == 1) {
			newWidth -= newWidth * this.options.percentMinus / 100;
			newWidth -= this.options.valMinus;
		} else if (this.options.order == 2) {
			newWidth -= this.options.valMinus;
			newWidth -= newWidth * this.options.percentMinus / 100;
		} else if (this.options.order == 3) {
			newWidth -= this.options.valMinus;
			newWidth -= newWidth * this.options.percentMinus / 100;
		} else if (this.options.order == 4) {
			newWidth -= newWidth * this.options.percentMinus / 100;
			newWidth -= this.options.valMinus;
		} else if (this.options.order == 5) {
			newWidth -= this.options.valMinus;
			newWidth -= newWidth * this.options.percentMinus / 100;
		}

		if (newWidth < this.options.minWidth) {
			newWidth = this.options.minWidth;
		}

		return [newWidth, -1];
	}
});
WidthParentDimCalculator.implement(new Options);

var WidthAndHeightParentDimCalculator = ParentDimCalculator.oniExtend({
	options: {
		widthPercentMinus: 0,
		widthValMinus: 0,
		widthElemsMinus: [],
		minWidth: 0,
		widthOrder: 0,
		heightPercentMinus: 0,
		heightValMinus: 0,
		heightElemsMinus: [],
		minHeight: 0,
		heightOrder: 0
			/*
			 * Possible orders :
			 *
			 * 0: percent, val, elems
			 * 1: percent, elems, val
			 * 2: val, percent, elems
			 * 3: val, elems, percent
			 * 4: elems, percent, val
			 * 5: elems, val, percent
			 *
			 */
	},

	initialize: function(options) {
		//this.parent(this.calcMethod.bind(this));
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(this.calcMethod.bind(this));
		this.setOptions(options);
	},

	calcMethod: function(caller, width, height) {

		newWidth = width;
		if (this.options.widthOrder == 0) {
			newWidth -= newWidth * this.options.widthPercentMinus / 100;
			newWidth -= this.options.widthValMinus;
		} else if (this.options.widthOrder == 1) {
			newWidth -= newWidth * this.options.widthPercentMinus / 100;
			newWidth -= this.options.widthValMinus;
		} else if (this.options.widthOrder == 2) {
			newWidth -= this.options.widthValMinus;
			newWidth -= newWidth * this.options.widthPercentMinus / 100;
		} else if (this.options.widthOrder == 3) {
			newWidth -= this.options.widthValMinus;
			newWidth -= newWidth * this.options.widthPercentMinus / 100;
		} else if (this.options.widthOrder == 4) {
			newWidth -= newWidth * this.options.widthPercentMinus / 100;
			newWidth -= this.options.widthValMinus;
		} else if (this.options.widthOrder == 5) {
			newWidth -= this.options.widthValMinus;
			newWidth -= newWidth * this.options.widthPercentMinus / 100;
		}

		if (newWidth < this.options.minWidth) {
			newWidth = this.options.minWidth;
		}
		
		newHeight = height;
		if (this.options.heightOrder == 0) {
			newHeight -= newHeight * this.options.heightPercentMinus / 100;
			newHeight -= this.options.heightValMinus;
		} else if (this.options.heightOrder == 1) {
			newHeight -= newHeight * this.options.heightPercentMinus / 100;
			newHeight -= this.options.heightValMinus;
		} else if (this.options.heightOrder == 2) {
			newHeight -= this.options.heightValMinus;
			newHeight -= newHeight * this.options.heightPercentMinus / 100;
		} else if (this.options.heightOrder == 3) {
			newHeight -= this.options.heightValMinus;
			newHeight -= newHeight * this.options.heightPercentMinus / 100;
		} else if (this.options.heightOrder == 4) {
			newHeight -= newHeight * this.options.heightPercentMinus / 100;
			newHeight -= this.options.heightValMinus;
		} else if (this.options.heightOrder == 5) {
			newHeight -= this.options.heightValMinus;
			newHeight -= newHeight * this.options.heightPercentMinus / 100;
		}

		if (newHeight < this.options.minHeight) {
			newHeight = this.options.minHeight;
		}

		return [newWidth, newHeight];
	}
});
WidthAndHeightParentDimCalculator.implement(new Options);

var ChildrenDimCalculator = new Class({
	initialize: function(method) {
		this.calcMethod = method;
	},

	getDims: function(caller, child, width, height) {
		if ($type(this.calcMethod) == 'function') {
			return this.calcMethod(caller, child, width, height);
		}
		return [-1, -1];
	}
});

var WidthChildrenDimCalculator = ChildrenDimCalculator.oniExtend({

	options: {
		percentAdd: 0,
		valAdd: 0,
		elemsAdd: [],
		minWidth: 0,
		order: 0
			/*
			 * Possible orders :
			 *
			 * 0: percent, val, elems
			 * 1: percent, elems, val
			 * 2: val, percent, elems
			 * 3: val, elems, percent
			 * 4: elems, percent, val
			 * 5: elems, val, percent
			 *
			 */
	},

	initialize: function(options) {
		//this.parent(this.calcMethod.bind(this));
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(this.calcMethod.bind(this));
		this.setOptions(options);
	},

	calcMethod: function(caller, children, width, height) {
		// We don't care aboute height here.

		var totalWidth = 0;
		children.each(function(child) {
				totalWidth = totalWidth + child.getWidth();
			} , this);

		newWidth = totalWidth;
		if (this.options.order == 0) {
			newWidth += newWidth * this.options.percentAdd / 100;
			newWidth += this.options.valAdd;
		} else if (this.options.order == 1) {
			newWidth += newWidth * this.options.percentAdd / 100;
			newWidth += this.options.valAdd;
		} else if (this.options.order == 2) {
			newWidth += this.options.valAdd;
			newWidth += newWidth * this.options.percentAdd / 100;
		} else if (this.options.order == 3) {
			newWidth += this.options.valAdd;
			newWidth += newWidth * this.options.percentAdd / 100;
		} else if (this.options.order == 4) {
			newWidth += newWidth * this.options.percentAdd / 100;
			newWidth += this.options.valAdd;
		} else if (this.options.order == 5) {
			newWidth += this.options.valAdd;
			newWidth += newWidth * this.options.percentAdd / 100;
		}

		if (newWidth < this.options.minWidth) {
			newWidth = this.options.minWidth;
		}

		return [newWidth, -1];
	}
});
WidthChildrenDimCalculator.implement(new Options);

var VerticalFloatingBlockElement = LinkedBlockElement.oniExtend({
	options: {
		onRatioChange: Class.empty
	},

	initialize: function(el, insideLinkedBlockElement) {
		//this.parent(el);
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el);
		this.insideBlock = insideLinkedBlockElement;

		this.getElement().setStyle('overflow', 'hidden');
		this.insideBlock.getElement().setStyle('position', 'relative');

		var insideWidthCalculator = new WidthParentDimCalculator({
				valMinus: 0
			});
		this.insideBlock.calcDimsFromParent = insideWidthCalculator;

		this.insideBlock.setParent(this);

		this.currentPos = 0;
	},

	changeEvent: function(eventName, eventMethod) {
		if (eventName == 'onRatioChange') {
			if ($type(this.options.onRatioChange) == 'function') {
				this.removeEvent('onRatioChange', this.options.onRatioChange);
			}
			this.setOptions({'onRatioChange': eventMethod});
		}
	},

	setDims: function(width, height) {
		this.getCurrentOniClass(arguments.callee).parentProto.setDims.bind(this)(width, height);
		this.checkPosition();
		this.checkRatio();
	},

	checkRatio: function() {
		if ($type(this.lastRatio) != 'number') {
			this.fireEvent('onRatioChange', this.getRatio());
			return;
		}
		var tmpLastRatio = this.lastRatio;
		var newRatio = this.getRatio();
		if (newRatio != tmpLastRatio) {
			this.fireEvent('onRatioChange', newRatio);
		}
	},

	getRatio: function() {
		outsideHeight = this.getHeight();
		insideHeight = this.insideBlock.getHeight();

		if (outsideHeight == 0) {
			return 0;
		}
		this.lastRatio = insideHeight / outsideHeight;
		return this.lastRatio;
	},

	checkPosition: function() {
		var curPos = this.getPosition();
		if (curPos < 0) {
			this.goToPosition(0);
			return;
		}
		var maxPos = this.getMaxPosition();
		if (curPos > maxPos) {
			this.goToPosition(maxPos);
		}
	},



	getPosition: function() {
		if ($type(this.currentPos) == 'number') {
			return this.currentPos;
		}
		return 0;
	},

	getPositionPercent: function() {
		return this.pixelToPercent(this.getPosition());
	},

	goToPositionWithEffect: function(position) {
		if (position < 0) {
			position = 0;
		}
		var maxPosition = this.getMaxPosition();
		if (position > maxPosition) {
			position = maxPosition;
		}
		if (!this.slideEffect) {
			this.slideEffect = new Fx.StyleWithTransitionEvent(this.insideBlock.getElement(), 'top', {duration: 500, transition: Fx.Transitions.Expo.easeOut,
				onTransition: function() {
					this.currentPos = -parseInt(this.insideBlock.getElement().getStyle('top'));
					//this.fireEvent('onChange', this.pixelToPercent(this.currentPos));
				}.bind(this)
			});
		}
		this.slideEffect.stop();
		this.slideEffect.start(-position);
	},

	goToPositionPercentWithEffect: function(positionPercent) {
		this.goToPositionWithEffect(this.percentToPixel(positionPercent));
	},

	goToPosition: function(position) {
		if (position < 0) {
			position = 0;
		}
		var maxPosition = this.getMaxPosition();
		if (position > maxPosition) {
			position = maxPosition;
		}
		this.insideBlock.getElement().setStyle('top', (-position)+"px");
		this.currentPos = position;
	},
	goToPositionPercent: function(positionPercent) {
		this.goToPosition(this.percentToPixel(positionPercent));
	},

	pixelToPercent: function(position) {
		var maxPosition = this.getMaxPosition();
		if (position > maxPosition) {
			return 100;
		}
		if (position < 0) {
			return 0;
		}
		if (maxPosition == 0) {
			return 0;
		}
		return position * 100 / maxPosition;
	},
	percentToPixel: function(positionPercent) {
		var maxPosition = this.getMaxPosition();
		return Math.round(positionPercent * maxPosition / 100);
	},

	getMaxPosition: function() {
		outsideHeight = this.getHeight();
		insideHeight = this.insideBlock.getHeight();

		if (insideHeight <= outsideHeight) {
			return 0;
		}
		return insideHeight - outsideHeight;
	}
});
VerticalFloatingBlockElement.implement(new Options);
VerticalFloatingBlockElement.implement(new Events);

var VerticalAutoMouseFloatingBlockElement = VerticalFloatingBlockElement.oniExtend({

	initialize: function(el, insideLinkedBlockElement) {
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el, insideLinkedBlockElement);

		this.getElement().addEvent('mousemove', this.mouseMove.bindWithEvent(this));
	},

	mouseMove: function(event) {
		var position = event.page['y'] - this.getElement().getTop();
		var positionPercent = parseInt(position * 100 / this.getHeight());
		positionPercent = ((positionPercent - 50) * 1.5) + 50;

		this.goToPositionPercent(positionPercent);
		//alert('test : '+positionPercent);
	}

});

var HorizontalFloatingBlockElement = LinkedBlockElement.oniExtend({
	options: {
		onRatioChange: Class.empty
	},

	initialize: function(el, insideLinkedBlockElement) {
		//this.parent(el);
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el);
		this.insideBlock = insideLinkedBlockElement;

		this.getElement().setStyle('overflow', 'hidden');
		this.insideBlock.getElement().setStyle('position', 'relative');

		/*insideOldParent = this.insideBlock.getParent();
		if (insideOldParent != null) {
			this.setParent(insideOldParent);
		}*/

		var insideHeightCalculator = new HeightParentDimCalculator({
				percentMinus: 0
			});
		this.insideBlock.calcDimsFromParent = insideHeightCalculator;

		this.insideBlock.setParent(this);

		this.currentPos = 0;
	},

	changeEvent: function(eventName, eventMethod) {
		if (eventName == 'onRatioChange') {
			if ($type(this.options.onRatioChange) == 'function') {
				this.removeEvent('onRatioChange', this.options.onRatioChange);
			}
			this.setOptions({'onRatioChange': eventMethod});
		}
	},

	setDims: function(width, height) {
		this.getCurrentOniClass(arguments.callee).parentProto.setDims.bind(this)(width, height);
		this.checkPosition();
		this.checkRatio();
	},

	checkRatio: function() {
		if ($type(this.lastRatio) != 'number') {
			this.fireEvent('onRatioChange', this.getRatio());
			return;
		}
		var tmpLastRatio = this.lastRatio;
		var newRatio = this.getRatio();
		if (newRatio != tmpLastRatio) {
			this.fireEvent('onRatioChange', newRatio);
		}
	},

	getRatio: function() {
		outsideWidth = this.getWidth();
		insideWidth = this.insideBlock.getWidth();

		if (outsideWidth == 0) {
			return 0;
		}
		//alert('outside : '+outsideWidth+"\ninside : "+insideWidth);
		this.lastRatio = insideWidth / outsideWidth;
		return this.lastRatio;
	},

	checkPosition: function() {
		var curPos = this.getPosition();
		if (curPos < 0) {
			this.goToPosition(0);
			return;
		}
		var maxPos = this.getMaxPosition();
		if (curPos > maxPos) {
			this.goToPosition(maxPos);
		}
	},

	getPosition: function() {
		if ($type(this.currentPos) == 'number') {
			return this.currentPos;
		}
		return 0;
	},

	getPositionPercent: function() {
		return this.pixelToPercent(this.getPosition());
	},

	goToPosition: function(position) {
		if (position < 0) {
			position = 0;
		}
		var maxPosition = this.getMaxPosition();
		if (position > maxPosition) {
			position = maxPosition;
		}
		/*alert('windowWidth : '+window.getOnifinWidth());
		alert('outside : '+this.getWidth()+"\ninside : "+this.insideBlock.getWidth());
		alert('go to pos : '+position);*/
		this.insideBlock.getElement().setStyle('left', (-position)+"px");
		this.currentPos = position;
	},
	movePosition: function(pixels) {
		this.goToPosition(this.getPosition() + pixels);
	},
	goToPositionPercent: function(positionPercent) {
		this.goToPosition(this.percentToPixel(positionPercent));
	},

	pixelToPercent: function(position) {
		var maxPosition = this.getMaxPosition();
		if (position > maxPosition) {
			return 100;
		}
		if (position < 0) {
			return 0;
		}
		if (maxPosition == 0) {
			return 0;
		}
		return position * 100 / maxPosition;
	},
	percentToPixel: function(positionPercent) {
		var maxPosition = this.getMaxPosition();
		return Math.round(positionPercent * maxPosition / 100);
	},

	getMaxPosition: function() {
		outsideWidth = this.getWidth();
		insideWidth = this.insideBlock.getWidth();

		if (insideWidth <= outsideWidth) {
			return 0;
		}
		return insideWidth - outsideWidth;
	},

	getElementPositionByName: function(nom) {
		var elemChildren = this.insideBlock.getChildren();
		if (elemChildren == null) {
			return -1;
		}

		var position = -1;
		elemChildren.each(function(child, i) {
			if (child.getName() == nom) {
				var relativePosition = child.getElement().getCoordinates().left - this.insideBlock.getElement().getCoordinates().left;
				//alert('found it in position : '+relativePosition);
				position = relativePosition;
			}
		}.bind(this));

		return position;
	}
});
HorizontalFloatingBlockElement.implement(new Options);
HorizontalFloatingBlockElement.implement(new Events);

var OnifinHorizontalSlider = LinkedBlockElement.oniExtend({
	options: {
		onChange: Class.empty,
		onPositionPercentVariation: Class.empty,
		dimPercent: 10,
		positionBasedOnPercent: false
	},

	initialize: function(el, knob, options){
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el);

		this.setOptions(options);

		knob.setStyles({'left': 0, 'cursor': 'pointer'});

		this.getElement().addEvent('mousedown', this.clickedElement.bindWithEvent(this));

		this.knobBlock = new LinkedBlockElement(knob);
		this.knobChildCalculator = new WidthParentDimCalculator({
				percentMinus: 100 - this.options.dimPercent
			});

		this.knobBlock.calcDimsFromParent = this.knobChildCalculator;

		this.knobBlock.setParent(this);

		this.getElement().setStyle('text-align', 'left');

		var mod = {'x': 'left', 'y': false};
		var lim = {'x': [0, this.getMaxPosition()]};
		this.drag = new Drag.Base(knob, {
			limit: lim,
			modifiers: mod,
			onDrag: this.dragMoved.bind(this)
		});
	},

	changeEvent: function(eventName, eventMethod) {
		if (eventName == 'onChange') {
			if ($type(this.options.onChange) == 'function') {
				this.removeEvent('onChange', this.options.onChange);
			}
			this.setOptions({'onChange': eventMethod});
		} else if (eventName == 'onPositionPercentVariation') {
			if ($type(this.options.onPositionPercentVariation) == 'function') {
				this.removeEvent('onPositionPercentVariation', this.options.onPositionPercentVariation);
			}
			this.setOptions({'onPositionPercentVariation': eventMethod});
		}
	},

	clickedElement: function(event){
		/*alert(event.page['x']);
		alert(this.getElement().getLeft());*/
		var position = event.page['x'] - this.getElement().getLeft();
		if (position >= this.getPosition() && position <= this.getPosition() + this.knobBlock.getWidth()) {
			// We clicked on the bar.
			return;
		}

		// Let's get the position
		var realPos = position - (this.knobBlock.getWidth() / 2);
		//this.goToPosition(realPos);
		this.goToPositionWithEffect(realPos);
		//this.fireEvent('onChange', this.pixelToPercent(realPos));

		/*var position = event.page[this.z] - this.getPos() - this.half - this.options.offset;
		position = position.limit(0, this.max);
		this.step = this.toStep(position);
		this.checkStep();
		this.end();
		this.moveToStep(this.step);*/
		//this.fireEvent('onTick', position);
	},

	movePosition: function(pixels) {
		this.goToPosition(this.getPosition() + pixels);
		this.fireEvent('onChange', this.pixelToPercent(this.getPosition()));
	},

	movePositionWithEffect: function(pixels) {
		this.goToPositionWithEffect(this.getPosition() + pixels);
	},

	dragMoved: function(elem) {
		//alert('left : '+this.knobBlock.getElement().getStyle('left'));
		var pos = parseInt(this.knobBlock.getElement().getStyle('left'));
		//alert('pos : '+pos);
		if ($type(pos) != 'number') {
			return;
		}
		if (pos == this.currentPos) {
			return;
		}
		this.currentPos = pos;
		this.lastPosPercent = this.pixelToPercent(this.currentPos);
		this.fireEvent('onChange', this.pixelToPercent(this.currentPos));
	},

	setDims: function(width, height) {
		var tmpLastPosPercent = this.getPositionPercent();
		this.getCurrentOniClass(arguments.callee).parentProto.setDims.bind(this)(width, height);
		this.checkPosition();
		this.checkDraggable();
		this.checkMarkers();
		if (tmpLastPosPercent != this.getPositionPercent()) {
			this.fireEvent('onPositionPercentVariation', this.getPositionPercent());
		}
	},

	checkPosition: function() {
		var curPos = this.getPosition();
		if (curPos < 0) {
			this.goToPosition(0);
			return;
		}
		var maxPos = this.getMaxPosition();
		if (curPos > maxPos) {
			this.goToPosition(maxPos);
		}
	},

	checkDraggable: function() {
		var lim = {'x': [0, this.getMaxPosition()]};
		this.drag.setOptions({limit: lim});
	},

	getPosition: function() {
		if ($type(this.currentPos) == 'number') {
			return this.currentPos;
		}
		return 0;
	},

	getPositionPercent: function() {
		return this.pixelToPercent(this.getPosition());
	},

	goToPositionWithEffect: function(position) {
		if (position < 0) {
			position = 0;
		}
		var maxPosition = this.getMaxPosition();
		if (position > maxPosition) {
			position = maxPosition;
		}
		if (!this.slideEffect) {
			this.slideEffect = new Fx.StyleWithTransitionEvent(this.knobBlock.getElement(), 'left', {duration: 500, transition: Fx.Transitions.Expo.easeOut, /*onComplete: function() {
					//alert('test : '+this.currentPos+' => '+position);
					this.currentPos = parseInt(this.knobBlock.getElement().getStyle('left'));
					this.fireEvent('onChange', this.pixelToPercent(this.currentPos));
				}.bind(this),*/
				onTransition: function() {
					this.currentPos = parseInt(this.knobBlock.getElement().getStyle('left'));
					this.fireEvent('onChange', this.pixelToPercent(this.currentPos));
				}.bind(this)
			});
		}
		this.slideEffect.stop();
		this.slideEffect.start(position);
	},

	goToPositionPercentWithEffect: function(positionPercent) {
		this.goToPositionWithEffect(this.percentToPixel(positionPercent));
	},

	goToPosition: function(position) {
		if (position < 0) {
			position = 0;
		}
		var maxPosition = this.getMaxPosition();
		if (position > maxPosition) {
			position = maxPosition;
		}
		this.knobBlock.getElement().setStyle('left', position+"px");
		this.currentPos = position;
		this.lastPosPercent = this.pixelToPercent(this.currentPos);
	},

	goToPositionPercent: function(positionPercent) {
		this.goToPosition(this.percentToPixel(positionPercent));
	},

	pixelToPercent: function(position) {
		var maxPosition = this.getMaxPosition();
		if (position > maxPosition) {
			return 100;
		}
		if (position < 0) {
			return 0;
		}
		if (maxPosition == 0) {
			return 0;
		}
		return position * 100 / maxPosition;
	},

	percentToPixel: function(positionPercent) {
		var maxPosition = this.getMaxPosition();
		return Math.round(positionPercent * maxPosition / 100);
	},

	getMaxPosition: function() {
		outsideWidth = this.getWidth();
		insideWidth = this.knobBlock.getWidth();

		if (insideWidth >= outsideWidth) {
			return 0;
		}
		return outsideWidth - insideWidth;
	},

	setPercentWidth: function(percent) {
		var tmpPercent = percent;
		if (tmpPercent > 100) {
			tmpPercent = 100;
		}
		if (tmpPercent == this.options.dimPercent) {
			return;
		}
		if (tmpPercent == 100) {
			this.knobBlock.getElement().setStyle('visibility', 'hidden');
		} else {
			this.knobBlock.getElement().setStyle('visibility', 'visible');
		}
		this.setOptions({'dimPercent': tmpPercent});

		//alert('newPercent : '+this.options.dimPercent);

		/*this.knobChildCalculator = new WidthParentDimCalculator({
				percentMinus: 100 - this.options.dimPercent
			});*/
		this.knobChildCalculator.setOptions({percentMinus: 100 - this.options.dimPercent});

		this.knobBlock.checkParent();

		this.checkDraggable();
	},

	getPercentWidth: function() {
		return this.options.dimPercent;
	},

	checkMarkers: function() {
		if ((!$defined(this.markersList)) || this.markersList == null) {
			return;
		}

		for (markerName in this.markersList) {
			var marker = this.markersList[markerName][0];
			var markerPosPercent = this.markersList[markerName][1];

			var markerPos = marker.getPos();
			//alert(markerName+'\noldMarkerPos : '+markerPos+'\nnewMarkerPos : '+this.percentToPixel(markerPosPercent));
			var newMarkerPos = this.getPosMarkerFormPercent(markerPosPercent, marker);

			if (markerPos != this.percentToPixel(newMarkerPos)) {
				marker.changePos(newMarkerPos);
			}
		}
	},

	createMarker: function(markerName, markerPos) {
		if ((!$defined(this.markersList)) || this.markersList == null) {
			this.markersList = {};
		}

		var realPos = this.percentToPixel(markerPos);

		var newdiv = document.createElement('div');
		newdiv.setStyles({'visibility': 'hidden', 'position': 'absolute', 'top': '0px', 'left': realPos+'px'});
		newdiv.innerHTML = markerName;
		newdiv.className = 'OnifinHorizontalSliderMarker';

		var marker = new OnifinHorizontalSliderMarker(newdiv, realPos);
		this.markersList[markerName] = [marker, markerPos];

		newdiv.addEvent('click', function(e) {
			this.goToPositionWithEffect(marker.getPos());
		}.bind(this));

		newdiv.inject(this.getElement());

		marker.setWidth(marker.getWidth + 20);
		var realPos = this.getPosMarkerFormPercent(markerPos, maker);
		this.markersList[markerName][0].changePos(realPos);

		newdiv.setStyle('visibility', 'visible');
	},

	addMarker: function(el, markerName, markerPos) {
		if ((!$defined(this.markersList)) || this.markersList == null) {
			this.markersList = {};
		}

		var realPos = this.getPosMarkerFormPercent(markerPos, el);
		el.changePos(realPos);
		this.markersList[markerName] = [el, markerPos];
	},

	changeMarkerPos: function(markerName, markerPos) {
		if ($defined(this.markersList[markerName][0]) && this.markersList[markerName][0] != null) {
			this.markersList[markerName][1] = markerPos;
			var realPos = this.getPosMarkerFormPercent(markerPos, this.markersList[markerName][0]);
			this.markersList[markerName][0].changePos(realPos);
		}
	},

	getPosMarkerFormPercent: function(percentPos, marker) {
		var markerWidth = marker.getWidth();
		var posPixels = this.percentToPixel(percentPos);
		var knobWidth = this.knobBlock.getWidth();

		var posAdjustement = Math.floor((knobWidth - markerWidth) / 2);

		var realPos = posPixels + posAdjustement;

		if (realPos + markerWidth > this.getWidth()) {
			realPos = this.getWidth - markerWidth;
		} 

		if (realPos < 0) {
			realPos = 0;
		}

		return realPos;

	}
});
OnifinHorizontalSlider.implement(new Options);
OnifinHorizontalSlider.implement(new Events);

var OnifinHorizontalSliderMarker = BlockElement.oniExtend({

	initialize: function(el, pos) {
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el);
		this.position = pos;

		el.setStyle('left', pos+'px');
	},

	getPos: function() {
		return this.position;
	},

	changePos: function(pos) {
		if (pos == this.position) {
			return;
		}

		this.position = pos;
		this.getElement().setStyle('left', pos+'px');
	}

});

var HorizontalFloatingWithSliderBlockElement = new Class({
	initialize: function(horizFloating, scrollBar) {
		//this.parent(el);
		this.horizBlock = horizFloating;
		this.scrollBarBlock = scrollBar;

		this.previousRatio = this.horizBlock.getRatio();

		this.checkScrollBarFromRatio();

		this.horizBlock.changeEvent('onRatioChange', this.ratioChanged.bind(this));
		this.scrollBarBlock.changeEvent('onChange', this.scrollBarMoved.bind(this));
		this.scrollBarBlock.changeEvent('onPositionPercentVariation', this.scrollBarPercentChange.bind(this));
	},

	movePosition: function(posMove) {
		this.horizBlock.movePosition(posMove);

		var previousHorizPos = this.horizBlock.getPositionPercent();
		var previousScrollPos = this.scrollBarBlock.getPositionPercent();

		if (previousHorizPos != previousScrollPos) {
			this.scrollBarBlock.goToPositionPercent(previousHorizPos);
		}
	},

	movePositionWithEffect: function(posMove) {
		this.goToPositionWithEffect(this.horizBlock.getPosition() + posMove);
	},

	goToPositionPercentWithEffect: function(posPercent) {
		if (posPercent < 0) {
			posPercent = 0;
		}
		if (posPercent > 100) {
			posPercent = 100;
		}

		this.scrollBarBlock.goToPositionPercentWithEffect(posPercent);
	},

	goToInsideElementWithEffect: function(elementName) {
		var pos = this.horizBlock.getElementPositionByName(elementName);
		if (pos < 0) {
			return;
		}

		this.goToPositionWithEffect(pos);
	},

	goToPositionWithEffect: function(pos) {
		var oldPos = this.horizBlock.getPosition();
		var newPos = pos;
		var minPos = 0;
		var maxPos = this.horizBlock.getMaxPosition();

		if (newPos < minPos) {
			newPos = minPos;
		}
		if (newPos > maxPos) {
			newPos = maxPos;
		}

		if (newPos == oldPos) {
			return;
		}

		this.scrollBarBlock.goToPositionPercentWithEffect(this.horizBlock.pixelToPercent(newPos));
	},

	checkScrollBarFromRatio: function() {
		var tmpScrollWidth = 100 / this.previousRatio;
		if (tmpScrollWidth > 100) {
			tmpScrollWidth = 100;
		}

		if (tmpScrollWidth != this.scrollBarBlock.getPercentWidth()) {
			this.scrollBarBlock.setPercentWidth(tmpScrollWidth);
		}
	},

	ratioChanged: function(newRatio) {
		if (newRatio == this.previousRatio) {
			return;
		}
		this.previousRatio = newRatio;
		this.checkScrollBarFromRatio();

		var previousHorizPos = this.horizBlock.getPositionPercent();
		var previousScrollPos = this.scrollBarBlock.getPositionPercent();

		//alert(previousHorizPos+" / "+previousScrollPos);

		if (previousHorizPos != previousScrollPos) {
			this.scrollBarBlock.goToPositionPercent(previousHorizPos);
		}

		this.checkElemMarkers();
	},

	scrollBarPercentChange: function(newPercent) {
		if (newPercent != this.horizBlock.getPositionPercent()) {
			this.scrollBarBlock.goToPositionPercent(this.horizBlock.getPositionPercent());
		}
	},

	scrollBarMoved: function(newPosPercent) {
		this.horizBlock.goToPositionPercent(newPosPercent);
	},

	checkElemMarkers: function() {
		if ((!$defined(this.elemMarkersList)) || this.elemMarkersList == null) {
			return;
		}

		for (elemName in this.elemMarkersList) {
			var elemPos = this.horizBlock.getElementPositionByName(elemName);
			if (elemPos < 0) {
				continue;
			}
			var elemPercentPos = this.horizBlock.pixelToPercent(elemPos);
			var markerName = this.elemMarkersList[elemName][1];
			var markerPercentPos = this.elemMarkersList[elemName][2];

			if (elemPercentPos != markerPercentPos) {
				this.scrollBarBlock.changeMarkerPos(markerName, elemPercentPos);
			}
		}
	},

	createMarkerOnElement: function(markerName, elemName) {
		var pos = this.horizBlock.getElementPositionByName(elemName);
		if (pos < 0) {
			return;
		}

		if ((!$defined(this.elemMarkersList)) || this.elemMarkersList == null) {
			this.elemMarkersList = {};
		}

		var percentPos = this.horizBlock.pixelToPercent(pos);
		var realPos = this.scrollBarBlock.percentToPixel(percentPos);


		var newdiv = document.createElement('div');
		newdiv = new Element(newdiv);
		if (!window.ie) {
			newdiv.setStyles({'visibility': 'hidden', 'position': 'absolute', 'top': '0px', 'left': realPos+'px'});
		}
		newdiv.innerHTML = markerName;
		newdiv.className = 'OnifinHorizontalSliderMarker';

		newdiv.inject(this.scrollBarBlock.getElement());

		if (window.ie) {
			newdiv.setStyles({'position': 'absolute', 'top': '0px', 'left': realPos+'px'});
		}
		newdiv.addEvent('click', function(e) {
			this.goToInsideElementWithEffect(elemName);
		}.bind(this));

		var sliderMarker = new OnifinHorizontalSliderMarker(newdiv, realPos);
		this.elemMarkersList[elemName] = [sliderMarker, markerName, percentPos];

		sliderMarker.setWidth(sliderMarker.getWidth() + 20);

		newdiv.setStyle('visibility', 'visible');

		this.scrollBarBlock.addMarker(sliderMarker, markerName, percentPos);

		//this.scrollBarBlock.createMarker(markerName, percentPos);
	},

	addMarkerOnElement: function(markerElement, elemName) {
		var pos = this.horizBlock.getElementPositionByName(elemName);
		if (pos < 0) {
			return;
		}

		var percentPos = this.horizBlock.pixelToPercent(pos);
		this.scrollBarBlock.addMarker(markerElement, elemName, percentPos);
	}
});


var VerticallyOrganisedBlockElement = LinkedBlockElement.oniExtend({
	options: {
		onConditionChanged: Class.empty,
		pos_taille: null
	},

	initialize: function(el, options) {
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el);
		this.setOptions(options);
	},

	changeEvent: function(eventName, eventMethod) {
		if (eventName == 'onConditionChanged') {
			if ($type(this.options.onConditionChanged) == 'function') {
				this.removeEvent('onConditionChanged', this.options.onConditionChanged);
			}
			this.setOptions({'onConditionChanged': eventMethod});
		}
	},

	getTailleMini: function(pos) {
		if (this.options.pos_taille != null && this.options.pos_taille.length > 0) {
			if (this.options.pos_taille.length > pos && $defined(this.options.pos_taille[pos]) && $defined(this.options.pos_taille[pos]['mini'])) {
				return this.options.pos_taille[pos]['mini'];
			} else if ($defined(this.options.pos_taille[this.options.pos_taille.length - 1]['mini'])) {
				return this.options.pos_taille[this.options.pos_taille.length - 1]['mini'];
			} 
		}
		return this.getHeight();
	},

	getTailleSouhaitee: function(pos) {
		if (this.options.pos_taille != null && this.options.pos_taille.length > 0) {
			if (this.options.pos_taille.length > pos && $defined(this.options.pos_taille[pos]) && $defined(this.options.pos_taille[pos]['souhaitee'])) {
				return this.options.pos_taille[pos]['souhaitee'];
			} else if ($defined(this.options.pos_taille[this.options.pos_taille.length - 1]['souhaitee'])) {
				return this.options.pos_taille[this.options.pos_taille.length - 1]['souhaitee'];
			} 
		}
		return this.getHeight();
	},

	getTailleMaxi: function(pos) {
		if (this.options.pos_taille != null && this.options.pos_taille.length > 0) {
			if (this.options.pos_taille.length > pos && $defined(this.options.pos_taille[pos]) && $defined(this.options.pos_taille[pos]['maxi'])) {
				return this.options.pos_taille[pos]['maxi'];
			} else if ($defined(this.options.pos_taille[this.options.pos_taille.length - 1]['maxi'])) {
				return this.options.pos_taille[this.options.pos_taille.length - 1]['maxi'];
			} 
		}
		return this.getHeight();
	},

	getHorizAlign: function(pos) {
		if (this.options.pos_taille != null && this.options.pos_taille.length > 0) {
			if (this.options.pos_taille.length > pos && $defined(this.options.pos_taille[pos]) && $defined(this.options.pos_taille[pos]['horiz'])) {
				return this.options.pos_taille[pos]['horiz'];
			} else if ($defined(this.options.pos_taille[this.options.pos_taille.length - 1]['horiz'])) {
				return this.options.pos_taille[this.options.pos_taille.length - 1]['horiz'];
			} 
		}
		return null;
	},

	getVerticalAlign: function(pos) {
		if (this.options.pos_taille != null && this.options.pos_taille.length > 0) {
			if (this.options.pos_taille.length > pos && $defined(this.options.pos_taille[pos]) && $defined(this.options.pos_taille[pos]['vertical'])) {
				return this.options.pos_taille[pos]['vertical'];
			} else if ($defined(this.options.pos_taille[this.options.pos_taille.length - 1]['vertical'])) {
				return this.options.pos_taille[this.options.pos_taille.length - 1]['vertical'];
			}
		}
		return null;
	},

	getPos: function() {
		if ($defined(this.currentPos)) {
			return this.currentPos;
		}
		return -1;
	},

	setPosAndDims: function(pos, width, height) {
		this.currentPos = pos;
		this.setDims(width, height);
	}

});
VerticallyOrganisedBlockElement.implement(new Options);
VerticallyOrganisedBlockElement.implement(new Events);

var TShirtVerticallyOrganisedBlockElement = VerticallyOrganisedBlockElement.oniExtend({
	initialize: function(el) {
		//var arraySizes = [{'mini': 317, 'souhaitee': 317, 'maxi': 317}, {'mini': 250, 'souhaitee': 250, 'maxi': 250}];
		/*var arraySizes = [{'mini': 267, 'souhaitee': 267, 'maxi': 267}, {'mini': 267, 'souhaitee': 267, 'maxi': 267}];*/
		var arraySizes = [{'mini': 267, 'souhaitee': 267, 'maxi': 267, 'horiz': 'center', 'vertical': 'bottom'}];
		//var arraySizes = [{'mini': 200, 'souhaitee': 200, 'maxi': 200}];
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el, {'pos_taille': arraySizes});
	},

	setPosAndDims: function(pos, width, height) {
		if (pos > 0) {
			if (this.getElement().className) {
				this.getElement().className = this.getElement().className+' tshirt_under';
			} else {
				this.getElement().className = 'tshirt_under';
			}
		} else {
			// if there is a class
			if (this.getElement().className) {
				// the classes are just a space separated list, so first get the list
				var arrList = this.getElement().className.split(' ');

				// find all instances and remove them
				for ( var i = 0; i < arrList.length; i++ ) {
					// if class found
					if ( arrList[i].toUpperCase() == 'TSHIRT_UNDER' ) {
						// remove array item
						arrList.splice(i, 1);

						// decrement loop counter as we have adjusted the array's contents
						i--;
					}

				}

				// assign modified class name attribute
				this.getElement().className = arrList.join(' ');
			}
		}
		this.getCurrentOniClass(arguments.callee).parentProto.setPosAndDims.bind(this)(pos, width, height);
	}

});
TShirtVerticallyOrganisedBlockElement.implement(new Options);
TShirtVerticallyOrganisedBlockElement.implement(new Events);



var VerticallyOrganisedContainerBlockElement = LinkedBlockElement.oniExtend({
	options: {
		default_vertical_position: 'top',
		default_horiz_position: 'left',
		default_horiz_space: 0
	},

	initialize: function(el, options) {
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el);
		this.setOptions(options);
	},

	check: function(height) {
		var tmpChildren = this.getChildren();

		if (tmpChildren == null) {
			return;
		}

		var groups = new Array();
		var currentGroup = null;

		for (i = 0; i < tmpChildren.length;) {
			var tmpChild = tmpChildren[i];
			var taille_restant = height;
			var elemPos = 0;
			if (currentGroup != null) {
				for (j = 0; j < currentGroup.length; j++) {
					var tmpElem = currentGroup[j];
					taille_restant -= tmpElem['taille'];
					elemPos++;
				}
			}
			if ($defined(tmpChild.getTailleSouhaitee)) {
				var childTailleSouhaitee = tmpChild.getTailleSouhaitee(elemPos);
				if (childTailleSouhaitee > taille_restant) {
					if (currentGroup == null) {
						var childTailleMini = tmpChild.getTailleMini();
						var realTaille = 0;
						if (childTailleMini > height) {
							realTaille = childTailleMini;
						} else {
							realTaille = height;
						}
						currentGroup = [];
						currentGroup[0] = [];
						currentGroup[0]['elem'] = tmpChild;
						currentGroup[0]['taille'] = realTaille;
					
						groups.push(currentGroup);
						currentGroup = null;
						i++;
						continue;
					} else {
						groups.push(currentGroup);
						currentGroup = null;
						continue;
					}
				} else {
					var tmpElem = new Array();
					tmpElem['elem'] = tmpChild;
					tmpElem['taille'] = childTailleSouhaitee;
					if (currentGroup == null) {
						currentGroup = [];
					}
					currentGroup.push(tmpElem);
					i++;
					continue;
				}
			}
		}

		if (currentGroup != null) {
			groups.push(currentGroup);
		}

		for (i = 0; i < groups.length; i++) {
			var tmpElem = groups[i];
			var strAlert = '';
			for (j = 0; j < tmpElem.length; j++) {
				strAlert = strAlert+j+'. '+tmpElem[j]['taille']+'\n';
			}
			//alert('group '+i+'\n'+strAlert);
		}

		//Lets get the positions
		var currentLeft = 0;
		for (i = 0; i < groups.length; i++) {
			var tmpElem = groups[i];
			var currentTop = 0;
			var maxWidth = 0;
			for (j = 0; j < tmpElem.length; j++) {
				tmpElem[j]['elem'].getElement().setStyles({'overflow': 'hidden', 'position': 'absolute', 'top': currentTop, 'left': currentLeft});
				tmpElem[j]['top'] = currentTop;
				tmpElem[j]['left'] = currentLeft;

				currentTop += tmpElem[j]['taille'];

				var elemWidth = tmpElem[j]['elem'].getWidth();
				if (elemWidth > maxWidth) {
					maxWidth = elemWidth;
				}
			}

			// Let's get the horizontal position :
			for (j = 0; j < tmpElem.length; j++) {
				var horiz_pos = this.options.default_horiz_position;
				if (tmpElem[j]['elem'].getHorizAlign(j) != null) {
					horiz_pos = tmpElem[j]['elem'].getHorizAlign(j);
				}
				if (horiz_pos == 'left') {
					continue;
				} else if (horiz_pos == 'center') {
					var elemWidth = tmpElem[j]['elem'].getWidth();
					if (maxWidth == elemWidth) {
						continue;
					}
					tmpElem[j]['left'] = currentLeft + Math.floor((maxWidth - elemWidth) / 2);
				} else if (horiz_pos == 'right') {
					var elemWidth = tmpElem[j]['elem'].getWidth();
					if (maxWidth == elemWidth) {
						continue;
					}
					tmpElem[j]['left'] = currentLeft + (maxWidth - elemWidth);
				}
			}

			// Let's check the vertical align
			for (j = 0; j < tmpElem.length; j++) {
				var vertical_pos = this.options.default_vertical_position;
				if (tmpElem[j]['elem'].getVerticalAlign(j) != null) {
					vertical_pos = tmpElem[j]['elem'].getVerticalAlign(j);
				}
				if (vertical_pos == 'top') {
					// Do nothing
					continue;
				} else if (vertical_pos == 'center') {
					var topMargin = Math.floor((height - currentTop) / 2);
					if (topMargin > 0) {
						tmpElem[j]['top'] += topMargin;
					}
					continue;
				} else if (vertical_pos == 'bottom') {
					var topMargin = (height - currentTop);
					if (topMargin > 0) {
						tmpElem[j]['top'] += topMargin;
					}
				}
			}


			currentLeft += maxWidth;
			if (this.options.default_horiz_space > 0) {
				currentLeft += this.options.default_horiz_space;
			}
		}

		this.setAllMyChildrenToCallMe(false);
		//currentLeft = 0;
		for (i = 0; i < groups.length; i++) {
			var tmpElem = groups[i];
			var currentTop = 0;
			var maxWidth = 0;
			for (j = 0; j < tmpElem.length; j++) {
				//tmpElem[j]['elem'].getElement().setStyles({'overflow': 'hidden', 'position': 'absolute', 'top': currentTop, 'left': currentLeft});
				tmpElem[j]['elem'].getElement().setStyles({'overflow': 'hidden', 'position': 'absolute', 'top': tmpElem[j]['top'], 'left': tmpElem[j]['left']});
				tmpElem[j]['elem'].setPosAndDims(j, -1, tmpElem[j]['taille']);

				/*currentTop += tmpElem[j]['taille'];

				var elemWidth = tmpElem[j]['elem'].getWidth();
				if (elemWidth > maxWidth) {
					maxWidth = elemWidth;
				}*/
			}
			//currentLeft += maxWidth;
		}
		this.setDims(currentLeft, -1);
		this.checkChildren();
		this.setAllMyChildrenToCallMe(true);
	},

	setDims: function(width, height) {
		//alert(width+"x"+height);
		if (width != -1) {
			this.getCurrentOniClass(arguments.callee).parentProto.setDims.bind(this)(width, height);
		} else if (height != -1) { // Should always be true
			if (height == this.getHeight()) {
				return;
			}
			//alert('height: '+height+' / thisHeight: '+this.getHeight());
			this.getCurrentOniClass(arguments.callee).parentProto.setDims.bind(this)(-1, height);
			this.check(height);
		}
	}
});

VerticallyOrganisedContainerBlockElement.implement(new Options);






/********************************** EVENT TRANSPARENCY **********************************/
var EventTransparentBlockElement = BlockElement.oniExtend({

	initialize: function(el) {
		this.getCurrentOniClass(arguments.callee).parentProto.initialize.bind(this)(el);

		el.addEventListener('mousedown', this.propagate.bind(this), false);
	},

	propagate: function(e) {
		event = new Event(e);

		var pagePosX = -1;
		var pagePosY = -1;

		if ($defined(event.screenX)) {
			pagePosX = event.screenX;
			pagePosY = event.screenY;
		} else if ($defined(event.page)) {
			pagePosX = event.page['x'];
			pagePosY = event.page['y'];
		} else {
			return;
		}
		
		var parentNode = this.getElement().getParent();
		if (parentNode == null) {
			return;
		}

		var brothersIncludingMe = parentNode.getChildren();
		if (brothersIncludingMe == null) {
			return;
		}

		brothersIncludingMe.each(function(brother) {
				// Is that me ?
				if (brother == this.getElement()) {
					return;
				}

				var broEl = new Element(brother);
				var brotherCoords = broEl.getCoordinates();
				if (brotherCoords.left > pagePosX
						|| brotherCoords.left + brotherCoords.width < pagePosX
						|| brotherCoords.top > pagePosY
						|| brotherCoords.top + brotherCoords.height < pagePosY) {
					//this brother isn't concerned by the event
					return;
				}

				/*for(key in brother) {
					alert(key+" : "+brother[key]);
				}*/
				if ($defined(brother.$events) && brother.$events != null && $defined(brother.$events[event.type])) {
					brother.fireEvent(event.type, event);
				}
			}.bind(this));
	}
});

