function Container()
{
	this.widgets = [];
	
	this.onWidgetAdded		= new EventDelegate();
	this.onWidgetRemoved	= new EventDelegate();
	
	extend(this, Widget);
}

Container.prototype = new Widget;

// public void clear();
Container.prototype.clear = function Container_clear()
{
	this.setUpdateSuspended(true);
    while(this.widgets.length > 0)
    {
        this.remove(this.widgets[this.widgets.length - 1]);
    }
    
    this.setUpdateSuspended(false);
};

// public void add(Widget widget);
Container.prototype.add = function Container_add(widget, constraints)
{
	if(widget == null)
	{
		throw new Error("Container.add() - Parameter 'widget' cannot be null");
	} else if(!widget.domContainer)
	{
		throw new Error("Container.add() - Invalid widget, no DOM container found");
	} else
	{
		if(widget.parent)
		{
			widget.parent.remove(widget);
		}
		
		widget.container = this;
		
		this.widgets.push(widget);
		this.domContainer.appendChild(widget.domContainer);
		
		widget.layoutConstraints = constraints;
				
		this.onWidgetAdded.fireEvent(this, widget);
		
		this.invokeUpdate();
	}
};

// public void remove(Widget widget);
Container.prototype.remove = function Container_remove(widget)
{
	var index = this.getIndexOf(widget);
	
	if(index != -1)
	{
		this.widgets.splice(index, 1);
		this.domContainer.removeChild(widget.domContainer);
		
		this.onWidgetRemoved.fireEvent(this, widget);
	}
};

// public Widget getWidget(int index) throws IndexOutOfBoundsException;
Container.prototype.getWidget = function Container_getWidget(index)
{
	if(index < 0 || index >= this.widgets.length)
	{
		throw new Error("Container.getWidget(index = " + index + ") - Index out of bounds (0 <= index < " + this.widgets.length + ")");
	} else
	{
		return this.widgets[index];
	}
};

// public int getWidgetAt(int x, int y);
Container.prototype.getWidgetAt = function Container_getWidgetAt(x, y)
{
	for(var widget in this.widgets)
	{
		var bounds = widget.getBounds();
		
		if(x > bounds.x && x < bounds.x + bounds.width && y > bounds.y && y < bounds.y + bounds.height)
		{
			return widget;
		}
	}
	
	return null;
};

// public int getIndexOf(Widget widget);
Container.prototype.getIndexOf = function Container_getIndexOf(widget)
{
	for(var i = 0; i < this.widgets.length; i++)
	{
		if(this.widgets[i] == widget)
		{
			return i;
		}
	}
	
	return -1;
};

// public int getWidgetCount();
Container.prototype.getWidgetCount = function Container_getWidgetCount()
{
    return this.widgets.length;
};

// public void setUpdateSuspended(boolean suspended);
Container.prototype.setUpdateSuspended = function Container_setUpdateSuspended(suspended)
{
	Widget.prototype.setUpdateSuspended.apply(this, [suspended]);
	
	for(var i = 0; i < this.widgets.length; i++)
	{
		this.widgets[i].setUpdateSuspended(suspended);
	}
};

// public void setLayout(Layout layout);
Container.prototype.setLayout = function Container_setLayout(layout)
{
	this.layout = layout;
	
	if(this.layout)
	{
		// this.setPreferredSize(this.layout.getPreferredSize(this));
		this.invokeUpdate();
	}
}

// public Layout getLayout();
Container.prototype.getLayout = function Container_getLayout()
{
	return this.layout;
}

// public override void setPreferredSize({width:int, height:int} size);
Container.prototype.setPreferredSize = function Container_setPreferredSize(size)
{
	this.preferredSizeExplicitlySet = true;
	Widget.prototype.setPreferredSize.apply(this, [size]);
}

// public override {width:int, height:int} getPreferredSize();
Container.prototype.getPreferredSize = function Container_getPreferredSize()
{
	if(this.preferredSizeExplicitlySet || !this.layout)
	{
		return Widget.prototype.getPreferredSize.apply(this, []);
	} else
	{
		return this.layout.getPreferredSize(this);
	}
}

// public void update();
Container.prototype.update = function Container_update()
{
	if(this.layout)
	{
		this.layout.doLayout(this);
	}
}

Container.prototype.toString = function Container_toString()
{
	return Widget.prototype.toString.apply(this, []) + "/Container [widgets = " + this.widgets.length + "]";
}
