from .descriptor import restricted_property
from . import restrictions
from .processors import processor_typecast


#######################################################
# Predefined Restrictions
#######################################################
RESTRICT_INT = restrictions.restrict_type(int)
RESTRICT_FLOAT = restrictions.restrict_type(float)
RESTRICT_NUMBER = restrictions.restrict_type((int, float))

RESTRICT_NONZERO = ~restrictions.restrict_value_list([0])
RESTRICT_POSITIVE = restrictions.restrict_range(lower = 0, lower_inc = False)
RESTRICT_NEGATIVE = restrictions.restrict_range(upper = 0, upper_inc = False)
RESTRICT_NONNEGATIVE = restrictions.restrict_range(lower = 0, lower_inc = True)
RESTRICT_NONPOSITIVE = restrictions.restrict_range(upper = 0, upper_inc = True)
RESTRICT_BOOL = restrictions.restrict_type(bool)
RESTRICT_FRACTION = restrictions.restrict_range(lower = 0, upper = 1, lower_inc = True, upper_inc = True)
RESTRICT_STRING = restrictions.restrict_type(str)
RESTRICT_ID_STRING = RESTRICT_STRING & ~restrictions.restrict_contains(" \/+")
RESTRICT_TUPLE = restrictions.restrict_type(tuple)
RESTRICT_TUPLE2 = RESTRICT_TUPLE & restrictions.restrict_len(2)
RESTRICT_INT_TUPLE2 = RESTRICT_TUPLE & restrictions.restrict_len(2) & restrictions.restrict_typelist(int)
RESTRICT_NUMBER_TUPLE2 = RESTRICT_TUPLE & restrictions.restrict_len(2) & restrictions.restrict_typelist((int, float))

######################################################
# predefined properties
######################################################
def int_property(internal_member_name= None, restriction = None,**kwargs):
    R = RESTRICT_INT & restriction
    return restricted_property(internal_member_name, restriction = R,**kwargs)
def float_property(internal_member_name= None, restriction = None,**kwargs):
    R = RESTRICT_FLOAT & restriction
    return restricted_property(internal_member_name, restriction = R,**kwargs)
def number_property(internal_member_name= None, restriction = None,**kwargs):
    R = RESTRICT_NUMBER & restriction
    return restricted_property(internal_member_name, restriction = R,**kwargs)
def string_property(internal_member_name= None, restriction = None,**kwargs):
    R = RESTRICT_STRING & restriction
    return restricted_property(internal_member_name, restriction = R,**kwargs)
def id_string_property(internal_member_name= None, restriction = None,**kwargs):
    R = RESTRICT_ID_STRING & restriction
    return restricted_property(internal_member_name, restriction = R,**kwargs)
def filename_property(internal_member_name= None, restriction = None,**kwargs):
    R = RESTRICT_STRING & restriction
    return restricted_property(internal_member_name, restriction = R,**kwargs)


def bool_property(internal_member_name= None, restriction = None,**kwargs):
    R = RESTRICT_BOOL & restriction
    return restricted_property(internal_member_name, restriction = R,**kwargs)

def length_property(internal_member_name= None, restriction = None,**kwargs):
    R = RESTRICT_NUMBER & RESTRICT_POSITIVE & restriction
    return restricted_property(internal_member_name, restriction = R,**kwargs)

def zero_length_property(internal_member_name= None, restriction = None,**kwargs):
    R = RESTRICT_NUMBER & RESTRICT_NONNEGATIVE & restriction
    return restricted_property(internal_member_name, restriction = R,**kwargs)

angle_property = number_property # to be specified later
normalized_angle_property = number_property # to be specified later


def time_property(internal_member_name= None, restriction = None, **kwargs):
    import time
    R = RESTRICT_NUMBER & restriction
    if not 'default' in kwargs:
        kwargs['default'] = time.time
    return restricted_property(internal_member_name, restriction = R,**kwargs)
    
