#pragma once

class PhaseNorm
{
	public:
		PhaseNorm(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 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(double Load);

	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 PhaseNorm::Freq = 1000.0;
long PhaseNorm::Update = 100;  // 100%
double PhaseNorm::Quant = (Freq * Update);

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

void PhaseNorm::set(const double c2)
{
	Integ_L = Current = 1;
	Integ_C1 = Voltage = 5;
	C2 = c2;
	Buffer_C2 = Buffer = 5;
	Integ_C2 = 5;
	Count = 0;
	Step = 0;
}

void PhaseNorm::convert(const bool on, const long compare)
{
	double pulse = 1.0 - (((double)compare) / 100.0);
	if (!on) pulse = 1.0;
	//---
	double var1 = V - (Integ_L * R1) - Integ_C1;
	var1 = var1 / (R1 * C1);
	Integ_C1 += var1 / Quant;
	Voltage = Integ_C1;
	//---
	double var2 = Integ_C1 - Integ_C2 * pulse;
	var2 -= Integ_L * R2;
	var2 /= L;
	Integ_L += var2 / Quant;
	Current = Integ_L;
	//---
	Buffer_C2 += pulse * Integ_L;
}

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