# This file includes node dynamics 

abstract type AbstractNode end

"""
    $TYPEDEF

Lorenz dyanmics 

# Fields 

    $TYPEDFIELDS
"""
@kwdef mutable struct Lorenz <: AbstractNode
    σ::Float64 = 10.0
    β::Float64 = 8 / 3
    ρ::Float64 = 35.0
    x::Vector{Float64} = rand(3)
    t::Float64 = 0.0
end

function (node::Lorenz)(dx, x, u, t)
    dx[1] = node.σ * (x[2] - x[1])
    dx[2] = x[1] * (node.ρ - x[3]) - x[2]
    dx[3] = x[1] * x[2] - node.β * x[3]
end

dimension(::Type{Lorenz}) = 3

"""
    $TYPEDEF

Rossler dyanmics 

# Fields 

    $TYPEDFIELDS
"""
@kwdef mutable struct Rossler <: AbstractNode
    a::Float64 = 0.2
    b::Float64 = 0.2
    c::Float64 = 5.7
    x::Vector{Float64} = rand(3)
    t::Float64 = 0.0
end

function (node::Rossler)(dx, x, u, t)
    dx[1] = -x[2] - x[1]
    dx[2] = x[1] + node.a * x[2]
    dx[3] = node.b + x[3] * (x[1] - node.c)
end

dimension(::Type{Rossler}) = 3

# Piecewise Chua diode 
@kwdef struct Diode
    a::Float64 = -8 / 7
    b::Float64 = -5 / 7
end

function (diode::Diode)(x)
    if x > 1
        diode.b * x + diode.a - diode.b
    elseif abs(x) ≤ 1
        diode.a * x
    else
        diode.b * x - diode.a + diode.b
    end
end

@kwdef mutable struct Chua <: AbstractNode
    diode::Diode = Diode()
    α::Float64 = 9.0
    β::Float64 = 100 / 7
    x::Vector{Float64} = 1e-3 * rand(3)
    t::Float64 = 0.00
end

function (ds::Chua)(dx::AbstractVector, x::AbstractVector, u, t)
    dx[1] = ds.α * (x[2] - x[1] - ds.diode(x[1]))
    dx[2] = x[1] - x[2] + x[3]
    dx[3] = -ds.β * x[2]
end
