import '../../globals.js';
// Copyright 2013-2024, University of Colorado Boulder
/**
 * Dimension2 is a basic width and height, like a Bounds2 but without the position defined.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import InfiniteNumberIO from '../../tandem/js/types/InfiniteNumberIO.js';
import IOType from '../../tandem/js/types/IOType.js';
import Bounds2 from './Bounds2.js';
import dot from './dot.js';
const STATE_SCHEMA = {
    width: InfiniteNumberIO,
    height: InfiniteNumberIO
};
class Dimension2 {
    constructor(width, height) {
        this.width = width;
        this.height = height;
    }
    /**
     * Debugging string for the dimension.
     */
    toString() {
        return `[${this.width}w, ${this.height}h]`;
    }
    /**
     * Sets this dimension to be a copy of another dimension.
     * This is the mutable form of the function copy(). This will mutate (change) this dimension, in addition to returning
     * this dimension itself.
     */
    set(dimension) {
        this.width = dimension.width;
        this.height = dimension.height;
        return this;
    }
    /**
     * Sets the width of the dimension, returning this.
     */
    setWidth(width) {
        this.width = width;
        return this;
    }
    /**
     * Sets the height of the dimension, returning this.
     */
    setHeight(height) {
        this.height = height;
        return this;
    }
    /**
     * Creates a copy of this dimension, or if a dimension is passed in, set that dimension's values to ours.
     * This is the immutable form of the function set(), if a dimension is provided. This will return a new dimension,
     * and will not modify this dimension.
     *
     * @param [dimension] - If not provided, creates a new Dimension2 with filled in values. Otherwise, fills
     *                      in the values of the provided dimension so that it equals this dimension.
     */
    copy(dimension) {
        if (dimension) {
            return dimension.set(this);
        }
        else {
            return new Dimension2(this.width, this.height);
        }
    }
    /**
     * Swap width and height and return a new Dimension2
     */
    swapped() {
        return new Dimension2(this.height, this.width);
    }
    /**
     * Creates a Bounds2 from this dimension based on passing in the minimum (top-left) corner as (x,y).
     * @param [x] - Minimum x coordinate of the bounds, or 0 if not provided.
     * @param [y] - Minimum y coordinate of the bounds, or 0 if not provided.
     */
    toBounds(x, y) {
        x = x !== undefined ? x : 0;
        y = y !== undefined ? y : 0;
        return new Bounds2(x, y, this.width + x, this.height + y);
    }
    /**
     * Exact equality comparison between this dimension and another dimension.
     */
    equals(that) {
        return this.width === that.width && this.height === that.height;
    }
    /**
     * Exact equality comparison between this dimension and another dimension.
     *
     * Whether difference between the two dimensions has no component with an absolute value greater than epsilon.
     */
    equalsEpsilon(that, epsilon = 0) {
        return Math.max(Math.abs(this.width - that.width), Math.abs(this.height - that.height)) <= epsilon;
    }
    toStateObject() {
        return {
            width: InfiniteNumberIO.toStateObject(this.width),
            height: InfiniteNumberIO.toStateObject(this.height)
        };
    }
    static fromStateObject(stateObject) {
        return new Dimension2(InfiniteNumberIO.fromStateObject(stateObject.width), InfiniteNumberIO.fromStateObject(stateObject.height));
    }
}
Dimension2.Dimension2IO = new IOType('Dimension2IO', {
    valueType: Dimension2,
    documentation: 'A dimension with "width" and "height" members.',
    stateSchema: STATE_SCHEMA,
    toStateObject: (range) => range.toStateObject(),
    fromStateObject: (stateObject) => Dimension2.fromStateObject(stateObject)
});
export default Dimension2;
dot.register('Dimension2', Dimension2);
//# sourceMappingURL=Dimension2.js.map