# This file contains a library of subclasses of Validator
# These are the actual validator classes you'll use in your work

from BaseValidatorClasses import ValidatorConverter, InvalidField, FormValidator

class MustChoose(ValidatorConverter):

    def _validate(self, value):
        if not value:
            return "You must choose at least one"
        else:
            return None


class MaxLength(ValidatorConverter):

    def __init__(self, maxlength):
        self._maxlength = maxlength

    def _validate(self, value):
        try:
            if len(value) > self._maxlength:
                return "Enter a value less than %i characters long" \
                       % self._maxlength
            else:
                return None
        except TypeError:
            return "Invalid value"


class MinLength(ValidatorConverter):

    def __init__(self, minlength):
        self._minlength = minlength

    def _validate(self, value):
        try:
            if len(value) < self._minlength:
                return "Enter a value at least %i characters long" \
                       % self._minlength
            else:
                return None
        except TypeError:
            return "Invalid value"


class ExactLength(ValidatorConverter):

    def __init__(self, length):
        self._length = length

    def _validate(self, value):
        try:
            if len(value) != self._length:
                return "Enter a value %i characters long" % self._length
            else:
                return None
        except TypeError:
            return "Invalid value"
        

class RequiredField(ValidatorConverter):

    def __init__(self, minlength):
        self._minlength = minlength

    def _validate(self, value):
        try:
            if len(value) < self._minlength:
                return "This field is required"
            else:
                return None
        except TypeError:
            return "Invalid value"


class NotEmpty(ValidatorConverter):
    def _validate(self,value):
        if value in ("",None):
            return "Please enter some value"
        else:
            return None


class FileUploaded(ValidatorConverter):
    '''To requires user to upload a file with a FileField'''

    def _validate(self,value):
        if str(value):
            return None
        else:
            return "Please upload a file"


class ConvertToInt(ValidatorConverter):
    def _convert(self, value):
        try:
            return int(value)
        except ValueError:
            raise InvalidField, "Please enter an integer value"


class UpperAllChars(ValidatorConverter):
    '''Converts all characters in a string into caps'''
    def _convert(self, value):
        return str( value ).upper()


class CapitalizeAllWords(ValidatorConverter):
    '''Capitalizes each word in a string'''
    def _convert(self, value):
        bits = str(value).split()
        newVal = ''
        for bit in bits:
            newVal += bit.capitalize() + ' '
        return newVal.strip()


class DollarAmountAsString(ValidatorConverter):
    """ Checks that the value is a valid dollar amount 
    (i.e. "10.95", "$1.50", "1", etc.) and converts the value to a string,
    stripping the '$' if present. """
    # this class donated by Jason Hildebrand (jason@remotequote.ca)

    def _validate(self,value):
        if len(value) > 0 and value[0] == "$":
            value = value[1:]
        if not value:
            return "Please enter a dollar amount."
        try:
            p = float(value)
        except:
            return "This field must be a dollar amount."
        return None

    def _convert(self, value):
        if len(value) > 0 and value[0] == "$":
            value = value[1:]
        p = float(value)
        return "%.2f" % p


class EmailAddress(ValidatorConverter):
    """ Checks the value to make sure it at least looks like a valid email address.
    In normal mode it checks using a regular expression.  If you pass checkdns=1 to
    the constructor, it will check that the domain exists.  This requires the 
    pydns module from http://pydns.sf.net (Debian users: apt-get install python-dns) """
    # this class donated by Jason Hildebrand (jason@remotequote.ca)
    # Note that some features are dependent on the external library

    def __init__(self,checkdns=0):
        self._checkdns = checkdns

    def _validate(self,value):
        if self._checkdns:
            try:
                import DNS
                i = value.find('@')
                if i != -1:
                    domain = value[i+1:]
                    if domain:
                        DNS.ParseResolvConf()
                        r = DNS.DnsRequest(name=domain,qtype='ANY')
                        a = r.req()
                        if a.answers:
                            return None
                return "Please enter a valid email address."
            except:
                pass
        import re
        if re.match('[^@]+@[^\.]+(\.[^\.]+)+',value) is None:
            return "Please enter a valid email address."
        return None