# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/01_mixs.ipynb.

# %% auto 0
__all__ = ['KWixMixin', 'KWixClsFns', 'KWixProps', 'KWix']

# %% ../nbs/01_mixs.ipynb 4
from typing import (
    Type, Optional, Union, Callable, Tuple, List
)

from ispec.types import (AttrLvl)
from ispec.utils import (getattrs, funkws, kwskws, unpack_optout,)

# %% ../nbs/01_mixs.ipynb 5
from kwix.utils import (         
    get_kws_at_lvl, getattrs_at_lvl,
    get_kws_cur, get_kws_all, get_kws_inh, 
    getattrs_cur, getattrs_all, getattrs_inh
)

# %% ../nbs/01_mixs.ipynb 8
class KWixMixin:
    
    @classmethod
    def from_dict(cls, **kwargs):
        all_kws = cls.get_kws_at_lvl(float('inf'), agg=True, verbose=False)
        return cls(**dict((k, v) for k, v in kwargs.items() if k in all_kws))

    @classmethod
    def get_kws_at_lvl(cls, lvl: AttrLvl, agg: bool = True, return_cls: bool = False, verbose: bool = False) -> Union[dict, Tuple[dict, Type]]:
        kws, lvlcls = unpack_optout(get_kws_at_lvl(cls, lvl, agg, return_cls, verbose))
        if return_cls: return kws, lvlcls
        return kws

    @classmethod
    def getattrs_at_lvl(cls, lvl: AttrLvl, agg: bool = True, use_lvl_vals: bool = False, verbose: bool = False) -> dict:
        return getattrs_at_lvl(cls, lvl, agg, use_lvl_vals, verbose)

    def get_params_at_lvl(self, lvl: AttrLvl, agg: bool = True, use_lvl_vals: bool = False, verbose: bool = False) -> dict:
        clsattrs = self.getattrs_at_lvl(lvl, agg, use_lvl_vals, verbose)
        curattrs = getattrs(self, clsattrs)
        return curattrs

    def prepare_params(self, func: Optional[Callable] = None, lvl: AttrLvl = float('inf'), **kwargs) -> dict:
        tmpkws = funkws(self.get_params_at_lvl, **kwargs)
        params = self.get_params_at_lvl(lvl, **tmpkws)
        params = funkws(func or type(self), **{**params, **kwargs})
        return params

# %% ../nbs/01_mixs.ipynb 10
class KWixClsFns:
    @classmethod
    def get_kws_cur(cls, verbose: bool = False):
        return get_kws_cur(cls, verbose=verbose)
    @classmethod
    def get_kws_all(cls, verbose: bool = False):
        return get_kws_all(cls, verbose=verbose)
    @classmethod
    def get_kws_inh(cls, verbose: bool = False):
        return get_kws_inh(cls, verbose=verbose)      

    @classmethod
    def getattrs_cur(cls, use_lvl_vals: bool = False, verbose: bool = False):
        return getattrs_cur(cls, use_lvl_vals, verbose=verbose)
    @classmethod
    def getattrs_all(cls, use_lvl_vals: bool = False, verbose: bool = False):
        return getattrs_all(cls, use_lvl_vals, verbose=verbose)
    @classmethod
    def getattrs_inh(cls, use_lvl_vals: bool = False, verbose: bool = False):
        return getattrs_inh(cls, use_lvl_vals, verbose=verbose)


# %% ../nbs/01_mixs.ipynb 12
class KWixProps:
    @property
    def curkws(cls) -> List[str]:
        return cls.get_kws_cur()
    @property
    def allkws(cls) -> List[str]:
        return cls.get_kws_all()
    @property
    def inhkws(cls) -> List[str]:
        return cls.get_kws_inh()
    
    @property
    def curattrs(cls, use_lvl_vals: bool = False) -> dict:
        return cls.getattrs_cur(use_lvl_vals)
    @property
    def allattrs(cls, use_lvl_vals: bool = False) -> dict:
        return cls.getattrs_all(use_lvl_vals)
    @property
    def inhattrs(cls, use_lvl_vals: bool = False) -> dict:
        return cls.getattrs_inh(use_lvl_vals)
    
    @property
    def curbase(self) -> dict:
        return getattrs(self, self.curattrs)
    @property
    def inhbase(self) -> dict:
        return getattrs(self, self.inhattrs)
    @property
    def allbase(self) -> dict:
        return getattrs(self, self.allattrs)
        
    def curvals(self, **kwargs) -> dict:
        return kwskws(self.curbase, **kwargs)
    def inhvals(self, **kwargs) -> dict:
        return kwskws(self.inhbase, **kwargs)
    def allvals(self, **kwargs) -> dict:
        return kwskws(self.allbase, **kwargs)


# %% ../nbs/01_mixs.ipynb 14
class KWix(KWixMixin, KWixClsFns, KWixProps):
    ...
