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

namespace EZGL2DexampleParticles
{
    class Particle
    {
        public float x { get; set; }
        public float y { get; set; }
        public float dx { get; set; }
        public float dy { get; set; }
        public float angle { get; set; }
        public float speed { get; set; }

        private int ticks;

        public Particle()
        {

        }

        public void spawn(float x, float y, float angle, float speed)
        {
            this.angle = angle;
            this.x = x;
            this.y = y;
            this.speed = speed;
            dx = (float)Math.Cos(angle) * speed;
            dy = (float)Math.Sin(angle) * speed;

        }

        public bool update( int screenWidth, int screenHeight )
        {
            ticks++;

            x += dx;
            y += dy;
            if (x < -32) return true;
            if (x > screenWidth + 32) return true;
            if (y < -32) return true;
            if (y > screenHeight + 32) return true;

            return false;
        }


    }

    class ParticleSystem
    {

        public IList<Particle> particles = new List<Particle>();

        private int size;
        private int max;
        private Random random = new Random();
        private int ticks;

        public ParticleSystem(int numParticles)
        {
            this.max = numParticles;
            this.size = 0;

            for (int i = 0; i < (max + 1); i++)
            {
                Particle p = new Particle();
                particles.Add(p);
            }
        }

        private void spawn(float x, float y, float angle, float speed)
        {
            if (size < max)
            {
                particles[size].spawn(x, y,
                                       angle,
                                       speed);
                size++;
            }

        }

        private void kill(int index)
        {
            if (index < size)
            {
                size--;
                particles[max] = particles[index];
                particles[index] = particles[size];
                particles[size] = particles[max];
            }
        }

        public void update(int screenWidth, int screenHeight)
        {
            ticks++;
            float angle = ticks / 4.0f;
            float dx = ((float)Math.Cos(ticks / 40.0d) + (float)Math.Cos(ticks / 74.0d)) * 150;
            float dy = ((float)Math.Sin(ticks / 54.0d) + (float)Math.Cos(ticks / 30.0d)) * 100;
            float x = screenWidth / 2 - dx;
            float y = screenHeight/2 - dy;
            float speed = 8;
            spawn(x, y, angle, speed);
            spawn(x, y, angle + (float)(Math.PI / 2), speed);
            spawn(x, y, angle + (float)(Math.PI), speed);
            spawn(x, y, angle - (float)(Math.PI / 2), speed);

            angle = -ticks / 4.0f;
            x = screenWidth/2 + dx;
            y = screenHeight/2 + dy;
            spawn(x, y, angle, speed);
            spawn(x, y, angle + (float)(Math.PI / 2), speed);
            spawn(x, y, angle + (float)(Math.PI), speed);
            spawn(x, y, angle - (float)(Math.PI / 2), speed);

            for (int i = 0; i < size; i++)
            {
                if (particles[i].update(screenWidth, screenHeight))
                {
                    kill(i);
                }
            }
        }

        public void draw(GL2D.SpriteGL sprite)
        {
            for (int i = 0; i < size; i++)
            {
                Particle p = particles[i];
                GL2D.SpriteRotateScale((int)p.x, (int)p.y,
                                          (float)(p.angle * 180 / Math.PI),
                                          1, 1,
                                          GL2D.SpriteGL.FLIP_NONE,
                                          sprite);
                
            }
        }

    }
}
