/**
 * バリデーションエラーのレスポンスのコレクションをラップし、特定のフィールドに対するアクセスやエラー用に便利な関数を提供します。
 *
 * 通常、このクラスを直接インスタンス化する必要はありません。そのかわり、 モデルのインスタンスで{@link Ext.data.Model#validate バリデーション}を行うと、インスタンスが自動的に作成されます。
 *
 *      // Validate some existing model instance - in this case it returned 2 failures
 *      // messages
 *      
 *      var errors = myModel.validate();
 *      errors.isValid(); //false
 *      
 *      errors.length; //2
 *      errors.getByField('name');  // [{field: 'name',  message: 'must be present'}]
 *      errors.getByField('title'); // [{field: 'title', message: 'is too short'}]
 *
 * @deprecated 5.0では代わりに、`Ext.data.Validation`を使用します。
 */
Ext.define('Ext.data.ErrorCollection', {
    extend: 'Ext.util.MixedCollection', // not Ext.util.Collection due to API differences

    alternateClassName: 'Ext.data.Errors',

    requires: [
        'Ext.data.Error'
    ],

    init: function (record) {
        var me = this,
            fields = record.fields,
            data = record.data,
            before, field, item, i, len, msg, val, name;

        for (i = 0, len = fields.length; i < len; ++i) {
            field = fields[i];
            name = field.name;
            val = data[name];

            if (field.validate && !field.validate.$nullFn) {
                before = me.length;
                msg = field.validate(val, null, me);
                if (before === me.length && msg !== true) {
                    me.add(name, msg);
                }
            }
        }

        return me;
    },

    add: function (key, value) {
        var me = this,
            defaultMessage = Ext.data.field.Field.defaultInvalidMessage,
            obj = key, // for single argument form
            current;

        if (Ext.isString(key)) {
            obj = new Ext.data.Error({
                field: key,
                message: value || defaultMessage
            });
        } else {
            if (!(obj.isError)) {
                obj = new Ext.data.Error({
                    field: obj.field || obj.name,
                    message: obj.error || obj.message || obj.msg || defaultMessage
                });
            }

            key = obj.field;
        }

        current = me.get(key);
        if (current) {
            if (Ext.isArray(current)) {
                current.push(obj);
                return current;
            }

            me.removeAtKey(key);
            obj = [ current, obj ];
            obj.field = key;

            // Because the value we want in the collection is an array, we need to wrap it
            // another layer of array or the base add method will add each element.
            obj = [ obj ];
        }

        return me.callParent([ obj ]);
    },

    getKey: function (item) {
        return item.field;
    },

    /**
     * コレクション中にエラーがなければtrueを返します。
     * @return {Boolean}

     */
    isValid: function() {
        return this.length === 0;
    },

    /**
     * 指定されたフィールドの全てのエラーを返します。
     * @param {String} fieldName エラーを取得するフィールドです。
     * @return {Object[]} 指定されたフィールドの全てのエラーです。
     */
    getByField: function(fieldName) {
        var values = this.get(fieldName);

        if (values && !Ext.isArray(values)) {
            values = [values];
        }

        return values || [];
    }
});