using System;
using GraphiXNA.Cameras;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using GraphiXNA.Graphics;

namespace GraphiXNA.Materials
{
    public class NormalMapping : MaterialEffect
    {
        public Texture2D ColorTexture = null;
        public Texture2D NormalHeightTexture = null;

        private Light _Light = new Light(new Vector3(0, -1, 1));

        public Vector4 MaterialAmbient = new Vector4(0.2f, 0.2f, 0.2f, 1);
        public Vector4 MaterialDiffuse = new Vector4(0.8f, 0.8f, 0.8f, 1);
        public Vector4 MaterialSpecular = new Vector4(0.0f, 0.0f, 0.0f, 1);
        public float MaterialShininess = 0;

        public NormalMapping(GraphicsDevice graphicsDevice)
            : base(graphicsDevice)
        {
            _Effect = ResourceManager.GetNormalMappingEffect(GraphicsDevice, false);
        }


        public Light Light
        {
            get { return _Light; }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException();
                }
                _Light = value;
            }
        }

        public override void SetWorld(Camera camera, ref Matrix world)
        {
            _Effect.Parameters["WorldViewProjection"].SetValue(world * camera._ViewProjection);
            _Effect.Parameters["World"].SetValue(world);
            _Effect.Parameters["WorldIT"].SetValueTranspose(Matrix.Invert(world));
            _Effect.Parameters["CameraPosition"].SetValue(camera.Position);
        }

        internal override void OnBegin()
        {
            _Effect.Parameters["colorMapTexture"].SetValue(ColorTexture);
            _Effect.Parameters["normalMapTexture"].SetValue(NormalHeightTexture);

            _Effect.Parameters["LightDirection"].SetValue(_Light.Direction);
            _Effect.Parameters["LightPosition"].SetValue(_Light.Position);
            _Effect.Parameters["LightRange"].SetValue(_Light.Range);
            _Effect.Parameters["LightSpotInnerCone"].SetValue(_Light.SpotInnerCone);
            _Effect.Parameters["LightSpotOuterCone"].SetValue(_Light.SpotOuterCone);

            _Effect.Parameters["MaterialAmbient"].SetValue(MaterialAmbient);
            _Effect.Parameters["MaterialDiffuse"].SetValue(MaterialDiffuse);
            _Effect.Parameters["MaterialSpecular"].SetValue(MaterialSpecular);
            _Effect.Parameters["MaterialShininess"].SetValue(MaterialShininess);

            switch (_Light.LightT)
            {
                case Light.LightType.Directional:
                    _Effect.CurrentTechnique = _Effect.Techniques[0];
                    break;
                case Light.LightType.Point:
                    _Effect.CurrentTechnique = _Effect.Techniques[1];
                    break;
                case Light.LightType.Spot:
                    _Effect.CurrentTechnique = _Effect.Techniques[2];
                    break;
                default:
                    _Effect.CurrentTechnique = _Effect.Techniques[0];
                    break;
            }

            //_Effect.CommitChanges();
        }
    }
}
