# Path: src/astrodynamics/constants/wgs84.py
# WGS84_EQUATORIAL_RADIUS = Constant(
#     name='WGS84 semi-major axis',
#     value=6378137,
#     unit='m',
#     uncertainty=0,
#     reference='World Geodetic System 1984')
# 
# WGS84_FLATTENING = Constant(
#     name='WGS84 Earth flattening factor',
#     value=1 / 298.257223563,
#     unit='',
#     uncertainty=0,
#     reference='World Geodetic System 1984')
# 
# WGS84_MU = Constant(
#     name='WGS84 geocentric gravitational constant',
#     value=3.986004418e14,
#     unit='m3 / s2',
#     uncertainty=0,
#     reference='World Geodetic System 1984')
# 
# WGS84_ANGULAR_VELOCITY = Constant(
#     name='WGS84 nominal earth mean angular velocity',
#     value=7.292115e-5,
#     unit='rad / s',
#     uncertainty=0,
#     reference='World Geodetic System 1984')
# 
# Path: src/astrodynamics/utils/helper.py
# def read_only_property(name, docstring=None):
#     """Return property for accessing attribute with name `name`
# 
#     Parameters:
#         name: Attribute name
#         docstring: Optional docstring for getter.
# 
#     Example:
#         .. code-block:: python
# 
#             class Circle:
#                 def __init__(self, radius):
#                     self._radius = radius
# 
#                 radius = read_only_property('_radius')
#     """
#     def fget(self):
#         return getattr(self, name)
# 
#     fget.__doc__ = docstring
#     return property(fget)
# 
# def verify_unit(quantity, unit):
#     """Verify unit of passed quantity and return it.
# 
#     Parameters:
#         quantity: :py:class:`~astropy.units.Quantity` to be verified. Bare
#                   numbers are valid if the unit is dimensionless.
#         unit: Equivalent unit, or string parsable by
#               :py:class:`astropy.units.Unit`
# 
#     Raises:
#         ValueError: Units are not equivalent.
# 
#     Returns:
#         ``quantity`` unchanged. Bare numbers will be converted to a dimensionless
#         :py:class:`~astropy.units.Quantity`.
# 
#     Example:
#         .. code-block:: python
# 
#             def __init__(self, a):
#                 self.a = verify_unit(a, astropy.units.m)
# 
#     """
#     if not isinstance(unit, UnitBase):
#         unit = Unit(unit)
# 
#     q = quantity * u.one
#     if unit.is_equivalent(q.unit):
#         return q
#     else:
#         raise ValueError(
#             "Unit '{}' not equivalent to quantity '{}'.".format(unit, quantity))


from astropy.units import Quantity
from represent import ReprHelperMixin
from ..constants import (
    WGS84_ANGULAR_VELOCITY, WGS84_EQUATORIAL_RADIUS, WGS84_FLATTENING,
    WGS84_MU)
from ..utils import read_only_property, verify_unit
    'Ellipsoid',
    'ReferenceEllipsoid',
    'wgs84',
)


class Ellipsoid(ReprHelperMixin, object):
    """Ellipsoid

    Parameters:
        a: Semi-major axis (equatorial radius) [m]
        b: Semi-minor axis (polar radius) [m]
        f: Flattening [-]

    Either ``b`` or ``f`` must be specified: the other will be calculated.
    """
    def __init__(self, a, b=None, f=None):
        if (b is None and f is None) or (b and f):
            raise TypeError('Either b or f must be specified, but not both.')

        self._a = verify_unit(a, 'm')

        if b is None:
            self._b = verify_unit(a * (1 - f), 'm')
            self._f = verify_unit(f, '')

        if f is None:
            self._b = verify_unit(b, 'm')
            self._f = verify_unit(1 - (b / a), '')


# Path: src/astrodynamics/constants/wgs84.py
# WGS84_EQUATORIAL_RADIUS = Constant(
#     name='WGS84 semi-major axis',
#     value=6378137,
#     unit='m',
#     uncertainty=0,
#     reference='World Geodetic System 1984')
# 
# WGS84_FLATTENING = Constant(
#     name='WGS84 Earth flattening factor',
#     value=1 / 298.257223563,
#     unit='',
#     uncertainty=0,
#     reference='World Geodetic System 1984')
# 
# WGS84_MU = Constant(
#     name='WGS84 geocentric gravitational constant',
#     value=3.986004418e14,
#     unit='m3 / s2',
#     uncertainty=0,
#     reference='World Geodetic System 1984')
# 
# WGS84_ANGULAR_VELOCITY = Constant(
#     name='WGS84 nominal earth mean angular velocity',
#     value=7.292115e-5,
#     unit='rad / s',
#     uncertainty=0,
#     reference='World Geodetic System 1984')
# 
# Path: src/astrodynamics/utils/helper.py
# def read_only_property(name, docstring=None):
#     """Return property for accessing attribute with name `name`
# 
#     Parameters:
#         name: Attribute name
#         docstring: Optional docstring for getter.
# 
#     Example:
#         .. code-block:: python
# 
#             class Circle:
#                 def __init__(self, radius):
#                     self._radius = radius
# 
#                 radius = read_only_property('_radius')
#     """
#     def fget(self):
#         return getattr(self, name)
# 
#     fget.__doc__ = docstring
#     return property(fget)
# 
# def verify_unit(quantity, unit):
#     """Verify unit of passed quantity and return it.
# 
#     Parameters:
#         quantity: :py:class:`~astropy.units.Quantity` to be verified. Bare
#                   numbers are valid if the unit is dimensionless.
#         unit: Equivalent unit, or string parsable by
#               :py:class:`astropy.units.Unit`
# 
#     Raises:
#         ValueError: Units are not equivalent.
# 
#     Returns:
#         ``quantity`` unchanged. Bare numbers will be converted to a dimensionless
#         :py:class:`~astropy.units.Quantity`.
# 
#     Example:
#         .. code-block:: python
# 
#             def __init__(self, a):
#                 self.a = verify_unit(a, astropy.units.m)
# 
#     """
#     if not isinstance(unit, UnitBase):
#         unit = Unit(unit)
# 
#     q = quantity * u.one
#     if unit.is_equivalent(q.unit):
#         return q
#     else:
#         raise ValueError(
#             "Unit '{}' not equivalent to quantity '{}'.".format(unit, quantity))


# Path: src/astrodynamics/bodies/ellipsoid.py
from astropy.units import Quantity
from represent import ReprHelperMixin
from ..constants import (
    WGS84_ANGULAR_VELOCITY, WGS84_EQUATORIAL_RADIUS, WGS84_FLATTENING,
    WGS84_MU)
from ..utils import read_only_property, verify_unit

    'Ellipsoid',
    'ReferenceEllipsoid',
    'wgs84',
)


class Ellipsoid(ReprHelperMixin, object):
    """Ellipsoid

    Parameters:
        a: Semi-major axis (equatorial radius) [m]
        b: Semi-minor axis (polar radius) [m]
        f: Flattening [-]

    Either ``b`` or ``f`` must be specified: the other will be calculated.
    """
    def __init__(self, a, b=None, f=None):
        if (b is None and f is None) or (b and f):
            raise TypeError('Either b or f must be specified, but not both.')

        self._a = verify_unit(a, 'm')

        if b is None:
            self._b = verify_unit(a * (1 - f), 'm')
            self._f = verify_unit(f, '')

        if f is None:
            self._b = verify_unit(b, 'm')
            self._f = verify_unit(1 - (b / a), '')


    a = read_only_property('_a', 'Semi-major axis')