// Symulacja funkcji z helper.h
static inline int set_float_ptr(float *src, float **dst)
{
    *dst = src;
    return 0;
}

static inline int set_bit_ptr_struct(struct binary_io *src, struct binary_io **dst)
{
    *dst = src;
    return 0;
}

static inline int set_pointer_in_ptr(u32 *src, u32 **dst)
{
    *dst = src;
    return 0;
}

static inline int set_pointer_out_ptr(u32 *src, u32 **dst)
{
    *dst = src;
    return 0;
}

static inline int check_struct(struct binary_io *ptr)
{
    return (ptr && ptr->val) ? 1 : 0;
}

static inline void check_and_set_struct(u8 condition, struct binary_io **ptr)
{
    if (*ptr)
        (*ptr)->val = condition ? 1 : 0;
}

static inline void clear_struct(struct binary_io **ptr)
{
    if (*ptr)
        (*ptr)->val = 0;
}

// Funkcja testowa (zwraca 0 w normalnym trybie)
static inline int czy_test_R() { return 0; }
// Szybka odwrotność pierwiastka (Reciprocal Square Root)
static inline float _rcpsp(float x)
{
    if (x <= 1e-9f)
        return 0.0f; // Zabezpieczenie przed dzieleniem przez zero
    return 1.0f / sqrtf(x);
}

// Funkcje kątowe (e_phi.h)
static inline float get_phase(float y, float x)
{
    return atan2f(y, x) * 180.0f / 3.14159265f;
}

static inline float get_phase_diff(float angle1, float angle2)
{
    float diff = angle1 - angle2;
    while (diff <= -180.0f)
        diff += 360.0f;
    while (diff > 180.0f)
        diff -= 360.0f;
    return diff;
}

// Timer / Układ opóźniający (filtr P)
// Liczy czas w pętlach programu
static inline void sprawdz_P(u8 *out, u8 cond_start, u8 cond_reset, short *counter, int time_set, int time_reset)
{
    if (cond_reset)
    {
        *counter = 0;
        *out = 0;
    }
    else if (cond_start)
    {
        if (*counter < time_set)
            (*counter)++;
        if (*counter >= time_set)
            *out = 1;
    }
    else
    {
        if (*counter > 0)
            (*counter)--;
        if (*counter == 0)
            *out = 0;
    }
}

// Struktura dla pojedynczej strefy wielokątnej (poligonalnej)
struct n_pol_struct
{
    float Rr, Xr;             // Granice Rezystancji i Reaktancji (prawo/góra)
    float Rp, Xp;             // Granice (lewo/dół lub po przesunięciu kp)
    float Z, Zp;              // Impedancja graniczna (moduł)
    float Rrtanfi1, Rptanfi1; // Granice nachylone
};

// Struktura wyjścia
struct wyjscie_struct
{
    float przekladnia;
    void *Zdist_dw; // Wskaźnik void na log->dw
    int *on;        // Wskaźnik na log->nast_.on_
    u8 SOTF_zwrotnie;
};

// Struktura obliczonych nastaw (log->nast_)
struct nast_struct
{
    int on_;
    int bl_;
    int Bl_L[6]; // Blokady Load
    int z6_kolo;

    float ReK1, ImK1;
    float ReKr, ImKr;
    float ReKrown, ImKrown;
    float Krown_ignac;

    float kp, kpp, kpk;
    float kp_obc, kpp_obc;

    int typ[6]; // Typy stref
    float tanfi1, tanfi2;

    struct n_pol_struct n_pol[6][2]; // [strefa][typ pętli: 0=fazowa, 1=miedzyfazowa]

    float Xr1f, Xr1fp;
    float Xr1Wf, Xr1Wfp;
    float Igr, Igrp;
    float Zgr;
    int kierunek[6];

    float XKR, XKX, KL;
    float RLf, RLr;
    float Iogr, khio, Uomin;

    struct wyjscie_struct wyjscie;
};

// Struktura zmiennych wewnętrznych (pomiary, flagi, liczniki) -> log->dw
struct Z_measurement
{
    float R[9], X[9], Z[9], E[9]; // 9 pętli pomiarowych
    float absR[9], absX[9];
    float XRtanfi1_noabs[9], XRtanfi2[9];
};

struct dw_struct
{
    float I1, I2, I3, U1, U2, U3;
    struct Z_measurement Z;
    u8 Igr[6]; // Warunki prądowe

    void *log_ptr; // Wskaźnik zwrotny na logic

    u8 XKp[6][9], XKm[6][9]; // Kierunkowość
    u8 BL_Load[9];           // Blokada od obciążenia
    u8 Zm[9];                // Zmienne pomocnicze

    // Liczniki czasu (timery)
    short liczpIo;
    short liczp11[6][9], liczp12[6][9], liczp10[9];
    short liczps[6][9];
    short liczKdod;

    u8 Iogr;   // Przekroczenie I0 granicznego
    u8 Kp, Km; // Kierunek (+/-)

    u8 P_s[6][9];   // Pobudzenia surowe
    u8 P_sss[6][9]; // Pobudzenia super surowe?
    u8 Pbk[6][9];   // Pobudzenia bezkierunkowe
    u8 P[6][9];     // Pobudzenia finalne (kierunkowe)
};

// Wejścia IO - wskaźniki na zmienne zewnętrzne
struct ZDistA_komp_io
{
    struct binary_io *bl_in;
    struct binary_io *bl_k_in;

    float *i1_orta_float_in, *i1_ortb_float_in, *i1_float_in;
    float *i2_orta_float_in, *i2_ortb_float_in, *i2_float_in;
    float *i3_orta_float_in, *i3_ortb_float_in, *i3_float_in;

    float *u1_orta_float_in, *u1_ortb_float_in, *u1_float_in;
    float *u2_orta_float_in, *u2_ortb_float_in, *u2_float_in;
    float *u3_orta_float_in, *u3_ortb_float_in, *u3_float_in;

    float *u12_orta_float_in, *u12_ortb_float_in, *u12_float_in;
    float *u23_orta_float_in, *u23_ortb_float_in, *u23_float_in;
    float *u31_orta_float_in, *u31_ortb_float_in, *u31_float_in;

    // Składowe symetryczne / dodatkowe
    float *i1_zg_orta_float_in, *i1_zg_ortb_float_in, *i1_zg_float_in; // I1 (zgodna)
    float *i2_pr_orta_float_in, *i2_pr_ortb_float_in, *i2_pr_float_in; // I2 (przeciwna)
    float *io_orta_float_in, *io_ortb_float_in, *io_float_in;          // I0 (zerowa)

    float *u1_zg_orta_float_in, *u1_zg_ortb_float_in, *u1_zg_float_in;
    float *u2_pr_orta_float_in, *u2_pr_ortb_float_in, *u2_pr_float_in;
    float *uo_orta_float_in, *uo_ortb_float_in, *uo_float_in;

    u32 *i_param_an_ptr_in;
    u32 *u_param_an_ptr_in;

    struct binary_io *test_in;
    struct binary_io *deakt_in;

    // Kompensacja linii równoległej
    float *i_rown_orta_float_in;
    float *i_rown_ortb_float_in;
    u32 *i_rown_an_ptr_in;

    struct binary_io *wyl_in;

    // Wyjścia (Pobudzenia) - wskaźniki na struct binary_io
    struct binary_io *P1W_L1E_out, *P1W_L2E_out, *P1W_L3E_out;
    struct binary_io *P1W_L1L2_out, *P1W_L2L3_out, *P1W_L3L1_out;

    struct binary_io *P1_L1E_out, *P1_L2E_out, *P1_L3E_out;
    struct binary_io *P1_L1L2_out, *P1_L2L3_out, *P1_L3L1_out;

    struct binary_io *P2_L1E_out, *P2_L2E_out, *P2_L3E_out;
    struct binary_io *P2_L1L2_out, *P2_L2L3_out, *P2_L3L1_out;

    struct binary_io *P3_L1E_out, *P3_L2E_out, *P3_L3E_out;
    struct binary_io *P3_L1L2_out, *P3_L2L3_out, *P3_L3L1_out;

    struct binary_io *P4_L1E_out, *P4_L2E_out, *P4_L3E_out;
    struct binary_io *P4_L1L2_out, *P4_L2L3_out, *P4_L3L1_out;

    struct binary_io *P5_L1E_out, *P5_L2E_out, *P5_L3E_out;
    struct binary_io *P5_L1L2_out, *P5_L2L3_out, *P5_L3L1_out;

    u32 *wy_ptr_out;

    // Debug
    float *z1_float_out, *z2_float_out, *z3_float_out;
    float *z4_float_out, *z5_float_out, *z6_float_out;
};

// Struktura parametrów (Nastawy)
struct ZDistA_komp_params
{
    long bity;
    float Kk1, Kk1_kat;
    float KkC, KkC_kat;
    float kp, kp_obc;
    int Typ0, Typ1, Typ2, Typ3, Typ4, Typ5;
    float fi1, fi2, fi3, fi4, fi5;

    // Rezystancje/Reaktancje dla pętli (dużo zmiennych)
    // Zastępujemy je blokiem lub listą na podstawie kodu init
    double R1W_Zf1W_LE, R1W_Zf1W_LL;
    double R1_Zf1_LE, R1_Zf1_LL;
    double R2_Zf2_LE, R2_Zf2_LL;
    double R3_Zf3_LE, R3_Zf3_LL;
    double R4_Zf4_LE, R4_Zf4_LL;
    double R5_Zf5_LE, R5_Zf5_LL;

    double X1W_Zr1W_LE, X1W_Zr1W_LL;
    double X1_Zr1_LE, X1_Zr1_LL;
    double X2_Zr2_LE, X2_Zr2_LL;
    double X3_Zr3_LE, X3_Zr3_LL;
    double X4_Zr4_LE, X4_Zr4_LL;
    double X5_Zr5_LE, X5_Zr5_LL;

    float I_min, Iomin;
    int K0, K1, K2, K3, K4, K5;

    float RLf, RLr, Iokh, Uomin;
    float Krown, Krown_kat;
};

struct ZDistA_komp_args
{
    struct ZDistA_komp_io io;
    struct ZDistA_komp_params params;
};

// Główna struktura stanu logicznego (Instance Data)
struct ZDistA_komp_logic
{
    struct binary_io stan_bl;
    struct binary_io Bl_K;

    // Wskaźniki na pomiary
    float *I1_orta, *I1_ortb, *I1;
    float *I2_orta, *I2_ortb, *I2;
    float *I3_orta, *I3_ortb, *I3;

    float *U1_orta, *U1_ortb, *U1;
    float *U2_orta, *U2_ortb, *U2;
    float *U3_orta, *U3_ortb, *U3;

    float *U12_orta, *U12_ortb, *U12;
    float *U23_orta, *U23_ortb, *U23;
    float *U31_orta, *U31_ortb, *U31;

    float *sI1_orta, *sI1_ortb, *sI1; // zgodna
    float *sI2_orta, *sI2_ortb, *sI2; // przeciwna
    float *sI0_orta, *sI0_ortb, *sI0; // zerowa

    float *sU1_orta, *sU1_ortb, *sU1;
    float *sU2_orta, *sU2_ortb, *sU2;
    float *sU0_orta, *sU0_ortb, *sU0;

    struct param_I_struct *param_I;
    struct param_U_struct *param_U;

    struct binary_io test;
    struct binary_io deakt;

    float *I_row_orta, *I_row_ortb;
    struct param_I_struct *param_I_rown;

    struct binary_io wyl;

    // Wyjścia logiczne (wskaźniki na struktury binary_io)
    // Uwaga: w kodzie init jest: set_bit_ptr_struct(..., &log->P1W_L1E)
    // To sugeruje, że w strukturze logic te pola to WSKAŹNIKI (struct binary_io*)
    struct binary_io *P1W_L1E, *P1W_L2E, *P1W_L3E;
    struct binary_io *P1W_L1L2, *P1W_L2L3, *P1W_L3L1;

    struct binary_io *P1_L1E, *P1_L2E, *P1_L3E;
    struct binary_io *P1_L1L2, *P1_L2L3, *P1_L3L1;

    struct binary_io *P2_L1E, *P2_L2E, *P2_L3E;
    struct binary_io *P2_L1L2, *P2_L2L3, *P2_L3L1;

    struct binary_io *P3_L1E, *P3_L2E, *P3_L3E;
    struct binary_io *P3_L1L2, *P3_L2L3, *P3_L3L1;

    struct binary_io *P4_L1E, *P4_L2E, *P4_L3E;
    struct binary_io *P4_L1L2, *P4_L2L3, *P4_L3L1;

    struct binary_io *P5_L1E, *P5_L2E, *P5_L3E;
    struct binary_io *P5_L1L2, *P5_L2L3, *P5_L3L1;

    float *z[6]; // Wyjścia debugowe

    struct nast_struct nast_;
    struct dw_struct dw;

    int l_nieustalony;
};

