import { SVGRenderingContext2D } from "./svg";
import { BBox } from "./bbox";
import { div, canvas } from "../dom";
export class CanvasLayer {
    backend;
    hidpi;
    static __name__ = "CanvasLayer";
    _canvas;
    get canvas() {
        return this._canvas;
    }
    _ctx;
    get ctx() {
        return this._ctx;
    }
    _el;
    get el() {
        return this._el;
    }
    pixel_ratio = 1;
    bbox = new BBox();
    constructor(backend, hidpi) {
        this.backend = backend;
        this.hidpi = hidpi;
        switch (backend) {
            case "webgl":
            case "canvas": {
                this._el = this._canvas = canvas({ class: "bk-layer" });
                const ctx = this.canvas.getContext("2d");
                if (ctx == null) {
                    throw new Error("unable to obtain 2D rendering context");
                }
                this._ctx = ctx;
                if (hidpi) {
                    this.pixel_ratio = devicePixelRatio;
                }
                break;
            }
            case "svg": {
                const ctx = new SVGRenderingContext2D();
                this._ctx = ctx;
                this._canvas = ctx.get_svg();
                this._el = div({ class: "bk-layer" });
                const shadow_el = this._el.attachShadow({ mode: "open" });
                shadow_el.appendChild(this._canvas);
                break;
            }
        }
        this._ctx.layer = this;
    }
    resize(width, height) {
        if (this.bbox.width == width && this.bbox.height == height) {
            return;
        }
        this.bbox = new BBox({ left: 0, top: 0, width, height });
        const { target } = this;
        target.width = width * this.pixel_ratio;
        target.height = height * this.pixel_ratio;
    }
    get target() {
        return this._ctx instanceof SVGRenderingContext2D ? this._ctx : this.canvas;
    }
    undo_transform(fn) {
        const { ctx } = this;
        const current_transform = ctx.getTransform();
        ctx.resetTransform();
        try {
            fn(ctx);
        }
        finally {
            ctx.setTransform(current_transform);
        }
    }
    prepare() {
        const { ctx, hidpi, pixel_ratio } = this;
        ctx.save();
        if (hidpi) {
            ctx.scale(pixel_ratio, pixel_ratio);
            ctx.translate(0.5, 0.5);
        }
        this.clear();
    }
    clear() {
        const { x, y, width, height } = this.bbox;
        this.ctx.clearRect(x, y, width, height);
    }
    finish() {
        this.ctx.restore();
    }
    to_blob() {
        const { _canvas } = this;
        if (_canvas instanceof HTMLCanvasElement) {
            return new Promise((resolve, reject) => {
                _canvas.toBlob((blob) => blob != null ? resolve(blob) : reject(), "image/png");
            });
        }
        else {
            const ctx = this._ctx;
            const svg = ctx.get_serialized_svg(true);
            const blob = new Blob([svg], { type: "image/svg+xml" });
            return Promise.resolve(blob);
        }
    }
}
//# sourceMappingURL=canvas.js.map