#!/usr/bin/env node
var request = require('request');
var funkit = require('funkit');

var interpreter = require('../public/js/interpreter');

main();

function main() {
    var delay = 20;

    interpreter(global, {x: 8, y: 8, z: 8}, {
        execute: function(init, cb) {
            animate(init, cb);
        },
        code: function() {
            return 'function effect(cube) {\n' +
                'cube().off();\n' +
                'cube({z: 0}).map(function(led) {\n' +
                    'led.z = 0.25 * (2 + math.sin(led.x / 2 + ticks / 300) + math.sin(led.y / 2 + ticks / 400)) * cube.z;\n' +
                    'return led;\n' +
                '}).on();\n' +
            '}';
        },
        ok: function() {},
        error: function() {},
        playing: function() {
            return {};
        }
    });

    function animate(init, cb) {
        var res = cb(init.ticks);

        if(res.ok) execute(res.ops);

        setTimeout(animate.bind(undefined, init, cb), delay);
    }
}

function execute(ops) {
    ops.forEach(function(op) {
        if(!op) return;

        var o = {
            on: function() {
                renderFrame(op.coords, op.intensity);
            },
            off: function() {
                renderFrame(op.coords, 0);
            }
        }[op.op]();
    });
}

function renderFrame(coords, alpha) {
    var i, len, coord;
    var data = setAll(0);
    var dims = {x: 8, y: 8, z: 8};

    for(i = 0, len = coords.length; i < len; i++) {
        coord = coords[i];

        data[parseInt(coord.x, 10) + parseInt(coord.y, 10) * dims.x * dims.y + parseInt(coord.z, 10) * dims.z] = alpha;
    }

    putData(data);
}

function putData(data) {
    var uri = 'http://84.251.8.171:8081/frame';

    request({
        method: 'PUT',
        uri: uri,
        json: data
    }, function(err, res, d) {
        if(err) throw err;
    });
}

function setAll(val) {
    var amount = 512;

    return funkit.functional.map(function(v) {
        return val;
    }, funkit.math.range(amount));
}

@@ -167,29 +167,8 @@
 ) %7B%0A
-    var delay = 20;%0A%0A
     
@@ -915,31 +915,10 @@
 .ops
-);%0A%0A        setTimeout(
+, 
 anim
@@ -950,15 +950,8 @@
  cb)
-, delay
 );%0A 
@@ -978,16 +978,20 @@
 cute(ops
+, cb
 ) %7B%0A    
@@ -1140,16 +1140,20 @@
 ntensity
+, cb
 );%0A     
@@ -1232,16 +1232,20 @@
 oords, 0
+, cb
 );%0A     
@@ -1318,16 +1318,20 @@
 s, alpha
+, cb
 ) %7B%0A    
@@ -1634,16 +1634,20 @@
 ata(data
+, cb
 );%0A%7D%0A%0Afu
@@ -1665,16 +1665,20 @@
 ata(data
+, cb
 ) %7B%0A    
@@ -1853,16 +1853,31 @@
 row err;
+%0A%0A        cb();
 %0A    %7D);

Send a new frame on OK