# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/07_sint.ipynb.

# %% auto 0
__all__ = ['base', 'sint']

# %% ../nbs/07_sint.ipynb 3
from typing import Any, Optional
from numbers import Number

# %% ../nbs/07_sint.ipynb 4
from chck import isnone
from .types import NumStr, SignSym, SignChr, SignInt, NumStrQ, SignIntQ, ExpoChr
from .guard import ispos, isneg, iszer, isnumstr, issignint
from .sign import sign, P, Z, N
from .cons import (BASE)
from sint.utils import (
    psyn, nsyn, zsyn, 
    any2signint, num2signint, str2signint, bool2signint,
    numstr2signint, tosignint, matchsign, 
    toint, tochr, tosym, tosyn, toset, topow, tosign, totuple,
    from_bstr, from_estr, from_fstr, make_bstr, make_fstr, make_estr,
)
from .errs import SignIntError

# %% ../nbs/07_sint.ipynb 6
class base:
    force = False
    default = None
    boolneg = True
    @classmethod
    def ispos(cls, n: Number) -> bool: 
        return ispos(n)

    @classmethod
    def isneg(cls, n: Number) -> bool: 
        return isneg(n)

    @classmethod
    def iszer(cls, n: Number) -> bool: 
        return iszer(n)
        
    @classmethod
    def psyn(cls, s: str) -> bool: 
        return psyn(s)

    @classmethod
    def nsyn(cls, s: str) -> bool: 
        return nsyn(s)

    @classmethod
    def zsyn(cls, s: str) -> bool: 
        return zsyn(s)

    @classmethod
    def any2signint(cls, val: Any, posfn = ispos, negfn = isneg) -> SignInt: 
        return any2signint(val, posfn, negfn)

    @classmethod
    def num2signint(cls, s: Number) -> SignInt: 
        return num2signint(s)

    @classmethod
    def bool2signint(cls, s: bool, boolneg: bool = None) -> SignInt:
        if isnone(boolneg): boolneg = cls.boolneg
        return bool2signint(s, boolneg)

    @classmethod
    def str2signint(cls, s: str) -> SignInt: 
        return str2signint(s)

    @classmethod
    def numstr2signint(cls, s: NumStrQ, boolneg: bool = None) -> SignInt:
        if isnone(boolneg): boolneg = cls.boolneg
        return numstr2signint(s, boolneg)

    @classmethod
    def tosignint(cls, s: Any, boolneg: bool = None) -> SignIntQ:
        if isnone(boolneg): boolneg = cls.boolneg
        return tosignint(s, boolneg)

    @classmethod
    def match(
        cls, val: Any, pos: Any = P.int, neg: Any = N.int, nil: Any = Z.int, 
        default: Any = None, boolneg: bool = None
    ) -> Any:
        if isnone(default): default = cls.default
        if isnone(boolneg): boolneg = cls.boolneg
        return matchsign(val, pos, neg, nil, default, boolneg)
    
    @classmethod
    def toint(cls, s: NumStr, default: Any = None, boolneg: bool = None) -> SignInt:
        if isnone(default): default = cls.default
        if isnone(boolneg): boolneg = cls.boolneg
        return toint(s, default, boolneg)
        
    @classmethod
    def tochr(cls, s: NumStr, default: Any = None, boolneg: bool = None) -> SignChr:
        if isnone(default): default = cls.default
        if isnone(boolneg): boolneg = cls.boolneg
        return tochr(s, default, boolneg)
        
    @classmethod
    def tosym(cls, s: NumStr, default: Any = None, boolneg: bool = None) -> SignSym:
        if isnone(default): default = cls.default
        if isnone(boolneg): boolneg = cls.boolneg
        return tosym(s, default, boolneg)
        
    @classmethod
    def tosyn(cls, s: NumStr, default: Any = None, boolneg: bool = None) -> SignSym:
        if isnone(default): default = cls.default
        if isnone(boolneg): boolneg = cls.boolneg
        return tosyn(s, default, boolneg)
        
    @classmethod
    def toset(cls, s: NumStr, default: Any = None, boolneg: bool = None) -> SignSym:
        if isnone(default): default = cls.default
        if isnone(boolneg): boolneg = cls.boolneg
        return toset(s, default, boolneg)
        

    @classmethod
    def topow(
        cls, base: int, expo: int, 
        sign: Optional[NumStr] = None, boolneg: bool = None
    ) -> Number:        
        if isnone(boolneg): boolneg = cls.boolneg
        return topow(base, expo, sign, boolneg)

    @classmethod
    def tosign(cls, s: NumStr, force: bool = False, boolneg: bool = None) -> sign:
        if isnone(force): force = cls.force
        if isnone(boolneg): boolneg = cls.boolneg
        return tosign(s, force, boolneg)
    
    @classmethod
    def totuple(cls, s: NumStr, force: bool = False, boolneg: bool = None) -> tuple:
        if isnone(force): force = cls.force
        if isnone(boolneg): boolneg = cls.boolneg
        return totuple(s, force, boolneg)


    def pow(self, base: int, expo: int, boolneg: bool = None) -> Number:         
        if isnone(boolneg): boolneg = type(self).boolneg
        return self.topow(base, expo, self, boolneg)

    def eval(
            self, pos: Any = 1, neg: Any = -1, nil: Any = 0, 
            default: Any = None, boolneg: bool = None
    ) -> Any:
        if isnone(default): default = type(self).default
        if isnone(boolneg): boolneg = type(self).boolneg
        return self.match(self, pos, neg, nil, default, boolneg)
    
    def tuple(self, force: bool = False, boolneg: bool = None) -> tuple:
        if isnone(force): force = type(self).force
        if isnone(boolneg): boolneg = type(self).boolneg
        return self.totuple(self, force, boolneg)
    
    def issyn(self, s: str) -> bool: 
        return s in self.set

    @classmethod
    def to(cls, s: NumStr) -> Optional['sint']:
        return cls(s) if isnumstr(s) else None
    
    @property
    def sym(self) -> str: return self.tosym(self)    
    @property
    def chr(self) -> str: return self.tochr(self)
    @property
    def syn(self) -> set: return self.tosyn(self)
    @property
    def set(self) -> set: return self.toset(self)

    @classmethod
    def from_bstr(cls, s: str) -> (Number, SignIntQ, Number): return from_bstr(s, base = BASE)
    @classmethod
    def from_estr(cls, s: str) -> (Number, SignIntQ, Number): return from_estr(s, base = BASE)
    @classmethod
    def from_fstr(cls, s: str) -> (Number, SignIntQ, Number): return from_fstr(s, base = BASE)

    @classmethod
    def make_bstr(cls, 
        expo: Number = 0, sign: Optional['sint'] = None, base: Number = BASE, 
        echr: ExpoChr = '^', showsign: bool = True, showbase: bool = True, boolneg: bool = True
    ) -> str:
        if isnone(boolneg): boolneg = cls.boolneg
        return make_bstr(expo, sign, base, echr, showsign, showbase, boolneg)
    
    @classmethod
    def make_fstr(cls, 
        expo: Number = 0, sign: Optional['sint'] = None, base: Number = BASE, 
        echr: ExpoChr = '^', showsign: bool = True, showbase: bool = True, boolneg: bool = True
    ) -> str: 
        if isnone(boolneg): boolneg = cls.boolneg
        return make_fstr(expo, sign, base, echr, showsign, showbase, boolneg)
    
    @classmethod
    def make_estr(cls, 
        expo: Number = 0, sign: Optional['sint'] = None, base: Number = BASE, 
        echr: ExpoChr = '^', showsign: bool = True, showbase: bool = True, boolneg: bool = True
    ) -> str: 
        if isnone(boolneg): boolneg = cls.boolneg
        return make_estr(expo, sign, base, echr, showsign, showbase, boolneg)
    
    def __new__(cls, val: NumStr, *args, **kwargs):

        force = kwargs.get('force', cls.force)
        default = kwargs.get('default', cls.default)
        boolneg = kwargs.get('boolneg', cls.boolneg)
        val = cls.tosignint(val, boolneg=boolneg)
        
        singleton = kwargs.get('__singleton__', False)        
        if not issignint(val): raise SignIntError(val)        
        if not singleton: return cls.match(val, cls.P, cls.N, cls.Z, default, boolneg)
        return super().__new__(cls, val)
    
    @classmethod
    def __initsigns__(cls):
        cls.P = cls( 1, __singleton__=True, force=cls.force, default=cls.default, boolneg=cls.boolneg)
        cls.N = cls(-1, __singleton__=True, force=cls.force, default=cls.default, boolneg=cls.boolneg)
        cls.Z = cls( 0, __singleton__=True, force=cls.force, default=cls.default, boolneg=cls.boolneg)
        return cls
    
    def __init_subclass__(cls, *args, **kwargs):
        cls.__initsigns__()

# %% ../nbs/07_sint.ipynb 8
class sint(base, int):
    '''Derived class from int to represent -1, 0, 1 as sint.

    Methods
    -------
    eval:
        Evaluate the sint object.
    match:
        Class method to match sints.
    tosym:
        Convert sint to its symbolic representation.
    tostr:
        Convert sint to its string representation.
    topow:
        Calculate the power using sint.
    sym:
        Property to get the symbolic representation.
    str:
        Property to get the string representation.
    pow:
        Calculate the power using sint.
    to:
        Class method to construct sint.
    '''
    ...
