#ifndef PARTICLE_H
#include "pixelGameEngine.h"
#include "defines.h"
using namespace olc;
#define PARTICLE_H

class Particle{
	public:
		vd2d pos;
		vd2d spd;
		vd2d acc;
		int lifetime; //In frames.
        bool wrap;
        Particle(vd2d pos,vd2d spd,vd2d acc,int lifetime,bool wrap=false)
        :pos(pos),spd(spd),acc(acc),lifetime(lifetime){};
        virtual void render(PixelGameEngine*game)=0;
        virtual void particleUpdate()=0;
        bool update() {
            spd+=acc;
            pos+=spd;
            if (wrap) {
                if (pos.x<0) {
                    pos.x+=WIDTH;    
                } else
                if (pos.y<0) {
                    pos.y+=HEIGHT;   
                }
                if (pos.x>WIDTH) {
                    pos.x-=WIDTH;    
                } else 
                if (pos.y>HEIGHT) {
                    pos.y-=HEIGHT;
                }
            }
            lifetime--;
            return lifetime>0;
        }
        vd2d GetPos() {
            return pos;
        }
        vd2d GetSpd() {
            return spd;
        }
        vd2d GetAcc() {
            return acc;
        }
        void SetPos(vd2d pos) {
            this->pos=pos;
        }
};

class LineParticle:public Particle{
    public:
        Pixel col;
        LineParticle(vd2d pos,vd2d spd,vd2d acc,int lifetime,Pixel col=WHITE,bool wrap=false)
        :col(col),Particle(pos,spd,acc,lifetime,wrap){}
        void particleUpdate()override{}
        void render(PixelGameEngine*game)override{
            game->DrawLineDecal(pos,pos+spd,col);
        }
};

class StaticLineParticle:public Particle{
    public:
        Pixel col;
        vd2d pos2;
        vd2d PickRandomPos() {
            return {rand()%100/100.0F*WIDTH,rand()%800/10.0F-40+HEIGHT/2};
        }
        StaticLineParticle(int lifetime,Pixel col=WHITE,bool wrap=false)
        :col(col),pos2(PickRandomPos()),Particle(PickRandomPos(),{0,0},{0,0},lifetime,wrap){}
        void particleUpdate()override{
            pos+={(rand()%100/100.0F-0.5)*20,(rand()%50/100.0F-0.25)*10};
            pos2+={(rand()%100/100.0F-0.5)*20,(rand()%50/100.0F-0.25)*10};
        }
        void render(PixelGameEngine*game)override{
            game->FillRectDecal(pos,pos2-pos,col);
        }
};

class SquareParticle:public Particle{
    private:
        vd2d size;
    public:
        Pixel col;
        SquareParticle(vd2d pos,vd2d size,vd2d spd,vd2d acc,int lifetime,Pixel col=WHITE,bool wrap=false)
        :col(col),size(size),Particle(pos,spd,acc,lifetime,wrap){}
        void particleUpdate()override{}
        void render(PixelGameEngine*game)override{
            game->FillRectDecal(pos,size,col);
        }
};

class WaterParticle:public Particle{
    private:
        vd2d size;
        vd2d PickRandomSpd() {
            return {rand()%60/10.0F-3,-rand()%100/10.0F-2};
        }
    public:
        Pixel col;
        WaterParticle(vd2d pos,vd2d size,vd2d acc,int lifetime,Pixel col=WHITE)
        :col(col),size(size),Particle(pos,PickRandomSpd(),acc,lifetime){}
        void particleUpdate()override{
            if (this->pos.y>HEIGHT) {
                this->spd=PickRandomSpd();
                this->pos={WIDTH/2,HEIGHT};
            }
        }
        void render(PixelGameEngine*game)override{
            game->FillRectDecal(pos,size,col);
        }
};

class FireParticle:public Particle{
    private:
        vd2d size;
        vd2d PickRandomSpd() {
            return {rand()%60/10.0F-3,(rand()%100/100.0F-0.5)*10};
        }
        vd2d PickRandomPos() {
            return {rand()%100/100.0F*WIDTH,HEIGHT/2};
        }
    public:
        Pixel col;
        FireParticle(vd2d size,vd2d acc,int lifetime,Pixel col=WHITE)
        :col(col),size(size),Particle(PickRandomPos(),PickRandomSpd(),acc,lifetime){}
        void particleUpdate()override{
            if (this->pos.y>HEIGHT) {
                this->spd=PickRandomSpd();
                this->pos=PickRandomPos();
            }
        }
        void render(PixelGameEngine*game)override{
            game->FillRectDecal(pos,size,col);
        }
};
#endif