import EmptyView from "../../../src/view/elements/EmptyView.js";
import LabelView from "../../../src/view/common/LabelView.js";

function format_field_name(name) {
    return name
        .replace(/([a-z])([A-Z])/g, '$1 $2') // break up camel case
        .replace(/([^.])_([^.])/g, '$1 $2') // break up underscore case
        .replace(/(^\w{1})|(\s+\w{1})/g, letter => letter.toUpperCase()); // capitalize every word
}

/**
 * @template CTX
 * @param {Object} object
 * @param {FieldDescriptor} field
 * @param {Map<*, TypeEditor>} registry
 */
export function createFieldEditor(object, field, registry) {

    const field_schema = field.schema;

    let vValue;

    /**
     * @type {TypeEditor}
     */
    let factory;
    if (field_schema !== undefined) {
        const specific_field_editor = field_schema.editor;

        if (specific_field_editor !== undefined) {
            // field has a dedicated editor
            factory = specific_field_editor;
        }
    }

    if (factory === undefined) {
        factory = registry.get(field.type);
    }

    let orientation_inline = true;

    if (factory !== undefined) {
        if (factory.hidden) {
            // hidden class
            return null;
        }

        vValue = factory.build(object, field, registry);

        if (vValue) {
            orientation_inline = factory.inline;
        }
    }

    if (vValue === null || vValue === undefined) {
        // no view
        return null;
    }

    vValue.addClass('field-value');

    const vResult = new EmptyView({
        classList: ['auto-field-editor']
    });

    if (orientation_inline) {
        vResult.addClass('orientation-inline');
    }

    const field_formatted_name = format_field_name(field.name);

    const vLabel = new LabelView(field_formatted_name, { classList: ['field-name'] });

    vResult.addChild(vLabel);
    vResult.addChild(vValue);


    if (field_schema !== undefined) {
        if (field_schema.description !== undefined && field_schema.description.length > 0) {
            // add tooltip
            vLabel.attr({
                title: field_schema.description
            });
        }

        if (field_schema.deprecated) {
            vResult.addClass('field-deprecated');
        }
    }

    return vResult;
}
