// http://threejs.org/examples/webgl_interactive_cubes_gpu.html

var FXBoxCloud = function () {

	FRAME.Module.call( this );

	var  x_min	= -2;
	var  x_max	= 2;
	var  y_min	= -2;
	var  y_max	= 2;
	var  z_min	= -4;
	var  z_max	= 4;

	this.parameters.input = {
	};

	var width = renderer.domElement.width;
	var height = renderer.domElement.height;

	var camera = new THREE.PerspectiveCamera( 60, width / height, 1, 5000 );

	var scene = new THREE.Scene;

  	var ambientLight = new THREE.AmbientLight( 0x22222222 );
    scene.add(ambientLight);

	var light1 = new THREE.PointLight( 0xffffff, 5, 300 );
	
	light1.position.set ( -20, 30, 250 );
	scene.add( light1 );

	this.numCubes = 400;
	this.radius = 200;

	this.cubeGeometry = new THREE.CubeGeometry(1,1,1);

	this.cubeMaterial = new THREE.ShaderMaterial( 
	{
		uniforms: 
		{
			texture:   { type: "t", value: resourceManager.getTexture("particle_steam") },
		},
		attributes:     
		{
			customVisible:	{ type: 'f',  value: [] },
			customSize:		{ type: 'f',  value: [] },
			customColor:	{ type: 'c',  value: new THREE.Color( 0xffffff ) },
			customOpacity:	{ type: 'f',  value: [] }
		},
		vertexShader: [

			"attribute float customSize;",
			"void main()",
			"{",
				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
				"gl_PointSize = customSize * ( 300.0 / length( mvPosition.xyz ) );",     // scale particles as objects in 3D space
				"gl_Position = projectionMatrix * mvPosition;",
			"}"
			].join("\n"),

		fragmentShader: [

			"uniform sampler2D texture;",
			"uniform float opacity;",
			"void main()", 
			"{",
				"gl_FragColor = texture2D( texture,  gl_PointCoord );",    
			"}"
			].join("\n"),

		transparent: true, 
		blending: THREE.NormalBlending, 
		depthTest: true,
		depthWrite: false
	});

    this.cubeMaterial = new THREE.MeshBasicMaterial({
        color: 0xff0000,
        wireframe: false
    });

	this.cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors	} );

	this.cubeMesh = new THREE.Mesh( this.cubeGeometry, this.cubeMaterial );

	this.randomizer = new THREE.Randomizer();
		
	this.cubes = [];

	camera.position.set( 0, 0, 10 );
	var type;

	this.init = function ( parameters ) {

		type = parameters.type;

		if ( type == 1 )
			camera.rotation.z = 0.7;
		
		this.lasttime = 0;

		//if (false)
			for( var i = 0; i < this.numCubes; i++ )
		{
			var position = new THREE.Vector3();
			position.x = this.randomizer.randFloat(x_min,x_max);
			position.y = this.randomizer.randFloat(y_min,y_max);
			position.z = this.randomizer.randFloat(z_min,z_max);

			var rotation = new THREE.Euler();
			rotation.x = this.randomizer.randFloat(0, 2 * Math.PI);
			rotation.y = this.randomizer.randFloat(0, 2 * Math.PI);
			rotation.z = this.randomizer.randFloat(0, 2 * Math.PI);

			var scale = new THREE.Vector3();
			scale.x = this.randomizer.randFloat(1,2);
			scale.y = this.randomizer.randFloat(1,2);
			scale.z = this.randomizer.randFloat(1,2);

			var cube = this.cubeMesh.clone();
			cube.position = position;
			cube.rotation = rotation;
			cube.quaternion.setFromEuler( rotation );
			cube.scale = scale;

			this.cubes.push( cube );
			scene.add( cube );
		}
	},

	this.animate = function (t, perc) 
	{
		var inc = t-this.lasttime;
		this.lasttime = t;

		for(var i = 0; i < this.numCubes; i++)
		{
			var cube = this.cubes[i];

			var rotation = new THREE.Euler();
			rotation.copy(cube.rotation);
			rotation.y += t;
			cube.quaternion.setFromEuler( rotation );
		}
	}

	this.update = function ( t, perc ) {

		this.animate( t, perc );

		if ( this.renderToTexture )
			renderer.render( scene, camera, this.fbo, this.clearBuffer );
		else
			renderer.render( scene, camera );

	};

};