# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/04_tmpl.ipynb.

# %% auto 0
__all__ = ['e', 'F', 'BASE', 'SCHRS', 'SSYMS', 'ECHRS', 'ftmpl', 'btmpl', 'etmpl', 'fpttn', 'bpttn', 'epttn', 'prep_strs',
           'make_fstr', 'make_bstr', 'make_estr', 'from_fstr', 'from_bstr', 'from_estr']

# %% ../nbs/04_tmpl.ipynb 3
import re
from numbers import Number
from typing import Tuple, get_args
from string import Template

# %% ../nbs/04_tmpl.ipynb 4
from .types import sint, SignChr, SignSym, ExpoChr, SignSymQ, SignChrQ, ExpoChrQ, SignIntQ
from .guard import isexpochr, isint
from .utils import tosign, toint

# %% ../nbs/04_tmpl.ipynb 6
e: str = 'e'
F: str = 'F'

BASE: int = 10

SCHRS = ''.join(get_args(SignChr))
SSYMS = ''.join(get_args(SignSym))
ECHRS = ''.join(get_args(ExpoChr))

ftmpl = Template(f'{F}$expo$sign')
btmpl = Template(f'$base$echr$sign$expo')
etmpl = Template(f'{e}$sign$expo')

# %% ../nbs/04_tmpl.ipynb 7
fpttn = re.compile(rf'{F}(?P<expo>\d+)(?P<sign>[{re.escape(SCHRS)}]?)')
bpttn = re.compile(rf'(?P<base>\d*)\s*[{re.escape(ECHRS)}]\s*(?P<sign>[{re.escape(SSYMS)}]?)(?P<expo>\d+)')
epttn = re.compile(rf'{e}(?P<sign>[{re.escape(SSYMS)}]?)(?P<expo>\d+)')

# %% ../nbs/04_tmpl.ipynb 8
def prep_strs(
    expo: Number = 0, sign: sint = None, base: Number = BASE, 
    echr: ExpoChr = '^', showsign: bool = True, showbase: bool = True
) -> Tuple[int, str, SignSymQ, SignChrQ, ExpoChrQ]:
    sign = tosign(sign or expo, force = True)
    bstr = str(base) if showbase else ''
    sstr = sign.sym if showsign else ''
    schr = sign.chr
    echr = echr if isexpochr(echr) else '^'
    estr = abs(expo)
    return bstr, sstr, schr, estr, echr

# %% ../nbs/04_tmpl.ipynb 9
def make_fstr(
    expo: Number = 0, sign: sint = None, base: Number = BASE, 
    echr: ExpoChr = '^', showsign: bool = True, showbase: bool = True
) -> str:
    bstr, sstr, schr, estr, echr = prep_strs(expo, sign, base, echr, showsign, showbase)
    return ftmpl.substitute(expo=estr, sign=schr)

def make_bstr(
    expo: Number = 0, sign: sint = None, base: Number = BASE, 
    echr: ExpoChr = '^', showsign: bool = True, showbase: bool = True
) -> str:
    bstr, sstr, schr, estr, echr = prep_strs(expo, sign, base, echr, showsign, showbase)
    return btmpl.substitute(base=bstr, sign=sstr, echr=echr, expo=estr)

def make_estr(
    expo: Number = 0, sign: sint = None, base: Number = BASE, 
    echr: ExpoChr = '^', showsign: bool = True, showbase: bool = True
) -> str:
    bstr, sstr, schr, estr, echr = prep_strs(expo, sign, base, echr, showsign, showbase)
    return etmpl.substitute(sign=sstr, expo=estr)


# %% ../nbs/04_tmpl.ipynb 11
def from_fstr(s: str, base: int = BASE) -> (Number, SignIntQ, Number):
    match = fpttn.match(s)
    if match:
        expo = int(match.group('expo'))
        sign = toint(match.group('sign'))
        return expo, sign, base
    raise ValueError(f"String '{s}' doesn't match factor format")

def from_bstr(s: str, base: int = BASE) -> (Number, SignIntQ, Number):
    match = bpttn.match(s)
    if match:
        base = int(match.group('base')) if match.group('base') else base
        expo = int(match.group('expo'))
        sign = toint(match.group('sign') + '1')
        return expo, sign, base
    raise ValueError(f"String '{s}' doesn't match base format")

def from_estr(s: str, base: int = BASE) -> (Number, Number, SignIntQ):
    match = epttn.match(s)
    if match:
        expo = int(match.group('expo'))
        sign = toint(match.group('sign') + '1')
        return expo, sign, base
    raise ValueError(f"String '{s}' doesn't match exponent format")

