/// class PD.Web.UI.Controls.ControlCollection

PD.Web.UI.Controls.ControlCollection = Class.extend({

    //===================================
    // FIELDS
    //===================================

    _parent: null,
    _list: null,
    _firedEvents: null,
    
    //===================================
    // CONSTRUCTOR
    //===================================

    init: function (parent) {
        this._parent = parent;
        this._list = new PD.BCL.List();
        this._firedEvents = new PD.BCL.List();
    },

    //===================================
    // PROPERTIES
    //===================================

    get_parent: function () {
        return this._parent;
    },

    //===================================
    // PUBLIC METHODS
    //===================================

    add: function (item) {
        if (!this._list.contains(item)) {
            this._list.add(item);
            this._syncToLifecycleEvent(item);
        }
    },

    insert: function (item, index) {
        if (!this._list.contains(item)) {
            this._list.insert(item, index);
            this._syncToLifecycleEvent(item);
        }
    },

    remove: function (item) {
        this._list.remove(item);
        item.remove();
    },

    each: function (fn) {
        this._list.each(fn);
    },

    fire: function (eventName) {

        var that = this;

        this.each(function (index, control) {
            that._fireControlEvent(control, eventName);
        });

        this._updateFiredEvents(eventName);

    },

    clear: function () {

        this.each(function (index, item) {
            item.remove();
        });

        this._list.clear();

    },

    indexOf: function (control) {
        return this._list.indexOf(control);
    },

    count: function () {
        return this._list.count();
    },

    getAtIndex: function (index) {
        return this._list.getAtIndex(index);
    },

    //===================================
    // PRIVATE METHODS
    //===================================

    _getEventArgs: function (control) {

        // TODO: Look to replace this code. Not enamoured with this means to get the event arguments. 
        // Making a call into a class to get an object I am passing right back to itself has a smell.

        var result = null,
            response = control.onRequestEventArgs({
                parent: this.get_parent()
            });

        if (response != null) {
            result = response;
        }
        else {
            result = new PD.Web.UI.ControlEventArgs({
                parent: this.get_parent()
            });
        }

        return result;

    },

    _updateFiredEvents: function (eventName) {
        if (!this._firedEvents.contains(eventName)) {
            this._firedEvents.add(eventName);
        }
    },

    _fireControlEvent: function (control, eventName) {
        if (control[eventName]) {
            control[eventName](this._getEventArgs(control));
        }
    },

    _syncToLifecycleEvent: function (control) {

        var that = this;

        this._firedEvents.each(function (index, eventName) {
            that._fireControlEvent(control, eventName);
        });

    }

});