from incf.countryutils import data
from incf.countryutils import transformations as trafos

class Country(object):
    """encapsulating information about a country
    
    The constructor needs to be passed in an ISO 3166 numeric, two or 
    three letter country code or the simple English name.

    Raises ValueError if no corresponding country can be found
    """

    def __init__(self, key):
        """Infer the country from the key
        
        Valid keys are: two letter, three letter or numeric country code
        acording to ISO 3166 or the countries simple English name.

        Raises ValueError if key is not found.
        """

        if key in data.cn_to_ccn:
            self.cn = self.name = key
            self.ccn = self.numeric = data.cn_to_ccn[key]
        else:
            try:
                code = trafos.cc_to_ccn(key)
            except KeyError:
                raise ValueError("%s is o ISO country code or name" % key)
            self.ccn = self.numeric = code
            self.cn = self.name = trafos.ccn_to_cn(self.ccn)

        self.cca2 = self.alpha2 = trafos.ccn_to_cca2(self.numeric)
        self.cca3 = self.alpha3 = trafos.ccn_to_cca3(self.numeric)
        self.con = self.official_name = trafos.ccn_to_con(self.numeric)
        
        self.ctca2 = trafos.ccn_to_ctca2(self.numeric)
        self.ctn = trafos.ccn_to_ctn(self.numeric)

    @property 
    def continent(self):
        return Continent(self.ctn)


class Continent(object):
    """encapsulating information about a continent
    
    The constructor needs to be passed a two letter continent code
    or name ('AF': 'Africa', 'AN': 'Antarctica', 'AS': 'Asia',
    'EU': 'Europe', 'NA': 'North America', 'OC': 'Oceania',
    'SA': 'South America').

    Raises ValueError if no corresponding continent can be found
    """

    def __init__(self, key):
        """Infer the country from the key"""
        if key in data.ctca2_to_ctn:
            self.ctca2 = self.alpha2 = key
            self.ctn = self.name = data.ctca2_to_ctn[key]
        elif key in data.ctn_to_ctca2:
            self.ctn = self.name = key
            self.ctca2 = self.alpha2 = data.ctn_to_ctca2[key]
        else:
            raise ValueError("%s is not a continent code or name" % key)

    @property
    def countries(self):
        return (Country(c) for c in data.ctca2_to_ccn[self.alpha2]) 
