#ifndef MOCKS_H
#define MOCKS_H

#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

// 1. Definicje typów z tdefs.h
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;

// 2. Struktury pomocnicze (symulacja wejść/wyjść sprzętowych)

// Struktury parametrów analogowych (np. przekładniki)
struct param_I_struct {
 float znam_wtor; // np. 1.0 lub 5.0 A
 float znam_pierw; // np. 400.0 A
};
struct param_U_struct {
 float znam_wtor; // np. 100.0 V
 float znam_pierw; // np. 110000.0 V
};
// 3. Mockowanie funkcji systemowych z helper.h
// Funkcje te w oryginale mapują pamięć. Na PC po prostu przypisujemy adresy.

// Włączamy helper.h - zawiera definicje struktur i funkcji
#include <helper.h>

// static inline int set_float_ptr(float *in_ptr, float **logic_ptr) {
//     *logic_ptr = in_ptr; // Przypisz adres zmiennej symulowanej do wskaźnika w logice
//     return 0;
// }

// static inline int set_bit_ptr_struct(struct binary_io *in_ptr, struct binary_io **logic_ptr) {
//     *logic_ptr = in_ptr;
//     return 0;
// }

// Obsługa wskaźników (void*)
// static inline int set_pointer_in_ptr(u32 *in_ptr, u32 **logic_ptr) {
//     *logic_ptr = (u32*)in_ptr; 
//     return 0;
// }

// static inline int set_pointer_out_ptr(u32 *out_ptr, u32 **logic_ptr) {
//     *logic_ptr = (u32*)out_ptr;
//     return 0;
// }

// // Funkcja pomocnicza check_struct
// static inline int check_struct(struct binary_io *ptr) {
//     return ptr->val;
// }

// // Funkcja ustawiająca wyjścia
// static inline void check_and_set_struct(u8 val, struct binary_io **out_ptr) {
//     if (*out_ptr) (*out_ptr)->val = val;
// }
// static inline void clear_struct(struct binary_io **out_ptr) {
//     if (*out_ptr) (*out_ptr)->val = 0;
// }

// 4. Funkcje matematyczne specyficzne dla platformy
// _rcpsp to zazwyczaj "reciprocal square root" (1/sqrt)
static inline float _rcpsp(float x) {
    if (x == 0.0f) return 0.0f; // Zabezpieczenie
    return 1.0f / sqrtf(x);
}

// Funkcje fazy (uproszczone dla testu)
static inline float get_phase(float im, float re) {
    return atan2f(im, re) * 180.0f / 3.14159265f;
}

static inline float get_phase_diff(float p1, float p2) {
    float diff = p1 - p2;
    if (diff > 180.0f) diff -= 360.0f;
    if (diff < -180.0f) diff += 360.0f;
    return diff;
}

// Funkcja sprawdzająca opóźnienia (timer)
// W teście na PC musisz symulować upływ czasu.
// Tu prosta implementacja inkrementująca licznik.
// 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 {
//         // Histereza/podtrzymanie (uproszczone)
//         if (*counter > 0) (*counter)--;
//         if (*counter == 0) *out = 0;
//     }
// }

// Atrapa funkcji czy_test_R - zdefiniowana w helper.h



// 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)
};


#endif
