package Mixer;
use Data::Dumper;

sub new($$) {
	my ($class) = @_;

	my $self = {};
	
	my $stdfragment = 
		"	
			varying vec3 normal;
			varying vec3 vertex_to_light_vector;
			varying vec3 vertex_color;
			varying vec2 texture_coordinate;
			uniform sampler2D my_color_texture;

			void main()
			{
				// Scaling The Input Vector To Length 1
				vec3 normalized_normal = normalize(normal);
				vec3 normalized_vertex_to_light_vector = normalize(vertex_to_light_vector);

				// Calculating The Diffuse Term And Clamping It To [0;1]
				float DiffuseTerm = clamp(dot(normal, vertex_to_light_vector), 0.0, 1.0);

				// Calculating The Final Color
				gl_FragColor = vec4(vertex_color,1) * DiffuseTerm;// * texture2D(my_color_texture, texture_coordinate);
			}
		"; 

	$stdvertex = "
		varying vec3 normal;
		varying vec3 vertex_to_light_vector;
		varying vec3 vertex_color;
		varying vec2 texture_coordinate;

		void main()
		{
			// Transforming The Vertex
			gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

			// Transforming The Normal To ModelView-Space
			normal = gl_NormalMatrix * gl_Normal; 

			// Transforming The Vertex Position To ModelView-Space
			vec4 vertex_in_modelview_space = gl_ModelViewMatrix * gl_Vertex;
			
			// Calculating The Vector From The Vertex Position To The Light Position
			vertex_to_light_vector = vec3(normalize(gl_LightSource[0].position - vertex_in_modelview_space));
			
			vertex_color = gl_Color.rgb;
			
			texture_coordinate = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0.xyzz);
		}
	";

	$self->{"engines"} = [];
	$self->{"pbuffers"} = [];

	bless $self;

	return $self;
}

sub SetParams($$) {
	my ($self,$params) = @_;
	
	if(defined($params->{"programs"}) && @{$self->{"engines"}} == 0) {
		foreach $program (@{$params->{"programs"}}) {
			$engine = new Program();
			$engine->SetParams({"program" => $program});
			push @{$self->{"engines"}}, $engine;
			
			$pbuffer = new PBuffer();
			push @{$self->{"pbuffers"}}, $pbuffer;
		}
	}
	
	$self->{"params"} = $params;
}

sub Render($$) {
	my ($self, $msec) = @_;
	my $engine;	
	my $i = 0;
	
	# Remember the current FB
	my $fb = OpenGL::getCurrentFB();

	# Render each engine to a pbuffer	
	foreach $engine (@{$self->{"engines"}}) {
		$self->{"pbuffers"}->[$i]->renderTo();
		OpenGL::glClear();
		$engine->Render($msec);
		
		$self->{"pbuffers"}->[$i]->renderFrom();
		$self->{"pbuffers"}->[$i]->generateMipmaps();
		$i++;
	}
	
	# Output pbuffers
	$i = 0;
	foreach $pbuffer (@{$self->{"pbuffers"}}) {
		if(defined($self->{"params"}->{"alpha" . $i})) {
			$alpha = $self->{"params"}->{"alpha" . $i};
		} else {
			$alpha = 1;
		}
			
		# Render to FB on entry
		OpenGL::renderTo($fb);
		$pbuffer->render($alpha);
		$i++;
	}
}

1;
