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

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

# %% ../nbs/02_mixs.ipynb 4
from dataclasses import dataclass, KW_ONLY

# %% ../nbs/02_mixs.ipynb 5
from typing import (
    Type, Optional, Union, Callable, Any, Tuple, List, Dict
)

# %% ../nbs/02_mixs.ipynb 6
from kwix.types import (
    Sig, Param, ObjQ, StrQ, ClassLevel,
    AttrKeysLike, AttrKeysLikeQ, AttrDefaults
)

# %% ../nbs/02_mixs.ipynb 7
from kwix.utils import ( 
    isp, iscls, isp_non_self, isp_non_empty, isp_w_default, is_attrkeys, isint, 
    null_cls_init_sig, getmro, getinit, getannots, getannots_kws, 
    make_attrvals, attrkeys_as_dict, getattrs, 
    getinit_sig, getinit_kws, getinit_kws_defaults,
    funkws, kwskws, unpack_optout,
    
    verb_get_kws_at_lvl, get_kws_at_lvl, getattrs_at_lvl,
    get_kws_cur, get_kws_all, get_kws_inh, getattrs_cur, getattrs_all, getattrs_inh
)

# %% ../nbs/02_mixs.ipynb 10
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: ClassLevel, 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: ClassLevel, 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: ClassLevel, 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: ClassLevel = 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/02_mixs.ipynb 12
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/02_mixs.ipynb 14
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/02_mixs.ipynb 16
class KWix(KWixMixin, KWixClsFns, KWixProps):
    ...
