//=============================================================================================================================================================

function showTurnFiguresAndClear(){
    log("SHOWING particleModels FIGURES W CLEAR ============================================");
    fadeOutAllCanvasExcept("particleModels");
    showTurnFigures();
}

function addTurnFigures(){
    log("ADDING particleModels FIGURES============================================");
    fadeInCanvas("particleModels");
    showTurnFigures();
}

function showTurnFigures(){
    //if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

    var SCREEN_HEIGHT = window.innerHeight;
    var SCREEN_WIDTH = window.innerWidth;

    var container;

    var camera, scene, figureRenderer, mesh, directionalLight;

    var parent, meshes = [], clonemeshes = [];

    var p;

    var aloader, bloader, sloader;

    var total = 0, totaln = 0;

    var composer, effectFocus;

    var clock = new THREE.Clock();

    init();
    animate();

    function init() {

        container = document.getElementById( 'particleModels' );
        console.log(container)
        //$("#particleModels").fadeIn();
        //fadeOutAllCanvasExcept("particleModels");


        camera = new THREE.PerspectiveCamera( 20, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 50000 );
        camera.position.set( 0, 700, 7000 );

        scene = new THREE.Scene();
        scene.fog = new THREE.FogExp2( 0xFF0104, 0.0000675 );

        camera.lookAt( scene.position );

        //

        aloader = new THREE.JSONLoader( );
        //bloader = new THREE.BinaryLoader( true );
        sloader = new THREE.STLLoader();

        //document.body.appendChild( bloader.statusDomElement );


        sloader.load( "/assets/3d/thingiverse/farmall.stl", function( geometry ) {
            createSTLMesh( geometry, scene, 4.05,   250, -350, 2500, 0xFFFFFF, true );

        } );


        figureRenderer = new THREE.WebGLRenderer({ antialias: false } );
        figureRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
        figureRenderer.autoClear = false;
        figureRenderer.sortObjects = false;
        container.appendChild( figureRenderer.domElement );

        figureRenderer.setClearColor( scene.fog.color, 1 );

        //

        parent = new THREE.Object3D();
        scene.add( parent );

        var grid = new THREE.PointCloud( new THREE.PlaneGeometry( 15000, 15000, 64, 64 ), new THREE.PointCloudMaterial( { color: 0x000000, size: 10 } ) );
        grid.position.y = -400;
        grid.rotation.x = - Math.PI / 2;
        parent.add( grid );

        totaln += 1;
        total += grid.geometry.vertices.length;

        // postprocessing

        var renderModel = new THREE.RenderPass( scene, camera );
        var effectBloom = new THREE.BloomPass( 0.75 );
        var effectFilm = new THREE.FilmPass( 0.5, 0.5, 1448, false );

        effectFocus = new THREE.ShaderPass( THREE.FocusShader );

        effectFocus.uniforms[ "screenWidth" ].value = window.innerWidth;
        effectFocus.uniforms[ "screenHeight" ].value = window.innerHeight;

        effectFocus.renderToScreen = true;

        composer = new THREE.EffectComposer( figureRenderer );

        composer.addPass( renderModel );
        composer.addPass( effectBloom );
        composer.addPass( effectFilm );
        composer.addPass( effectFocus );

        //

        window.addEventListener( 'resize', onWindowResize, false );

    }

    //

    function onWindowResize( event ) {

        figureRenderer.setSize( window.innerWidth, window.innerHeight );

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        camera.lookAt( scene.position );

        composer.reset();

        effectFocus.uniforms[ "screenWidth" ].value = window.innerWidth;
        effectFocus.uniforms[ "screenHeight" ].value = window.innerHeight;

    }

    function createSTLMesh( originalGeometry, scene, scale, x, y, z, color, dynamic ) {

        var i, c;

        var vertices = originalGeometry.attributes.position.array;
        var vl = vertices.length/3;

        var geometry = new THREE.Geometry();
        var vertices_tmp = [];

        for ( i = 0; i < vl; i ++ ) {

            //p = vertices[ i ];
            z = vertices[ i*3+0 ];
            x = vertices[ i*3+1 ];
            y = vertices[ i*3+2 ];


            geometry.vertices[ i ] = new THREE.Vector3(x,y,z);
            vertices_tmp[ i ] = [ x, y, z, 0, 0 ];

        }

        var clones = [

            [  6000, 0, -4000 ],
            [  5000, 0, 0 ],
            [  1000, 0, 5000 ],
            [  1000, 0, -5000 ],
            [  4000, 0, 2000 ],
            [ -4000, 0, 1000 ],
            [ -5000, 0, -5000 ],

            [ 0, 0, 0 ]

        ];

        if ( dynamic ) {

            for ( i = 0; i < clones.length; i ++ ) {

                c = ( i < clones.length -1 ) ? 0x252525 : color;

                mesh = new THREE.PointCloud( geometry, new THREE.PointCloudMaterial( { size: 3, color: c } ) );
                mesh.scale.x = mesh.scale.y = mesh.scale.z = scale;

                mesh.position.x = x + clones[ i ][ 0 ];
                mesh.position.y = y + clones[ i ][ 1 ];
                mesh.position.z = z + clones[ i ][ 2 ];

                parent.add( mesh );

                clonemeshes.push( { mesh: mesh, speed: 0.5 + Math.random() } );

            }

            totaln += clones.length;
            total += clones.length * vl;

        } else {

            mesh = new THREE.PointCloud( geometry, new THREE.PointCloudMaterial( { size: 3, color: color } ) );
            mesh.scale.x = mesh.scale.y = mesh.scale.z = scale;

            mesh.position.x = x;
            mesh.position.y = y;
            mesh.position.z = z;

            parent.add( mesh );

            totaln += 1;
            total += vl;

        }

        //bloader.statusDomElement.style.display = "none";


        meshes.push( {
            mesh: mesh, vertices: geometry.vertices, vertices_tmp: vertices_tmp, vl: vl,
            down: 0, up: 0, direction: 0, speed: 35, delay: Math.floor( 200 + 200 * Math.random() ),
            started: false, start: Math.floor( 100 + 200 * Math.random() ),
            dynamic: dynamic
        } );

    }

    var j, jl, cm, data, vertices, vertices_tmp, vl, d, vt;

    function animate () {

        requestAnimationFrame( animate );
        render();

    }

    function render () {

        delta = 10 * clock.getDelta();
        delta = delta < 2 ? delta : 2;
        parent.rotation.y += -0.02 * delta;

        for( j = 0, jl = clonemeshes.length; j < jl; j ++ ) {
            cm = clonemeshes[ j ];
            cm.mesh.rotation.y += -0.1 * delta * cm.speed;
        }

        for( j = 0, jl = meshes.length; j < jl; j ++ ) {
            data = meshes[ j ];
            mesh = data.mesh;
            vertices = data.vertices;
            vertices_tmp = data.vertices_tmp;
            vl = data.vl;
            if ( ! data.dynamic ) continue;
            if ( data.start > 0 ) {
                data.start -= 1;
            } else {
                if ( !data.started ) {
                    data.direction = -1;
                    data.started = true;
                }
            }

            for ( i = 0; i < vl; i ++ ) {
                p = vertices[ i ];
                vt = vertices_tmp[ i ];
                // falling down
                if ( data.direction < 0 ) {
                    // var d = Math.abs( p.x - vertices_tmp[ i ][ 0 ] ) + Math.abs( p.y - vertices_tmp[ i ][ 1 ] ) + Math.abs( p.z - vertices_tmp[ i ][ 2 ] );
                    // if ( d < 200 ) {
                    if ( p.y > 0 ) {
                        // p.y += data.direction * data.speed * delta;
                        p.x += 1.5 * ( 0.50 - Math.random() ) * data.speed * delta;
                        p.y += 3.0 * ( 0.25 - Math.random() ) * data.speed * delta;
                        p.z += 1.5 * ( 0.50 - Math.random() ) * data.speed * delta;
                    } else {
                        if ( ! vt[ 3 ] ) {
                            vt[ 3 ] = 1;
                            data.down += 1;
                        }
                    }
                }

                // rising up
                if ( data.direction > 0 ) {
                    //if ( p.y < vertices_tmp[ i ][ 1 ] ) {
                    //	p.y += data.direction * data.speed * delta;
                    d = Math.abs( p.x - vt[ 0 ] ) + Math.abs( p.y - vt[ 1 ] ) + Math.abs( p.z - vt[ 2 ] );
                    if ( d > 1 ) {
                        p.x += - ( p.x - vt[ 0 ] ) / d * data.speed * delta * ( 0.85 - Math.random() );
                        p.y += - ( p.y - vt[ 1 ] ) / d * data.speed * delta * ( 1 + Math.random() );
                        p.z += - ( p.z - vt[ 2 ] ) / d * data.speed * delta * ( 0.85 - Math.random() );
                    } else {
                        if ( ! vt[ 4 ] ) {
                            vt[ 4 ] = 1;
                            data.up += 1;
                        }
                    }
                }
            }

            // all down
            if ( data.down === vl ) {
                if ( data.delay === 0 ) {
                    data.direction = 1;
                    data.speed = 10;
                    data.down = 0;
                    data.delay = 320;
                    for ( i = 0; i < vl; i ++ ) {
                        vertices_tmp[ i ][ 3 ] = 0;
                    }
                } else {
                    data.delay -= 1;
                }
            }

            // all up
            if ( data.up === vl ) {
                if ( data.delay === 0 ) {
                    data.direction = -1;
                    data.speed = 35;
                    data.up = 0;
                    data.delay = 120;
                    for ( i = 0; i < vl; i ++ ) {
                        vertices_tmp[ i ][ 4 ] = 0;
                    }
                } else {
                    data.delay -= 1;
                }
            }
            mesh.geometry.verticesNeedUpdate = true;
        }
        figureRenderer.clear();
        composer.render( 0.01 );
    }
}