/*
 * Copyright (c) 2009-2012 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.jme3.post.ssao;

import com.jme3.asset.AssetManager;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.material.Material;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.Filter;
import com.jme3.post.Filter.Pass;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.Renderer;
import com.jme3.renderer.ViewPort;
import com.jme3.shader.VarType;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
import java.io.IOException;
import java.util.ArrayList;

/**
 * SSAO stands for screen space ambient occlusion
 * It's a technique that fake ambient lighting by computing shadows that near by objects would casts on each others 
 * under the effect of an ambient light
 * more info on this in this blog post <a href="http://jmonkeyengine.org/2010/08/16/screen-space-ambient-occlusion-for-jmonkeyengine-3-0/">http://jmonkeyengine.org/2010/08/16/screen-space-ambient-occlusion-for-jmonkeyengine-3-0/</a>
 * 
 * @author Rémy Bouquet aka Nehon
 */
public class SSAOFilter extends Filter {

    private Pass normalPass;
    private Vector3f frustumCorner;
    private Vector2f frustumNearFar;
    private Vector2f[] samples = {new Vector2f(1.0f, 0.0f), new Vector2f(-1.0f, 0.0f), new Vector2f(0.0f, 1.0f), new Vector2f(0.0f, -1.0f)};
    private float sampleRadius = 5.1f;
    private float intensity = 1.5f;
    private float scale = 0.2f;
    private float bias = 0.1f;
    private boolean useOnlyAo = false;
    private boolean useAo = true;
    private Material ssaoMat;
    private Pass ssaoPass;
//    private Material downSampleMat;
//    private Pass downSamplePass;
    private float downSampleFactor = 1f;

    /**
     * Create a Screen Space Ambient Occlusion Filter
     */
    public SSAOFilter() {
        super("SSAOFilter");
    }

    /**
     * Create a Screen Space Ambient Occlusion Filter
     * @param sampleRadius The radius of the area where random samples will be picked. default 5.1f
     * @param intensity intensity of the resulting AO. default 1.2f
     * @param scale distance between occluders and occludee. default 0.2f
     * @param bias the width of the occlusion cone considered by the occludee. default 0.1f
     */
    public SSAOFilter(float sampleRadius, float intensity, float scale, float bias) {
        this();
        this.sampleRadius = sampleRadius;
        this.intensity = intensity;
        this.scale = scale;
        this.bias = bias;
    }

    @Override
    protected boolean isRequiresDepthTexture() {
        return true;
    }

    @Override
    protected void postQueue(RenderManager renderManager, ViewPort viewPort) {
        Renderer r = renderManager.getRenderer();
        r.setFrameBuffer(normalPass.getRenderFrameBuffer());
        renderManager.getRenderer().clearBuffers(true, true, true);
        renderManager.setForcedTechnique("PreNormalPass");
        renderManager.renderViewPortQueues(viewPort, false);
        renderManager.setForcedTechnique(null);
        renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
    }

    @Override
    protected Material getMaterial() {
        return material;
    }

    @Override
    protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
        int screenWidth = w;
        int screenHeight = h;
        postRenderPasses = new ArrayList<Pass>();

        normalPass = new Pass();
        normalPass.init(renderManager.getRenderer(), (int) (screenWidth / downSampleFactor), (int) (screenHeight / downSampleFactor), Format.RGBA8, Format.Depth);


        frustumNearFar = new Vector2f();

        float farY = (vp.getCamera().getFrustumTop() / vp.getCamera().getFrustumNear()) * vp.getCamera().getFrustumFar();
        float farX = farY * ((float) screenWidth / (float) screenHeight);
        frustumCorner = new Vector3f(farX, farY, vp.getCamera().getFrustumFar());
        frustumNearFar.x = vp.getCamera().getFrustumNear();
        frustumNearFar.y = vp.getCamera().getFrustumFar();





        //ssao Pass
        ssaoMat = new Material(manager, "Common/MatDefs/SSAO/ssao.j3md");
        ssaoMat.setTexture("Normals", normalPass.getRenderedTexture());
        Texture random = manager.loadTexture("Common/MatDefs/SSAO/Textures/random.png");
        random.setWrap(Texture.WrapMode.Repeat);
        ssaoMat.setTexture("RandomMap", random);

        ssaoPass = new Pass() {

            @Override
            public boolean requiresDepthAsTexture() {
                return true;
            }
        };

        ssaoPass.init(renderManager.getRenderer(), (int) (screenWidth / downSampleFactor), (int) (screenHeight / downSampleFactor), Format.RGBA8, Format.Depth, 1, ssaoMat);
        ssaoPass.getRenderedTexture().setMinFilter(Texture.MinFilter.Trilinear);
        ssaoPass.getRenderedTexture().setMagFilter(Texture.MagFilter.Bilinear);
        postRenderPasses.add(ssaoPass);
        material = new Material(manager, "Common/MatDefs/SSAO/ssaoBlur.j3md");
        material.setTexture("SSAOMap", ssaoPass.getRenderedTexture());

        ssaoMat.setVector3("FrustumCorner", frustumCorner);
        ssaoMat.setFloat("SampleRadius", sampleRadius);
        ssaoMat.setFloat("Intensity", intensity);
        ssaoMat.setFloat("Scale", scale);
        ssaoMat.setFloat("Bias", bias);
        material.setBoolean("UseAo", useAo);
        material.setBoolean("UseOnlyAo", useOnlyAo);
        ssaoMat.setVector2("FrustumNearFar", frustumNearFar);
        material.setVector2("FrustumNearFar", frustumNearFar);
        ssaoMat.setParam("Samples", VarType.Vector2Array, samples);

        float xScale = 1.0f / w;
        float yScale = 1.0f / h;

        float blurScale = 2f;
        material.setFloat("XScale", blurScale * xScale);
        material.setFloat("YScale", blurScale * yScale);

    }

    /**
     * Return the bias<br>
     * see {@link  #setBias(float bias)}
     * @return 
     */
    public float getBias() {
        return bias;
    }

    /**
     * Sets the the width of the occlusion cone considered by the occludee default is 0.1f
     * @param bias 
     */
    public void setBias(float bias) {
        this.bias = bias;
        if (ssaoMat != null) {
            ssaoMat.setFloat("Bias", bias);
        }
    }

    /**
     * returns the ambient occlusion intensity
     * @return 
     */
    public float getIntensity() {
        return intensity;
    }

    /**
     * Sets the Ambient occlusion intensity default is 1.2f
     * @param intensity 
     */
    public void setIntensity(float intensity) {
        this.intensity = intensity;
        if (ssaoMat != null) {
            ssaoMat.setFloat("Intensity", intensity);
        }

    }

    /**
     * returns the sample radius<br>
     * see {link setSampleRadius(float sampleRadius)}
     * @return 
     */
    public float getSampleRadius() {
        return sampleRadius;
    }

    /**
     * Sets the radius of the area where random samples will be picked dafault 5.1f     
     * @param sampleRadius 
     */
    public void setSampleRadius(float sampleRadius) {
        this.sampleRadius = sampleRadius;
        if (ssaoMat != null) {
            ssaoMat.setFloat("SampleRadius", sampleRadius);
        }

    }

    /**
     * returns the scale<br>
     * see {@link #setScale(float scale)}
     * @return 
     */
    public float getScale() {
        return scale;
    }

    /**
     * 
     * Returns the distance between occluders and occludee. default 0.2f
     * @param scale 
     */
    public void setScale(float scale) {
        this.scale = scale;
        if (ssaoMat != null) {
            ssaoMat.setFloat("Scale", scale);
        }
    }

    /**
     * debugging only , will be removed
     * @return 
     */
    public boolean isUseAo() {
        return useAo;
    }

    /**
     * debugging only , will be removed
     */
    public void setUseAo(boolean useAo) {
        this.useAo = useAo;
        if (material != null) {
            material.setBoolean("UseAo", useAo);
        }

    }

    /**
     * debugging only , will be removed
     * @return 
     */
    public boolean isUseOnlyAo() {
        return useOnlyAo;
    }

    /**
     * debugging only , will be removed
     */
    public void setUseOnlyAo(boolean useOnlyAo) {
        this.useOnlyAo = useOnlyAo;
        if (material != null) {
            material.setBoolean("UseOnlyAo", useOnlyAo);
        }
    }

    @Override
    public void write(JmeExporter ex) throws IOException {
        super.write(ex);
        OutputCapsule oc = ex.getCapsule(this);
        oc.write(sampleRadius, "sampleRadius", 5.1f);
        oc.write(intensity, "intensity", 1.5f);
        oc.write(scale, "scale", 0.2f);
        oc.write(bias, "bias", 0.1f);
    }

    @Override
    public void read(JmeImporter im) throws IOException {
        super.read(im);
        InputCapsule ic = im.getCapsule(this);
        sampleRadius = ic.readFloat("sampleRadius", 5.1f);
        intensity = ic.readFloat("intensity", 1.5f);
        scale = ic.readFloat("scale", 0.2f);
        bias = ic.readFloat("bias", 0.1f);
    }
}
