import {
    createRainbowColors, docReady, pointDistance, randomInteger
} from "canvas-common";

var imageData = {};
var ctx = {};
var canvas = {};


var config = {
    size: {
        width: window.innerWidth,
        height: window.innerHeight
    },
    buBbles: {
        tileSize: 100,
        growFactorDivider: 5,
        radiusFactor: 1,
        bubbleChance: 0.5
    }
};

var rainbow = createRainbowColors(1/16);
// max distance from top left corner
var max = Math.sqrt(Math.pow(config.size.width + config.buBbles.tileSize, 2) + Math.pow(config.size.height + config.buBbles.tileSize, 2));
var startOffset = (rainbow.length * Math.random()) << 0;

function getRandomPoint(x, y) {
    var distance = Math.sqrt(x * x + y * y);
    var index = ((startOffset + distance / max * 100) << 0) % rainbow.length;
    var color = rainbow[index];
    color.a = 255;
    return {
        x: x + Math.random() * config.buBbles.tileSize,
        y: y + Math.random() * config.buBbles.tileSize,
        factor: Math.random() / config.buBbles.growFactorDivider,
        radius: Math.random() * config.buBbles.radiusFactor,
        color: color
    };
}

function getTilePoints(){
    var points = [];
    for(var x = 0; x < config.size.width; x += config.buBbles.tileSize){
        for(var y = 0; y < config.size.height; y += config.buBbles.tileSize){
            points.push(getRandomPoint(x, y));
        }
    }
    return points;
}

docReady(function () {
    canvas = document.getElementById('canvas')
    ctx = canvas.getContext("2d");
    canvas.width = config.size.width;
    canvas.height = config.size.height;

    var pointsOfInterest = getTilePoints();
    removeIntersecting(pointsOfInterest);
    updateCanvas(pointsOfInterest);
});

function grow(points){
    for(var i = 0; i < points.length; i++){
        var currentPoint = points[i];
        if(!intersectsAnotherPoint(currentPoint, points)){
            currentPoint.radius += currentPoint.factor;
        } else if(!currentPoint.spawnedAnother){
            currentPoint.spawnedAnother = true;
            currentPoint.radius += currentPoint.factor;
            addAnotherRandomPoint(points);
        }
    }

    if(Math.random() < config.buBbles.bubbleChance){
        addAnotherRandomPoint(points);
    }
}

function addAnotherRandomPoint(points){
    var probablePoint = getRandomPoint(randomInteger(config.size.width), randomInteger(config.size.height));
    if(!intersectsAnotherPoint(probablePoint, points)){
        points.push(probablePoint);
    }
}

function intersectsAnotherPoint(point, points){
    var intersects = false;
    points.forEach(function(pointToLookAt){
        if(intersects) return;
        var pointDist = pointDistance(point, pointToLookAt);
        if(pointDist > 0 && pointDist < (point.radius + pointToLookAt.radius)){
            intersects = true;
        }
    });

    return intersects;
}

function updateCanvas(points){
    ctx.clearRect(0, 0, config.size.width, config.size.height);
    grow(points);
    paintPoints(points, function(){
        requestAnimationFrame(function(){
            updateCanvas(points);
        });
    });

}


function removeIntersecting(points){
    for(var i = 0; i < points.length; ){
        if(intersectsAnotherPoint(points[i], points)){
            points.splice(i, 1);
        } else {
            i++;
        }
    }
}


function paintPoints(points, cb){
    for(var i = 0; i < points.length; i++){
        var point = points[i];
        if(point.radius < 0) continue;
        ctx.beginPath();
        ctx.fillStyle = point.color.styleRGB;
        ctx.arc(point.x, point.y, point.radius, 0, 2 * Math.PI);
        ctx.fill();
    }
    cb();
}




