import { TypeEditor } from "../../TypeEditor.js";
import { NativeListController } from "../../../../../src/view/controller/controls/NativeListController.js";
import { buildObjectEditorFromRegistry } from "../../createObjectEditor.js";
import LabelView from "../../../../../src/view/common/LabelView.js";
import { FieldDescriptor } from "../../FieldDescriptor.js";
import { FieldValueAdapter } from "../../FieldValueAdapter.js";

export class ListEditor extends TypeEditor {
    inline = false;

    build(parent, field, registry) {


        const list = field.adapter.read(parent, field.name);

        if (list.length > 100) {
            return new LabelView(`List is too big (length = ${list.length})`);
        }

        let ElementType;

        const field_schema = field.schema;

        if (field_schema !== undefined) {

            const type_parameters = field_schema.type_parameters;


            if (type_parameters === undefined || type_parameters.length < 1) {
                // no type specified on schema

            } else {

                ElementType = type_parameters[0];

            }
        }

        let inferred_type = false;

        if (ElementType === undefined && list.length > 0) {
            ElementType = list.get(0).constructor;
            inferred_type = true;
        }

        if (ElementType === undefined) {
            return undefined;
        }

        if (inferred_type && !registry.has(ElementType)) {
            // only work with known types when type is inferred, too messy otherwise
            return undefined;
        }

        return new NativeListController({
            model: list,
            elementFactory() {
                return new ElementType();
            },
            elementViewFactory(el) {
                const fd = new FieldDescriptor();

                let last_known = el;

                fd.type = ElementType;
                fd.adapter = new FieldValueAdapter();
                fd.adapter.read = (object, field_name) => {
                    return last_known;
                };
                fd.adapter.write = (object, field_name, value) => {
                    const i = list.indexOf(last_known);

                    list.set(i, value);

                    last_known = value;
                };

                return buildObjectEditorFromRegistry(el, registry, fd);
            }
        })

    }
}
