"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Canvas = void 0;
const Utils_1 = require("../Utils");
class Canvas {
    constructor(container) {
        this.container = container;
        this.size = {
            height: 0,
            width: 0,
        };
        this.context = null;
        this.generatedCanvas = false;
    }
    init() {
        this.resize();
        const container = this.container;
        const options = container.options;
        const cover = options.backgroundMask.cover;
        const color = cover.color;
        const trail = options.particles.move.trail;
        this.coverColor = Utils_1.ColorUtils.colorToRgb(color);
        this.trailFillColor = Utils_1.ColorUtils.colorToRgb(trail.fillColor);
        this.paint();
    }
    loadCanvas(canvas, generatedCanvas) {
        var _a;
        if (!canvas.className) {
            canvas.className = Utils_1.Constants.canvasClass;
        }
        if (this.generatedCanvas) {
            (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
        }
        this.generatedCanvas = generatedCanvas !== null && generatedCanvas !== void 0 ? generatedCanvas : false;
        this.element = canvas;
        this.size.height = canvas.offsetHeight;
        this.size.width = canvas.offsetWidth;
        this.context = this.element.getContext("2d");
        this.container.retina.init();
        this.initBackground();
    }
    destroy() {
        var _a;
        if (this.generatedCanvas) {
            (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
        }
        if (this.context) {
            Utils_1.CanvasUtils.clear(this.context, this.size);
        }
    }
    resize() {
        if (this.element) {
            this.element.width = this.size.width;
            this.element.height = this.size.height;
        }
    }
    paint() {
        const container = this.container;
        const options = container.options;
        if (this.context) {
            if (options.backgroundMask.enable && options.backgroundMask.cover && this.coverColor) {
                this.paintBase(Utils_1.ColorUtils.getStyleFromRgb(this.coverColor));
            }
            else {
                this.paintBase();
            }
        }
    }
    clear() {
        const container = this.container;
        const options = container.options;
        const trail = options.particles.move.trail;
        if (options.backgroundMask.enable) {
            this.paint();
        }
        else if (trail.enable && trail.length > 0 && this.trailFillColor) {
            this.paintBase(Utils_1.ColorUtils.getStyleFromRgb(this.trailFillColor, 1 / trail.length));
        }
        else if (this.context) {
            Utils_1.CanvasUtils.clear(this.context, this.size);
        }
    }
    isPointInPath(path, point) {
        var _a, _b;
        return (_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.isPointInPath(path, point.x, point.y)) !== null && _b !== void 0 ? _b : false;
    }
    drawLinkTriangle(p1, link1, link2) {
        var _a, _b;
        const container = this.container;
        const options = container.options;
        const p2 = link1.destination;
        const p3 = link2.destination;
        const triangleOptions = p1.particlesOptions.links.triangles;
        const opacityTriangle = (_a = triangleOptions.opacity) !== null && _a !== void 0 ? _a : (link1.opacity + link2.opacity) / 2;
        const pos1 = p1.getPosition();
        const pos2 = p2.getPosition();
        const pos3 = p3.getPosition();
        const ctx = this.context;
        if (!ctx) {
            return;
        }
        let colorTriangle = Utils_1.ColorUtils.colorToRgb(triangleOptions.color);
        if (!colorTriangle) {
            const linksOptions = p1.particlesOptions.links;
            const linkColor = linksOptions.id !== undefined
                ? container.particles.linksColors[linksOptions.id]
                : container.particles.linksColor;
            if (linkColor === Utils_1.Constants.randomColorValue) {
                colorTriangle = Utils_1.ColorUtils.getRandomRgbColor();
            }
            else if (linkColor === "mid") {
                const sourceColor = p1.getColor();
                const destColor = p2.getColor();
                if (sourceColor && destColor) {
                    colorTriangle = Utils_1.ColorUtils.mix(sourceColor, destColor, p1.size.value, p2.size.value);
                }
                else {
                    const hslColor = sourceColor !== null && sourceColor !== void 0 ? sourceColor : destColor;
                    if (!hslColor) {
                        return;
                    }
                    colorTriangle = Utils_1.ColorUtils.hslToRgb(hslColor);
                }
            }
            else {
                colorTriangle = linkColor;
            }
        }
        const width = (_b = p1.linksWidth) !== null && _b !== void 0 ? _b : container.retina.linksWidth;
        Utils_1.CanvasUtils.drawLinkTriangle(ctx, width, pos1, pos2, pos3, options.backgroundMask.enable, colorTriangle, opacityTriangle);
    }
    drawLinkLine(p1, link) {
        var _a;
        const container = this.container;
        const options = container.options;
        const p2 = link.destination;
        let opacity = link.opacity;
        const pos1 = p1.getPosition();
        const pos2 = p2.getPosition();
        const ctx = this.context;
        if (!ctx) {
            return;
        }
        let colorLine;
        const twinkle = p1.particlesOptions.twinkle.lines;
        if (twinkle.enable) {
            const twinkleFreq = twinkle.frequency;
            const twinkleRgb = Utils_1.ColorUtils.colorToRgb(twinkle.color);
            const twinkling = Math.random() < twinkleFreq;
            if (twinkling && twinkleRgb !== undefined) {
                colorLine = twinkleRgb;
                opacity = twinkle.opacity;
            }
        }
        if (!colorLine) {
            const linksOptions = p1.particlesOptions.links;
            const linkColor = linksOptions.id !== undefined
                ? container.particles.linksColors[linksOptions.id]
                : container.particles.linksColor;
            if (linkColor === Utils_1.Constants.randomColorValue) {
                colorLine = Utils_1.ColorUtils.getRandomRgbColor();
            }
            else if (linkColor === "mid") {
                const sourceColor = p1.getColor();
                const destColor = p2.getColor();
                if (sourceColor && destColor) {
                    colorLine = Utils_1.ColorUtils.mix(sourceColor, destColor, p1.size.value, p2.size.value);
                }
                else {
                    const hslColor = sourceColor !== null && sourceColor !== void 0 ? sourceColor : destColor;
                    if (!hslColor) {
                        return;
                    }
                    colorLine = Utils_1.ColorUtils.hslToRgb(hslColor);
                }
            }
            else {
                colorLine = linkColor;
            }
        }
        const width = (_a = p1.linksWidth) !== null && _a !== void 0 ? _a : container.retina.linksWidth;
        Utils_1.CanvasUtils.drawLinkLine(ctx, width, pos1, pos2, p1.particlesOptions.links.distance, container.canvas.size, p1.particlesOptions.links.warp, options.backgroundMask.enable, colorLine, opacity, p1.particlesOptions.links.shadow);
    }
    drawConnectLine(p1, p2) {
        var _a;
        const lineStyle = this.lineStyle(p1, p2);
        if (!lineStyle) {
            return;
        }
        const ctx = this.context;
        if (!ctx) {
            return;
        }
        const pos1 = p1.getPosition();
        const pos2 = p2.getPosition();
        Utils_1.CanvasUtils.drawConnectLine(ctx, (_a = p1.linksWidth) !== null && _a !== void 0 ? _a : this.container.retina.linksWidth, lineStyle, pos1, pos2);
    }
    drawGrabLine(particle, lineColor, opacity, mousePos) {
        var _a;
        const container = this.container;
        const ctx = container.canvas.context;
        if (!ctx) {
            return;
        }
        const beginPos = particle.getPosition();
        Utils_1.CanvasUtils.drawGrabLine(ctx, (_a = particle.linksWidth) !== null && _a !== void 0 ? _a : container.retina.linksWidth, beginPos, mousePos, lineColor, opacity);
    }
    drawParticle(particle, delta) {
        var _a, _b;
        const pColor = particle.getColor();
        if (pColor === undefined) {
            return;
        }
        const container = this.container;
        const options = container.options;
        const twinkle = particle.particlesOptions.twinkle.particles;
        const twinkleFreq = twinkle.frequency;
        const twinkleRgb = Utils_1.ColorUtils.colorToRgb(twinkle.color);
        const twinkling = twinkle.enable && Math.random() < twinkleFreq;
        const radius = (_a = particle.bubble.radius) !== null && _a !== void 0 ? _a : particle.size.value;
        const opacity = twinkling ? twinkle.opacity : (_b = particle.bubble.opacity) !== null && _b !== void 0 ? _b : particle.opacity.value;
        const infectionStage = particle.infectionStage;
        const infection = options.infection;
        const infectionStages = infection.stages;
        const infectionColor = infectionStage !== undefined ? infectionStages[infectionStage].color : undefined;
        const infectionRgb = Utils_1.ColorUtils.colorToRgb(infectionColor);
        const color = twinkling && twinkleRgb !== undefined ? twinkleRgb : infectionRgb !== null && infectionRgb !== void 0 ? infectionRgb : Utils_1.ColorUtils.hslToRgb(pColor);
        const colorValue = color !== undefined ? Utils_1.ColorUtils.getStyleFromRgb(color, opacity) : undefined;
        if (!this.context || !colorValue) {
            return;
        }
        if (particle.links.length > 0) {
            this.context.save();
            for (const link of particle.links) {
                if (particle.particlesOptions.links.triangles.enable) {
                    const links = particle.links.map((l) => l.destination);
                    const vertices = link.destination.links.filter((t) => links.indexOf(t.destination) >= 0);
                    if (vertices.length) {
                        for (const vertice of vertices) {
                            this.drawLinkTriangle(particle, link, vertice);
                        }
                    }
                }
                this.drawLinkLine(particle, link);
            }
            this.context.restore();
        }
        Utils_1.CanvasUtils.drawParticle(this.container, this.context, particle, delta, colorValue, options.backgroundMask.enable, radius, opacity, particle.particlesOptions.shadow);
    }
    drawPlugin(plugin, delta) {
        if (!this.context) {
            return;
        }
        Utils_1.CanvasUtils.drawPlugin(this.context, plugin, delta);
    }
    paintBase(baseColor) {
        if (this.context) {
            Utils_1.CanvasUtils.paintBase(this.context, this.size, baseColor);
        }
    }
    lineStyle(p1, p2) {
        const container = this.container;
        const options = container.options;
        const connectOptions = options.interactivity.modes.connect;
        if (this.context) {
            return Utils_1.CanvasUtils.gradient(this.context, p1, p2, connectOptions.links.opacity);
        }
    }
    initBackground() {
        const container = this.container;
        const options = container.options;
        const background = options.background;
        const element = this.element;
        if (!element) {
            return;
        }
        const elementStyle = element.style;
        if (background.color) {
            const color = Utils_1.ColorUtils.colorToRgb(background.color);
            if (color) {
                elementStyle.backgroundColor = Utils_1.ColorUtils.getStyleFromRgb(color, background.opacity);
            }
        }
        if (background.image) {
            elementStyle.backgroundImage = background.image;
        }
        if (background.position) {
            elementStyle.backgroundPosition = background.position;
        }
        if (background.repeat) {
            elementStyle.backgroundRepeat = background.repeat;
        }
        if (background.size) {
            elementStyle.backgroundSize = background.size;
        }
    }
}
exports.Canvas = Canvas;
