import { Property } from './Property';
import { RecordUtil } from './RecordUtil';
/**
 * An {@link Record} that manages two copies internally, a before and after, for 'undo' and comparison purposes.
 * An Record Represents a 'Record' or set of {@link Property} (names and values).
 * An Record may also have {@link Annotation}s (style annotations) that apply to the whole 'record'
 */
export class RecordBuffer {
    constructor(_before, _after) {
        this._before = _before;
        this._after = _after;
        if (!_before) {
            throw new Error('_before is null in RecordBuffer');
        }
        if (!_after) {
            this._after = _before;
        }
    }
    static createRecordBuffer(id, before, after, annotations) {
        return new RecordBuffer(RecordUtil.newRecord(id, before, annotations), RecordUtil.newRecord(id, after, annotations));
    }
    get after() {
        return this._after;
    }
    get annotations() {
        return this._after.annotations;
    }
    annotationsAtName(propName) {
        return this._after.annotationsAtName(propName);
    }
    afterEffects(afterAnother) {
        if (afterAnother) {
            return this._after.afterEffects(afterAnother);
        }
        else {
            return this._before.afterEffects(this._after);
        }
    }
    get backgroundColor() {
        return this._after.backgroundColor;
    }
    backgroundColorFor(propName) {
        return this._after.backgroundColorFor(propName);
    }
    get before() {
        return this._before;
    }
    get foregroundColor() {
        return this._after.foregroundColor;
    }
    foregroundColorFor(propName) {
        return this._after.foregroundColorFor(propName);
    }
    get imageName() {
        return this._after.imageName;
    }
    imageNameFor(propName) {
        return this._after.imageNameFor(propName);
    }
    get imagePlacement() {
        return this._after.imagePlacement;
    }
    imagePlacementFor(propName) {
        return this._after.imagePlacement;
    }
    get isBoldText() {
        return this._after.isBoldText;
    }
    isBoldTextFor(propName) {
        return this._after.isBoldTextFor(propName);
    }
    isChanged(name) {
        const before = this._before.propAtName(name);
        const after = this._after.propAtName(name);
        return before && after ? !before.equals(after) : !(!before && !after);
    }
    get isItalicText() {
        return this._after.isItalicText;
    }
    isItalicTextFor(propName) {
        return this._after.isItalicTextFor(propName);
    }
    get isPlacementCenter() {
        return this._after.isPlacementCenter;
    }
    isPlacementCenterFor(propName) {
        return this._after.isPlacementCenterFor(propName);
    }
    get isPlacementLeft() {
        return this._after.isPlacementLeft;
    }
    isPlacementLeftFor(propName) {
        return this._after.isPlacementLeftFor(propName);
    }
    get isPlacementRight() {
        return this._after.isPlacementRight;
    }
    isPlacementRightFor(propName) {
        return this._after.isPlacementRightFor(propName);
    }
    get isPlacementStretchUnder() {
        return this._after.isPlacementStretchUnder;
    }
    isPlacementStretchUnderFor(propName) {
        return this._after.isPlacementStretchUnderFor(propName);
    }
    get isPlacementUnder() {
        return this._after.isPlacementUnder;
    }
    isPlacementUnderFor(propName) {
        return this._after.isPlacementUnderFor(propName);
    }
    get isUnderline() {
        return this._after.isUnderline;
    }
    isUnderlineFor(propName) {
        return this._after.isUnderlineFor(propName);
    }
    get id() {
        return this._after.id;
    }
    get overrideText() {
        return this._after.overrideText;
    }
    overrideTextFor(propName) {
        return this._after.overrideTextFor(propName);
    }
    propAtIndex(index) {
        return this.properties[index];
    }
    propAtName(propName) {
        return this._after.propAtName(propName);
    }
    get propCount() {
        return this._after.propCount;
    }
    get propNames() {
        return this._after.propNames;
    }
    get properties() {
        return this._after.properties;
    }
    get propValues() {
        return this._after.propValues;
    }
    get type() {
        return this._after.type;
    }
    setValue(name, value, propDef) {
        const newProps = [];
        let found = false;
        let newProp = null;
        this.properties.forEach((prop) => {
            if (prop.name === name) {
                newProp = new Property(name, value, propDef.format, prop.annotations);
                newProps.push(newProp);
                found = true;
            }
            else {
                newProps.push(prop);
            }
        });
        if (!found) {
            newProp = new Property(name, value);
            newProps.push(newProps);
        }
        this._after = RecordUtil.newRecord(this.id, newProps, this.annotations);
        return newProp;
    }
    get tipText() {
        return this._after.tipText;
    }
    tipTextFor(propName) {
        return this._after.tipTextFor(propName);
    }
    toRecord() {
        return RecordUtil.newRecord(this.id, this.properties, this.annotations);
    }
    toJSON() {
        return this.afterEffects().toJSON();
    }
    valueAtName(propName) {
        return this._after.valueAtName(propName);
    }
}
