#-*- coding: utf-8 -*-
import phonenumbers
from django.core import validators
from phonenumbers.phonenumberutil import NumberParseException
from django.conf import settings


class PhoneNumber(phonenumbers.phonenumber.PhoneNumber):
    """
    A extended version of phonenumbers.phonenumber.PhoneNumber that provides some neat and more pythonic, easy
    to access methods. This makes using a PhoneNumber instance much easier, especially in templates and such.
    """
    @classmethod
    def from_string(cls, phone_number, region=None):
        phone_number_obj = cls()
        if region is None:
            region = getattr(settings, 'PHONENUMBER_DEFAULT_REGION', None)
        phonenumbers.parse(number=phone_number, region=region,
                           keep_raw_input=True, numobj=phone_number_obj)
        return phone_number_obj

    def __unicode__(self):
        if self.is_valid():
            return self.as_e164
        return self.raw_input

    def __str__(self):
        return str(unicode(self))

    def original_unicode(self):
        return super(PhoneNumber, self).__unicode__()

    def is_valid(self):
        """
        checks whether the number supplied is actually valid
        """
        return phonenumbers.is_valid_number(self)

    def format_as(self, format):
        if self.is_valid():
            return phonenumbers.format_number(self, format)
        else:
            return self.raw_input

    @property
    def as_international(self):
        return self.format_as(phonenumbers.PhoneNumberFormat.INTERNATIONAL)

    @property
    def as_e164(self):
        return self.format_as(phonenumbers.PhoneNumberFormat.E164)

    @property
    def as_national(self):
        return self.format_as(phonenumbers.PhoneNumberFormat.NATIONAL)

    @property
    def as_rfc3966(self):
        return self.format_as(phonenumbers.PhoneNumberFormat.RFC3966)

    def __len__(self):
        return len(self.__unicode__())


def to_python(value):
    if value in validators.EMPTY_VALUES:  # None or ''
        phone_number = None
    elif value and isinstance(value, basestring):
        try:
            phone_number = PhoneNumber.from_string(phone_number=value)
        except NumberParseException, e:
            # the string provided is not a valid PhoneNumber.
            phone_number = PhoneNumber(raw_input=value)
    elif isinstance(value, phonenumbers.phonenumber.PhoneNumber) and \
         not isinstance(value, PhoneNumber):
        phone_number = PhoneNumber(value)
    elif isinstance(value, PhoneNumber):
        phone_number = value
    return phone_number
@@ -458,24 +458,294 @@
 ch.%0A    %22%22%22%0A
+    format_map = %7B%0A        'E164': phonenumbers.PhoneNumberFormat.E164,%0A        'INTERNATIONAL': phonenumbers.PhoneNumberFormat.INTERNATIONAL,%0A        'NATIONAL': phonenumbers.PhoneNumberFormat.NATIONAL,%0A        'RFC3966': phonenumbers.PhoneNumberFormat.RFC3966,%0A    %7D%0A%0A
     @classme
@@ -1125,32 +1125,157 @@
 nicode__(self):%0A
+        format_string = getattr(settings, 'PHONENUMBER_DEFAULT_FORMAT', 'E164')%0A        fmt = self.format_map%5Bformat_string%5D%0A
         if self.
@@ -1310,23 +1310,30 @@
 rn self.
-as_e164
+format_as(fmt)
 %0A       

Support specifying PHONENUMBER_DEFAULT_FORMAT