/**
 * Entitas Generated Components and Extensions for {{ namespace }}
 *
 * do not edit this file
 */
namespace Entitas {

    const int POOL_SIZE = {{ alloc.components }};

    /**
    * Component extensions
    */
    const string[] components = {
{% for component in components %}        "{{ component.key }}Component",
{% endfor %}        ""
    };

    public enum Component {
{% for component in components %}        {{ component.key }},
{% endfor %}        TotalComponents
    }

{% for component in components %}
    public class {{ component.key }}Component : Object, IComponent {
{% if component.value == false %}        public bool active = true;
{% else %}{% for field in component.value %}        public {{ field | fieldType }} {{ field | property }};  
{% endfor %}{% endif %}
    }{% endfor %}

    /**
    * Entity extensions
    */
    public class Entity : EntityBase {

        public Entity(string[] componentsEnum, int totalComponents = 32) {
            base(componentsEnum, totalComponents);
            /* Preallocate component pools*/
{% for component in components %}{% if component.value == false %} 
            _{{ component.key | camel }}Component = new {{ component.key }}Component();
{% else %}            _{{ component.key | camel }}ComponentPool = new GLib.Queue<{{ component.key }}Component>();
            for (var i=0; i < POOL_SIZE; i++) {
                _{{ component.key | camel }}ComponentPool.push_head(new {{ component.key }}Component());
            }
{% endif %}{% endfor %}
        }
{% for component in components %}
        /** Entity: {{ component.key }} methods*/
{% if component.value == false %}

        /** @type boolean */
        public bool is{{ component.key }} {
            get {
                return hasComponent(Component.{{ component.key }});
            }
            set {
                if (value)
                    addComponent(Component.{{ component.key }}, _{{ component.key | camel }}Component);
                else
                    removeComponent(Component.{{ component.key }});
            }
        }
        /**
         * @param value boolean 
         * @returns entitas.Entity
         */
        public Entity set{{ component.key }}(bool value) {
            is{{ component.key }} = value;
            return this;
        }
{% else %}
        /** @type {{ component.key }} */
        public {{ component.key }}Component {{ component.key | camel }} {
            get {
                return ({{ component.key }}Component)getComponent(Component.{{ component.key }});
            }
        }
        /** @type boolean */
        public bool has{{ component.key }} {
            get {
                return hasComponent(Component.{{ component.key }});
            }
        }
        public void clear{{ component.key }}ComponentPool() {
            _{{ component.key | camel }}ComponentPool.clear();
        }
        /**{% for field in component.value %}
         * @param {{ field | property }} {{ field | fieldType }}{% endfor %}
         * @returns entitas.Entity
         */
        public Entity add{{ component.key }}({{ component.value | cparams }}) {
            var c = _{{ component.key | camel }}ComponentPool.length > 0 ? _{{ component.key | camel }}ComponentPool.pop_head() : new {{ component.key }}Component();
            {% for field in component.value %}c.{{ field | property }} = {{ field | property | camel }};
            {% endfor %}addComponent(Component.{{ component.key }}, c);
            return this;
        }
        /**{% for field in component.value %}
         * @param {{ field | property }} {{ field | fieldType }}{% endfor %}
         * @returns entitas.Entity
         */
        public Entity replace{{ component.key }}({{ component.value | cparams }}) {
            var previousComponent = has{{ component.key }} ? this.{{ component.key | camel }} : null;
            var c = _{{ component.key | camel }}ComponentPool.length > 0 ? _{{ component.key | camel }}ComponentPool.pop_head() : new {{ component.key }}Component();
            {% for field in component.value %}c.{{ field | property }} = {{ field | property | camel }};
            {% endfor %}replaceComponent(Component.{{ component.key }}, c) ;
            if (previousComponent != null)
                _{{ component.key | camel }}ComponentPool.push_head(previousComponent);
            return this;
        }
        /**
         * @returns entitas.Entity
         */
        public Entity remove{{ component.key }}() {
            var c = {{ component.key | camel }};
            removeComponent(Component.{{ component.key }});
            _{{ component.key | camel }}ComponentPool.push_head(c);
            return this;
        }
{% endif %}{% endfor %}
{% for component in components %}{% if component.value == false %}
        /** @type {{ component.key }} */
        {{ component.key }}Component _{{ component.key | camel }}Component;
{% else %}        /** @type entitas.utils.GLib.Queue<{{ component.key }}> */
        GLib.Queue<{{ component.key }}Component> _{{ component.key | camel }}ComponentPool;
{% endif %}{% endfor %}
    }    
}