from django.db import models
from django.contrib import admin

from django.forms import ValidationError as FormValidationError
from django.core.exceptions import ValidationError
from django.forms import fields, widgets

from decimal import Decimal
from IPy import IP
 
class IPAddressFormField(fields.Field):
    default_error_messages = {
        'invalid': u'Enter a valid IPv4 or IPv6 address.',
    }

    def clean(self, value):
        'Method for validating IPs on forms'
        if value in fields.EMPTY_VALUES:
            return u''
            
        try:
            IP(value)
        except Exception, e:
            raise FormValidationError(self.error_messages['invalid'])

        return super(IPAddressFormField, self).clean(value)

class IPAddressWidget(widgets.TextInput):
    def render(self, name, value, attrs=None):
        if isinstance(value, IP):
            value = value.strNormal()
    
        return super(IPAddressWidget, self).render(name, value, attrs)

class IPAddressField(models.Field):

    __metaclass__ = models.SubfieldBase

    def db_type(self):
        return 'inet'

    def to_python(self, value):
        if not value or ((isinstance(value, str) or isinstance(value, unicode)) and value == ''):
            return None

        try:
            value = IP(value)
        except Exception, e:
            raise ValidationError(e)

        return value

    def get_db_prep_value(self, value):
        if not value:
            return None
        else:
            return unicode(value)

    def formfield(self, **kwargs):
        defaults = {
            'form_class': IPAddressFormField, 
            'widget': IPAddressWidget 
        }
        defaults.update(kwargs)
        return super(IPAddressField, self).formfield(**defaults)