var Confetti = (function () {
    // Globals
    var canvas;
    var ctx;
    var W;
    var H;
    var mp = 250; // increased density
    var particles = [];
    var angle = 0;
    var tile = 0;
    var animationId;
    var colors = [[0, 210, 255], [0, 230, 118], [255, 61, 0], [255, 0, 85], [255, 196, 0]];

    function RandomFromTo(from, to) {
        return Math.floor(Math.random() * (to - from + 1) + from);
    }

    function confettiParticle() {
        this.x = Math.random() * W; // x-coordinate
        this.y = Math.random() * H - H; // y-coordinate
        this.r = RandomFromTo(10, 30); // radius;
        this.d = Math.random() * mp + 10; // density;
        this.color = colors[Math.floor(Math.random() * colors.length)];
        this.tilt = Math.floor(Math.random() * 10) - 10;
        this.tiltAngleIncremental = Math.random() * 0.07 + 0.05;
        this.tiltAngle = 0;

        this.draw = function () {
            ctx.beginPath();
            ctx.lineWidth = this.r / 2;
            ctx.strokeStyle = "rgba(" + this.color[0] + "," + this.color[1] + "," + this.color[2] + ",0.9)";
            ctx.moveTo(this.x + this.tilt + (this.r / 4), this.y);
            ctx.lineTo(this.x + this.tilt, this.y + this.tilt + (this.r / 4));
            return ctx.stroke();
        };
    }

    function update() {
        ctx.clearRect(0, 0, W, H);
        for (var i = 0; i < mp; i++) {
            var p = particles[i];
            angle += 0.01;
            p.tiltAngle += p.tiltAngleIncremental;
            p.y += (Math.cos(angle + p.d) + 3 + p.r / 2) / 2;
            p.x += Math.sin(angle);
            p.tilt = Math.sin(p.tiltAngle) * 15;

            if (p.x > W + 5 || p.x < -5 || p.y > H) {
                if (i % 5 > 0 || i % 2 == 0) //66.67% of the flakes
                {
                    particles[i] = new confettiParticle();
                    particles[i].y = -10;
                    particles[i].x = Math.random() * W;
                }
            }
            p.draw();
        }
        animationId = requestAnimationFrame(update);
    }

    function init() {
        // Create canvas if not exists
        if (!document.getElementById('confetti-canvas')) {
            canvas = document.createElement('canvas');
            canvas.id = 'confetti-canvas';
            canvas.style.position = 'fixed';
            canvas.style.top = '0';
            canvas.style.left = '0';
            canvas.style.width = '100%';
            canvas.style.height = '100%';
            canvas.style.zIndex = '25000'; // Above activation overlay
            canvas.style.pointerEvents = 'none';
            // Start visible
            canvas.style.opacity = '1';
            canvas.style.transition = 'opacity 1s ease-out';
            document.body.appendChild(canvas);
        } else {
            canvas = document.getElementById('confetti-canvas');
            canvas.style.opacity = '1';
            canvas.style.display = 'block';
        }

        ctx = canvas.getContext('2d');
        W = window.innerWidth;
        H = window.innerHeight;
        canvas.width = W;
        canvas.height = H;

        particles = [];
        for (var i = 0; i < mp; i++) {
            particles.push(new confettiParticle());
        }

        update();
    }

    function stop() {
        if (canvas) {
            // Fade out
            canvas.style.opacity = '0';
            // Wait for transition end then remove
            setTimeout(function () {
                if (animationId) cancelAnimationFrame(animationId);
                ctx.clearRect(0, 0, W, H);
                canvas.style.display = 'none'; // Keep element but hide
            }, 1000);
        }
    }

    return {
        start: function (duration) {
            init();
            if (duration) {
                setTimeout(stop, duration);
            }
        },
        stop: stop
    };
})();
