/*
 * Copyright 2016 MovingBlocks
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.terasology.rendering.dag.nodes;

import org.terasology.assets.ResourceUrn;
import org.terasology.config.Config;
import org.terasology.monitoring.PerformanceMonitor;
import org.terasology.registry.In;
import org.terasology.rendering.assets.material.Material;
import org.terasology.rendering.dag.AbstractNode;
import static org.terasology.rendering.opengl.DefaultDynamicFBOs.READ_ONLY_GBUFFER;
import org.terasology.rendering.opengl.FBO;
import org.terasology.rendering.opengl.FBOConfig;
import static org.terasology.rendering.opengl.ScalingFactors.FULL_SCALE;
import org.terasology.rendering.opengl.fbms.DisplayResolutionDependentFBOs;
import org.terasology.rendering.world.WorldRenderer;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.glClear;
import static org.terasology.rendering.opengl.OpenGLUtils.bindDisplay;
import static org.terasology.rendering.opengl.OpenGLUtils.setViewportToSizeOf;
import static org.terasology.rendering.opengl.OpenGLUtils.renderFullscreenQuad;

/**
 * TODO: Add diagram of this node
 */
public class ToneMappingNode extends AbstractNode {
    public static final ResourceUrn TONE_MAPPED = new ResourceUrn("engine:sceneToneMapped"); // HDR tone mapping

    @In
    private DisplayResolutionDependentFBOs displayResolutionDependentFBOs;

    @In
    private WorldRenderer worldRenderer;

    @In
    private Config config;

    private Material toneMapping;
    private FBO sceneToneMapped;

    @Override
    public void initialise() {
        requiresFBO(new FBOConfig(TONE_MAPPED, FULL_SCALE, FBO.Type.HDR), displayResolutionDependentFBOs);
        toneMapping = worldRenderer.getMaterial("engine:prog.hdr"); // TODO: rename shader to toneMapping)
    }

    /**
     * // TODO: write javadoc
     */
    // TODO: Tone mapping usually maps colors from HDR to a more limited range,
    // TODO: i.e. the 24 bit a monitor can display. This method however maps from an HDR buffer
    // TODO: to another HDR buffer and this puzzles me. Will need to dig deep in the shader to
    // TODO: see what it does.
    @Override
    public void process() {
        PerformanceMonitor.startActivity("rendering/toneMapping");
        sceneToneMapped = displayResolutionDependentFBOs.get(TONE_MAPPED);

        toneMapping.enable();

        sceneToneMapped.bind();
        setViewportToSizeOf(sceneToneMapped);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // TODO: verify this is necessary

        renderFullscreenQuad();

        bindDisplay();     // TODO: verify this is necessary
        setViewportToSizeOf(READ_ONLY_GBUFFER); // TODO: verify this is necessary

        PerformanceMonitor.endActivity();
    }
}

@@ -838,32 +838,82 @@
 ing.
-assets.material.Material
+dag.AbstractNode;%0Aimport org.terasology.rendering.dag.stateChanges.BindFBO
 ;%0Aim
@@ -942,36 +942,51 @@
 ndering.dag.
-AbstractNode
+stateChanges.EnableMaterial
 ;%0Aimport sta
@@ -974,39 +974,32 @@
 aterial;%0Aimport 
-static 
 org.terasology.r
@@ -1011,51 +1011,42 @@
 ing.
-opengl.DefaultDynamicFBOs.READ_ONLY_GBUFFER
+dag.stateChanges.SetViewportSizeOf
 ;%0Aim
@@ -1502,158 +1502,8 @@
 ar;%0A
-import static org.terasology.rendering.opengl.OpenGLUtils.bindDisplay;%0Aimport static org.terasology.rendering.opengl.OpenGLUtils.setViewportToSizeOf;%0A
 impo
@@ -1961,76 +1961,8 @@
 g;%0A%0A
-    private Material toneMapping;%0A    private FBO sceneToneMapped;%0A%0A
     
@@ -2109,24 +2109,25 @@
 tFBOs);%0A
+%0A
         
 toneMapp
@@ -2122,39 +2122,129 @@
     
-toneMapping = worldRenderer.get
+addDesiredStateChange(new BindFBO(TONE_MAPPED, displayResolutionDependentFBOs));%0A        addDesiredStateChange(new Enable
 Mate
@@ -2266,16 +2266,17 @@
 og.hdr%22)
+)
 ; // TOD
@@ -2308,16 +2308,115 @@
 apping)%0A
+        addDesiredStateChange(new SetViewportSizeOf(TONE_MAPPED, displayResolutionDependentFBOs));%0A
     %7D%0A%0A 
@@ -2875,192 +2875,8 @@
 %22);%0A
-        sceneToneMapped = displayResolutionDependentFBOs.get(TONE_MAPPED);%0A%0A        toneMapping.enable();%0A%0A        sceneToneMapped.bind();%0A        setViewportToSizeOf(sceneToneMapped);
 %0A   
@@ -2962,33 +2962,32 @@
 is is necessary%0A
-%0A
         renderFu
@@ -3007,152 +3007,8 @@
 );%0A%0A
-        bindDisplay();     // TODO: verify this is necessary%0A        setViewportToSizeOf(READ_ONLY_GBUFFER); // TODO: verify this is necessary%0A%0A
     

Add desiredStateChanges to ToneMappingNode