#pragma once

class Phase
{
	public:
		Phase(const double v, const double r1, const double r2, const double l, const double c1) : V(v), R1(r1), R2(r2), L(l), C1(c1) {}

		static double Freq;
		static long Update;
		static double Quant;

	private:
		double V;
		double R1;
		double R2;
		double L;
		double C1;

		double Cf = 0;
		double Rf = 0;

		double Integ_L = 0;
		double Integ_C1 = 0;

		double Integ_Cf = 0;

		static double C2;
		static double Buffer_C2;
		static double Integ_C2;

		static long Count;

		static unsigned long Step;

	public:
		double Current;
		double Current_Mid;
		double Voltage;
		static double Buffer;

	public:
		
		void filter(const double r, const double c) { Cf = c; Rf = r; }
		void set(const double c2);
		void convert(const bool on, const long compare);

    public:
		static unsigned long buffer();

	public:
		void update(const double v, const double r1, const double r2, const double l, const double c1) { V = v; R1 = r1; R2 = r2; L = l; C1 = c1; }
		static void freq(double f, long u) { Freq = f; Update = u; Quant = (Freq * Update); }
};

double Phase::Freq = 84000.0;
long Phase::Update = 100;  // 100%
double Phase::Quant = (Freq * Update);

double Phase::C2;
double Phase::Buffer_C2;
double Phase::Integ_C2;
long Phase::Count;
double Phase::Buffer;
unsigned long Phase::Step;

void Phase::set(const double c2)
{
	Integ_L = 0;
	Integ_C1 = 0;
	C2 = c2;
	Buffer_C2 = 0;
	Integ_C2 = 0;
	Count = 0;
	Step = 0;
}

void Phase::convert(const bool on, const long compare)
{
	bool pulse = compare > Count;
	//---
	double var1 = V - (Integ_L * R1) - Integ_C1;
	var1 = var1 / (R1 * C1);
	Integ_C1 += var1 / Quant;
	Voltage = Integ_C1;
	//---
	double var2 = on ? (pulse ? Integ_C1 : Integ_C1 - Integ_C2) : 0.0;
	var2 -= Integ_L * R2;
	var2 /= L;
	Integ_L += var2 / Quant;
	Current = Integ_L;
	//---
	Buffer_C2 += ((on && pulse) ? 0.0 : Integ_L);
	//---
	double filt = Current - Integ_Cf;
	filt = filt / (Rf * Cf);
	Integ_Cf += filt / Quant;
	Current_Mid = Integ_Cf;
}

unsigned long Phase::buffer()
{
	Count++;
	if (Count >= Update) Count = 0;
	//---
	Buffer_C2 /= C2;
	Integ_C2 += Buffer_C2 / Quant;
	Buffer_C2 = 0;
	//---
	Buffer = Integ_C2;
	//---
	return Step++;
}
