(function ($) {
var Color = net.brehaut.Color;
var min = Math.min, max = Math.max, round = Math.round, random = Math.random,
    sin = Math.sin, pow = Math.pow;

var numCircles = 100;

function clamp (bottom, top, n) {
	return max(min(top, n), bottom);
}

// weighted towards the middle
function cubic_random () {
	return 3.5 * pow((random()-0.5), 3) + 0.5;
}

// weighted towards 1
function sin_random () {
	return sin(random()* Math.PI);
}

// weighted towards zero
function asin_random () {
	return 1.0 - sin(random()* Math.PI);
}

function add_alpha (c, alpha) {
	var rgb = c.toRGB();
	return "rgba("+ round(rgb.getRed() * 256) +","+
	                round(rgb.getGreen() * 256) +","+
	                round(rgb.getBlue() * 256) +","+
	                alpha +")";
}

function generateCircleData (n) {
	circles = [];
	for (var i=0; i<n; i++) {
		var x,y,r, hueShift, valShift, satShift;
		x = (random() * 4) - 1.5;
		y = (random() * 4) - 1.5;
		r = random() * 1.0;
		hueShift = (cubic_random() * 40) - 20;
		satShift = (cubic_random() / 15) - 0.0333;

		circles.push({x: x, y: y, r: r, hueShift: hueShift, satShift: satShift});
	}
	return circles;
}
var circleData = generateCircleData(numCircles);

function setupInitialBackgroundValues () {
	var bodyColor = $('body').css('background-color');
	var color = Color(bodyColor).toHSV();

	return {primary: color,
			secondary: null,
			makeSecondary: function (c) {
				var schemeColors = c.analogousScheme().slice(1);
				this.secondary = schemeColors[Math.floor(Math.random()*schemeColors.length)];
				return this.secondary;
			}};
}
var colors = null;

function normalise(length, by) {
	return length * by;
}

function drawBackground (ctx, width, height) {
	var avgSize = (width + height) / 2;
	var color = colors.primary;

	var grad = ctx.createLinearGradient(0,0,width,0);
	grad.addColorStop(0, color.setSaturation(0.1).toString());
	grad.addColorStop(1, color.setSaturation(0.7).toString());


	ctx.fillStyle = grad;
	ctx.fillRect(0,0, width, height);

	var c;
	for (var i=0; i<circleData.length; i++) {
		c = circleData[i];

		color = color.setHue(color.getHue() + c.hueShift);
		color = color.setSaturation(clamp(0, 0.45, color.getSaturation() + c.satShift));

		ctx.fillStyle = add_alpha(color, 0.19);

		ctx.beginPath();
		ctx.arc(normalise(c.x, width), normalise(c.y, height), normalise(c.r, avgSize), 0, Math.PI * 2, false);
		ctx.fill();
	}
}

function fixFooter () {
	var w = $(window).width();
	if (w < 980) {
		$('#footer').css('position', 'absolute');
	} else {
		$('#footer').css('position', 'fixed');
		$('#footer').width(w-600);
	}
}

$(function () {

	(function () {
    	var contentDiv = $('#content');
    	var padding = (1 * contentDiv.css('padding-top').replace(/[^0-9\.]+/, '')) + (1 * contentDiv.css('padding-bottom').replace(/[^0-9\.]+/, ''));
    	var contentHeight = contentDiv.height() + padding;

    	if (contentHeight < $(window).height()) {
    	    contentDiv.height($(window).height() - padding);
    	}
	})();


	var windowWidth = $(window).width(),
	    windowHeight = $(window).height();
	$('body').prepend($(document.createElement('canvas')).attr({id:"background-canvas", width: windowWidth, height: windowHeight}));
	var canvas = $('#background-canvas');
	canvas.get(0).width = $(window).width();
	canvas.get(0).height = $(window).height();

	var hasCanvas = ('undefined' != typeof(canvas.get(0).getContext));

	// canvas/background only from here on
	if (!hasCanvas) { return; }

	colors = setupInitialBackgroundValues();

	function doDrawBackground (fade) {
		if (!hasCanvas) return null;

        if (fade) {
            var oldCanvas = canvas;
            canvas = oldCanvas.clone();
            canvas.css({zIndex: -2});
            $('body').prepend(canvas);
        }

		var canvasHeight = canvas.attr('height', $(window).height()).height();
		var canvasWidth = canvas.attr('width', $(window).width()).width();
		fixFooter();

		drawBackground(canvas.get(0).getContext('2d'), canvasWidth, canvasHeight);

		if (fade) {
    		oldCanvas.fadeOut(400, function () {
    		    canvas.css({zIndex: -1});
    		    $(this).remove();
    		});
		}
		return false;
	}


	var bgLink = $("<a href='#' id='new-background-link' title='Generate a new background' accesskey='r'>Regenerate</a>");
	bgLink.click(function () {
		circleData = generateCircleData(numCircles);
		colors = setupInitialBackgroundValues();
		doDrawBackground(true);
		return false;
	});
	$('body').append(bgLink);

	doDrawBackground();
	var resizeTimer = null;
	$(window).resize(function () {
		window.clearTimeout(resizeTimer);
		resizeTimer = window.setTimeout(doDrawBackground, 300);
	});

	var checkCanvas = function () {
		var top = $(window).scrollTop();
		if (canvas.offset().top != top) {
			canvas.height($('body').height());
		}
		if (top != 0) {
			$(window).unbind('scroll', checkCanvas);
		}
	};
	$(window).scroll(checkCanvas);

});


})(jQuery);

