import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir))
from interfaces import *
del sys, os

import re
from types import StringType

def ignoreRE(value, expression):
    ignore = re.compile(expression)
    return ignore.sub('', value)

class RegexValidator:
    __implements__ = (ivalidator,)

    def __init__(self, name, *args, **kw):
        self.name = name
        self.title = kw.get('title', name)
        self.description = kw.get('description', '')
        self.regex = []
        for r in args:
            self.regex.append(re.compile(r))

        self.ignore = kw.get('ignore', None)


    def __call__(self, value, *args, **kwargs):
        if type(value) != StringType:
            return ("Validation Failed(%s): %s of "
                    "type %s, expected 'string'" %
                    (self.name, value, type(value)))

        ignore = kwargs.get('ignore', None)
        if ignore:
            value = ignoreRE(value, ignore)
        elif self.ignore:
            value = ignoreRE(value, self.ignore)


        for r in self.regex:
            m = r.match(value)
            if not m:
                return ("Validation Failed(%s): on "
                        "%s" % (self.name, value))
        return 1


class RangeValidator:
    __implements__ = (ivalidator,)

    def __init__(self, name, title='', description=''):
        self.name = name
        self.title = title or name
        self.description = description

    def __call__(self, value, *args, **kwargs):
        min, max = args[:2]
        assert(min <= max)
        try:
            nval = float(value)
        except ValueError:
            return ("Validation Failed(%s): could "
                    "not convert %r to number" %
                    (self.name, value))
        if min <= nval < max:
            return 1

        return ("Validation Failed(%s): %s out "
                "of range(%s, %s)" %
                (self.name, value, min, max))
