define('jls/gui/TemplateContainer', ['jls/lang/Class', 'jls/lang/Exception', 'jls/gui/Element'], function(Class, Exception, Element) {

    var TemplateContainer = Class.create(Element, /** @lends jls.gui.TemplateContainer.prototype */
    {
        /**
         * Creates a template container.
         * 
         * @param {Object} [parameters] The element parameters that is the description of the element to create.
         * @param {jls.gui.Element} [parent] The parent.
         * @constructs
         * @class This class represents a graphical element composed by other elements.
         * @see jls.gui.Element
         */
        initialize : function($super, template, parameters, parent) {
            TemplateContainer.create(this, template, $super, parameters, parent);
        }
    });

    Object.extend(TemplateContainer, { /** @lends jls.gui.TemplateContainer */
        create : function(tc, template, $super, parameters, parent) {
            tc._container = null;
            var p = TemplateContainer.mergeParameters({}, template, parameters);
            TemplateContainer.mergeChildren(p, template);
            $super(p, parent);
            tc.setContainer(tc.getById('container'));
            tc.getContainer().setId(null);
            if (Object.isArray(parameters.children)) {
                tc.addChildren(parameters.children);
            }
        },
        mergeChildren : function(parameters) {
            if (! ('children' in parameters)) {
                parameters.children = [];
            }
            for (var i = 1; i < arguments.length; i++) {
                var p = arguments[i];
                if ('children' in p) {
                    for (var j = 0; j < p.children.length; j++) {
                        parameters.children.push(p.children[j]);
                    }
                }
            }
            return parameters;
        },
        mergeParameters : function(parameters) {
            // attributes style children events broker resource classname
            if (! ('attributes' in parameters)) {
                parameters.attributes = {};
            }
            if (! ('style' in parameters)) {
                parameters.style = {};
            }
            if (! ('events' in parameters)) {
                parameters.events = {};
            }
            for (var i = 1; i < arguments.length; i++) {
                var p = arguments[i];
                if ('attributes' in p) {
                    Object.extend(parameters.attributes, p.attributes);
                }
                if ('style' in p) {
                    Object.extend(parameters.style, p.style);
                }
                if ('events' in p) {
                    Object.extend(parameters.events, p.events);
                }
                if ('broker' in p) {
                    parameters.broker = p.broker;
                }
                if ('resource' in p) {
                    parameters.broker = p.broker;
                }
                if ('classname' in p) {
                    parameters.classname = p.classname;
                }
            }
            return parameters;
        },
        prepareClass : function(elementClass) {
            var ancestor = elementClass.superclass && elementClass.superclass.prototype;
            elementClass.addMethods({ /** @lends jls.gui.TemplateContainer.prototype */
                addChild : function($super, child) {
                    if (this._container != null) {
                        return this._container.addChild(child);
                    }
                    return $super(child);
                },
                addChildren : function($super, children) {
                    if (this._container != null) {
                        this._container.addChildren(children);
                        return this;
                    }
                    return $super(children);
                },
                removeChild : function($super, child) {
                    if (this._container != null) {
                        return this._container.removeChild(child);
                    }
                    return $super(child);
                },
                removeChildren : function($super) {
                    if (this._container != null) {
                        this._container.removeChildren();
                        return this;
                    }
                    return $super();
                },
                getChildren : function($super) {
                    if (this._container != null) {
                        return this._container.getChildren();
                    }
                    return $super();
                },
                getChildCount : function($super) {
                    if (this._container != null) {
                        return this._container.getChildCount();
                    }
                    return $super();
                },
                getChild : function($super, index) {
                    if (this._container != null) {
                        return this._container.getChild(index);
                    }
                    return $super(index);
                },
                getContainer : function() {
                    return this._container == null ? this : this._container;
                },
                setContainer : function(container) {
                    this._container = container === this ? null : container;
                }
            });
            return elementClass;
        }
    });

    return TemplateContainer.prepareClass(TemplateContainer);
});
