//Namespace
this.wideload = this.wideload || {};

/**
* Teddy part, first
*/

(function () {

    /**
	* Constructor
	* @param beginTime When the effect should start
	* @param prepareTime How long should the effect be allowed to stay in prepare phase (visible during previous parts end phase).
	         Value of 0 indicates immediate change. The endtime for previous part is the same as this parts prepare. First part has no prepare.
	         */
    var Background = function (main) {
        this.renderer = null; //Renderer is given from outside.
        this.main = main;
    }
    //Expose class
    wideload.Teddy.Background = Background;

    var p = Background.prototype = new Background();

    var sphere, uniforms, geometry;
    var noise = [];
    var values_size;
    var particles = 100000;
    
    /**
	* Initialize the part. This is called during page load.
	*/
    p.initialize = function () {
        // rendertarget
     //   this.renderTarget = new THREE.WebGLRenderTarget(this.main.resolution[0], this.main.resolution[1]);
        this.maxX = this.main.resolution[0] / 2;
        this.minX = -this.main.resolution[0] / 2;
        this.maxY = this.main.resolution[1] / 2;
        this.minY = -this.main.resolution[1] / 2;

        // Camera
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera(40, this.main.resolution[0]/this.main.resolution[1], 1, 10000);
        this.camera.position.z = 100;
        this.scene.add(this.camera);

        var attributes = {
            size: { type: 'f', value: null },
            customColor: { type: 'c', value: null }
        };

        var sparkTexture = new THREE.Texture(jsAsset_spark1);
        sparkTexture.needsUpdate = true;

        uniforms = {
            color: { type: "c", value: new THREE.Color(0xffffff) },
            texture: { type: "t", value: sparkTexture },
        };
        var shaderMaterial = new THREE.ShaderMaterial({
            uniforms: uniforms,
            attributes: attributes,
            vertexShader: document.getElementById('teddy_bg_vertexshader').textContent,
            fragmentShader: document.getElementById('teddy_bg_fragmentshader').textContent,
            blending: THREE.AdditiveBlending,
            depthTest: false,
            transparent: false
        });
		
        var radius = 150;
        geometry = new THREE.BufferGeometry();
        geometry.addAttribute('position', new Float32Array(particles * 3), 3);
        geometry.addAttribute('customColor', new Float32Array(particles * 3), 3);
        geometry.addAttribute('size', new Float32Array(particles), 1);
        var positions = geometry.getAttribute('position').array;
        var values_color = geometry.getAttribute('customColor').array;
        values_size = geometry.getAttribute('size').array;
        sphere = new THREE.ParticleSystem(geometry, shaderMaterial);
        // sphere.sortParticles = true;
        var color = new THREE.Color(0xffaa00);;
        for (var v = 0; v < particles; v++) {
            values_size[v] = 10;
            positions[v * 3 + 0] = (Math.random() * 2 - 1) * radius;
            positions[v * 3 + 1] = (Math.random() * 2 - 1) * radius;
            positions[v * 3 + 2] = (Math.random() * 2 - 1) * radius;
            if (positions[v * 3 + 0] < 0)
                color.setHSL(0.0 + 0.1 * (v / particles), 1.0, 1.0);
            else
                color.setHSL(0.0 + 0.1* (v / particles), 0.9, 0.29);
            values_color[v * 3 + 0] = color.r;
            values_color[v * 3 + 1] = color.g;
            values_color[v * 3 + 2] = color.b;
        }
        this.scene.add(sphere);
        this.animate();
    }

    /**
	* Main controller calls render function
	* @param renderTarget The rendertarget to render to
	*/
    p.animate = function() {
        //requestAnimationFrame(this.animate.bind(this));
        this.render();
    }
    p.render = function() {
        var time = Date.now() * 0.005;
        sphere.rotation.z = 0.01 * time;
        for (var i = 0; i < particles; i++) {
            values_size[i] = 10 +2* Math.sin(0.1 * i + time*0.5);
        }
        geometry.attributes.size.needsUpdate = true;
        this.main.renderer.render(this.scene, this.camera, this.renderTarget);
    }

}())