using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

using EVE.EVEShaders;
using EVE.EVEObjects;
using EVE.EVECameras;
using EVE.EVELights;

namespace EVE.EVEGpgpu
{
    public class EVEGpKernel : EVEShader
    {
        private VertexPositionTexture[] verts;
        private VertexDeclaration declaration;

        public EVEGpKernel(string asset) : base(asset) { }

        internal override void LoadContent(GraphicsDevice myDevice, ContentManager myLoader)
        {
            base.LoadContent(myDevice, myLoader);

            verts = new VertexPositionTexture[] {
                new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1)),
                new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 0)),
                new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1)),
                new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1, 0))
            };

            declaration = new VertexDeclaration(myDevice, VertexPositionTexture.VertexElements);

        }

        public void PerformDebugDraw(GraphicsDevice myDevice, string technique, RenderTarget2D inRT)
        {
            int w = myDevice.PresentationParameters.BackBufferWidth;
            int h = myDevice.PresentationParameters.BackBufferHeight;

            myDevice.SetRenderTarget(0, null);
            RenderTarget2D oldRT = myDevice.GetRenderTarget(0) as RenderTarget2D;
            myDevice.Clear(Color.Black);



            myEffect.CurrentTechnique = myEffect.Techniques[technique];
            myEffect.Parameters["gTextureSlot1"].SetValue(inRT.GetTexture());            

            myEffect.Begin();
            foreach (EffectPass pass in myEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                myDevice.VertexDeclaration = declaration;
                myDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, verts, 0, 2);
                pass.End();
            }
            myEffect.End();


        }

        public void PerformCopy(GraphicsDevice myDevice, RenderTarget2D inRT, RenderTarget2D resultRT)
        {
            RenderTarget2D oldRT = myDevice.GetRenderTarget(0) as RenderTarget2D;

            myDevice.SetRenderTarget(0, resultRT);

            myEffect.CurrentTechnique = myEffect.Techniques["CopyArray"];
            myEffect.Parameters["gTextureSlot1"].SetValue(inRT.GetTexture());
            myEffect.Begin();
            myEffect.CurrentTechnique.Passes[0].Begin();
            myDevice.VertexDeclaration = declaration;
            myDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, verts, 0, 2);
            myEffect.CurrentTechnique.Passes[0].End();
            myEffect.End();

            myDevice.SetRenderTarget(0, oldRT);
        }

        public void CalculateSingleKernel(GraphicsDevice myDevice, string technique, RenderTarget2D tempRT, RenderTarget2D resultRT)
        {
            RenderTarget2D oldRT = myDevice.GetRenderTarget(0) as RenderTarget2D;
            myDevice.SetRenderTarget(0, tempRT);

            myDevice.Clear(Color.Black);


            //myEffect.CurrentTechnique = myEffect.Techniques[technique];

            myEffect.Begin();
            foreach (EffectPass pass in myEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                myDevice.VertexDeclaration = declaration;
                myDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, verts, 0, 2);
                pass.End();
            }
            myEffect.End();



            myDevice.SetRenderTarget(0, resultRT);


            myEffect.CurrentTechnique = myEffect.Techniques["CopyArray"];
            myEffect.Parameters["gTextureSlot1"].SetValue(tempRT.GetTexture());
            myEffect.Begin();
            myEffect.CurrentTechnique.Passes[0].Begin();
            myDevice.VertexDeclaration = declaration;
            myDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, verts, 0, 2);
            myEffect.CurrentTechnique.Passes[0].End();
            myEffect.End();

            myDevice.SetRenderTarget(0, oldRT);
        }

        public void CalculateSingleKernel(GraphicsDevice myDevice, string technique, RenderTarget2D inRT, RenderTarget2D tempRT ,RenderTarget2D resultRT)
        {
            RenderTarget2D oldRT = myDevice.GetRenderTarget(0) as RenderTarget2D;
            myDevice.SetRenderTarget(0, tempRT);

            myDevice.Clear(Color.Black);



            myEffect.CurrentTechnique = myEffect.Techniques[technique];
            myEffect.Parameters["gTextureSlot1"].SetValue(inRT.GetTexture());

            myEffect.Begin();
            foreach (EffectPass pass in myEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                myDevice.VertexDeclaration = declaration;
                myDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, verts, 0, 2);
                pass.End();
            }
            myEffect.End();



            myDevice.SetRenderTarget(0, resultRT);


            myEffect.CurrentTechnique = myEffect.Techniques["CopyArray"];
            myEffect.Parameters["gTextureSlot1"].SetValue(tempRT.GetTexture());
            myEffect.Begin();
            myEffect.CurrentTechnique.Passes[0].Begin();
            myDevice.VertexDeclaration = declaration;
            myDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, verts, 0, 2);
            myEffect.CurrentTechnique.Passes[0].End();
            myEffect.End();

            myDevice.SetRenderTarget(0, oldRT);
        }

        public void CalculateSingleKernel(GraphicsDevice myDevice, string technique, RenderTarget2D inRT1, RenderTarget2D inRT2, RenderTarget2D tempRT, RenderTarget2D resultRT)
        {
            RenderTarget2D oldRT = myDevice.GetRenderTarget(0) as RenderTarget2D;
            myDevice.SetRenderTarget(0, tempRT);

            myDevice.Clear(Color.Black);


            myEffect.CurrentTechnique = myEffect.Techniques[technique];
            myEffect.Parameters["gTextureSlot1"].SetValue(inRT1.GetTexture());
            myEffect.Parameters["gTextureSlot2"].SetValue(inRT2.GetTexture());

            myEffect.Begin();
            foreach (EffectPass pass in myEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                myDevice.VertexDeclaration = declaration;
                myDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, verts, 0, 2);
                pass.End();
            }
            myEffect.End();



            myDevice.SetRenderTarget(0, resultRT);


            myEffect.CurrentTechnique = myEffect.Techniques["CopyArray"];
            myEffect.Parameters["gTextureSlot1"].SetValue(tempRT.GetTexture());
            myEffect.Begin();
            myEffect.CurrentTechnique.Passes[0].Begin();
            myDevice.VertexDeclaration = declaration;
            myDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, verts, 0, 2);
            myEffect.CurrentTechnique.Passes[0].End();
            myEffect.End();

            myDevice.SetRenderTarget(0, oldRT);
        }

    }
}
