/*
 * 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 InitialPostProcessingNode extends AbstractNode {
    public static final ResourceUrn SCENE_PRE_POST = new ResourceUrn("engine:scenePrePost");

    @In
    private Config config;

    @In
    private DisplayResolutionDependentFBOs displayResolutionDependentFBOs;

    @In
    private WorldRenderer worldRenderer;

    private FBO scenePrePost;

    private Material initialPost;

    @Override
    public void initialise() {
        initialPost = worldRenderer.getMaterial("engine:prog.prePost"); // TODO: rename shader to scenePrePost
        requiresFBO(new FBOConfig(SCENE_PRE_POST, FULL_SCALE, FBO.Type.HDR), displayResolutionDependentFBOs);

    }

    /**
     * Adds chromatic aberration, light shafts, 1/8th resolution bloom, vignette onto the rendering achieved so far.
     * Stores the result into its own buffer to be used at a later stage.
     */
    @Override
    public void process() {
        // Initial Post-Processing: chromatic aberration, light shafts, 1/8th resolution bloom, vignette
        PerformanceMonitor.startActivity("rendering/initialPostProcessing");
        scenePrePost = displayResolutionDependentFBOs.get(SCENE_PRE_POST);
        initialPost.enable();

        // TODO: verify what the inputs are
        scenePrePost.bind(); // TODO: see if we could write this straight into sceneOpaque

        setViewportToSizeOf(scenePrePost);
        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
@@ -1955,154 +1955,200 @@
     
-private FBO scenePrePost;%0A%0A    private Material initialPost;%0A%0A    @Override%0A    public void initialise() %7B%0A        initialPost = worldRenderer.get
+@Override%0A    public void initialise() %7B%0A        requiresFBO(new FBOConfig(SCENE_PRE_POST, FULL_SCALE, FBO.Type.HDR), displayResolutionDependentFBOs);%0A%0A        addDesiredStateChange(new Enable
 Mate
@@ -2174,16 +2174,17 @@
 rePost%22)
+)
 ; // TOD
@@ -2228,75 +2228,264 @@
     
-requiresFBO(new FBOConfig(SCENE_PRE_POST, FULL_SCALE, FBO.Type.HDR)
+// TODO: verify what the inputs are%0A        addDesiredStateChange(new BindFBO(SCENE_PRE_POST, displayResolutionDependentFBOs)); // TODO: see if we could write this straight into sceneOpaque%0A        addDesiredStateChange(new SetViewportSizeOf(SCENE_PRE_POST
 , di
@@ -2509,26 +2509,26 @@
 pendentFBOs)
+)
 ;
-%0A
 %0A    %7D%0A%0A    
@@ -2958,292 +2958,8 @@
 %22);%0A
-        scenePrePost = displayResolutionDependentFBOs.get(SCENE_PRE_POST);%0A        initialPost.enable();%0A%0A        // TODO: verify what the inputs are%0A        scenePrePost.bind(); // TODO: see if we could write this straight into sceneOpaque%0A%0A        setViewportToSizeOf(scenePrePost);
 %0A   
@@ -3041,33 +3041,32 @@
 is is necessary%0A
-%0A
         renderFu
@@ -3086,152 +3086,8 @@
 );%0A%0A
-        bindDisplay();     // TODO: verify this is necessary%0A        setViewportToSizeOf(READ_ONLY_GBUFFER); // TODO: verify this is necessary%0A%0A
     

Add desiredStateChanges to InitialPostProcessingNode