/* http://paulirish.com/2011/requestanimationframe-for-smart-animating/ */
window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame    ||
              window.oRequestAnimationFrame      ||
              window.msRequestAnimationFrame     ||
              function(/* function */ callback, /* DOMElement */ element){
                window.setTimeout(callback, 1000 / 20);
              };
    })();

var funEnabled = false;

function now() {
    return new Date().getTime();
}

function Flash(x, y) {
    this.el = $('<img class="backgroundflash" src="images/flash.png"/>');
    this.el.css('left', (x-10)+'px');
    this.el.css('top', y+'px');
    $('body').append(this.el);

    var that = this;
    this.el.fadeOut(250, function() {
	that.el.detach();
    });
}


function Raindrop(x, y, speedX) {
    this.lastUpdate = now();
    this.fadeUntil = now() + this.ttl;
    this.x = x;
    this.y = y;
    this.speedX = speedX;
    this.speedY = 0;

    this.el = $('<p class="backgroundraindrop"></p>');
    this.el.text(''+Math.floor(Math.random() * 2));
    var rotation = 45 - (Math.random() * 90);
    this.el.css('-webkit-transform', 'rotate('+rotation+'deg)');
    this.el.css('-moz-transform', 'rotate('+rotation+'deg)');
    this.el.css('-o-transform', 'rotate('+rotation+'deg)');
    this.el.css('-ms-transform', 'rotate('+rotation+'deg)');
    this.el.css('transform', 'rotate('+rotation+'deg)');
    $('body').append(this.el);
    this.render();
}

Raindrop.prototype.ttl = 3000;

Raindrop.prototype.render = function() {
    var t = now();
    var d = (t - this.lastUpdate) / 1000;
    this.x += this.speedX * d;
    this.speedY += 23 * d;  /* gravity */
    this.y += this.speedY * d;

    this.el.css('left', this.x+'px');
    this.el.css('top', this.y+'px');
    this.el.css('opacity', (this.fadeUntil - t) / this.ttl);

    this.lastUpdate = t;

    var that = this;
    requestAnimFrame(function() {
	if (now() > that.fadeUntil)
	    that.el.detach();
	else
	    that.render();
    }, this.el[0]);
};


function Cloud() {
    this.lastUpdate = now();
    this.speedX = 10 + Math.random() * 50;
    if (Math.random() < 0.5) {
	this.x = -80;
    } else {
	this.speedX *= -1;
	this.x = screen.width;
    }
    this.y = Math.floor(Math.random() * screen.height);
    this.el = $('<img class="backgroundcloud" src="images/cloud.png"/>');
    $('body').append(this.el);

    var that = this;
    this.el.mousemove(function(ev) {
	if (ev.offsetX < 36)
	    that.speedX += 10;
	else
	    that.speedX -= 10;
    });
}

Cloud.prototype.update = function() {
    this.x += this.speedX * (now() - this.lastUpdate) / 1000;
    this.lastUpdate = now();

    this.el.css('left', this.x + 'px');
    this.el.css('top', this.y + 'px');

    if (this.isDone())
	this.el.detach();
    else if (this.raining && Math.random() < 0.1)
	new Raindrop(this.x + 8 + Math.random() * 54, this.y + 22, this.speedX);
};

Cloud.prototype.isDone = function() {
    return (this.x < -80) || (this.x > screen.width);
};


var clouds = [];
function stepClouds() {
    if (clouds.length < 12 && Math.random() < 0.05)
	clouds.push(new Cloud());

    clouds = clouds.filter(function(cloud) {
	cloud.update();
	return !cloud.isDone();
    });
    for(var i = 1; i < clouds.length; i++)
	for(var j = 0; j < i; j++) {
	    var cloud1 = clouds[i];
	    var cloud2 = clouds[j];

	    if (cloud1 !== cloud2 &&
		cloud1.x > cloud2.x - 72 &&
		cloud1.x < cloud2.x + 72 &&
		cloud1.y > cloud2.y - 40 &&
		cloud1.y < cloud2.y + 40 &&
	        Math.random() < 0.01) {

		if (cloud1.y < cloud2.y) {
		    new Flash(cloud1.x + 36, cloud1.y + 38);
		    cloud2.raining = true;
		} else {
		    new Flash(cloud2.x + 36, cloud2.y + 38);
		    cloud1.raining = true;
		}
	    }
	}

    if (funEnabled) {
	requestAnimFrame(stepClouds, 'body');
    } else {
	clouds.forEach(function(cloud) {
	    cloud.el.detach();
	});
	clouds = [];
    }
}

$(document).ready(function() {
    $('#cloudy-sun').click(function() {
	funEnabled = !funEnabled;
	if (funEnabled) {
	    var solar = $('<div id="solar"> </div>');
	    solar.hide();
	    $('#cloudy').append(solar);
	    $('#solar').fadeIn(1000);
	    setTimeout(stepClouds, 100);
	} else {
	    $('#solar').detach();
	}
    });
});

