/*------------------------------------------------------------------------*/
Array.prototype.remove = function(f) {
	if (!f)
		f = function(i) {return i == undefined || i == null ? true : false;};
	
	var l = this.length;
	var n = 0;
	
	for(var i=0; i<l; i++)
		f(this[i]) ? n++ : this[i-n] = this[i];
		
	this.length = this.length - n;
};
/*------------------------------------------------------------------------*/

var AbstractBox = new Class({
	Implements : [Options, Events],
	options : {
		margin 		: 0,
		container 	: $empty,
		type 		: 'HBox',
		x 			: 0,
		y 			: 0,
		width		: 0,
		height		: 0,
	},
	
	width 	: 0,
	height 	: 0,
	items 	: $empty,
	index 	: 0,
	
	initBox : function(options){
		this.items = new Array();
		this.setOptions(options);
		
		this.width = this.options.width;
		this.height = this.options.height;
	},
	
	add : function(oItem, useFX) {
		if(useFX==null || useFX==undefined)
			useFX = true;
		
		this.items.push(oItem);
		this.position(useFX);
	},
	
	addAtBegin : function(oItem, useFX) {
		if(useFX==null || useFX==undefined)
			useFX = true;
			
		this.items.unshift(oItem);
		this.position(useFX);
	},
	
	addAt : function(oItem, i, useFX) {
		if(useFX==null || useFX==undefined)
			useFX = true;
			
		
		oItem.row = this;
		this.items.splice(i,0,oItem);
		this.position(useFX);
	},
	
	remove : function(oItem, useFX) {
		if(useFX==null || useFX==undefined)
			useFX = true;
			
		this.items.remove(function(o){
			if(o.instance()==oItem) {
				//console.log('item found and removed');
				return true;
			}
			return false;
		});
		this.position(useFX);
	},
	
	removeAt : function(iIndex) {
		var n_items = new Array();
		this.items.each(function(o,i){
			if(i!=iIndex) {
				n_items.push(o.instance());
			} else {
				//console.log('item found and removed');
			}
		});
		this.items = n_items;
		
		this.position();
	},
	
	is : function(sType) {
		return (this.options.type==sType);
	},
	
	position : function(useFX) {
	
		if(useFX==null || useFX==undefined)
			useFX = true;
		
		var x_offset = this.options.x;
		var y_offset = this.options.y;
		
		var t_width = 0;
		var t_height = 0;

		this.items.each(function(item, i) {
			
			if(item.instance().options.type=="HBox" || 
			item.instance().options.type=="VBox") {
			
				item.move(x_offset, y_offset, useFX);
				
			} else {
				var c;
				if(item.relativeTo!=null)
					c = item.relativeTo;
				else
					c = this.options.container;
				
				var init = {
					relativeTo:c, 
					position: {
						x:item.instance().left, 
						y:item.instance().top
					},
					offset: {
						x:x_offset+item.instance().offsetX,
						y:y_offset+item.instance().offsetY
					}	
				};
				
				if(!useFX) {
					item.position(init);
				} else {
					item.instance().move(init);
				}
			}
			
			var size_x = item.instance().getSize().x;
			var size_y = item.instance().getSize().y;
			
			x_offset += (this.is('HBox')) ? size_x + this.options.margin : 0;
			y_offset += (this.is('VBox')) ? size_y + this.options.margin : 0;
			
			t_width = (size_x > t_width) ? size_x : t_width;
			t_height = (size_y > t_height) ? size_y : t_height;

		}.bind(this));
		
		if(this.options.width==0)
			this.width = (this.is('HBox')) ? x_offset : t_width;
		
		if(this.options.height==0)
			this.height = (this.is('VBox')) ? y_offset : t_height;
			
		this.fireEvent('resize', this);
		
	},
	
	getSize : function() {
		return {x:this.width, y:this.height};
	},

	getLength : function() {
		return this.items.length;
	},
	
	instance : function() {
		return this;
	},
	
	get : function(i) {
		return this.items[i];
	},
	
	move : function(x,y,useFX) {
		if(useFX==null || useFX==undefined)
			useFX = true;
		
		this.options.x = x;
		this.options.y = y;
		this.position(useFX);
	},
	
	setRowOfItem : function(iIndex) {
		this.items[iIndex].instance().setRow(this);
	},
});

var HBox = new Class({
	Implements : AbstractBox,
	initialize : function(options) {
		options.type = 'HBox';
		this.initBox(options);
	}
});

var VBox = new Class({
	Implements : AbstractBox,
	initialize : function(options) {
		options.type = 'VBox';
		this.initBox(options);
	}
});
