YUI.add('aui-form-field-deprecated', function (A, NAME) {

var Lang = A.Lang,

    getClassName = A.getClassName,

    NAME = 'field',

    SPACE = ' ',

    getTypeClassName = A.cached(
        function(type, prefix) {
            var base = ['field'];

            if (prefix) {
                base.push(prefix);
            }

            base = base.join('-');

            var className = [getClassName(base, type)];

            if (type == 'password') {
                className.push(getClassName(base, 'text'));
            }

            return className.join(' ');
        }
    ),

    CSS_FIELD = getClassName(NAME),

    CSS_FIELD_CHECKBOX = getClassName(NAME, 'checkbox'),
    CSS_FIELD_CHOICE = getClassName(NAME, 'choice'),

    CSS_FIELD_CONTENT = getClassName(NAME, 'content'),
    CSS_FIELD_INPUT = getClassName(NAME, 'input'),
    CSS_FIELD_HINT = getClassName(NAME, 'hint'),
    CSS_FIELD_INVALID = getClassName(NAME, 'invalid'),
    CSS_FIELD_LABEL = getClassName(NAME, 'label'),

    CSS_FIELD_RADIO = getClassName(NAME, 'radio'),

    CSS_LABELS = getClassName(NAME, 'labels'),
    CSS_LABELS_INLINE = getClassName(NAME, 'labels', 'inline'),

    CSS_LABEL_ALIGN = {
        left: [CSS_LABELS, 'left'].join('-'),
        right: [CSS_LABELS, 'right'].join('-'),
        top: [CSS_LABELS, 'top'].join('-')
    },

    MAP_CSS_FIELD_TYPES = {
        radio: CSS_FIELD_RADIO,
        checkbox: CSS_FIELD_CHECKBOX
    },

    REGEX_INLINE_LABEL = /left|right/,

    TPL_BOUNDING_BOX = '<span class="' + CSS_FIELD + '"></span>',
    TPL_CONTENT_BOX = '<span class="' + CSS_FIELD_CONTENT + '"></span>',
    TPL_FIELD_HINT = '<span class="' + CSS_FIELD_HINT + '"></span>',
    TPL_INPUT = '<input autocomplete="off" class="{cssClass}" id="{id}" name="{name}" type="{type}" />',
    TPL_LABEL = '<label class="' + CSS_FIELD_LABEL + '"></label>',

    _FIELD_INSTANCES = {};

var Field = A.Component.create({
    NAME: NAME,

    ATTRS: {
        readOnly: {
            value: false
        },

        name: {
            value: '',
            getter: function(value) {
                var instance = this;

                return value || instance.get('id');
            }
        },

        disabled: {
            value: false,
            validator: Lang.isBoolean
        },

        id: {
            getter: function(value) {
                return value || A.guid();
            }
        },

        type: {
            value: 'text',
            validator: Lang.isString,
            writeOnce: true
        },

        labelAlign: {
            valueFn: function() {
                var instance = this;

                return instance._getChoiceCss() ? 'left' : null;
            }
        },

        labelNode: {
            valueFn: function() {
                var instance = this;

                return A.Node.create(TPL_LABEL);
            }
        },

        labelText: {
            valueFn: function() {
                var instance = this;

                return instance.get('labelNode').get('innerHTML');
            },

            setter: function(value) {
                var instance = this;

                instance.get('labelNode').set('innerHTML', value);

                return value;
            }
        },

        node: {
            value: null,
            setter: function(value) {
                var instance = this;

                return A.one(value) || instance._createFieldNode();
            }
        },

        fieldHint: {
            value: ''
        },

        fieldHintNode: {
            value: null,
            setter: function(value) {
                var instance = this;

                return A.one(value) || instance._createFieldHint();
            }
        },

        prevVal: {
            value: ''
        },

        valid: {
            value: true,
            getter: function(value) {
                var instance = this;

                var validator = instance.get('validator');

                var valid = instance.get('disabled') || validator(instance.get('value'));

                return valid;
            }
        },

        dirty: {
            value: false,
            getter: function(value) {
                var instance = this;

                if (instance.get('disabled')) {
                    value = false;
                }
                else {
                    var currentVal = String(instance.get('value'));
                    var prevVal = String(instance.get('prevVal'));

                    value = (currentVal !== prevVal);
                }

                return value;
            }
        },

        size: {},

        validator: {
            valueFn: function() {
                var instance = this;

                return instance.fieldValidator;
            },
            validator: Lang.isFunction
        },

        value: {
            getter: '_getNodeValue',
            setter: '_setNodeValue',
            validator: 'fieldValidator'
        }
    },

    HTML_PARSER: {
        labelNode: 'label',
        node: 'input, textarea, select'
    },

    BIND_UI_ATTRS: [
   'disabled',
   'id',
   'readOnly',
   'name',
   'size',
   'tabIndex',
   'type',
   'value'
  ],

    getTypeClassName: getTypeClassName,

    getField: function(field) {
        var fieldWidget = null;

        if (field instanceof A.Field) {
            fieldWidget = field;
        }
        else if (field && (Lang.isString(field) || field instanceof A.Node || field.nodeName)) {
            var fieldId = A.one(field).get('id');

            fieldWidget = _FIELD_INSTANCES[fieldId];

            if (!fieldWidget) {
                var boundingBox = field.ancestor('.field');
                var contentBox = field.ancestor('.field-content');

                fieldWidget = new Field({
                    boundingBox: boundingBox,
                    contentBox: contentBox,
                    node: field
                });
            }
        }
        else if (Lang.isObject(field)) {
            fieldWidget = new Field(field);
        }

        return fieldWidget;
    },

    prototype: {
        BOUNDING_TEMPLATE: TPL_BOUNDING_BOX,
        CONTENT_TEMPLATE: TPL_CONTENT_BOX,
        FIELD_TEMPLATE: TPL_INPUT,
        FIELD_TYPE: 'text',

        initializer: function() {
            var instance = this;

            var id = instance.get('node').guid();

            _FIELD_INSTANCES[id] = instance;
        },

        renderUI: function() {
            var instance = this;

            instance._renderField();
            instance._renderLabel();
            instance._renderFieldHint();
        },

        bindUI: function() {
            var instance = this;

            instance.after('labelAlignChange', instance._afterLabelAlignChange);
            instance.after('fieldHintChange', instance._afterFieldHintChange);
        },

        syncUI: function() {
            var instance = this;

            instance.set('prevVal', instance.get('value'));
        },

        fieldValidator: function(value) {
            var instance = this;

            return true;
        },

        isValid: function() {
            var instance = this;

            return instance.get('valid');
        },

        isDirty: function() {
            var instance = this;

            return instance.get('dirty');
        },

        resetValue: function() {
            var instance = this;

            instance.set('value', instance.get('prevVal'));

            instance.clearInvalid();
        },

        markInvalid: function(message) {
            var instance = this;

            instance.set('fieldHint', message);
            instance.get('fieldHintNode').show();

            instance.get('boundingBox').addClass(CSS_FIELD_INVALID);
        },

        clearInvalid: function() {
            var instance = this;

            instance.reset('fieldHint');

            if (!instance.get('fieldHint')) {
                instance.get('fieldHintNode').hide();
            }

            instance.get('boundingBox').removeClass(CSS_FIELD_INVALID);
        },

        validate: function() {
            var instance = this;

            var valid = instance.get('valid');

            if (valid) {
                instance.clearInvalid();
            }

            return valid;
        },

        _afterFieldHintChange: function(event) {
            var instance = this;

            instance._uiSetFieldHint(event.newVal, event.prevVal);
        },

        _afterLabelAlignChange: function(event) {
            var instance = this;

            instance._uiSetLabelAlign(event.newVal, event.prevVal);
        },

        _createFieldHint: function() {
            var instance = this;

            var fieldHint = A.Node.create(TPL_FIELD_HINT);

            instance.get('contentBox').append(fieldHint);

            return fieldHint;
        },

        _createFieldNode: function() {
            var instance = this;

            var fieldTemplate = instance.FIELD_TEMPLATE;

            instance.FIELD_TEMPLATE = Lang.sub(
                fieldTemplate, {
                    cssClass: CSS_FIELD_INPUT,
                    id: instance.get('id'),
                    name: instance.get('name'),
                    type: instance.get('type')
                }
            );

            return A.Node.create(instance.FIELD_TEMPLATE);
        },

        _getChoiceCss: function() {
            var instance = this;

            var type = instance.get('type');

            return MAP_CSS_FIELD_TYPES[type];
        },

        _getNodeValue: function() {
            var instance = this;

            return instance.get('node').val();
        },

        _renderField: function() {
            var instance = this;

            var node = instance.get('node');

            node.val(instance.get('value'));

            var boundingBox = instance.get('boundingBox');
            var contentBox = instance.get('contentBox');

            var type = instance.get('type');

            var cssClass = [getTypeClassName(type)];

            var choiceCss = instance._getChoiceCss();

            if (choiceCss) {
                cssClass.push(CSS_FIELD_CHOICE);
                cssClass.push(choiceCss);
            }

            boundingBox.addClass(cssClass.join(SPACE));
            node.addClass(getTypeClassName(type, 'input'));

            if (!contentBox.contains(node)) {
                if (node.inDoc()) {
                    node.placeBefore(boundingBox);

                    contentBox.appendChild(node);
                }
                else {
                    contentBox.appendChild(node);
                }
            }

            boundingBox.removeAttribute('tabIndex');
        },

        _renderFieldHint: function() {
            var instance = this;

            var fieldHint = instance.get('fieldHint');

            if (fieldHint) {
                instance._uiSetFieldHint(fieldHint);
            }
        },

        _renderLabel: function() {
            var instance = this;

            var labelText = instance.get('labelText');

            if (labelText !== false) {
                var node = instance.get('node');
                var id = node.guid();

                labelText = instance.get('labelText');

                var labelNode = instance.get('labelNode');

                labelNode.addClass(getClassName(instance.name, 'label'));
                labelNode.setAttribute('for', id);
                labelNode.set('innerHTML', labelText);

                instance._uiSetLabelAlign(instance.get('labelAlign'));

                var contentBox = instance.get('contentBox');
                var labelAlign = instance.get('labelAlign');
                var type = instance.get('type').toLowerCase();

                var isLabelInline = REGEX_INLINE_LABEL.test(labelAlign);

                var action = 'prepend';

                if (isLabelInline && instance._getChoiceCss()) {
                    action = 'append';
                }

                contentBox[action](labelNode);
            }
        },

        _setNodeValue: function(value) {
            var instance = this;

            instance._uiSetValue(value);

            return value;
        },

        _uiSetDisabled: function(val) {
            var instance = this;
            var node = instance.get('node');

            if (val) {
                node.setAttribute('disabled', val);
            }
            else {
                node.removeAttribute('disabled');
            }
        },

        _uiSetFieldHint: function(newVal, prevVal) {
            var instance = this;

            instance.get('fieldHintNode').set('innerHTML', newVal);
        },

        _uiSetId: function(newVal, src) {
            var instance = this;

            instance.get('node').set('id', newVal);
        },

        _uiSetLabelAlign: function(newVal, prevVal) {
            var instance = this;

            var boundingBox = instance.get('boundingBox');

            boundingBox.replaceClass(CSS_LABEL_ALIGN[prevVal], CSS_LABEL_ALIGN[newVal]);

            var action = 'removeClass';

            if (REGEX_INLINE_LABEL.test(newVal)) {
                action = 'addClass';
            }

            boundingBox[action](CSS_LABELS_INLINE);
        },

        _uiSetName: function(newVal, src) {
            var instance = this;

            instance.get('node').setAttribute('name', newVal);
        },

        _uiSetReadOnly: function(newVal, src) {
            var instance = this;

            instance.get('node').setAttribute('readOnly', newVal);
        },

        _uiSetSize: function(newVal, src) {
            var instance = this;

            instance.get('node').setAttribute('size', newVal);
        },

        _uiSetTabIndex: function(newVal, src) {
            var instance = this;

            instance.get('node').setAttribute('tabIndex', newVal);
        },

        _uiSetValue: function(newVal, src) {
            var instance = this;

            instance.get('node').val(newVal);
        },

        _requireAddAttr: false
    }
});

A.Field = Field;

}, '3.1.0-deprecated.112', {"requires": ["aui-base-deprecated", "aui-component"]});
