using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Innovation
{
    // Applies a post processing effect to a texture or the frame buffer
    public class PostProcessor : Component, I2DComponent
    {
        // The post processor fx file
        public Effect Effect;

        // Width and height the the render target/frame buffer
        protected int Width;
        protected int Height;

        // Texture that will processed
        Texture2D input;

        public Texture2D Input
        {
            get { return input; }
            set
            {
                input = value;

                if (Effect.Parameters["InputTexture"] != null)
                    Effect.Parameters["InputTexture"].SetValue(value);
            }
        }

        // Draw rectangle
        public Rectangle Rectangle { get { return new Rectangle(0, 0, Width, Height); } set { this.Width = value.Width; this.Height = value.Height; } }

        public PostProcessor()
            : base()
        {
            Setup(null, Engine.GraphicsDevice.Viewport.Width, Engine.GraphicsDevice.Viewport.Height);
        }

        public PostProcessor(Effect Effect, int Width, int Height)
            : base()
        {
            Setup(Effect, Width, Height);
        }

        public PostProcessor(Effect Effect, int Width, int Height, GameScreen Parent)
            : base(Parent)
        {
            Setup(Effect, Width, Height);
        }

        // Set the effect, width, and height, and inititalize the Input texture
        void Setup(Effect Effect, int Width, int Height)
        {
            this.Effect = Effect;
            Input = new Texture2D(Engine.GraphicsDevice, 1, 1);
            Input.SetData<Color>(new Color[] { Color.White });
            this.Width = Width;
            this.Height = Height;
        }

        // Gets the current scene texture from the frame buffer
        public void GetInputFromFrameBuffer()
        {
            // Make sure we are working with a resolve texture
            if (!(Input is ResolveTexture2D))
                Input = GraphicsUtil.CreateResolveTexture();

            // Then resolve the frame buffer to the Input texture
            Engine.GraphicsDevice.ResolveBackBuffer((ResolveTexture2D)Input);
        }

        public override void Draw()
        {
            Engine.GraphicsDevice.Clear(Color.Black);

            // Begin in a mode that will overrite everything and draw immediately
            Engine.SpriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
            Effect.Begin();

            // For each pass...
            foreach (EffectPass pass in Effect.CurrentTechnique.Passes)
            {
                pass.Begin();
                // Draw the input texture with the effect applied
                Engine.SpriteBatch.Draw(Input, Rectangle, Color.White);
                pass.End();
            }

            Effect.End();
            Engine.SpriteBatch.End();

            base.Draw();
        }
    }
}