"""
Math Primitives Library

Trigonometry, rounding, clamping, random numbers, etc.
"""
import math
import random as rand_module


def prim_sin(x):
    return math.sin(x)


def prim_cos(x):
    return math.cos(x)


def prim_tan(x):
    return math.tan(x)


def prim_asin(x):
    return math.asin(x)


def prim_acos(x):
    return math.acos(x)


def prim_atan(x):
    return math.atan(x)


def prim_atan2(y, x):
    return math.atan2(y, x)


def prim_sqrt(x):
    return math.sqrt(x)


def prim_pow(x, y):
    return math.pow(x, y)


def prim_exp(x):
    return math.exp(x)


def prim_log(x, base=None):
    if base is None:
        return math.log(x)
    return math.log(x, base)


def prim_abs(x):
    return abs(x)


def prim_floor(x):
    return math.floor(x)


def prim_ceil(x):
    return math.ceil(x)


def prim_round(x):
    return round(x)


def prim_min(*args):
    if len(args) == 1 and hasattr(args[0], '__iter__'):
        return min(args[0])
    return min(args)


def prim_max(*args):
    if len(args) == 1 and hasattr(args[0], '__iter__'):
        return max(args[0])
    return max(args)


def prim_clamp(x, lo, hi):
    return max(lo, min(hi, x))


def prim_lerp(a, b, t):
    """Linear interpolation: a + (b - a) * t"""
    return a + (b - a) * t


def prim_smoothstep(edge0, edge1, x):
    """Smooth interpolation between 0 and 1."""
    t = prim_clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0)
    return t * t * (3 - 2 * t)


def prim_random(lo=0.0, hi=1.0):
    return rand_module.uniform(lo, hi)


def prim_randint(lo, hi):
    return rand_module.randint(lo, hi)


def prim_gaussian(mean=0.0, std=1.0):
    return rand_module.gauss(mean, std)


def prim_sign(x):
    if x > 0:
        return 1
    elif x < 0:
        return -1
    return 0


def prim_fract(x):
    """Fractional part of x."""
    return x - math.floor(x)


PRIMITIVES = {
    # Trigonometry
    'sin': prim_sin,
    'cos': prim_cos,
    'tan': prim_tan,
    'asin': prim_asin,
    'acos': prim_acos,
    'atan': prim_atan,
    'atan2': prim_atan2,

    # Powers and roots
    'sqrt': prim_sqrt,
    'pow': prim_pow,
    'exp': prim_exp,
    'log': prim_log,

    # Rounding
    'abs': prim_abs,
    'floor': prim_floor,
    'ceil': prim_ceil,
    'round': prim_round,
    'sign': prim_sign,
    'fract': prim_fract,

    # Min/max/clamp
    'min': prim_min,
    'max': prim_max,
    'clamp': prim_clamp,
    'lerp': prim_lerp,
    'smoothstep': prim_smoothstep,

    # Random
    'random': prim_random,
    'randint': prim_randint,
    'gaussian': prim_gaussian,

    # Constants
    'pi': math.pi,
    'tau': math.tau,
    'e': math.e,
}
