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

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

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

# %% ../nbs/04_sint.ipynb 4
from .types import NumStr, SignSym, SignChr, SignInt, NumStrQ, SignIntQ
from .guard import ispos, isneg, iszer, isnumstr, issignint
from .sign import sign, P, Z, N
from sint.utils import (
    psyn, nsyn, zsyn, 
    any2signint, num2signint, str2signint, 
    numstr2signint, tosignint, matchsign, 
    toint, tochr, tosym, tosyn, toset, topow, tosign, totuple,
)

# %% ../nbs/04_sint.ipynb 6
class SignIntError(ValueError):
    def __init__(self, val: Any):
        msg = f'Invalid sint: {val}. Must be one of {P.int, Z.int, N.int}, a string integer, or {P.syn | Z.syn | N.syn}.'
        super().__init__(msg)

# %% ../nbs/04_sint.ipynb 8
class base:    
    @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 str2signint(cls, s: str) -> SignInt: return str2signint(s)
    @classmethod
    def numstr2signint(cls, s: NumStrQ) -> SignInt: return numstr2signint(s)
    @classmethod
    def tosignint(cls, s: Any) -> SignIntQ: return tosignint(s)

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

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

    @classmethod
    def tosign(cls, s: NumStr) -> sign: return tosign(s)
    @classmethod
    def totuple(cls, s: NumStr) -> tuple: return totuple(s)


    def pow(self, base: int, expo: int) -> Number: return self.topow(base, expo, self)
    def eval(self, pos: Any = 1, neg: Any = -1, nil: Any = 0, default: Any = None) -> Any:
        return self.match(self, pos, neg, nil, default)
    def tuple(self) -> tuple: return self.totuple(self)
    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)
    
    def __new__(cls, val: NumStr, *args, **kwargs):
        val = cls.tosignint(val)
        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)
        return super().__new__(cls, val)
    
    @classmethod
    def __initsigns__(cls):
        cls.P = cls( 1, __singleton__=True)
        cls.N = cls(-1, __singleton__=True)
        cls.Z = cls( 0, __singleton__=True)
        return cls
    
    def __init_subclass__(cls, *args, **kwargs):
        cls.__initsigns__()

# %% ../nbs/04_sint.ipynb 10
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.
    '''
    ...
