import { Camera } from './camera.js';
import { Matrix4x4 } from '@zephyr3d/base';

/**
 * Orthogonal camera class
 * @public
 */ class OrthoCamera extends Camera {
    /** @internal */ _left;
    _right;
    _top;
    _bottom;
    _near;
    _far;
    _window;
    /**
   * Creates an instance of OrthoCamera
   * @param scene - The scene that the camera belongs to.
   * @param left - The left clip plane
   * @param right - The right clip plane
   * @param bottom - The bottom clip plane
   * @param top - The top clip plane
   * @param near - The near clip plane
   * @param far - The far clip plane
   */ constructor(scene, left = -1, right = 1, bottom = -1, top = 1, near = -1, far = 1){
        super(scene);
        this._left = left;
        this._right = right;
        this._bottom = bottom;
        this._top = top;
        this._near = near;
        this._far = far;
        this._window = null;
        this._invalidate(true);
    }
    /** Sub-window of the frustum */ get window() {
        return this._window;
    }
    set window(val) {
        this._window = val?.slice() ?? null;
        this._invalidate(true);
    }
    /** The near clip plane */ get near() {
        return this._near;
    }
    set near(val) {
        if (val !== this._near) {
            this._near = val;
            this._invalidate(true);
        }
    }
    /** The far clip plane */ get far() {
        return this._far;
    }
    set far(val) {
        if (val !== this._far) {
            this._far = val;
            this._invalidate(true);
        }
    }
    /** The left clip plane */ get left() {
        return this.adapted ? this.getProjectionMatrix().getLeftPlane() : this._left;
    }
    set left(val) {
        if (val !== this._left) {
            this._left = val;
            this._invalidate(true);
        }
    }
    /** The right clip plane */ get right() {
        return this.adapted ? this.getProjectionMatrix().getRightPlane() : this._right;
    }
    set right(val) {
        if (val !== this._right) {
            this._right = val;
            this._invalidate(true);
        }
    }
    /** The top clip plane */ get top() {
        return this.adapted ? this.getProjectionMatrix().getTopPlane() : this._top;
    }
    set top(val) {
        if (val !== this._top) {
            this._top = val;
            this._invalidate(true);
        }
    }
    /** The bottom clip plane */ get bottom() {
        return this.adapted ? this.getProjectionMatrix().getBottomPlane() : this._bottom;
    }
    set bottom(val) {
        if (val !== this._bottom) {
            this._bottom = val;
            this._invalidate(true);
        }
    }
    /**
   * Not valid for OrthoCamera
   *
   * @remarks
   * This method is only valid for {@link Camera} class or {@link PerspectiveCamera} class.
   */ setPerspective() {
        throw new Error(`setPerspective() not allowed on OrthoCamera`);
    }
    /**
   * {@inheritDoc Camera.setOrtho}
   */ setOrtho(left, right, bottom, top, near, far) {
        this._left = left;
        this._right = right;
        this._bottom = bottom;
        this._top = top;
        this._near = near;
        this._far = far;
        this._invalidate(true);
        return this;
    }
    /**
   * Setup a projection matrix for the camera
   * @param matrix - The projection matrix
   */ setProjectionMatrix(matrix) {
        if (matrix !== this._projMatrix) {
            if (matrix?.isOrtho()) {
                super.setProjectionMatrix(matrix);
                this._left = matrix.getLeftPlane();
                this._right = matrix.getRightPlane();
                this._near = matrix.getNearPlane();
                this._far = matrix.getFarPlane();
                this._top = matrix.getTopPlane();
                this._bottom = matrix.getBottomPlane();
            } else {
                throw new Error(`OrthoCamera.setProjectionMatrix(): param is not an orthogonal projection matrix`);
            }
        }
    }
    /** @internal */ _computeProj() {
        if (this.adapted) {
            this.calcAdaptedOrthographicProjection(this._near, this._far, this._projMatrix);
        } else {
            let left = this._left;
            let right = this._right;
            let bottom = this._bottom;
            let top = this._top;
            if (this._window) {
                const width = right - left;
                const height = top - bottom;
                left += width * this._window[0];
                bottom += height * this._window[1];
                right = left + width * this._window[2];
                top = bottom + height * this._window[3];
            }
            this._projMatrix.ortho(left, right, bottom, top, this._near, this._far);
        }
        Matrix4x4.invert(this._projMatrix, this._invProjMatrix);
    }
}

export { OrthoCamera };
//# sourceMappingURL=orthocamera.js.map
