import { ctxFlip, ctxRotate, drawImage, setGlobalAlpha, getParent, CanvasLayer, } from '../pen';
import { rgba } from '../utils';
import { createOffscreen } from './offscreen';
export class CanvasImage {
    parentElement;
    store;
    isBottom;
    canvas = document.createElement('canvas');
    /**
     * 非图片的绘制
     * isBottom true 指背景颜色，背景网格
     * isBottom false 指 标尺
     */
    otherOffsreen = createOffscreen(); // 非图片的
    offscreen = createOffscreen();
    animateOffsScreen = createOffscreen();
    fitOffscreen = createOffscreen();
    fitFlag = false; //开启自定义填充
    currentFit;
    activeFit;
    constructor(parentElement, store, isBottom) {
        this.parentElement = parentElement;
        this.store = store;
        this.isBottom = isBottom;
        parentElement.appendChild(this.canvas);
        this.canvas.style.backgroundRepeat = 'no-repeat';
        this.canvas.style.backgroundSize = '100% 100%';
        this.canvas.style.position = 'absolute';
        this.canvas.style.top = '0';
        this.canvas.style.left = '0';
    }
    resize(w, h) {
        this.canvas.style.width = w + 'px';
        this.canvas.style.height = h + 'px';
        w = (w * this.store.dpiRatio) | 0;
        h = (h * this.store.dpiRatio) | 0;
        this.canvas.width = w;
        this.canvas.height = h;
        this.otherOffsreen.width = w;
        this.otherOffsreen.height = h;
        this.offscreen.width = w;
        this.offscreen.height = h;
        this.animateOffsScreen.width = w;
        this.animateOffsScreen.height = h;
        this.fitOffscreen.width = w;
        this.fitOffscreen.height = h;
        this.otherOffsreen
            .getContext('2d')
            .scale(this.store.dpiRatio, this.store.dpiRatio);
        this.otherOffsreen.getContext('2d').textBaseline = 'middle';
        this.offscreen
            .getContext('2d')
            .scale(this.store.dpiRatio, this.store.dpiRatio);
        this.offscreen.getContext('2d').textBaseline = 'middle';
        this.animateOffsScreen
            .getContext('2d')
            .scale(this.store.dpiRatio, this.store.dpiRatio);
        this.animateOffsScreen.getContext('2d').textBaseline = 'middle';
        this.fitOffscreen
            .getContext('2d')
            .scale(this.store.dpiRatio, this.store.dpiRatio);
        this.fitOffscreen.getContext('2d').textBaseline = 'middle';
        this.init();
    }
    init() {
        this.offscreen
            .getContext('2d')
            .clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.animateOffsScreen
            .getContext('2d')
            .clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.fitOffscreen
            .getContext('2d')
            .clearRect(0, 0, this.canvas.width, this.canvas.height);
        for (const pen of this.store.data.pens) {
            if (this.hasImage(pen)) {
                // 只影响本层的
                pen.calculative.imageDrawed = false;
            }
        }
        if (this.isBottom) {
            this.store.patchFlagsBackground = true;
        }
        else {
            this.store.patchFlagsTop = true;
        }
    }
    clear() {
        this.otherOffsreen
            .getContext('2d')
            .clearRect(0, 0, this.otherOffsreen.width, this.otherOffsreen.height);
        this.offscreen
            .getContext('2d')
            .clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.animateOffsScreen
            .getContext('2d')
            .clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.fitOffscreen
            .getContext('2d')
            .clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.canvas
            .getContext('2d')
            .clearRect(0, 0, this.canvas.width, this.canvas.height);
    }
    hasImage(pen) {
        pen.calculative.hasImage =
            pen.calculative &&
                pen.calculative.inView &&
                // !pen.isBottom == !this.isBottom && // undefined == false 结果 false
                ((this.isBottom && pen.canvasLayer === CanvasLayer.CanvasImageBottom) ||
                    (!this.isBottom && pen.canvasLayer === CanvasLayer.CanvasImage)) &&
                pen.image &&
                pen.calculative.img &&
                pen.name !== 'gif';
        return pen.calculative.hasImage;
    }
    render() {
        let patchFlags = false;
        let patchFlagsAnimate = false;
        for (const pen of this.store.data.pens) {
            if (this.hasImage(pen)) {
                if (this.store.animates.has(pen)) {
                    patchFlagsAnimate = true;
                }
                else if (!pen.calculative.imageDrawed) {
                    patchFlags = true;
                }
                if (pen.parentId && this.store.animates.has(getParent(pen, true))) {
                    patchFlagsAnimate = true;
                }
            }
        }
        const patchFlagsBackground = this.store.patchFlagsBackground;
        // if (patchFlagsBackground && this.isBottom) {
        //   const ctx = this.otherOffsreen.getContext('2d');
        //   ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        //   const width = this.store.data.width || this.store.options.width;
        //   const height = this.store.data.height || this.store.options.height;
        //   const x = this.store.data.x || this.store.options.x;
        //   const y = this.store.data.y || this.store.options.y;
        //   if (width && height && this.store.bkImg) {
        //     ctx.save();
        //     ctx.drawImage(
        //       this.store.bkImg,
        //       this.store.data.origin.x + x,
        //       this.store.data.origin.y + y,
        //       width * this.store.data.scale,
        //       height * this.store.data.scale
        //     );
        //     ctx.restore();
        //   }
        //   const background =
        //     this.store.data.background ||
        //     (this.store.bkImg ? undefined : this.store.options.background);
        //   if (background) {
        //     ctx.save();
        //     ctx.fillStyle = background;
        //     if (width && height) {
        //       ctx.fillRect(
        //         this.store.data.origin.x + x,
        //         this.store.data.origin.y + y,
        //         width * this.store.data.scale,
        //         height * this.store.data.scale
        //       );
        //     } else {
        //       ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
        //     }
        //     ctx.restore();
        //   }
        //   this.renderGrid(ctx);
        // }
        const patchFlagsTop = this.store.patchFlagsTop;
        if (patchFlagsTop && !this.isBottom) {
            const ctx = this.otherOffsreen.getContext('2d');
            ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
            this.renderRule(ctx);
        }
        // 从有图片画布层切换到无图片画布
        const patchFlagsLast = this.store.patchFlagsLast;
        if (patchFlagsLast) {
            const ctx = this.offscreen.getContext('2d');
            ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        }
        if (patchFlags) {
            const ctx = this.offscreen.getContext('2d');
            ctx.save();
            ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
            ctx.translate(this.store.data.x, this.store.data.y);
            for (const pen of this.store.data.pens) {
                //pen.calculative.imageDrawed  只用于判断是否需要重绘整块画布，不用于判断改图片节点是否绘制过
                if (!pen.calculative.hasImage ||
                    this.store.animates.has(pen) ||
                    this.store.animates.has(getParent(pen, true))) {
                    continue;
                }
                // if (pen.template) {
                if (pen.canvasLayer === CanvasLayer.CanvasTemplate) {
                    continue;
                }
                // if (pen.name === 'combine' && !pen.draw){
                //   continue;
                // }
                pen.calculative.imageDrawed = true;
                ctx.save();
                ctxFlip(ctx, pen);
                if (pen.rotateByRoot || pen.calculative.rotate) {
                    ctxRotate(ctx, pen);
                }
                setGlobalAlpha(ctx, pen);
                drawImage(ctx, pen);
                ctx.restore();
            }
            ctx.restore();
        }
        if (patchFlagsAnimate) {
            const ctx = this.animateOffsScreen.getContext('2d');
            ctx.save();
            ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
            ctx.translate(this.store.data.x, this.store.data.y);
            for (const pen of this.store.animates) {
                if (!pen.calculative.hasImage) {
                    continue;
                }
                // if (pen.template) {
                if (pen.canvasLayer === CanvasLayer.CanvasTemplate) {
                    continue;
                }
                if (pen.visible === false || pen.calculative.visible === false) {
                    //动画控制显示隐藏
                    continue;
                }
                pen.calculative.imageDrawed = true;
                ctx.save();
                ctxFlip(ctx, pen);
                if (pen.rotateByRoot || pen.calculative.rotate) {
                    ctxRotate(ctx, pen);
                }
                setGlobalAlpha(ctx, pen);
                drawImage(ctx, pen);
                ctx.restore();
            }
            //图片组合节点 动画
            for (const pen of this.store.data.pens) {
                if (!pen.calculative.hasImage || !pen.parentId) {
                    continue;
                }
                // if (pen.template) {
                if (pen.canvasLayer === CanvasLayer.CanvasTemplate) {
                    continue;
                }
                if (pen.visible === false || pen.calculative.visible === false) {
                    continue;
                }
                if (this.store.animates.has(getParent(pen, true))) {
                    pen.calculative.imageDrawed = true;
                    ctx.save();
                    ctxFlip(ctx, pen);
                    if (pen.rotateByRoot || pen.calculative.rotate) {
                        ctxRotate(ctx, pen);
                    }
                    setGlobalAlpha(ctx, pen);
                    drawImage(ctx, pen);
                    ctx.restore();
                }
            }
            ctx.restore();
        }
        if (!this.isBottom && !this.store.data.locked && this.fitFlag) {
            const width = (this.store.data.width || this.store.options.width) *
                this.store.data.scale;
            const height = (this.store.data.height || this.store.options.height) *
                this.store.data.scale;
            const x = this.store.data.origin.x + this.store.data.x ||
                this.store.options.x ||
                0;
            const y = this.store.data.origin.y + this.store.data.y ||
                this.store.options.y ||
                0;
            const ctx = this.fitOffscreen.getContext('2d');
            ctx.save();
            ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
            ctx.fillStyle = '#ffffff66';
            ctx.strokeStyle = this.store.styles.activeColor;
            this.store.data.fits?.forEach((item, index) => {
                ctx.fillRect(x + width * item.x, y + height * item.y, width * item.width, height * item.height);
                if (item.active) {
                    ctx.strokeRect(x + width * item.x, y + height * item.y, width * item.width, height * item.height);
                }
            });
            ctx.restore();
        }
        if (patchFlags ||
            patchFlagsAnimate ||
            (patchFlagsBackground && this.isBottom) ||
            // this.isBottom ||
            (patchFlagsTop && !this.isBottom)) {
            const ctxCanvas = this.canvas.getContext('2d');
            ctxCanvas.clearRect(0, 0, this.canvas.width, this.canvas.height);
            if (this.isBottom) {
                //   ctxCanvas.drawImage(
                //     this.otherOffsreen,
                //     0,
                //     0,
                //     this.canvas.width,
                //     this.canvas.height
                //   );
                this.store.patchFlagsBackground = false;
            }
            ctxCanvas.drawImage(this.offscreen, 0, 0, this.canvas.width, this.canvas.height);
            ctxCanvas.drawImage(this.animateOffsScreen, 0, 0, this.canvas.width, this.canvas.height);
            if (!this.isBottom) {
                ctxCanvas.drawImage(this.otherOffsreen, 0, 0, this.canvas.width, this.canvas.height);
                this.store.patchFlagsTop = false;
                if (!this.store.data.locked && this.fitFlag) {
                    ctxCanvas.drawImage(this.fitOffscreen, 0, 0, this.canvas.width, this.canvas.height);
                }
            }
        }
    }
    // renderGrid(
    //   ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D
    // ) {
    //   const { data, options } = this.store;
    //   const { grid, gridRotate, gridColor, gridSize, scale } = data;
    //   if (!(grid ?? options.grid)) {
    //     // grid false 时不绘制, undefined 时看 options.grid
    //     return;
    //   }
    //   ctx.save();
    //   const { width, height } = this.canvas;
    //   if (gridRotate) {
    //     ctx.translate(width / 2, height / 2);
    //     ctx.rotate((gridRotate * Math.PI) / 180);
    //     ctx.translate(-width / 2, -height / 2);
    //   }
    //   ctx.lineWidth = 1;
    //   ctx.strokeStyle = gridColor || options.gridColor;
    //   ctx.beginPath();
    //   const size = (gridSize || options.gridSize) * scale;
    //   const longSide = Math.max(width, height);
    //   const count = Math.ceil(longSide / size);
    //   for (let i = -size * count; i < longSide * 2; i += size) {
    //     ctx.moveTo(i, -longSide);
    //     ctx.lineTo(i, longSide * 2);
    //   }
    //   for (let i = -size * count; i < longSide * 2; i += size) {
    //     ctx.moveTo(-longSide, i);
    //     ctx.lineTo(longSide * 2, i);
    //   }
    //   ctx.stroke();
    //   ctx.restore();
    // }
    renderRule(ctx) {
        const { data, options } = this.store;
        const { rule, ruleColor, scale, origin } = data;
        if (!(rule ?? options.rule)) {
            // rule false 时不绘制, undefined 时看 options.rule
            return;
        }
        const span = scale * 10;
        ctx.save();
        const finalRuleColor = ruleColor || options.ruleColor || "#ccc";
        ctx.strokeStyle = rgba(finalRuleColor, 0.7);
        const x = origin.x + data.x;
        const y = origin.y + data.y;
        const { width, height } = this.canvas;
        let h = options.ruleOptions?.height || 20;
        if (options.ruleOptions?.background) {
            //背景颜色
            ctx.beginPath();
            ctx.fillStyle = options.ruleOptions?.background;
            ctx.rect(0, 0, width, h);
            ctx.fill();
            ctx.rect(0, 0, h, height);
            ctx.fill();
        }
        if (options.ruleOptions?.underline) {
            ctx.beginPath();
            ctx.fillStyle = rgba(finalRuleColor, 0.7);
            ctx.moveTo(0, h);
            ctx.lineTo(width, h);
            ctx.stroke();
            ctx.moveTo(h, 0);
            ctx.lineTo(h, height);
            ctx.stroke();
        }
        let b_y = h / 4;
        if (options.ruleOptions?.baseline === "bottom") {
            b_y = h * 3 / 4;
        }
        // horizontal rule
        ctx.beginPath();
        ctx.lineWidth = h / 2;
        ctx.lineDashOffset = -x % span;
        ctx.setLineDash([1, span - 1]);
        ctx.moveTo(0, b_y);
        ctx.lineTo(width, b_y);
        ctx.stroke();
        // vertical rule
        ctx.beginPath();
        ctx.lineDashOffset = -y % span;
        ctx.moveTo(b_y, 0);
        ctx.lineTo(b_y, height);
        ctx.stroke();
        // the big rule
        ctx.strokeStyle = finalRuleColor;
        ctx.beginPath();
        ctx.lineWidth = h;
        ctx.lineDashOffset = -x % (span * 10);
        ctx.setLineDash([1, span * 10 - 1]);
        ctx.moveTo(0, h / 2);
        ctx.lineTo(width, h / 2);
        ctx.stroke();
        ctx.beginPath();
        ctx.lineDashOffset = -y % (span * 10);
        ctx.moveTo(h / 2, 0);
        ctx.lineTo(h / 2, height);
        ctx.stroke();
        ctx.beginPath();
        ctx.fillStyle = options.ruleOptions?.textColor || ctx.strokeStyle;
        let text = 0 - Math.floor(x / span / 10) * 100;
        let textTop = options.ruleOptions?.textTop || 16;
        let textLeft = options.ruleOptions?.textLeft || 4;
        if (x < 0) {
            text -= 100;
        }
        for (let i = x % (span * 10); i < width; i += 10 * span, text += 100) {
            if (span < 3 && text % 500) {
                continue;
            }
            ctx.fillText(text.toString(), i + textLeft, textTop);
        }
        text = 0 - Math.floor(y / span / 10) * 100;
        if (y < 0) {
            text -= 100;
        }
        for (let i = y % (span * 10); i < height; i += 10 * span, text += 100) {
            if (span < 3 && text % 500) {
                continue;
            }
            ctx.save();
            ctx.beginPath();
            ctx.translate(textTop, i - textLeft);
            ctx.rotate((270 * Math.PI) / 180);
            ctx.fillText(text.toString(), 0, 0);
            ctx.restore();
        }
        ctx.restore();
    }
}
//# sourceMappingURL=canvasImage.js.map