from zope.interface import directlyProvides
from zope.schema.interfaces import IVocabularyFactory
from zope.schema.vocabulary import SimpleTerm
from zope.schema.vocabulary import SimpleVocabulary
from bda.plone.checkout.vocabularies import country_vocabulary
from bda.plone.checkout.vocabularies import gender_vocabulary
from bda.plone.shipping import Shippings
from .utils import get_shop_article_settings
from .utils import get_shop_tax_settings
from . import message_factory as _


# This are the overall avaiable quantity units which then can be reduced in
# control panel. If you need to provide more quantity units add it here or
# patch this vocab
AVAILABLE_QUANTITY_UNITS = {
    'quantity': _('quantity', default='Quantity'),
    'meter': _('meter', default='Meter'),
    'kilo': _('kilo', default='Kilo'),
    'liter': _('liter', default='Liter'),
}


def AvailableQuantityUnitVocabulary(context):
    # vocab is used in shop settings control panel
    items = AVAILABLE_QUANTITY_UNITS.items()
    return SimpleVocabulary([SimpleTerm(value=k, title=v) for k, v in items])
directlyProvides(AvailableQuantityUnitVocabulary, IVocabularyFactory)


def QuantityUnitVocabulary(context):
    # vocab is used for buyable items
    settings = get_shop_article_settings()
    if not settings:
        return
    terms = []
    for quantity_unit in settings.quantity_units:
        title = AVAILABLE_QUANTITY_UNITS.get(quantity_unit, quantity_unit)
        terms.append(SimpleTerm(value=quantity_unit, title=title))
    return SimpleVocabulary(terms)
directlyProvides(QuantityUnitVocabulary, IVocabularyFactory)


# This are the overall avaiable VAT values which then can be reduced in
# control panel. If you need to provide more vat values add it here or
# patch this vocab
AVAILABLE_VAT_VALUES = {
    '0': '0%',
    '10': '10%',
    '20': '20%',
    '25': '25%',
}


def AvailableVatVocabulary(context):
    # vocab is used in shop settings control panel
    items = AVAILABLE_VAT_VALUES.items()
    return SimpleVocabulary([SimpleTerm(value=k, title=v) for k, v in items])
directlyProvides(AvailableVatVocabulary, IVocabularyFactory)


def VatVocabulary(context):
    # vocab is used for buyable items
    settings = get_shop_tax_settings()
    if not settings:
        return
    terms = []
    if settings.vat:
        for vat in settings.vat:
            title = AVAILABLE_VAT_VALUES.get(vat, vat)
            terms.append(SimpleTerm(value=vat, title=title))
    return SimpleVocabulary(terms)
directlyProvides(VatVocabulary, IVocabularyFactory)


# This are the overall avaiable currency values available in
# control panel. If you need to provide more currencies add it here or
# patch this vocab
AVAILABLE_CURRENCIES = {
    'EUR': _('EUR', default='Euro'),
    'USD': _('USD', default='US Dollar'),
    'INR': _('INR', default='Indian Rupee'),
    'CAD': _('CAD', default='Canadian Dollar'),
    'CHF': _('CHF', default='Swiss Franc'),
    'GBP': _('GBP', default='British Pound Sterling'),
    'AUD': _('AUD', default='Australian Dollar'),
    'NOK': _('NOK', default='Norwegian Krone'),
    'SEK': _('SEK', default='Swedish Krona'),
    'DKK': _('DKK', default='Danish Krone'),
    'YEN': _('YEN', default='Japanese Yen'),
}


def AvailableCurrenciesVocabulary(context):
    items = AVAILABLE_CURRENCIES.items()
    return SimpleVocabulary([SimpleTerm(value=k, title=v) for k, v in items])
directlyProvides(AvailableCurrenciesVocabulary, IVocabularyFactory)


def AvailableShippingMethodsVocabulary(context):
    items = Shippings(context).vocab
    return SimpleVocabulary([SimpleTerm(value=k, title=v) for k, v in items])
directlyProvides(AvailableShippingMethodsVocabulary, IVocabularyFactory)


def CurrencyDisplayOptionsVocabulary(context):
    items = [
        ('yes', _('yes', default='Yes')),
        ('no', _('no', default='No')),
        ('symbol', _('symbol', default='Symbol')),
    ]
    return SimpleVocabulary([SimpleTerm(value=k, title=v) for k, v in items])
directlyProvides(CurrencyDisplayOptionsVocabulary, IVocabularyFactory)


def GenderVocabulary(context):
    return SimpleVocabulary([SimpleTerm(value=k, title=v)
                             for k, v in gender_vocabulary()])
directlyProvides(GenderVocabulary, IVocabularyFactory)


def CountryVocabulary(context):
    """VocabularyFactory for countries from ISO3166 source.
    """
    return SimpleVocabulary([SimpleTerm(value=k, title=v)
                             for k, v in country_vocabulary()])
directlyProvides(CountryVocabulary, IVocabularyFactory)

@@ -2,46 +2,204 @@
 rom 
-zope.interface import directlyP
+bda.plone.checkout.vocabularies import country_vocabulary%0Afrom bda.plone.checkout.vocabularies import gender_vocabulary%0Afrom bda.plone.shipping import Shippings%0Afrom zope.interface import p
 rovide
-s
+r
 %0Afro
@@ -356,168 +356,37 @@
 rom 
-bda.plone.checkout.vocabularies import country_vocabulary%0Afrom bda.plone.checkout.vocabularies import gender_vocabulary%0Afrom bda.plone.shipping import Shippings
+. import message_factory as _
 %0Afro
@@ -472,43 +472,8 @@
 ngs%0A
-from . import message_factory as _%0A
 %0A%0A# 
@@ -3217,32 +3217,62 @@
 nese Yen'),%0A%7D%0A%0A%0A
+@provider(IVocabularyFactory)%0A
 def AvailableCur
@@ -3422,56 +3422,19 @@
 s%5D)%0A
-directlyProvides(AvailableCurrenciesVocabulary, 
+%0A@provider(
 IVoc
@@ -3445,26 +3445,24 @@
 aryFactory)%0A
-%0A%0A
 def Availabl
@@ -3617,61 +3617,20 @@
 s%5D)%0A
-directlyProvides(AvailableShippingMethodsVocabulary, 
+%0A%0A@provider(
 IVoc
@@ -3641,26 +3641,24 @@
 aryFactory)%0A
-%0A%0A
 def Currency
@@ -3926,59 +3926,20 @@
 s%5D)%0A
-directlyProvides(CurrencyDisplayOptionsVocabulary, 
+%0A%0A@provider(
 IVoc
@@ -3950,26 +3950,24 @@
 aryFactory)%0A
-%0A%0A
 def GenderVo
@@ -4110,43 +4110,19 @@
 )%5D)%0A
-directlyProvides(GenderVocabulary, 
+%0A@provider(
 IVoc
@@ -4133,26 +4133,24 @@
 aryFactory)%0A
-%0A%0A
 def CountryV
@@ -4363,60 +4363,4 @@
 )%5D)%0A
-directlyProvides(CountryVocabulary, IVocabularyFactory)%0A

use decorator