# Path: beyond/errors.py
# class UnknownFrameError(_Unknown):
#     """Unknown frame (ITRF, EME2000, etc.)"""
# 
#     pass
# 
# class UnknownBodyError(_Unknown):
#     """Unknown Body (Earth, Moon, Sun, etc.)"""
# 
#     pass
# 
# Path: beyond/constants.py
# G = 6.6740831e-11
# class Body:
#     def __init__(self, name, mass, equatorial_radius, *, flattening=1, **kwargs):
#     def __repr__(self):
#     def __getattr__(self, name):
#     def mu(self):
#     def eccentricity(self):
#     def polar_radius(self):
#     def propagate(self, date):
# 
# Path: beyond/utils/matrix.py
# def rot3(theta):
#     """
#     Args:
#         theta (float): Angle in radians
#     Return:
#         Rotation matrix of angle theta around the Z-axis
#     """
#     return np.array(
#         [
#             [np.cos(theta), np.sin(theta), 0],
#             [-np.sin(theta), np.cos(theta), 0],
#             [0, 0, 1],
#         ]
#     )
# 
# def expand(m, rate=None):
#     """Transform a 3x3 rotation matrix into a 6x6 rotation matrix
# 
#     Args:
#         m (numpy.ndarray) : 3x3 matrix transforming a position vector
#             from frame1 to frame2
#         rate (numpy.array) : 1D 3 elements vector rate of frame2
#             expressed in frame1
#     Return:
#         numpy.ndarray : 6x6 rotation matrix
# 
#     Example:
# 
#     >>> m = np.array([[0, -1, 0], [-1, 0, 0], [0, 0, 1]])
#     >>> print(expand(m))
#     [[ 0. -1.  0.  0.  0.  0.]
#      [-1.  0.  0.  0.  0.  0.]
#      [ 0.  0.  1.  0.  0.  0.]
#      [ 0.  0.  0.  0. -1.  0.]
#      [ 0.  0.  0. -1.  0.  0.]
#      [ 0.  0.  0.  0.  0.  1.]]
#     >>> print(expand(m, rate=[1,2,3]))
#     [[ 0. -1.  0.  0.  0.  0.]
#      [-1.  0.  0.  0.  0.  0.]
#      [ 0.  0.  1.  0.  0.  0.]
#      [-3.  0. -2.  0. -1.  0.]
#      [ 0.  3.  1. -1.  0.  0.]
#      [ 1. -2.  0.  0.  0.  1.]]
#     """
# 
#     out = np.zeros((6, 6))
#     out[:3, :3] = m
#     out[3:, 3:] = m
# 
#     if rate is not None:
#         R = np.array(
#             [[0, -rate[2], rate[1]], [rate[2], 0, -rate[0]], [-rate[1], rate[0], 0]]
#         )
#         out[3:, :3] = -R @ m
# 
#     return out
# 
# Path: beyond/frames/local.py
# def to_local(frame, orbit, expanded=True):
#     """Provide the transformation matrix to convert a vector from an inertial frame
#     to a local orbital reference frame of choice
# 
#     Args:
#         frame (str): Name of the local orbital frame ('QSW' or 'TNW')
#         orbit (List[float]) : cartesian coordinates (length 6)
#         expanded (bool) : If ``True`` the returned matrix is 6x6, 3x3 otherwise
#     Return:
#         numpy.ndarray : Transformation matrix
# 
#     >>> delta_tnw = [1, 0, 0]
#     >>> p = [-6142438.668, 3492467.560, -25767.25680]
#     >>> v = [505.8479685, 942.7809215, 7435.922231]
#     >>> pv = p + v
#     >>> mat = to_local("TNW", pv, expanded=False).T
#     >>> delta_inert = mat @ delta_tnw
#     >>> all(delta_inert == v / norm(v))
#     True
#     """
# 
#     if frame.upper() == "QSW":
#         m = to_qsw(orbit)
#     elif frame.upper() == "TNW":
#         m = to_tnw(orbit)
#     else:
#         raise ValueError(f"Unknown local orbital frame : {frame}")
# 
#     if expanded:
#         m = expand(m)
# 
#     return m


import sys
import logging
import numpy as np
from ..config import config
from ..errors import UnknownFrameError, UnknownBodyError
from ..constants import Earth
from ..utils.matrix import rot3, expand
from . import orient, center
from .local import to_local
        from ..env.jpl import create_frames, JplConfigError
"""This dictionary contains all the frames. Those defined here, and those created on the fly
by the developer.
"""

sys.modules[__name__ + ".dynamic"] = dynamic


def get_frame(frame):
    """Frame factory

    Args:
        frame (str): name of the desired frame
    Return:
        Frame: the object representing the frame demanded
    Raise:
        ~beyond.frames.frames.UnknownFrameError
    """

    if frame not in dynamic.keys() and config.get(
        "env", "jpl", "dynamic_frames", fallback=False
    ):

        try:
            create_frames()
        except (JplConfigError, UnknownBodyError) as e:
            raise UnknownFrameError(frame) from e

    try:
        return dynamic[frame]
    except KeyError:

# Path: beyond/errors.py
# class UnknownFrameError(_Unknown):
#     """Unknown frame (ITRF, EME2000, etc.)"""
# 
#     pass
# 
# class UnknownBodyError(_Unknown):
#     """Unknown Body (Earth, Moon, Sun, etc.)"""
# 
#     pass
# 
# Path: beyond/constants.py
# G = 6.6740831e-11
# class Body:
#     def __init__(self, name, mass, equatorial_radius, *, flattening=1, **kwargs):
#     def __repr__(self):
#     def __getattr__(self, name):
#     def mu(self):
#     def eccentricity(self):
#     def polar_radius(self):
#     def propagate(self, date):
# 
# Path: beyond/utils/matrix.py
# def rot3(theta):
#     """
#     Args:
#         theta (float): Angle in radians
#     Return:
#         Rotation matrix of angle theta around the Z-axis
#     """
#     return np.array(
#         [
#             [np.cos(theta), np.sin(theta), 0],
#             [-np.sin(theta), np.cos(theta), 0],
#             [0, 0, 1],
#         ]
#     )
# 
# def expand(m, rate=None):
#     """Transform a 3x3 rotation matrix into a 6x6 rotation matrix
# 
#     Args:
#         m (numpy.ndarray) : 3x3 matrix transforming a position vector
#             from frame1 to frame2
#         rate (numpy.array) : 1D 3 elements vector rate of frame2
#             expressed in frame1
#     Return:
#         numpy.ndarray : 6x6 rotation matrix
# 
#     Example:
# 
#     >>> m = np.array([[0, -1, 0], [-1, 0, 0], [0, 0, 1]])
#     >>> print(expand(m))
#     [[ 0. -1.  0.  0.  0.  0.]
#      [-1.  0.  0.  0.  0.  0.]
#      [ 0.  0.  1.  0.  0.  0.]
#      [ 0.  0.  0.  0. -1.  0.]
#      [ 0.  0.  0. -1.  0.  0.]
#      [ 0.  0.  0.  0.  0.  1.]]
#     >>> print(expand(m, rate=[1,2,3]))
#     [[ 0. -1.  0.  0.  0.  0.]
#      [-1.  0.  0.  0.  0.  0.]
#      [ 0.  0.  1.  0.  0.  0.]
#      [-3.  0. -2.  0. -1.  0.]
#      [ 0.  3.  1. -1.  0.  0.]
#      [ 1. -2.  0.  0.  0.  1.]]
#     """
# 
#     out = np.zeros((6, 6))
#     out[:3, :3] = m
#     out[3:, 3:] = m
# 
#     if rate is not None:
#         R = np.array(
#             [[0, -rate[2], rate[1]], [rate[2], 0, -rate[0]], [-rate[1], rate[0], 0]]
#         )
#         out[3:, :3] = -R @ m
# 
#     return out
# 
# Path: beyond/frames/local.py
# def to_local(frame, orbit, expanded=True):
#     """Provide the transformation matrix to convert a vector from an inertial frame
#     to a local orbital reference frame of choice
# 
#     Args:
#         frame (str): Name of the local orbital frame ('QSW' or 'TNW')
#         orbit (List[float]) : cartesian coordinates (length 6)
#         expanded (bool) : If ``True`` the returned matrix is 6x6, 3x3 otherwise
#     Return:
#         numpy.ndarray : Transformation matrix
# 
#     >>> delta_tnw = [1, 0, 0]
#     >>> p = [-6142438.668, 3492467.560, -25767.25680]
#     >>> v = [505.8479685, 942.7809215, 7435.922231]
#     >>> pv = p + v
#     >>> mat = to_local("TNW", pv, expanded=False).T
#     >>> delta_inert = mat @ delta_tnw
#     >>> all(delta_inert == v / norm(v))
#     True
#     """
# 
#     if frame.upper() == "QSW":
#         m = to_qsw(orbit)
#     elif frame.upper() == "TNW":
#         m = to_tnw(orbit)
#     else:
#         raise ValueError(f"Unknown local orbital frame : {frame}")
# 
#     if expanded:
#         m = expand(m)
# 
#     return m


# Path: beyond/frames/frames.py
import sys
import logging
import numpy as np
from ..config import config
from ..errors import UnknownFrameError, UnknownBodyError
from ..constants import Earth
from ..utils.matrix import rot3, expand
from . import orient, center
from .local import to_local
        from ..env.jpl import create_frames, JplConfigError

"""This dictionary contains all the frames. Those defined here, and those created on the fly
by the developer.
"""

sys.modules[__name__ + ".dynamic"] = dynamic


def get_frame(frame):
    """Frame factory

    Args:
        frame (str): name of the desired frame
    Return:
        Frame: the object representing the frame demanded
    Raise:
        ~beyond.frames.frames.UnknownFrameError
    """

    if frame not in dynamic.keys() and config.get(
        "env", "jpl", "dynamic_frames", fallback=False
    ):

        try:
            create_frames()
        except (JplConfigError, UnknownBodyError) as e:
            raise UnknownFrameError(frame) from e

    try:
        return dynamic[frame]
    except KeyError:

        raise UnknownFrameError(frame)