import '../../../../assert/js/assert.js';
import '../../../../globals.js';
import TinyEmitter from '../../../../axon/js/TinyEmitter.js';
import assertMutuallyExclusiveOptions from '../../../../phet-core/js/assertMutuallyExclusiveOptions.js';
import memoize from '../../../../phet-core/js/memoize.js';
import { scenery } from '../../imports.js';
const MARGIN_LAYOUT_CONFIGURABLE_OPTION_KEYS = [
    'margin',
    'xMargin',
    'yMargin',
    'leftMargin',
    'rightMargin',
    'topMargin',
    'bottomMargin',
    'minContentWidth',
    'minContentHeight',
    'maxContentWidth',
    'maxContentHeight'
];
// (scenery-internal)
const MarginLayoutConfigurable = memoize((Type) => {
    return class MarginLayoutConfigurableMixin extends Type {
        /**
         * (scenery-internal)
         */
        constructor(...args) {
            super(...args);
            // (scenery-internal)
            this._leftMargin = null;
            this._rightMargin = null;
            this._topMargin = null;
            this._bottomMargin = null;
            this._minContentWidth = null;
            this._minContentHeight = null;
            this._maxContentWidth = null;
            this._maxContentHeight = null;
            this.changedEmitter = new TinyEmitter();
        }
        /**
         * (scenery-internal)
         */
        mutateConfigurable(options) {
            assertMutuallyExclusiveOptions(options, ['margin'], ['xMargin', 'yMargin']);
            assertMutuallyExclusiveOptions(options, ['xMargin'], ['leftMargin', 'rightMargin']);
            assertMutuallyExclusiveOptions(options, ['yMargin'], ['topMargin', 'bottomMargin']);
        }
        /**
         * Resets values to the "base" state.
         *
         * This is the fallback state for a constraint where every value is defined and valid. If a cell does not have a
         * specific "overridden" value, or a constraint doesn't have an "overridden" value, then it will take the value
         * defined here.
         *
         * These should be the default values for constraints.
         *
         * NOTE: min/max content width/height are null here (since null is a valid default, and doesn't indicate an
         * "inherit" value like the other types).
         *
         * (scenery-internal)
         */
        setConfigToBaseDefault() {
            this._leftMargin = 0;
            this._rightMargin = 0;
            this._topMargin = 0;
            this._bottomMargin = 0;
            this._minContentWidth = null;
            this._minContentHeight = null;
            this._maxContentWidth = null;
            this._maxContentHeight = null;
            this.changedEmitter.emit();
        }
        /**
         * Resets values to the "don't override anything, only inherit from the constraint" state
         *
         * These should be the default values for cells (e.g. "take all the behavior from the constraint, nothing is
         * overridden").
         *
         * NOTE: If ignoreOptions is provided, we will omit setting any values for keys that are defined in the ignoreOptions.
         * This allows us to avoid resetting values that we are just about to set to another value.
         *
         * (scenery-internal)
         */
        setConfigToInherit(ignoreOptions) {
            if (!ignoreOptions || ignoreOptions.leftMargin === undefined) {
                this._leftMargin = null;
            }
            if (!ignoreOptions || ignoreOptions.rightMargin === undefined) {
                this._rightMargin = null;
            }
            if (!ignoreOptions || ignoreOptions.topMargin === undefined) {
                this._topMargin = null;
            }
            if (!ignoreOptions || ignoreOptions.bottomMargin === undefined) {
                this._bottomMargin = null;
            }
            if (!ignoreOptions || ignoreOptions.minContentWidth === undefined) {
                this._minContentWidth = null;
            }
            if (!ignoreOptions || ignoreOptions.minContentHeight === undefined) {
                this._minContentHeight = null;
            }
            if (!ignoreOptions || ignoreOptions.maxContentWidth === undefined) {
                this._maxContentWidth = null;
            }
            if (!ignoreOptions || ignoreOptions.maxContentHeight === undefined) {
                this._maxContentHeight = null;
            }
            this.changedEmitter.emit();
        }
        /**
         * (scenery-internal)
         */
        get leftMargin() {
            return this._leftMargin;
        }
        /**
         * (scenery-internal)
         */
        set leftMargin(value) {
            assert && assert(value === null || (typeof value === 'number' && isFinite(value)));
            if (this._leftMargin !== value) {
                this._leftMargin = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get rightMargin() {
            return this._rightMargin;
        }
        /**
         * (scenery-internal)
         */
        set rightMargin(value) {
            assert && assert(value === null || (typeof value === 'number' && isFinite(value)));
            if (this._rightMargin !== value) {
                this._rightMargin = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get topMargin() {
            return this._topMargin;
        }
        /**
         * (scenery-internal)
         */
        set topMargin(value) {
            assert && assert(value === null || (typeof value === 'number' && isFinite(value)));
            if (this._topMargin !== value) {
                this._topMargin = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get bottomMargin() {
            return this._bottomMargin;
        }
        /**
         * (scenery-internal)
         */
        set bottomMargin(value) {
            assert && assert(value === null || (typeof value === 'number' && isFinite(value)));
            if (this._bottomMargin !== value) {
                this._bottomMargin = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get xMargin() {
            assert && assert(this._leftMargin === this._rightMargin);
            return this._leftMargin;
        }
        /**
         * (scenery-internal)
         */
        set xMargin(value) {
            assert && assert(value === null || (typeof value === 'number' && isFinite(value)));
            if (this._leftMargin !== value || this._rightMargin !== value) {
                this._leftMargin = value;
                this._rightMargin = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get yMargin() {
            assert && assert(this._topMargin === this._bottomMargin);
            return this._topMargin;
        }
        /**
         * (scenery-internal)
         */
        set yMargin(value) {
            assert && assert(value === null || (typeof value === 'number' && isFinite(value)));
            if (this._topMargin !== value || this._bottomMargin !== value) {
                this._topMargin = value;
                this._bottomMargin = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get margin() {
            assert && assert(this._leftMargin === this._rightMargin &&
                this._leftMargin === this._topMargin &&
                this._leftMargin === this._bottomMargin);
            return this._topMargin;
        }
        /**
         * (scenery-internal)
         */
        set margin(value) {
            assert && assert(value === null || (typeof value === 'number' && isFinite(value)));
            if (this._leftMargin !== value || this._rightMargin !== value || this._topMargin !== value || this._bottomMargin !== value) {
                this._leftMargin = value;
                this._rightMargin = value;
                this._topMargin = value;
                this._bottomMargin = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get minContentWidth() {
            return this._minContentWidth;
        }
        /**
         * (scenery-internal)
         */
        set minContentWidth(value) {
            if (this._minContentWidth !== value) {
                this._minContentWidth = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get minContentHeight() {
            return this._minContentHeight;
        }
        /**
         * (scenery-internal)
         */
        set minContentHeight(value) {
            if (this._minContentHeight !== value) {
                this._minContentHeight = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get maxContentWidth() {
            return this._maxContentWidth;
        }
        /**
         * (scenery-internal)
         */
        set maxContentWidth(value) {
            if (this._maxContentWidth !== value) {
                this._maxContentWidth = value;
                this.changedEmitter.emit();
            }
        }
        /**
         * (scenery-internal)
         */
        get maxContentHeight() {
            return this._maxContentHeight;
        }
        /**
         * (scenery-internal)
         */
        set maxContentHeight(value) {
            if (this._maxContentHeight !== value) {
                this._maxContentHeight = value;
                this.changedEmitter.emit();
            }
        }
    };
});
scenery.register('MarginLayoutConfigurable', MarginLayoutConfigurable);
export default MarginLayoutConfigurable;
export { MARGIN_LAYOUT_CONFIGURABLE_OPTION_KEYS };
//# sourceMappingURL=MarginLayoutConfigurable.js.map