#pragma once
#include <vector>
#include <array>
#include <memory>
#include <string>

typedef std::array<float, 2> XYVector;

namespace Polyparti {
    class ParticleField {
    public:
        ParticleField();
        ~ParticleField();
        ParticleField(const ParticleField& other);
        ParticleField(ParticleField&& other) noexcept;
        ParticleField& operator=(const ParticleField& other);
        ParticleField& operator=(ParticleField&& other) noexcept;
        

        void addParticle(float x, float y, float vx, float vy);
        void deleteParticle(int index);
        void updateField(std::vector<XYVector> verticies, double time);
        const std::vector<XYVector>& getPositions() const;
        int getSize();
        void setColor(std::string newColor);
        int* getColor();
        void setCount(int count);
        int getCount();
        void setInterval(const float diff);
        void setDecay(const float t, const float d);
        bool isDead();

    private:
        struct ColCode;
        std::unique_ptr<ColCode> colcode;
    };

    class Room {
    private:
        struct ImplRoom;
        std::unique_ptr<ImplRoom> implRoom;
        struct fieldInfo {
            int count;
            float velocity, x, y, deg_start, deg_end, start, life, decayRate;
            int screenWidth, screenHeight;
            std::string color;
        };
        std::vector<fieldInfo> info, later;
        std::vector<ParticleField> field;
        std::string name;
        float x_min = 0, x_max = 0, y_min = 0, y_max = 0;
        inline static float interval = 1.0f / 60;
        inline static float screenWidth = 1920;
        inline static float screenHeight = 1080;
        int moreCount = 0;
    public:
        int fieldCount = 0;

        Room();
        Room(int w, int h);
        Room(int w, int h, int fps);
        ~Room();
        Room(const Room& other);
        Room(Room&& other) noexcept;
        Room& operator=(const Room& other);
        Room& operator=(Room&& other) noexcept;
    
        static void setFPS(const int fps) {
            interval = 1.0f / fps;
        }
        void addCorner(float x, float y);
        void checkCorners(); 
        std::vector<XYVector> getCorners(); //implement
        void loadRoom(std::string name);
        void loadParticles(std::string name);
        void rotateRoom(float degrees); 
        void initField(fieldInfo info); 
        void addFields();
        void updateFields(double time);
        ParticleField& getField(int index);
        void adjustInterval(const float pct);
        void reverseInterval();
        int getFieldCount();
        std::string getName();
    };

    class Beam : public ParticleField {

    };
};