var drawMandelSet = function drawMandelSet(){
    var mandelPanel = $('body');

    var width = mandelPanel.innerWidth();
    var height = mandelPanel.innerHeight();
 
    var range = [{
        x: -2,
        y: -1.4
    }, {
        x: 5,
        y: 1.4
    }];
    
    $('canvas#fractal').height(height + 100);
    $('canvas#fractal').width(width  - 50);
    var left = 0;
    var top = 0;
    
    var canvas = $("canvas#fractal")[0];
    var ctx = canvas.getContext("2d");
    var params = {
        range: range,
        startx: 0.0,
        starty: 0.0,
        width: width,
        height: height
    };
    var y_array = [];

    var worker = {
        params: params,
        
        draw: function draw(data){
            data.forEach(function d(point){
                if (this.axis.x[point.drawLoc.x] === undefined) {
                    this.axis.x[point.drawLoc.x] = point.point.x;
                }
                if (this.axis.y[height - point.drawLoc.y] === undefined) {
                    this.axis.y[height - point.drawLoc.y] = point.point.y;
                }
                
                ctx.fillStyle = pickColor(point.escapeValue);
                ctx.fillRect(point.drawLoc.x + 0.5, 
                             height - point.drawLoc.y + 0.5, 1, 1);
            }, this);
        },
        
        axis: {
            x: [],
            y: [],
            find: function(x, y){
                return new Complex(this.x[x], this.y[y]);
            },
            
            reset: function(){
                this.x = [], this.y = [];
            }
        },
        myWorker: false,
        
        run: function startWorker(params){
            this.myWorker = new Worker("js/worker.js");
            
            var that = this;
            this.myWorker.postMessage(JSON.stringify(params));
            
            this.myWorker.onmessage = function(event){
            
                var data = JSON.parse(event.data);
                if (data.type === 'draw') {
                    that.draw(JSON.parse(data.data));
                }
                else 
                    if (event.data.type === 'log') {
                        console.info(event);
                    }
          };
        }
    };
    
    worker.run(params);
    return worker;
};

$(document).ready(drawMandelSet);

Function.prototype.createDelegate = function createDelegate(scope){
    var fn = this;
    return function(){
        fn.call(scope, arguments);
    };
};

function pickColor(escapeValue){
    if (escapeValue === Complex.prototype.max_iteration) {
        return "black";
    }
    var tone = 255 - escapeValue * 10; 
    var colorCss = "rgb({r},{g},{b})".populate({
        r: tone,
        g: tone,
        b: tone
    });
    return colorCss;
}

String.prototype.populate = function populate(params) {
    var str = this.replace(/\{\w+\}/g, function stringFormatInner(word) {
        return params[word.substr(1, word.length - 2)];
    });
    return str;
};