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

/**
* Fireballs 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 Fireballs = function( main, cache, id){
	    
		this.main = main;
		this.partId = id;
	}
	//Expose class
	wideload.Fireballs = Fireballs;
	
	var p = Fireballs.prototype = new wideload.BasePart(20);
	p.superInitialize = p.initialize;
	/**
	* Initialize the part. This is called during page load.
	*/
	p.initialize = function(renderer){
		this.superInitialize(renderer);
		this.renderer = renderer;
		this.random = wideload.Random;

		this.scene = new THREE.Scene();
		
		this.camera = new THREE.PerspectiveCamera(50,1,0.1,2000);
		this.camera.position.z = 1;
		this.scene.add(this.camera);

		this.particles = 50000;

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

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

        this.uniforms = {
            color: { type: "c", value: new THREE.Color(0xffffff) },
            texture: { type: "t", value: sparkTexture },
        };
        var shaderMaterial = new THREE.ShaderMaterial({
            uniforms: this.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(this.particles * 3), 3);
        geometry.addAttribute('customColor', new Float32Array(this.particles * 3), 3);
        geometry.addAttribute('size', new Float32Array(this.particles), 1);
        var positions = geometry.getAttribute('position').array;
        var values_color = geometry.getAttribute('customColor').array;
        this.values_size = geometry.getAttribute('size').array;
        this.sphere = new THREE.ParticleSystem(geometry, shaderMaterial);
        // sphere.sortParticles = true;
        var color = new THREE.Color(0xffaa00);;
        for (var v = 0; v < this.particles; v++) {
            this.values_size[v] = 10;
            positions[v * 3 + 0] = (this.random.nextFloat() * 2 - 1) * radius;
            positions[v * 3 + 1] = (this.random.nextFloat() * 2 - 1) * radius;
            positions[v * 3 + 2] = (this.random.nextFloat() * 2 - 1) * radius;
            if (positions[v * 3 + 0] < 0)
                color.setHSL(0.0 + 0.1 * (v / this.particles), 1.0, 1.0);
            else
                color.setHSL(0.0 + 0.1* (v / this.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(this.sphere);
	}
	
	/**
	* Prepare the part for coming up next. This is called when previous effect notifies the main controller it is ready to end.
	* @param previous Previous part.
	*/
	p.prepare = function(elapsedtime,previous){
		this.renderer.setClearColor(0x000000);
	}
	
	
	/**
	* Previous effect has stopped playback. Start playback part.
	*/
	p.begin = function(elapsedtime){

	}
	
	/**
	* Pre render action if required
	*/
	p.preRender = function(elapsedtime){

	}

	/**
	* Main controller calls render function
	* @param renderTarget The rendertarget to render to
	*/
	p.internalRender = function (elapsedtime, renderTarget) {
	    //this.camera.position.x = Math.cos(elapsedtime / 4000) * 10 +15 ;
	    this.camera.position.y = Math.sin(elapsedtime / 4000) * 50;
	    //this.camera.position.z = Math.sin(elapsedtime / 4500) * 10;
	    this.camera.lookAt(new THREE.Vector3(0, 0, 0));
	    
        this.sphere.rotation.z = 0.0001 * elapsedtime;
        for (var i = 0; i < this.particles; i++) {
            this.values_size[i] = 10 +2* Math.sin(0.1 * i + elapsedtime*0.5);
        }
        geometry.attributes.size.needsUpdate = true;
        this.renderer.render(this.scene, this.camera, this.renderTarget);
	}
	
	/**
	* Post render if required. Postprocessing actions can be done here for example.
	* @param renderTarget The rendertarget for final image. It is different than the one given in render-function.
	*/
	p.postRender = function(elapsedtime){
		
	}
	
	/**
	* Ending is near. Start animating ending if necessary
	* @param next part
	*/
	p.prepareEnd = function(elapsedtime,next){
		
	}

	/**
	* Order to end the part
	*/
	p.endPart = function(elapsedtime){

	}
	
}())