"""
Author: socHACKi
This class is to be used for linear modeling of PLL systems.  There are a few
architectures available for the pll's that are modeled by this class.
"""

import numpy as np

from socHACKi.socHACKiUtilityPackage import AttrDict
from simpyle_systems.synthesizer import PhaseNoise

# %%
import matplotlib.pyplot as plt
# %%
# Synthesizer Values
Kv = 121 # In MHZ / Volt
Kp = 0.000397887 # In Amps / Rad
phase_detector_FOM = -239
phase_detector_frequency = 10000000
N = 3280 # Feedback divider setting
M = 1 # Reference Divider Setting
# %%
# Phase Noise Information
phase_noise_offset_frequencies_hz = [0.1, 1, 10, 100, 1000,
                                     10000, 100000, 1000000, 10000000]
#loop_filter_output_voltage_noise =
loop_filter_output_phase_noise = \
    PhaseNoise([[0.1,-144], [1,-165], [10,-167],
                [100,-168], [1000,-168], [10000,-169]],
               0,
               50)
vco_phase_noise = \
    PhaseNoise([[100,-30], [1000,-60], [10000,-91],
                [100000,-114], [1000000,-134], [10000000,-153]],
               5.8482e9,
               50)

reference_phase_noise = \
    PhaseNoise([[0.1,-87], [1,-119], [10,-140],
                [100,-157], [1000,-160], [10000,-165]],
               10e6,
               50)
# %%
# Loop Filter Component Values
C1 = 37.1e-9
C2 = 681e-9
C3 = 24.2e-9
C4 = 7.8e-9
R2 = 31.7
R3 = 19.9
R4 = 110
# %%
# Passive Loop FIlter Model
# Generate Passive Loop Filter Coefficients From Component Values

# +------+                                                           +--------+
# |      |                          R3                 R4            |  Kvco  |
# | Kpd  +-------+----------+----+/\/\/\+-----+-----+/\/\/\+----+----+   ---  |
# |      |       |          |                 |                 |    |    s   |
# +------+       |          |                 |                 |    +--------+
#                +          +                 +                 +
#               ___        ___               ___               ___
#            C1 ___     C2 ___            C3 ___            C4 ___
#                +          +                 +                 +
#                |          |                 |                 |
#                +          +                 +                 +
#               _|_         \                _|_               _|_
#               \ /      R2 /                \ /               \ /
#                -          \                 -                 -
#                           /
#                          _|_
#                          \ /
#                           -

A0 = C1 + C2 + C3 + C4

A1 = (C2 * R2 * (C1 + C3 + C4)) + \
     (R3 * (C1 + C2) * (C3 + C4)) + \
     (C4 * R4 * (C1 + C2 + C3))

A2 = ((C1 * C2 * R2 * R3 * (C3 + C4)) + \
      (C4 * R4 * ((C2 * C3 * R3) + \
                  (C1 * C3 * R3) + \
                  (C1 * C2 * R2) + \
                  (C2 * C3 * R2)
                  )
      )
     )

A3 = C1 * C2 * C3 * C4 * R2 * R3 * R4

T2 = R2 * C2
 # %%
 # Synthesizer Functions
def loop_filter_transfer_impedance(frequency, T2, A3, A2, A1, A0):
    s = 1j * 2 * np.pi * frequency
    return ((1 + (s * T2)) /
            (s * ((A3 * np.power(s, 3)) +
                  (A2 * np.power(s, 2)) +
                  (A1 * s) +
                  (A0)
                 )