/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { brand } from "../util";
import { ModularChangeFamily, ModularEditBuilder, } from "./modular-schema";
import { forbidden, optional, sequence, value as valueFieldKind } from "./defaultFieldKinds";
const defaultFieldKinds = new Map([valueFieldKind, optional, sequence, forbidden].map((f) => [f.identifier, f]));
/**
 * Implementation of {@link ChangeFamily} based on the default set of supported field kinds.
 *
 * @sealed
 */
export class DefaultChangeFamily {
    constructor() {
        this.modularFamily = new ModularChangeFamily(defaultFieldKinds);
    }
    get rebaser() {
        return this.modularFamily.rebaser;
    }
    get codecs() {
        return this.modularFamily.codecs;
    }
    intoDelta(change) {
        return this.modularFamily.intoDelta(change);
    }
    buildEditor(changeReceiver, anchorSet) {
        return new DefaultEditBuilder(this, changeReceiver, anchorSet);
    }
}
export const defaultChangeFamily = new DefaultChangeFamily();
/**
 * Implementation of {@link ProgressiveEditBuilder} based on the default set of supported field kinds.
 * @sealed
 */
export class DefaultEditBuilder {
    constructor(family, changeReceiver, anchors) {
        this.modularBuilder = new ModularEditBuilder(family, changeReceiver, anchors);
    }
    enterTransaction() {
        this.modularBuilder.enterTransaction();
    }
    exitTransaction() {
        this.modularBuilder.exitTransaction();
    }
    apply(change) {
        this.modularBuilder.apply(change);
    }
    setValue(path, value) {
        this.modularBuilder.setValue(path, value);
    }
    addValueConstraint(path, value) {
        this.modularBuilder.addValueConstraint(path, value);
    }
    valueField(field) {
        return {
            set: (newContent) => {
                const change = brand(valueFieldKind.changeHandler.editor.set(newContent));
                this.modularBuilder.submitChange(field, valueFieldKind.identifier, change);
            },
        };
    }
    optionalField(field) {
        return {
            set: (newContent, wasEmpty) => {
                const change = brand(optional.changeHandler.editor.set(newContent, wasEmpty));
                this.modularBuilder.submitChange(field, optional.identifier, change);
            },
        };
    }
    move(sourceField, sourceIndex, count, destinationField, destIndex) {
        const changes = sequence.changeHandler.editor.move(sourceIndex, count, destIndex, this.modularBuilder.generateId());
        this.modularBuilder.submitChanges([
            {
                field: sourceField,
                fieldKind: sequence.identifier,
                change: brand(changes[0]),
            },
            {
                field: destinationField,
                fieldKind: sequence.identifier,
                change: brand(changes[1]),
            },
        ], brand(0));
    }
    sequenceField(field) {
        return {
            insert: (index, newContent) => {
                const change = brand(sequence.changeHandler.editor.insert(index, newContent, this.modularBuilder.generateId(Array.isArray(newContent) ? newContent.length : 1)));
                this.modularBuilder.submitChange(field, sequence.identifier, change);
            },
            delete: (index, count) => {
                const change = brand(sequence.changeHandler.editor.delete(index, count));
                this.modularBuilder.submitChange(field, sequence.identifier, change);
            },
            move: (sourceIndex, count, destIndex) => {
                const moves = sequence.changeHandler.editor.move(sourceIndex, count, destIndex, this.modularBuilder.generateId());
                this.modularBuilder.submitChanges([
                    {
                        field,
                        fieldKind: sequence.identifier,
                        change: brand(moves[0]),
                    },
                    {
                        field,
                        fieldKind: sequence.identifier,
                        change: brand(moves[1]),
                    },
                ], brand(0));
            },
            revive: (index, count, detachedBy, reviver, detachIndex, isIntention) => {
                const change = brand(sequence.changeHandler.editor.revive(index, count, detachedBy, reviver, detachIndex, isIntention));
                this.modularBuilder.submitChange(field, sequence.identifier, change);
            },
        };
    }
    /**
     * {@inheritDoc (ProgressiveEditBuilder:interface).getChanges}
     */
    getChanges() {
        return this.modularBuilder.getChanges();
    }
}
//# sourceMappingURL=defaultChangeFamily.js.map