#region File Description
//-----------------------------------------------------------------------------
// AlphaTestEffect.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace StockEffects
{
    /// <summary>
    /// The default effect used by SpriteBatch.
    /// </summary>
    public class PostProcessEffect : Effect
    {
        #region Effect Parameters

        EffectParameter matrixParam;
        EffectParameter resolutionParam;
        EffectParameter depthTextureParam;
        EffectParameter edgeStrengthParam;
        EffectParameter depthThresholdParam;
        EffectParameter depthMultiplyerParam;

        #endregion
        #region Fields

        float multiplyer = 40;
        // Max edge strength on each border {right, left, top, bottom}
        Vector4 edgeStrength = new Vector4(0.2f, 0.45f, 0.3f, 0.35f);
        // depth threashold for edge detection on each border {right, left, top, bottom}
        Vector4 depthThreshold = new Vector4(0.02f, 0.02f, 0.05f, 0.08f);

        Texture2D depthTexture = null;
        
        #endregion
        #region Methods
        public float DepthMultiplyer {
            get {
                return multiplyer;
            }
            set {
                multiplyer = value;
            }
        }
        public Vector4 EdgeStrength {
            get {
                return edgeStrength;
            }
            set {
                edgeStrength = value;
            }
        }
        public Vector4 DepthThreshold {
            get {
                return depthThreshold;
            }
            set {
                depthThreshold = value;
            }
        }
        public Texture2D DepthTexture {
            get {
                return depthTexture;
            }
            set {
                depthTexture = value;
            }
        }

        /// <summary>
        /// Creates a new SpriteEffect.
        /// </summary>
        public PostProcessEffect(GraphicsDevice device)
            : base(device, Resources.PostProcessEffect) {
            CacheEffectParameters();
        }


        /// <summary>
        /// Creates a new SpriteEffect by cloning parameter settings from an existing instance.
        /// </summary>
        protected PostProcessEffect(PostProcessEffect cloneSource)
            : base(cloneSource) {
            CacheEffectParameters();
        }


        /// <summary>
        /// Creates a clone of the current SpriteEffect instance.
        /// </summary>
        public override Effect Clone() {
            return new PostProcessEffect(this);
        }


        /// <summary>
        /// Looks up shortcut references to our effect parameters.
        /// </summary>
        void CacheEffectParameters() {
            matrixParam = Parameters["MatrixTransform"];
            resolutionParam = Parameters["ScreenResolution"];
            depthTextureParam = Parameters["NormalDepthTexture"];
            edgeStrengthParam = Parameters["EdgeStrength"];
            depthMultiplyerParam = Parameters["DepthMultiplyer"];
            depthThresholdParam = Parameters["DepthThreshold"];
        }


        /// <summary>
        /// Lazily computes derived parameter values immediately before applying the effect.
        /// </summary>
        protected override void OnApply() {
            Viewport viewport = GraphicsDevice.Viewport;
            int w = viewport.Width;
            int h = viewport.Height;
            Matrix projection = Matrix.CreateOrthographicOffCenter(0, w, h, 0, 0, 1);
            Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);
            matrixParam.SetValue(halfPixelOffset * projection);
            Vector2 resolution = new Vector2(w, h);
            resolutionParam.SetValue(resolution);
            depthTextureParam.SetValue(depthTexture);

            edgeStrengthParam.SetValue(edgeStrength);
            depthMultiplyerParam.SetValue(multiplyer);
            depthThresholdParam.SetValue(depthThreshold);
        }


        #endregion
    }
}
