
var w = 50;
var h = 40;
var scale = 1;

var smoothColors = true;
var algo = "mandelbrot";

var pixelSize = 16;

var vx = -0.7;
var vy = 0;
var zoom = 1.5;
var zoomFactor = 2;
var startit = 30;
var xmin, xmax, ymin, ymax, dx, dy;
var er = 2;
var log2 = 1 / Math.log(2.0);

var fractals = {
	mandelbrot : function(x, y, it, er2) {
		var x0 = x, y0 = y;
		var xx = x*x, yy = y*y;
		var lastxx, lastyy;
		do {
			y = (x+x)*y + y0;
			x = xx - yy + x0;
			yy = y*y;
			xx = x*x;
			if (xx+yy > er2) {
				y = (x+x)*y + y0; // iterate once more for smoother colors
				x = xx - yy + x0;
				yy = y*y;
				xx = x*x;

				break;
			}
		} while(--it)
		return {
			it : it, x : x, y : y, xx : xx, yy : yy
		};
	}
}

function render() {
	var canvas = document.createElement("canvas");
	var ctx = canvas.getContext("2d");
	canvas.width = w * pixelSize;
	canvas.height = h * pixelSize;
	canvas.style.width = canvas.width + "px";
	canvas.style.height = canvas.height + "px";
	canvas.style.border = "1px solid black";

	var time = new Date().getTime();

	var mi = Math.max(startit, Math.round(Math.max(Math.log(zoom),1) * startit));
	var itfac = 1/mi*startit

	xmin = vx - 2/zoom;
	xmax = vx + 2/zoom;
	ymin = vy - 2/zoom;
	ymax = vy + 2/zoom;

	dx = xmax-xmin;
	dy = ymax-ymin;

	var px, py, it;

	var er2 = er*er;

	var fncFrac = fractals[algo];

	var i = (w*h);
	do {
		var offset = (i-1)*4;

		px = ((i-1)%w);
		py = h-(((i-1)/w)|0);

		var res = fncFrac(
			xmin + px/w * dx, 
			ymin + py/h * dy, 
			mi, er2
		)

		it = mi - res.it;

		var mag = smoothColors ? 
				(it * itfac) - (Math.log(Math.log(res.xx+res.yy))) * log2
				: it * itfac;

		var bright = ((res.it==mi) ? 255 : 255 - mag/startit * 255)>>0;

		if (bright < 0) bright = 0;
		if (bright > 255) bright = 255;

		var ix = (px|0);
		var iy = h-((py|0));

		var photoList = photosByBrightness[bright];
		if (!photoList) {
			for (var p=0;p<255;p++) {
				if (photosByBrightness[bright+p]) {
					photoList = photosByBrightness[bright+p];
					break;
				}
				if (photosByBrightness[bright-p]) {
					photoList = photosByBrightness[bright-p];
					break;
				}
			}
		}

		ctx.fillStyle = "rgb("+bright+","+bright+","+bright+")";
		ctx.fillRect(ix*pixelSize, iy*pixelSize, pixelSize, pixelSize);

		if (photoList) {
			var numPhotos = photoList.length;
			if (numPhotos > 1) {
				var photo = photoList[ Math.floor(Math.random()*numPhotos) ]
			} else {
				var photo = photoList[0];
			}
			var img = photo.img;
			ctx.drawImage(img,
				0,0,75,75,
				ix*pixelSize, iy*pixelSize, pixelSize, pixelSize
			);
		}

	} while(--i);

	document.body.appendChild(canvas);
}

