"""This file defines something akin to setting some "global" variables. These
numbers come from `SLBMGlobals.h` and `CPPGlobals.h`. They will be accessible a
la `rstt.Sn` and `rstt.PWAVE`. There are also a couple helper functions to
convert between string and integer phases and attributes."""

################################################################################
# 
#  Copyright 2009 National Technology & Engineering Solutions of Sandia, LLC
#  (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
#  Government retains certain rights in this software.
# 
#  BSD Open Source License
#  All rights reserved.
# 
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are met:
# 
#    1. Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
# 
#    2. Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
# 
#    3. Neither the name of the copyright holder nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
# 
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#  POSSIBILITY OF SUCH DAMAGE.
# 
################################################################################

#-----------------------------------------
# initialization
#-----------------------------------------

# everything that will be imported when we invoke `from .globals import *`
__all__ = ["version", "DEG_PER_RAD", "RAD_PER_DEG", "PWAVE", "SWAVE", "WATER",
           "SEDIMENT1", "SEDIMENT2", "SEDIMENT3", "UPPER_CRUST",
           "MIDDLE_CRUST_N", "MIDDLE_CRUST_G", "LOWER_CRUST", "MANTLE",
           "NLAYERS", "Pn","Sn","Pg", "Lg", "TT","SH","AZ", "phases",
           "attributes"]

# import statements
from . import libslbmPyshell  # libslbmPyshell, imported from __init__.py
import math                   # math functions


#-----------------------------------------
# globals
#-----------------------------------------

# rstt version
version = libslbmPyshell.SlbmVersion

# some radian<-->degree conversions
DEG_PER_RAD = 180. / math.pi
RAD_PER_DEG = math.pi / 180.

# p and s-wave indices
PWAVE = libslbmPyshell.PWAVE
SWAVE = libslbmPyshell.SWAVE

# RSTT layers
WATER          = libslbmPyshell.WATER
SEDIMENT1      = libslbmPyshell.SEDIMENT1
SEDIMENT2      = libslbmPyshell.SEDIMENT2
SEDIMENT3      = libslbmPyshell.SEDIMENT3
UPPER_CRUST    = libslbmPyshell.UPPER_CRUST
MIDDLE_CRUST_N = libslbmPyshell.MIDDLE_CRUST_N
MIDDLE_CRUST_G = libslbmPyshell.MIDDLE_CRUST_G
LOWER_CRUST    = libslbmPyshell.LOWER_CRUST
MANTLE         = libslbmPyshell.MANTLE
NLAYERS        = libslbmPyshell.NLAYERS

# phases
Pn = libslbmPyshell.Pn
Sn = libslbmPyshell.Sn
Pg = libslbmPyshell.Pg
Lg = libslbmPyshell.Lg

# attributes
TT = libslbmPyshell.TT
SH = libslbmPyshell.SH
AZ = libslbmPyshell.AZ


#-----------------------------------------
# helper functions
#-----------------------------------------

def phases(x: str or int) -> int or str:
    """Convert RSTT phase strings to their respective numbers, and vice-versa.

    Examples
    --------
        >>> rstt.phases('Sn')
        1

        >>> rstt.phases(1)
        'Sn'

    Parameters
    ----------
    x : str or int
        Either the phase number or string (case-insensitive)

    Returns
    -------
    int or str
        Returns an `int` or `str`, opposite the argument type
    """
    d = {'Pn': Pn, 'Sn': Sn, 'Pg': Pg, 'Lg': Lg}
    if isinstance(x, str):
        return [key.lower() for key in d].index(x.lower())  # get phase number from dict
    else:
        return list(d.keys())[x]  # get phase string from list of strings


def attributes(x: str or int) -> int or str:
    """Convert RSTT attribute strings to their respective numbers, and vice-versa.

    Examples
    --------
        >>> rstt.attributes('AZ')
        2

        >>> rstt.attributes(0)
        'TT'

    Parameters
    ----------
    x : str or int
        Either the phase number or string (case-insensitive)

    Returns
    -------
    int or str
        Returns an `int` or `str`, opposite the argument type
    """
    d = {'TT': TT, 'SH': SH, 'AZ': AZ}
    if isinstance(x, str):
        return [key.lower() for key in d].index(x.lower())  # get attrib number from dict
    else:
        return list(d.keys())[x]  # get attrib string from list of strings
