var text = [
     "Is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain?"
    ,"Occasionally circumstances occur in which toil and pain can procure some great pleasure."
    ,"But who has any right to find fault with a person who chooses to enjoy a pleasure, or one who avoids a pain that produces no pleasure?"
    ,"Blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue."
    ,"Equal blame belongs to those who fail in their duty through weakness of will,"
    ,"which is the same as through shrinking from toil and pain."
];


function getTextWord(animation, textSection) {
    var wordArray = text[textSection];
    var progress = Utils.calculateProgress(animation.start, animation.duration);
    return wordArray[Math.floor(wordArray.length*progress)];
}

var textPositions;

function getTextWordPosition(animation) {
    if (textPositions[animation.iter] === void null) {
        textPositions[animation.iter] = {
            "x":getScreenWidth()*Math.random(),
            "y":getScreenHeight()*Math.random()
        };
    }

    return textPositions[animation.iter];
}

Demo.prototype.addTextWriter = function(start, duration, layer, fboName, textSection)
{

    if (textPositions === void null) {
        textPositions = new Array(text.length);
        for(var i = 0; i < text.length; i++) {
            text[i] = text[i].split(/(\s+)/);
            textPositions[i] = void null;
        }
    }

    //return;

    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"begin"}
    }]);

    var textScale = 4;
    for(var i = 0; i < 10; i++) {
        this.loader.addAnimation([
        {
             "start": start, "duration": 10
            ,"layer": layer
            ,"text":{"name":"data/DroidSerif-Regular.ttf","string":"{return getTextWord(animation, "+textSection+");}"}
            //,"layer": 100, "text":{"name":"arialbd.ttf","string":scroller}
            ,"scale": [
                  {"uniform2d":1+textScale*Math.random()}
            ]
            ,"position":[
                {"iter": i, "x":"{return getTextWordPosition(animation).x;}","y":"{return getTextWordPosition(animation).y;}"}]
            ,"color":[{"a":"{return (1+Math.sin(getSceneTimeFromStart()*5))/2*255}"}]
        }]);
    }

    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"unbind"}
    }]);
}

Demo.prototype.addTextFlicker = function(start, duration, layer, textSection) {
    this.addTextWriter(start, duration, 0, "textWriterFbo", textSection);
    this.loader.addAnimation([{
         "start": start, "duration": duration, "layer": layer
        ,"image": "textWriterFbo.color.fbo"
    }]);
}

Demo.prototype.addTileTunnel = function(start, duration, layer, fboName)
{
    this.loader.addAnimation([
    { 
         "start": start, "duration": duration
        ,"layer": layer
        ,"fbo":{"name":"feedbackFbo","action":"begin"}
    }]);
    var colorFade = 255;
    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "feedbackFbo2.color.fbo"
        ,"angle": [{"degreesZ":"{return 10*Math.sin(getSceneTimeFromStart());}"}]
        ,"scale": [{"uniform2d":1.3}]
        ,"color": [{"r":colorFade,"g":colorFade,"b":colorFade}]
        ,"shader":{"name":"data/noise.fs"}
        ,"layer": layer
    }]);

    /*this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/illuminati.png"
        //,"image": "data/hand_1.png"
        ,"angle": [{},{"duration":30,"degreesZ":360*4}]
        ,"scale": [{"uniform2d":0.7}]
        ,"layer": layer
        //,"shader":{"name":"data/noise.fs"}
    }]);*/
    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/satellite_point.png"
        ,"layer": layer
        ,"color":[{"a":"{return getSignalColor(animation);}"}]
        //,"color":[{"r":"{return getSignalColor(animation);}","g":"{return getSignalColor(animation);}","b":"{return getSignalColor(animation);}"}]
    }]);

    this.loader.addAnimation([{
         "start": start, "duration": duration
        ,"layer": layer
        ,"initFunction": "{initTunnel(animation);}"
        ,"deinitFunction": "{deinitTunnel(animation);}"
        ,"runFunction": "{drawTunnel(animation);}"
    }]);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"layer": layer
        ,"fbo":{"name":"feedbackFbo","action":"unbind"}
    }]);
    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer+1
        ,"fbo":{"name":fboName,"action":"begin"}
    }]);
    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "feedbackFbo.color.fbo"
        ,"passToFbo": {name:"feedbackFbo2"}
        ,"scale": [{"uniform2d":1.0}]
        ,"layer": layer+1
    }]);
    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "feedbackFbo.color.fbo"
        ,"layer": layer+1
    }]);

    this.addTextFlicker(start+5,10,layer+1,0);

    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer+1
        ,"fbo":{"name":fboName,"action":"end"}
    }]);

}

var tunnelMesh = void null;
var tunnelLineMesh = void null;
var tunnelMeshTexture = void null;
function initTunnel(animation) {
    tunnelMesh = meshNew();
    tunnelLineMesh = meshNew();
    if (tunnelMesh.ptr === void null || tunnelLineMesh.ptr === void null) {
        loggerFatal("Could not initialize Mesh");
    }

    tunnelMeshTexture = imageLoadImage("data/blinds.png");
    meshMaterialSetTexture(tunnelMesh.ptr, tunnelMeshTexture.ptr, 0);

    var precision = 24;

    meshSetFaceDrawType(tunnelMesh.ptr, TRIANGLES);

    for(var j = 0; j < 160; j++) {
        var z1 = -j * 3;
        var z2 = z1-(2+Math.random()*2);
        for (var i=0; i < precision; i+=Math.floor(Math.random()*8))
        {
            var radius = 1.0 + Math.random()*5;
            var angle = (i+precision)*2*Math.PI/precision;
            var x1 = Math.cos(angle) * radius;
            var y1 = Math.sin(angle) * radius;
            angle = ((i+1)+precision)*2*Math.PI/precision;
            var x2 = Math.cos(angle) * radius;
            var y2 = Math.sin(angle) * radius;

            var uMin = 0.0;
            var uMax = 1.0;
            var vMin = 0.0;
            var vMax = 1.0;

            meshAddTexCoord(tunnelMesh.ptr, uMin, vMax);
            meshAddVertex(tunnelMesh.ptr, x1,y1,z2);
            meshAddTexCoord(tunnelMesh.ptr, uMax, vMax);
            meshAddVertex(tunnelMesh.ptr, x2,y2,z2);
            meshAddTexCoord(tunnelMesh.ptr, uMin, vMin);
            meshAddVertex(tunnelMesh.ptr, x1,y1,z1);

            meshAddTexCoord(tunnelMesh.ptr, uMin, vMin);
            meshAddVertex(tunnelMesh.ptr, x1,y1,z1);
            meshAddTexCoord(tunnelMesh.ptr, uMax, vMax);
            meshAddVertex(tunnelMesh.ptr, x2,y2,z2);
            meshAddTexCoord(tunnelMesh.ptr, uMax, vMin);
            meshAddVertex(tunnelMesh.ptr, x2,y2,z1);
        }
    }

    meshGenerate(tunnelMesh.ptr);

    //glLineWidth(10);
    var lineMax = 480;
    meshSetFaceDrawType(tunnelLineMesh.ptr, LINE_STRIP);
    for(var i = 0; i < lineMax; i++) {
        var x = Math.cos(i/100*22)*2;
        var y = Math.sin(i/100*20)*2;
        var z = -i
        meshAddVertex(tunnelLineMesh.ptr, x,y,z);
    }
    for(var i = 0; i < lineMax; i++) {
        var x = Math.sin(i/100*20)*2;
        var y = Math.cos(i/100*10)*2;
        var z = -i
        meshAddVertex(tunnelLineMesh.ptr, x,y,z);
    }
    for(var i = 0; i < lineMax; i++) {
        var x = Math.sin(i/100*15)*2;
        var y = Math.cos(i/100*30)*2;
        var z = -i
        meshAddVertex(tunnelLineMesh.ptr, x,y,z);
    }
    for(var i = 0; i < lineMax; i++) {
        var x = Math.sin(i/100*10)*3;
        var y = Math.cos(i/100*10)*3;
        var z = -i
        meshAddVertex(tunnelLineMesh.ptr, x,y,z);
    }
    meshGenerate(tunnelLineMesh.ptr);

}

function deinitTunnel(animation) {
    meshDelete(tunnelMesh.ptr);
    meshDelete(tunnelLineMesh.ptr);
    texturedQuadDeinit(tunnelMeshTexture.ptr);
}

function drawTunnel(animation) {
    glPushMatrix();
    perspective2dEnd();
        
    //glTranslatef(0,0,-200 * ((getSceneStartTime()/animation.duration)));
    //glTranslatef(0,0,-0);
    glTranslatef(-0.5,0,-20 + 20 * getSceneTimeFromStart()*0.5);
    glRotatef(getSceneTimeFromStart()*20,0,0,1);
    meshDraw(tunnelMesh.ptr);
    glColor4f(1,1,1,(1+Math.sin(getSceneTimeFromStart()*70))/2)
    meshDraw(tunnelLineMesh.ptr);

    glPopMatrix();
}

var sphereMesh = void null;
function initSphere(animation) {
    sphereMesh = meshNew();

    var precision = 30;

    meshSetFaceDrawType(sphereMesh.ptr, TRIANGLE_STRIP);

    for (var ring=0; ring < 10; ring++) {
        var radius = 1+ring;

        for (var i=0; i <= precision; i++)
        {
            var angle = (i+precision)*2*Math.PI/precision;
            var x = Math.cos(angle) * radius;
            var y = Math.sin(angle) * radius;
            var z = -1;
            meshAddVertex(sphereMesh.ptr, x,y,z);
        }
    }

    meshGenerate(sphereMesh.ptr);
}

function deinitSphere(animation) {
    meshDelete(sphereMesh.ptr);
}

function drawSphere(animation) {
    glPushMatrix();
    perspective2dEnd();
        
    glTranslatef(0,0,-20);
    //glRotatef(getSceneTimeFromStart()*20,0,0,1);
    meshDraw(sphereMesh.ptr);

    glPopMatrix();
}

Demo.prototype.addBeacon = function(start, duration, layer, fboName)
{
    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"begin"}
    }]);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"layer": layer
        ,"image": "data/_embedded/defaultWhite.png"
        ,"color": [{"a":220}]
        ,"shader":{"name":"data/noise.fs"}
    }]);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/satellite_point.png"
        ,"layer": layer
        ,"color":[{"a":"{return getSignalColor(animation);}"}]
        //,"color":[{"r":"{return getSignalColor(animation);}","g":"{return getSignalColor(animation);}","b":"{return getSignalColor(animation);}"}]
    }]);

    /*this.loader.addAnimation([{
         "start": start, "duration": duration
        ,"layer": layer
        ,"initFunction": "{initSphere(animation);}"
        ,"deinitFunction": "{deinitSphere(animation);}"
        ,"runFunction": "{drawSphere(animation);}"
        ,"shader":{"name":["data/forest.fs","data/forest.vs"]}
    }]);*/

    this.loader.addAnimation([
    {
         "start": start, "duration": duration, "layer": layer
        //,"image": "data/raym.png"
        ,"image": "data/_embedded/defaultTransparent.png"
        //,"image": "data/satellite_point.png"
        //,"scale":[{"uniform2d":10}]
        ,"sphereStart":12
        ,"sphereFade":2
        ,"sphereDuration":16
        ,"shader":{"name":"data/raymarching.fs",
            "variable":[
                 {"name":"spherePos1","value":"{return getSpherePosition(animation, 1);}"}
                ,{"name":"spherePos2","value":"{return getSpherePosition(animation, 2);}"}
                ,{"name":"spherePos3","value":"{return getSpherePosition(animation, 3);}"}
                ,{"name":"spherePos4","value":"{return getSpherePosition(animation, 4);}"}
                ,{"name":"spherePos5","value":"{return getSpherePosition(animation, 5);}"}
                ,{"name":"masterScale","value":["{return getSphereMasterScale(animation);}"]}
            ]
        }
    }]);

    this.addTextFlicker(start+2,5,layer,1);
    this.addTextFlicker(start+8,10,layer,2);

    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"end"}
    }]);

}

function getGlowValue(animation, type, name)
{
    //var p = 1-Utils.calculateProgress(animation.start+animation.warpSlowStart, animation.warpSlowDuration);

    var samples = 25;
    var spread = 0.013;
    var intensity = 0.14;
    var alpha = 1;

    if (name === "samples")
    {
        return samples;
    }
    else if (name === "spread")
    {
        if (type == 1) {
            spread += 0.004;
        }
        return spread;
    }
    else if (name === "intensity")
    {
        return intensity;
    }
    else if (name === "alpha")
    {
        return alpha;
    }
    else if (name === "glowAlpha")
    {
        return 1.0;
    }
    else if (name === "showOnlyGlow")
    {
        return 1;
    }
    
    return void null;
}

Demo.prototype.addSunAppear = function(start, duration, layer, fboName)
{
    var sunPosition = [{"x":getScreenWidth()/2*0.98,"y":120},{"duration":10,"y":350}]
    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":"sunGlowSourceFbo","action":"begin"}
    }]);

    this.loader.addAnimation([{
         "start": start, "duration": duration, "layer": layer
        ,"image": "data/sun.png"
        ,"shader":{"name":"data/wavy.fs","variable":[
            {"name":"magnitude","value":[0.08,0.08]}
        ]}
        ,"scale":[{"uniform2d":0.4}]
        ,"position":sunPosition
    }]);

    this.loader.addAnimation([{
         "start": start, "duration": duration, "layer": layer
        ,"image": "data/planet_earth_moon.png"
        ,"scale":[{"uniform2d":0.9}]
        ,"position":[{"x":getScreenWidth()/2,"y":-180}]
        ,"color":[{"r":0,"g":0,"b":0}]
    }]);

    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":"sunGlowSourceFbo","action":"unbind"}
    }]);


    this.loader.addAnimation([{
         "start": start, "duration": duration, "layer": layer
        ,"image": "sunGlowSourceFbo.color.fbo"
        ,"passToFbo": {name:"sunGlowFbo"}
        ,"shader":[
             {"name":"data/glow.fs","variable":[
                 {"name":"direction","value":[1,0]}
                ,{"name":"glowAlpha","value":["{return getGlowValue(animation, 0, \"glowAlpha\");}"]}
                ,{"name":"spread","value":["{return getGlowValue(animation, 0, \"spread\");}"]}
                ,{"name":"intensity","value":["{return getGlowValue(animation, 0, \"intensity\");}"]}
                ,{"name":"samples","type":"int","value":["{return getGlowValue(animation, 0, \"samples\");}"]}
            ]}
            ,{"name":"data/glow.fs","variable":[
                 {"name":"direction","value":[0,1]}
                ,{"name":"glowAlpha","value":["{return getGlowValue(animation, 1, \"glowAlpha\");}"]}
                ,{"name":"spread","value":["{return getGlowValue(animation, 1, \"spread\");}"]}
                ,{"name":"intensity","value":["{return getGlowValue(animation, 1, \"intensity\");}"]}
                ,{"name":"samples","type":"int","value":["{return getGlowValue(animation, 1, \"samples\");}"]}
                ,{"name":"showOnlyGlow","type":"int","value":["{return getGlowValue(animation, 1, \"showOnlyGlow\");}"]}
                ,{"name":"alpha","value":["{return getGlowValue(animation, 1, \"alpha\");}"]}
            ]}
        ]
    }]);


    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"begin"}
    }]);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/_embedded/defaultWhite.png"
        ,"color": [{"a":100}]
        ,"shader":{"name":"data/noise.fs"}
        ,"layer": layer
    }]);

    this.loader.addAnimation([{
         "start": start, "duration": duration, "layer": layer
        ,"image": "data/sun.png"
        ,"shader":{"name":"data/wavy.fs","variable":[
            {"name":"magnitude","value":[0.01,0.01]}
        ]}
        ,"scale":[{"uniform2d":0.4}]
        ,"position":sunPosition
    }]);

    this.loader.addAnimation([{
         "start": start, "duration": duration, "layer": layer
        ,"image": "data/planet_earth_moon.png"
        ,"scale":[{"uniform2d":0.9}]
        ,"position":[{"x":getScreenWidth()/2,"y":-200}]
    }]);
    this.loader.addAnimation([{
         "start": start, "duration": duration, "layer": layer
        ,"image": "sunGlowFbo.color.fbo"
        ,"color":[{"a":220}]
    }]);
    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"unbind"}
    }]);

    /*this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":"distortionFbo","action":"end"}
        ,"shader":{
            "name":"data/distortion.fs",
            "variable":[
                 ,{"name":"distortionResolutionX","value":[7.8]}
                 ,{"name":"distortionResolutionY","value":[7.3]}
                 ,{"name":"distortionX","value":[0.1]}
                 ,{"name":"distortionY","value":[0.05]}
                 ,{"name":"distortionSpeed","value":[2.0]}
                 ,{"name":"shakeSizeY","value":[0.005]}
                 ,{"name":"glitchSize","value":[0.005]}
                 ,{"name":"noiseAlpha","value":[0.0]}
            ]
        }
    }]);*/

}


function getSignalScale(animation)
{
    return ((getSceneTimeFromStart()-animation.start)%animation.signalDuration)/animation.signalDuration*animation.signalScale;
}
function getSignalColor(animation)
{
    return (1-Math.cos((getSceneTimeFromStart()-animation.start)*3.469))/2*255;
}

Demo.prototype.addSatelliteDish = function(start, duration, layer, fboName)
{
    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"begin"}
    }]);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/_embedded/defaultWhite.png"
        ,"color": [{"a":220}]
        ,"shader":{"name":"data/noise.fs"}
        ,"layer": layer
    }]);

    var panDuration = 6;

    this.loader.addAnimation([
    {
         "start": start+panDuration, "duration": duration-panDuration
        ,"image": "data/line.png"
        ,"color":[{"a":"{return (1+Math.sin(getSceneTimeFromStart()*50))/2*255}"}]
        ,"position": [{"x":getScreenWidth()*0.85,"y":getScreenHeight()*0.57}]
        ,"shader":{"name":"data/sine.fs"}
        ,"layer": layer
    }]);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/satellite_point.png"
        ,"layer": layer
        ,"scale":[{"uniform2d":1.9},{"duration":panDuration,"uniform2d":0.3}]
        ,"position":[{"x":680,"y":410},{"duration":panDuration,"x":390,"y":450}]
        ,"color":[{"a":"{return getSignalColor(animation);}"}]
        //,"color":[{"r":"{return getSignalColor(animation);}","g":"{return getSignalColor(animation);}","b":"{return getSignalColor(animation);}"}]
    }]);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/satellite_dish.png"
        ,"layer": layer
        ,"scale":[{"x":-2,"y":2},{"duration":panDuration,"x":-0.4,"y":0.4}]
        ,"position":[{"x":getScreenWidth()/2-500,"y":getScreenHeight()/2-1030},{"duration":panDuration,"x":280,"y":230}]
    }]);

    this.addTextFlicker(start+2,5,layer,3);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/_embedded/defaultWhite.png"
        ,"perspective": "3d"
        ,"position":[{"z":-1,"x":-0.87,"y":0.31}]
        //,"angle":[{"degreesX":80,"degreesY":140}]
        //,"scale":[{"uniform2d":"{return ((getSceneTimeFromStart()-animation.start)%animation.signalDuration)*1/animation.signalDuration;}"}]
        ,"scale":[
            {"uniform2d":0},
            {"duration":panDuration+2},
            {"signalDuration": 2, "signalScale":30, "uniform2d":"{return getSignalScale(animation);}"}
        ]
        //,"color": [{"a":200}]
        ,"shader":{"name":"data/signal.fs"}
        ,"layer": layer
    }]);

    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"unbind"}
    }]);
}

function getSpherePosition(animation, sphereI)
{
    var array = [0,0,0];
    var time = getSceneTimeFromStart()*10;

    if (sphereI == 1)
    {
        array[0] = Math.cos(time)*0.5+0.2;
        array[1] = Math.sin(time)*0.8+0.3;
        array[2] = Math.sin(time)*0.5;
    }
    else if (sphereI == 2)
    {
        array[0] = Math.sin(time)*0.5-0.5;
        array[1] = Math.cos(time)*0.5-0.25;
        array[2] = Math.sin(time)+0.5;
    }
    else if (sphereI == 3)
    {
        array[0] = Math.cos(time)*0.5-0.5;
        array[1] = Math.sin(time)*0.7-0.25;
        array[2] = Math.cos(time)*0.6+0.3;
    }
    else if (sphereI == 4)
    {
        array[0] = Math.cos(time)*0.8;
        array[1] = Math.sin(time)*0.4;
        array[2] = Math.cos(time)*0.8;
    }
    else if (sphereI == 5)
    {
        array[0] = Math.sin(time)*0.9;
        array[1] = Math.sin(time)*0.9;
        array[2] = Math.sin(time)*0.2;
    }

    return array;
}

function getSphereMasterScale(animation)
{
    var progress = Utils.calculateProgress(animation.start+animation.sphereStart, animation.sphereFade);
    if (progress >= 1.0)
    {
        progress = 1 - Utils.calculateProgress(animation.start+animation.sphereStart+animation.sphereDuration, animation.sphereFade);
    }
    return progress;
}

Demo.prototype.addTiles = function(start, duration, layer, fboName)
{
    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"begin"}
    }]);

    /*this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/_embedded/defaultWhite.png"
        ,"color": [{"a":220}]
        ,"shader":{"name":"data/noise.fs"}
        ,"layer": layer
    }]);*/


    /*var tiles = [
         {}
        ,{}
        ,{}
        ,{}
        ,{}
        ,{}
    ];

    this.loader.addAnimation([
    {
         "start": start, "duration": duration, "layer": layer
        ,"image": "data/raym.png"
        //,"image": "data/_embedded/defaultWhite.png"
        //,"image": "data/satellite_point.png"
        //,"scale":[{"uniform2d":10}]
        ,"sphereStart":0
        ,"sphereFade":1
        ,"sphereDuration":16
        ,"shader":{"name":"data/raymarching.fs",
            "variable":[
                 {"name":"spherePos1","value":"{return getSpherePosition(animation, 1);}"}
                ,{"name":"spherePos2","value":"{return getSpherePosition(animation, 2);}"}
                ,{"name":"spherePos3","value":"{return getSpherePosition(animation, 3);}"}
                ,{"name":"spherePos4","value":"{return getSpherePosition(animation, 4);}"}
                ,{"name":"spherePos5","value":"{return getSpherePosition(animation, 5);}"}
                ,{"name":"masterScale","value":["{return getSphereMasterScale(animation);}"]}
            ]
        }
    }]);*/


    /*for(var i = 0; i < tiles.length; i++) {
        this.loader.addAnimation([
        {
             "start": start, "duration": duration
            ,"image": "data/white_tile.png"
            ,"scale": [{"uniform2d":1.0}]
            ,"layer": layer
            ,"position":[{
                "x":getScreenWidth()*(0.25 + ((i%3)*0.25)),
                "y":getScreenHeight()*(0.73 - ((Math.floor(i/3)%3)*0.44))}]
            ,"shader":{"name":"data/noise.fs"}
        }]);
    }*/

    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"unbind"}
    }]);
}

function getStaticNoiseResolution(animation) {
    var v1 = (1+Math.sin(getSceneTimeFromStart()*25))/2;
    return [1280*(v1), 720*(v1)];
}

var woodMesh = void null;
function initWood(animation) {
    woodMesh = meshNew();

    var precision = 30;

    meshSetFaceDrawType(woodMesh.ptr, LINE_STRIP);

    for (var ring=0; ring < 9; ring++) {
        var radius = 1+ring;

        for (var i=0; i <= precision; i++)
        {
            var angle = (i+precision)*2*Math.PI/precision;
            var x = Math.cos(angle) * radius;
            var y = Math.sin(angle) * radius;
            var z = -1;
            meshAddColor(woodMesh.ptr, 0,0,0,255);
            meshAddVertex(woodMesh.ptr, x,y,z);
        }
    }

    meshGenerate(woodMesh.ptr);
}

function deinitWood(animation) {
    meshDelete(woodMesh.ptr);
}

function drawWood(animation) {
    glPushMatrix();
    perspective2dEnd();
        
    glTranslatef(0,0,-20);
    //glRotatef(getSceneTimeFromStart()*20,0,0,1);
    meshDraw(woodMesh.ptr);

    glPopMatrix();
}

function getWoodColor(animation) {
    var progress = Utils.calculateProgress(animation.start, animation.duration);
    return [0,0,0,1];
}

Demo.prototype.addStatic = function(start, duration, layer, fboName)
{
    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"begin"}
    }]);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/_embedded/defaultWhite.png"
        ,"color": [{"a":255}]
        ,"shader":{"name":"data/noise.fs"
            ,"variable":[
                 {"name":"usePlasma","type":"int","value":[0]}
                ,{"name":"resolution","value":"{return getStaticNoiseResolution(animation);}"}
            ]
        }
        ,"layer": layer
    }]);


    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/line.png"
        ,"color":[{"a":"{return (1+Math.sin(getSceneTimeFromStart()*50))/2*255}"}]
        ,"position": [{"x":getScreenWidth()*0.5,"y":getScreenHeight()*0.57}]
        ,"shader":{"name":"data/sine.fs"}
        ,"layer": layer
    }]);

    this.addTextFlicker(start+2,5,layer,4);
    this.addTextFlicker(start+8,10,layer,5);

    this.loader.addAnimation([
    {
         "start": start, "duration": duration
        ,"image": "data/_embedded/defaultWhite.png"
        ,"color": [{"a":0},{"duration":18},{"duration":2,"a":255}]
        ,"layer": layer
    }]);

    this.loader.addAnimation([{
         "start": start+18, "duration": duration
        ,"layer": layer+20
        ,"initFunction": "{initWood(animation);}"
        ,"deinitFunction": "{deinitWood(animation);}"
        ,"runFunction": "{drawWood(animation);}"
        //,"color": [{"a":255,"r":0,"g":0,"b":0},{"duration":1,"a":255}]
        ,"shader":{"name":["data/forest.fs","data/forest.vs"]}
    }]);

    this.loader.addAnimation([
    {
         "start": start+20, "duration": 10
        ,"layer": layer
        ,"text":{"name":"data/DroidSerif-Regular.ttf","string":"Solskogen 2017"}
        ,"scale": [
              {"uniform2d":1.5}
        ]
        ,"color":[{"a":"{return (1+Math.sin(getSceneTimeFromStart()*5))/2*255}"}]
        ,"position":[{"x":getScreenWidth()/2.0-0,"y":getScreenHeight()/2.0}]
    }]);

    this.loader.addAnimation([
    { 
         "start": start, "duration": duration, "layer": layer
        ,"fbo":{"name":fboName,"action":"unbind"}
    }]);
}

Demo.prototype.init = function()
{
    var start = 0;
    var duration = 200;
    var layer = 1;
  /*  this.loader.addAnimation([{
         "start": start, "duration": duration
        ,"layer": layer
        ,"warningStripFadeStart":18
        ,"warningStripFadeDuration":2
        ,"runFunction":"{drawWarningStripes(animation);}"
    }]);
*/



    //0:00: Sun appear
    //0:20: Satellite signals
    //0:40: Feedback tunnel
    //1:09: 
    //1:23: 
    //2:10: ending
    this.timeline = [
    //{"name": "addTiles", "start": 0, "duration": 22}

         //{"name": "addTileTunnel", "start": 0, "duration": 31}
         {"name": "addSunAppear", "start": 0, "duration": 22}
        ,{"name": "addTileTunnel", "start": 20, "duration": 31}
        ,{"name": "addBeacon", "start": 50, "duration": 35}
        ,{"name": "addSatelliteDish", "start": 83.5, "duration": 32}
        ,{"name": "addStatic", "start": 110.0, "duration": 27}
        
        //,{"name": "addTiles", "start": 69, "duration": 22}
    ];

    for (var i = 0; i < this.timeline.length; i++) {
        var timeline = this.timeline[i];
        //timeline.function(timeline.start, timeline.duration, 1);
        eval("this." + timeline.name + "(" + timeline.start +","+timeline.duration+",1,'"+timeline.name+"Fbo');");
    }

    layer = layer+10;
    this.loader.addAnimation([
    { 
         "start": start, "duration": duration
        ,"layer": layer
        ,"fbo":{"name":"distortionFbo","action":"begin"}
    }]);

    for (var i = 0; i < this.timeline.length; i++) {
        var timeline = this.timeline[i];

        var fadeDuration = 1;

        this.loader.addAnimation([{
             "start": timeline.start, "duration": timeline.duration, "layer": layer
            ,"image": timeline.name + "Fbo.color.fbo"
            ,"color":[
                 {"start":timeline.start,"a":0}
                ,{"duration":fadeDuration,"a":255}
                ,{"duration":timeline.duration-fadeDuration*2}
                ,{"duration":fadeDuration,"a":0}
            ]
        }]);
    }

    this.loader.addAnimation([
    { 
         "start": start, "duration": duration
        ,"layer": layer
        ,"fbo":{"name":"distortionFbo","action":"unbind"}
    }]);

    this.loader.addAnimation([{
         "start": start, "duration": duration, "layer": layer
        ,"image": "distortionFbo.color.fbo"
        ,"shader":{
            "name":"data/distortion.fs", "variable":[
                  {"name":"time","value":"{return getSceneTimeFromStart()*0.01;}"}
                 ,{"name":"distortionResolutionX","value":[12]}
                 ,{"name":"distortionResolutionY","value":[12]}
                 ,{"name":"distortionX","value":[0.15]}
                 ,{"name":"distortionY","value":[0.05]}
                 ,{"name":"distortionSpeed","value":[5.0]}
                 ,{"name":"shakeSizeY","value":[0.001]}
                 ,{"name":"glitchSize","value":[0.000]}
                 ,{"name":"noiseAlpha","value":[0.05]}
            ]
        }
    }]);

    this.loader.addAnimation([{
         "start": start, "duration": duration, "layer": layer
        ,"image": "data/vignette.png"
        ,"color":[{"a":255},{"duration":129},{"duration":1,"a":0}]
    }]);
}
