from itertools import islice
from operator import itemgetter

from django_countries.conf import settings


class Countries(object):
    """
    An object containing a list of ISO3166-1 countries.

    Iterating this object will return the countries as tuples (of the country
    code and name), sorted by name.
    """

    @property
    def countries(self):
        """
        Return the countries list, modified by any overriding settings.
        The result is cached so future lookups are less work intensive.
        """
        # Local import so that countries aren't loaded into memory until first
        # used.
        from django_countries.data import COUNTRIES

        if not hasattr(self, '_countries'):
            self._countries = []
            overrides = settings.COUNTRIES_OVERRIDE
            for code, name in COUNTRIES.items():
                if code in overrides:
                    name = overrides[code]
                if name is not None:
                    self._countries.append((code, name))
            for key in set(overrides) - set(COUNTRIES):
                self._countries.append((key, overrides[key]))

            if settings.COUNTRIES_ONLY:
                self._countries = [(code, name) for code, name in settings.COUNTRIES_ONLY.items()]

        return self._countries

    @countries.deleter
    def countries(self):
        """
        Reset the countries cache in case for some crazy reason the settings
        change. But surely no one is crazy enough to do that, right?
        """
        if hasattr(self, '_countries'):
            del self._countries

    def __iter__(self):
        """
        Return an iterator of countries, sorted by name.

        Each country record consists of a tuple of the two letter ISO3166-1
        country code and short name.
        """
        return iter(sorted(self.countries, key=itemgetter(1)))

    def name(self, code):
        """
        Return the name of a country, based on the code.

        If no match is found, returns an empty string.
        """
        return dict(self.countries).get(code, '')

    def __len__(self):
        """
        len() used by several third party applications to calculate the length
        of choices this will solve bug related to generating fixtures
        django_dynamic_fixture
        """
        return len(self.countries)

    def __getitem__(self, index):
        """
        some applications expect to be able to access members of the field
        choices by index
        """
        try:
            return next(islice(self.__iter__(), index, index+1))
        except TypeError:
            return list(islice(self.__iter__(), index.start, index.stop,
                               index.step))

countries = Countries()

@@ -704,32 +704,158 @@
  '_countries'):%0A
+            if settings.COUNTRIES_ONLY:%0A                self._countries = list(settings.COUNTRIES_ONLY)%0A            else:%0A    
             self
@@ -871,16 +871,20 @@
 es = %5B%5D%0A
+    
         
@@ -935,24 +935,28 @@
             
+ 
+   
 for code, na
@@ -996,16 +996,20 @@
         
+    
 if code 
@@ -1042,16 +1042,20 @@
         
+  
+  
 name = o
@@ -1081,24 +1081,28 @@
             
+    
 if name is n
@@ -1122,32 +1122,36 @@
                 
+   
+ 
 self._countries.
@@ -1171,16 +1171,20 @@
  name))%0A
+    
         
@@ -1239,32 +1239,36 @@
                 
+    
 self._countries.
@@ -1302,148 +1302,8 @@
 ))%0A%0A
-            if settings.COUNTRIES_ONLY:%0A                self._countries = %5B(code, name) for code, name in settings.COUNTRIES_ONLY.items()%5D%0A%0A
     
@@ -2305,39 +2305,9 @@
 ures
-%0A        django_dynamic_fixture
+.
 %0A   
@@ -2405,17 +2405,17 @@
         
-s
+S
 ome appl
@@ -2496,16 +2496,17 @@
 by index
+.
 %0A       

Tidy up how COUNTRIES_ONLY works