var m_w = 123456789;
var m_z = 987654321;
var mask = 0xffffffff;

// Takes any integer
function seed(i) {
    m_w = i;
}

// Returns number between 0 (inclusive) and 1.0 (exclusive),
// just like Math.random().
function random()
{
    m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;
    m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;
    var result = ((m_z << 16) + m_w) & mask;
    result /= 4294967296;
    return result + 0.5;
}
function toHex(c) {
    var hex = c.toString(16);
    return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r,g,b){
    var rHex = toHex(r);
    var gHex = toHex(g);
    var bHex = toHex(b);
    return '0x'+rHex+gHex+bHex;
}

function Effect6(controller) {
    var ribbonPalette = [0xffae00, 0xffe900, 0xff5900, 0xa67100, 0xffc340, 0xeed373, 0xbf9230, 0xa67100];
    var floorPalette = [rgbToHex(255,255,255), rgbToHex(22,255,64), rgbToHex(21,21,32), rgbToHex(26,26,26), rgbToHex(31,31,31), rgbToHex(1,12,16), rgbToHex(16,11,18), rgbToHex(2,3,4)];
    var obju = [];
    var backgroundcolor;
    var startTime;
    var passedtime = 0.0;
    var floorheight = [];
    var floor = [];
    var plane;
    var renderTexture;
    var vertShader;
    var uniforms;
    var materialScreen;
    var attributes;
    var size = 300;
    var dataColor = new Float32Array( size * 4 );
    var map;
    var uniforms;
    var surfaceMaterial;
    var quad;
    var surfaceGeometry;
    var surface;
    var light;
    var startTime;
    var previous_time;
    var loota = [];
        backgroundcolor=new THREE.Color();
    //init START
    this.init=function(){
        renderer.setSize(WIDTH, HEIGHT);
        container.appendChild(renderer.domElement); //linking rendering window to container on the DOM
        //calculate_effect5();
        obju = [];
        plane = new THREE.PlaneGeometry(WIDTH / HEIGHT, 6.0);
        renderTexture = new THREE.WebGLRenderTarget(WIDTH, HEIGHT, {
            minFilter: THREE.LinearFilter,
            magFilter: THREE.NearestFilter,
            format: THREE.RGBAFormat,
            depthBuffer: true
        });
        vertShader = [
            'varying vec4 verpos;',
            'void main() {',
            'gl_Position = projectionMatrix *',
            'modelViewMatrix *',
            'vec4(position,1.0);',
            '}'
        ].join('\n');


        uniforms = {
            scene: {
                type: "t",
                value: renderTexture
            },
            iResolution: {
                type: 'v2',
                value: new THREE.Vector2(WIDTH, HEIGHT)
            },
            globalTime: {
                type: 'f',
                value: (new Date()).getDate()
            }
        };
        materialScreen = /*new THREE.ShaderMaterial({ map:renderTexture, side:THREE.DoubleSide });*/
            new THREE.ShaderMaterial({
                uniforms: uniforms,
                vertexShader: vertShader,
                fragmentShader: document.getElementById('shader-fs').textContent,
                depthWrite: false,
                side: THREE.DoubleSide
            });
        attributes = {
            displacement: {
                type: 'f',
                value: []
            }
        };


        for(var i = 0; i < size; i++) {
                dataColor[ i * 4 + 0 ] = -500.0+random()*1000.0;
                dataColor[ i * 4 + 1 ] = -500.0+random()*1000.0;
                dataColor[ i * 4 + 2 ] = -random()*50.0;
                dataColor[ i * 4 + 3 ] = 0.0;
        }
        map = new THREE.DataTexture(dataColor, size, 1, THREE.RGBAFormat, THREE.FloatType );
        map.needsUpdate = true;

        uniforms = { 
                    globalTime: { type: "f", value: 1.0 }, 
                    resolution: { type: "v2", value: new THREE.Vector2() },
                    amplitude: { type: 'f', value: 0 },
                    bumps: {type:'t', value:map}
                    };
        surfaceMaterial = new THREE.ShaderMaterial( 
                    { 
                    side: THREE.DoubleSide,
                    attributes: attributes,
                    uniforms: uniforms, 
                    vertexShader: document.getElementById( 'scene6vs' ).textContent, 
                    fragmentShader: document.getElementById( 'scene6fs' ).textContent
                    } );
        quad = new THREE.Mesh(plane, materialScreen);

        surfaceGeometry=new THREE.PlaneGeometry(1000.0, 1000.0, 160.0, 120.0);
        surface=new THREE.Mesh( surfaceGeometry, surfaceMaterial);
    }
    this.launch=function(){
    scene3D.add(camera3D); //lets add our camera to the scene
    scene2D.add(camera2D);
    surface.position.z=0.0;
    surface.rotation.x=(90.0/180.0)*Math.PI;
    scene3D.add(surface);
    startTime = demosong.currentTime;
    light = new THREE.PointLight();
    light.position.set(40.0, 4110.0, 0.0);
    scene3D.add(light);
    quad.position.z = -1;
    scene2D.add(quad);
    objutorni.position.set(0.0, 10.0, 0.0);
    scene3D.add(objutorni);
    previous_time=(demosong.currentTime - startTime);
    }
    //snd.play();
    this.updateScreen = function () {
        var time = (demosong.currentTime - startTime);

        for(var i = 0; i < size; i++)
        {
            dataColor[ i * 4 + 0 ] +=((i%255)/64.0+0.45)*5.0*(time-previous_time);
            if(dataColor[ i * 4 + 0 ]>2000.0) dataColor[ i * 4 + 0 ]=-2000.0;
            dataColor[ i * 4 + 1 ] +=((i%255)/64.0+0.45)*5.0*(time-previous_time);
            if(dataColor[ i * 4 + 1 ]>2000.0) dataColor[ i * 4 + 0 ]=-2000.0;
        }
        var map = new THREE.DataTexture(dataColor, size, 1, THREE.RGBAFormat, THREE.FloatType );
        map.needsUpdate = true;

        uniforms.bumps.value = map;

        this.render3D();
        this.render2D();
        uniforms.globalTime.value = time;
        previous_time=time;
    };
    this.render2D = function () {
        renderer.render(scene2D, camera2D);
    }
    this.render3D = function () {
        var time = (demosong.currentTime - startTime);
        backgroundcolor.r=Math.min(0.65*time*0.02856, 0.65);
        backgroundcolor.g=Math.min(0.6*time*0.017171, 0.2);
        backgroundcolor.b=Math.min(0.4*time*0.017171, 0.1);
        renderer.setClearColor(backgroundcolor.getHex(), 1 );
        camera3D.position.set(Math.sin(time*0.021)*100.0, 10.0-time*0.01, Math.cos(time*0.02)*100.0);
        camera3D.lookAt(new THREE.Vector3(objutorni.position.x-250.0+Math.min(time,280.0), objutorni.position.y+180.0-Math.min(time*4.0,210.0), objutorni.position.z));

        //renderer.render(scene3D, camera3D);
        renderer.render(scene3D, camera3D, renderTexture, true);
    }
};