define(['./field.js'], function (Field) {

    /**
     * Form field controller class
     * @class
     * @constructor
     * @property {Object} collection - Fields.Collection object
     * @property {Object} view - Fields.View object
     */
    var Fields = function () {
        'use strict';
        /**
         * Fields.Collection object
         * @public
         * @type {Object}
         */
        this.collection = new Fields.Collection();

        /**
         * Fields.View object
         * @public
         * @type {Object}
         */
        this.view = new Fields.View();

        this.collection.setView(this.view);
        this.view.setCollection(this.collection);
    };

    /**
     * Form field collection class
     * @class
     * @constructor
     * @property {Object} view - Fields.View object
     * @property {Array} rights - An array of Field objects
     */
    Fields.Collection = function (fields) {
        'use strict';
        this.view = null;

        /**
         * An array of Field objects
         * @private
         * @type {Array}
         */
        this.fields = [];
    };

    Fields.Collection.prototype = (function () {
        'use strict';
        /**
         * Set the view object
         * @private
         * @memberOf Fields.Collection
         * @param {Object} view - Fields.View object
         */
        var setView = function (view) {
            this.view = view;
        };

        /**
         * Get the view object
         * @private
         * @memberOf Field.Model
         * @returns {Object}
         */
        var getView = function () {
            return this.view;
        };

        /**
         * Add Field objects to the collection
         * @private
         * @memberOf Fields.Collection
         * @param {Array} fields - array of Field objects or JSON data
         */
        var setData = function (fields, group_id) {
            var self = this;
            self.group_id = group_id;
            _.each(fields, function (field) {
                if (field instanceof Field) {
                    self.fields.push(field);
                } else {
                    var instance = new Field();
                    instance.model.setData(field);
                    self.fields.push(instance);
                }
            });
        };

        /**
         * Get array of Field objects
         * @private
         * @memberOf Fields.Collection
         * @returns {Array}
         */
        var getFields = function () {
            if (_.isArray(this.fields)) {
                return this.fields;
            } else {
                return [];
            }
        };

        return {
            /**
             * Get the view object
             * @public
             * @memberOf Fields.Collection
             */
            view: getView,

            /**
             * Set the view object
             * @public
             * @memberOf Fields.Collection
             */
            setView: setView,

            /**
             * Initalise object
             * @public
             * @memberOf Fields.Collection
             */
            setData: setData,

            /**
             * Get the field symbolic name
             * @public
             * @memberOf Fields.Collection
             */
            fields: getFields,

            /**
             * Get the Group Id (if known)
             * @public
             * @memberOf Fields.Collection
             */
            group_id: 0
        };
    })();

    /**
     * Fields collection view class
     * @class
     * @constructor
     * @property {Object} collection - Fields.Collection
     * @property {Object} el - DOM element
     */
    Fields.View = function () {
        'use strict';
        /**
         * Fields.Collection
         * @private
         * @type {Object}
         */
        this.collection = null;

        /**
         * DOM element
         * @private
         * @type {Object}
         */
        this.el = null;
    };

    Fields.View.prototype = (function () {
        'use strict';
        /**
         * @private
         * @memberOf Fields.View
         */
        var setCollection = function (collection) {
            this.collection = collection;
        };

        /**
         * Set DOM element
         * @private
         * @memberOf Fields.View
         * @param {Object} el - jQuery DOM element from Group.View
         */
        var setElement = function (el) {
            this.el = el.find('.field-list');
        };

        /**
         * Get DOM element
         * @private
         * @memberOf Fields.View
         * @returns {Object}
         */
        var getElement = function () {
            return this.el;
        };

        /**
         * Render the collection
         * @private
         * @memberOf Fields.View
         */
        var render = function (el) {
            var active_fields_element = $('<div>');
            var inactive_fields_element = $('<div>');
            var self = this;
            var inactive_fields = [];
            var active_fields = [];

            _.each(this.collection.fields, function (field) {
                if (field.model.active === false) {
                    inactive_fields.push(field);
                } else {
                    active_fields.push(field);
                }
            });

            setElement.call(this, el);

            var activeFieldsColumns = format(active_fields);
            var inactiveFieldsColumns = format(inactive_fields);

            if (active_fields.length === 0) {
                active_fields_element.append('<div class="text-muted">There are no fields in this group.</div>');
            } else {
                _.each(activeFieldsColumns, function (fields) {
                    var fieldList = '';
                    _.each(fields, function (field) {
                        fieldList += field.view.render();
                    });

                    active_fields_element.append(_.template($('#fields-column-tmpl').html())({
                        fieldList: fieldList
                    }));
                });
            }

            _.each(inactiveFieldsColumns, function (fields) {
                var fieldList = '';
                _.each(fields, function (field) {
                    fieldList += field.view.render();
                });

                inactive_fields_element.append(_.template($('#fields-column-tmpl').html())({
                    fieldList: fieldList
                }));
            });

            self.el.append(_.template($('#fields-tmpl').html())({
                active_fields: active_fields_element.html(),
                inactive_fields: inactive_fields_element.html(),
                group_id: self.collection.group_id
            }));
            self.el.find()
        };

        /**
         * Create array with four nester arrays for fields list
         * @private
         * @param fields
         * @memberOf Fields.View
         * @returns {Object} Group
         */
        var format = function (fields) {
            var columns = [];
            var i = 0;
            _.each(fields, function (field) {
                var index = i % 4;
                columns[index] = columns[index] || [];
                columns[index].push(field);
                i++;
            });
            return columns;
        };

        return {
            /**
             * @public
             * @memberOf Fields.View
             */
            setCollection: setCollection,

            /**
             * Get DOM element
             * @public
             * @memberOf Fields.View
             * @returns {Object}
             */
            el: getElement,

            /**
             * Render the collection
             * @public
             * @memberOf Fields.View
             */
            render: render
        };
    })();

    return Fields;
});
