using System;
using System.Collections.Generic;
using System.Text;
using Vortex;
using Vortex.Drawing;

namespace Vortex.Tutorials.GameDemo
{
    class FireSystem
    {
        List<Sprite> _Sprites;
        List<Texture> _Textures;
        List<FireParticle> _Particles;

        Sprite _CoverSprite;

        public Vector2 Source;
        public float ParticleLife=300.0f;
        public float SourceDelta = 15.0f;
        public ColorU ParticleColor=ColorU.Yellow;
        public float ParticleSpeed=0.2f;
        public int ParticleCount;
        public ColorGradient ColorGradient;
        public float StartSize=0.3f;
        public float EndSize=0.1f;
        public float StartAlpha = 1.0f;
        public float EndAlpha = 0.0f;
        public Blending Blending=Blending.Normal;
        


        public FireSystem(int ParticleCount)
        {
            _Sprites = new List<Sprite>();
            _Textures = new List<Texture>();
            this.ParticleCount = ParticleCount;
            _Particles = new List<FireParticle>(ParticleCount);
            ColorGradient = new ColorGradient();
        }

        public void Init()
        {
            for (int i = 0; i < ParticleCount; i++)
            {
                _Particles.Add(new FireParticle());
            }
        }

        public void AddSprite(string file)
        {
            Texture T = new Texture(file);
            Sprite S = T.ToSprite();
            _Sprites.Add(S);
            _Textures.Add(T);
        }

        public void AddCoverSprite(string file) {

            Texture T = new Texture(file);
            _CoverSprite = T.ToSprite();
        }

        public void Update(GameTime time)
        {
            foreach (FireParticle P in _Particles)
            {
                P.Update(time);

                if (P.Life <= 0.0f)
                {
                    P.InitialLife = ParticleLife + Vortex.Utils.RandomUtils.NextFloat(-100.0f, 100.0f);
                    P.Life = P.InitialLife;
                    P.Position = new Vector2(
                        Source.X + Vortex.Utils.RandomUtils.NextFloat(-SourceDelta, +SourceDelta),
                        Source.Y + Vortex.Utils.RandomUtils.NextFloat(-SourceDelta, +SourceDelta));

                    P.Angle = Vortex.Utils.RandomUtils.NextFloat(0.0f, 3.14f);
                    P.Direction = new Vector2(Vortex.Utils.RandomUtils.NextFloat(-0.34f, 0.35f), -1.0f);
                    P.Direction.Normalize();
                    P.Speed = ParticleSpeed;
                    P.SpriteIndex = Vortex.Utils.RandomUtils.NextInt(0, _Sprites.Count - 1);
                }
                else
                {
                    float b = P.Life/P.InitialLife;
                    P.Size = StartSize - Math.Abs(StartSize - EndSize) *(1-b);
                    P.Alpha = StartAlpha - Math.Abs(StartAlpha - EndAlpha) * (1 - b);
                    P.Angle += 0.01f;
                    P.Color = ColorGradient.GetColor(1 - P.Life / P.InitialLife);
                    P.Color.A = Convert.ToByte(255 * P.Alpha);
                    P.Position += P.Speed * P.Direction * time.FrameTimeMs;
                }
            }
        }

        public void RenderParticle(FireParticle P, Canvas2D canvas)
        {
            Sprite S = _Sprites[P.SpriteIndex];
            canvas.DrawSprite(
                P.Position,
                new Vector2(S.Size.X * P.Size, S.Size.Y * P.Size),
                P.Angle,
                S,
                P.Color);
        }

        public void Render(Canvas2D canvas)
        {
            canvas.Blending = Blending;
            for (int i = 0; i < _Sprites.Count; i++ )
                foreach (FireParticle P in _Particles)
                {
                    if (P.SpriteIndex==i)
                        RenderParticle(P, canvas);
                }

            if (_CoverSprite != null)
            {
                canvas.DrawSprite(Source, _CoverSprite, ColorU.White);
            }

            canvas.Blending = Blending.Normal;
        }

        public void Dispose()
        {
            foreach (Texture T in _Textures)
            {
                T.Dispose();
            }
        }



    }
}
