(function(){function o(){g.clearRect(0,0,a,a);var b=g.createRadialGradient(0,0,0,0,0,a),c=[e(i),e(i),e(i)];b.addColorStop(0,"rgb("+c.join(",")+")");c=[e(i),e(i),e(i)];b.addColorStop(1,"rgb("+c.join(",")+")");g.fillStyle=b;g.fillRect(0,0,a,a);l=g.getImageData(0,0,a,a).data;m=g.getImageData(0,0,a,a)}function e(b){return Math.round(Math.random()*b)}var a=200,i=255,h=[],k=[],f,g,l,m,n;f=document.body.children[0];f.width=f.height=a;f.onclick=function(b){if(b.shiftKey)o();else h[b.clientY*a+b.clientX]=
-900};g=f.getContext("2d");o();f=l.length/4;do{h[f]=0;k[f]=0}while(--f);n=h.length-a;setInterval(function(){var b=k,c=h,d=n;do{if(d==a)break;var j=d%a;if(!(!j||j==199)){c[d]=(b[d-1]+b[d+1]+b[d-a]+b[d+a]>>1)-c[d];c[d]-=c[d]>>5}}while(--d);b=h;h=k;k=b;b=h;c=n;do{if(c==a)break;d=c%a;if(!(!d||d==199)){d=c+(b[c-1]-b[c+1])+(b[c-a]-b[c+a])*a;if(d>0&&d<b.length){j=4;do m.data[c*4+j]=l[d*4+j];while(--j)}}}while(--c);try{g.putImageData(m,0,0)}catch(p){}},80);setInterval(function(){h[e(a)*a+e(a)]+=e(-900)},
600)})();
          /**
Generates procedural water ripple effects on top of a randomly generated gradient background.
Click on the canvas to generate a new wave, hold Shift + Click to change the gradient background.
There is an issue with the Firefox canvas implementation that is a known bug (https://bugzilla.mozilla.org/show_bug.cgi?id=498826)
There is no way around this issue at this time, with a test case to confirm this:
http://philip.html5.org/tests/canvas/suite/tests/index.2d.imageData.put.dirty.html
1.0
  * Original Release
1.1
  * Fix for Firefox
1.2
  * Further exception catch for Firefox canvas bug (https://bugzilla.mozilla.org/show_bug.cgi?id=498826)
  * Added onclick to canvas to randomly change gradient background
  * Savage Optimisation
1.3
  * Removed onready stuff
  * Removed setter methods on canvas for size
  * Added handler for click to create new ripple, Ctrl + Click to change background
  * Fred Savage Optimisation
1.4
  * Changed handler from Ctrl to Shift for better Mac support
1.5
  * Savage Garden Optimisation, final version for submission
Some work based on the origional algorithim from http://bit.ly/bmDo1Q, optimised
for 1Kb
*/
(function() {
    var size = 200,
    check = 199,
    color = 255,
    wavemod = -900,
    buffer1 = [],
    buffer2 = [],
    cvs,
    ctx,
    initData,
    renderData,
    j;
    function genGradient() {
        ctx.clearRect(0, 0, size, size);
        var gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, size);
        var c1 = [mathRand(color), mathRand(color), mathRand(color)];
        gradient.addColorStop(0, 'rgb(' + c1.join(',') + ')');
        var c2 = [mathRand(color), mathRand(color), mathRand(color)];
        gradient.addColorStop(1, 'rgb(' + c2.join(',') + ')');
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, size, size);
        initData = ctx.getImageData(0, 0, size, size).data;
        renderData = ctx.getImageData(0, 0, size, size);
    }
    function processWater(source, dest) {
        var i = j
        do {
            if (i == size) break;
            var xi = i % size;
            if (!xi || xi == check) continue;
            dest[i] = (
            ((source[i - 1] +
            source[i + 1] +
            source[i - size] +
            source[i + size]) >> 1)) - dest[i];
            dest[i] -= (dest[i] >> 5);
        }
        while (--i);
    }
    function texture(buffer) {
        var i = j
        do {
            if (i == size) break;
            var xi = i % size;
            if (!xi || xi == check) continue;
            var offset = i + (buffer[i - 1] - buffer[i + 1]) + (buffer[i - size] - buffer[i + size]) * size;
            if (offset > 0 && offset < buffer.length) {
              var x = 4;
              do {
                renderData.data[i * 4 + x] = initData[offset * 4 + x];  
              }
              while(--x);
            }
        }
        while (--i);
        try {
            ctx.putImageData(renderData, 0, 0);
        } catch(e) {
            return;
            // This is to catch the occasional error thrown up in Firefox
            // Known Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=498826
            // Canvas test suite to confirm: http://philip.html5.org/tests/canvas/suite/tests/index.2d.imageData.put.dirty.html
        }
    }
    function mathRand(modifier) {
        return Math.round(Math.random() * modifier);
    }
    function clickHandler(e) {
        (e.shiftKey) ? genGradient() : create(e);
    }
    function create(e) {
        var eX = e.clientX;
        var eY = e.clientY;
        buffer1[eY * size + eX] = wavemod;
    }
    cvs = document.body.children[0];
    cvs.width = cvs.height = size;
    cvs.onclick = clickHandler;
    ctx = cvs.getContext('2d');
    genGradient();
    var i = initData.length / 4;
    do {
        buffer1[i] = 0;
        buffer2[i] = 0;
    }
    while (--i);
    j = buffer1.length - size
    setInterval(function() {
        processWater(buffer2, buffer1);
        var tmp = buffer1;
        buffer1 = buffer2;
        buffer2 = tmp;
        texture(buffer1);
    },
    80);
    setInterval(function() {
        buffer1[mathRand(size) * size + mathRand(size)] += mathRand(wavemod);
    },
    600);
})();