# Path: stoqdrivers/interfaces.py
# class IChequePrinter(IDevice):
#     """ Interface specification for cheque printers. """
# 
#     cheque_printer_charset = Attribute("The charset name which the cheque "
#                                        "printer uses.")
# 
#     def get_banks():
#         """ Returns a dictionary of all banks supported by the printer. The
#         dictionary's key is the bank name and its value are BankConfiguration
#         instances (this classe [BankConfiguration] is used to store and manage
#         the values of each section in the configuration file).
#         """
# 
#     def print_cheque(bank, value, thirdparty, city, date=None):
#         """ Prints a cheque
# 
#         @param bank:      the code of bank
#         @type bank:       one of codes returned by get_banks method.
# 
#         @param value:     the value of the cheque
#         @type value:      Decimal
# 
#         @param thirdparty: receiver of the cheque
#         @type thirdparty: str
# 
#         @param city:
#         @type city:       str
# 
#         @param date:      when the cheque was payed, optional
#         @type date:       datetime
#         """
# 
#     def get_capabilities():
#         """ Returns a capabilities dictionary, where the keys are the strings
#         below and its values are Capability instances
# 
#         * cheque_thirdparty   (str)
#         * cheque_value        (Decimal)
#         * cheque_city         (str)
#         """
# 
# Path: stoqdrivers/exceptions.py
# class ConfigError(Exception):
#     "Bad config file arguments or sections"
# 
# Path: stoqdrivers/printers/base.py
# class BasePrinter(BaseDevice):
#     device_dirname = "printers"
#     device_type = DeviceType.PRINTER
# 
#     def check_interfaces(self):
#         driver_interfaces = providedBy(self._driver)
#         if (ICouponPrinter not in driver_interfaces
#                 and IChequePrinter not in driver_interfaces
#                 and INonFiscalPrinter not in driver_interfaces):
#             raise TypeError("The driver `%r' doesn't implements a valid "
#                             "interface" % self._driver)
# 
#     def get_constants(self):
#         return self._driver.get_constants()
# 
#     def get_tax_constant(self, item):
#         for enum, constant, value in self.get_tax_constants():
#             if enum == item:
#                 return constant
# 
#     def get_model_name(self):
#         return self._driver.model_name
# 
# Path: stoqdrivers/utils.py
# def encode_text(text, encoding):
#     """ Converts the string 'text' to encoding 'encoding' and optionally
#     normalizes the string (currently only for ascii)
# 
#     @param text:       text to convert
#     @type text:        str
#     @param encoding:   encoding to use
#     @type text:        str
#     @returns:          converted text
#     """
#     if encoding == "ascii":
#         text = unicodedata.normalize("NFKD", text)
#     # If we use text.encode we will get this sometimes:
#     # TypeError: 'abicomp' encoder returned 'str' instead of 'bytes';
#     #   use codecs.encode() to encode to arbitrary types
#     text = codecs.encode(text, encoding, "ignore")
#     # Only do the bellow conversion if the encoding above worked
#     if isinstance(text, bytes):
#         # Use bytes2str instead of decode or otherwise we would encode
#         # the bytes in unicode. This way we will still keep them in the
#         # encoding that we want (since SerialBase.write will do the reversal
#         # operation, str2bytes) even though we will get some strange
#         # characters in the "unicode version" of the string
#         text = bytes2str(text)
#     return text
# 
# Path: stoqdrivers/translation.py
# def stoqdrivers_gettext(message):
#     return gettext.dgettext('stoqdrivers', message)


from configparser import ConfigParser
from numbers import Real
from typing import Optional
from zope.interface.exceptions import DoesNotImplement
from zope.interface import providedBy
from stoqdrivers.interfaces import IChequePrinter
from stoqdrivers.exceptions import ConfigError
from stoqdrivers.printers.base import BasePrinter
from stoqdrivers.utils import encode_text
from stoqdrivers.translation import stoqdrivers_gettext
import datetime
import pkg_resources


class BaseChequePrinter:
    """ A base class for all printers that implements IChequePrinter interface.
    This class knows how to deal with the configuration file, that contains
    all the configuration of all supported cheques by the printer.

    @cvar CHEQUE_CONFIGFILE: This constant must be redefined in subclass and
                             must specify the filename where the cheque printer
                             configuration can be found.
    """
    CHEQUE_CONFIGFILE = None

    def __init__(self):
        self._banks = {}

    def get_banks(self):
        configfile = self.__module__.split('.')[-2] + '.ini'

        config = ConfigParser()
        resource_name = 'conf/%s' % configfile
        filename = pkg_resources.resource_filename('stoqdrivers', resource_name)
        if not config.read(filename):
            return None
        for section in config.sections():
            # With this, we'll have a dictionary in this format:
            # CONFIG_NAME: "Y,X"
            items = dict(config.items(section))
            try:
                bank = self._parse_bank(items)

# Path: stoqdrivers/interfaces.py
# class IChequePrinter(IDevice):
#     """ Interface specification for cheque printers. """
# 
#     cheque_printer_charset = Attribute("The charset name which the cheque "
#                                        "printer uses.")
# 
#     def get_banks():
#         """ Returns a dictionary of all banks supported by the printer. The
#         dictionary's key is the bank name and its value are BankConfiguration
#         instances (this classe [BankConfiguration] is used to store and manage
#         the values of each section in the configuration file).
#         """
# 
#     def print_cheque(bank, value, thirdparty, city, date=None):
#         """ Prints a cheque
# 
#         @param bank:      the code of bank
#         @type bank:       one of codes returned by get_banks method.
# 
#         @param value:     the value of the cheque
#         @type value:      Decimal
# 
#         @param thirdparty: receiver of the cheque
#         @type thirdparty: str
# 
#         @param city:
#         @type city:       str
# 
#         @param date:      when the cheque was payed, optional
#         @type date:       datetime
#         """
# 
#     def get_capabilities():
#         """ Returns a capabilities dictionary, where the keys are the strings
#         below and its values are Capability instances
# 
#         * cheque_thirdparty   (str)
#         * cheque_value        (Decimal)
#         * cheque_city         (str)
#         """
# 
# Path: stoqdrivers/exceptions.py
# class ConfigError(Exception):
#     "Bad config file arguments or sections"
# 
# Path: stoqdrivers/printers/base.py
# class BasePrinter(BaseDevice):
#     device_dirname = "printers"
#     device_type = DeviceType.PRINTER
# 
#     def check_interfaces(self):
#         driver_interfaces = providedBy(self._driver)
#         if (ICouponPrinter not in driver_interfaces
#                 and IChequePrinter not in driver_interfaces
#                 and INonFiscalPrinter not in driver_interfaces):
#             raise TypeError("The driver `%r' doesn't implements a valid "
#                             "interface" % self._driver)
# 
#     def get_constants(self):
#         return self._driver.get_constants()
# 
#     def get_tax_constant(self, item):
#         for enum, constant, value in self.get_tax_constants():
#             if enum == item:
#                 return constant
# 
#     def get_model_name(self):
#         return self._driver.model_name
# 
# Path: stoqdrivers/utils.py
# def encode_text(text, encoding):
#     """ Converts the string 'text' to encoding 'encoding' and optionally
#     normalizes the string (currently only for ascii)
# 
#     @param text:       text to convert
#     @type text:        str
#     @param encoding:   encoding to use
#     @type text:        str
#     @returns:          converted text
#     """
#     if encoding == "ascii":
#         text = unicodedata.normalize("NFKD", text)
#     # If we use text.encode we will get this sometimes:
#     # TypeError: 'abicomp' encoder returned 'str' instead of 'bytes';
#     #   use codecs.encode() to encode to arbitrary types
#     text = codecs.encode(text, encoding, "ignore")
#     # Only do the bellow conversion if the encoding above worked
#     if isinstance(text, bytes):
#         # Use bytes2str instead of decode or otherwise we would encode
#         # the bytes in unicode. This way we will still keep them in the
#         # encoding that we want (since SerialBase.write will do the reversal
#         # operation, str2bytes) even though we will get some strange
#         # characters in the "unicode version" of the string
#         text = bytes2str(text)
#     return text
# 
# Path: stoqdrivers/translation.py
# def stoqdrivers_gettext(message):
#     return gettext.dgettext('stoqdrivers', message)


# Path: stoqdrivers/printers/cheque.py
from configparser import ConfigParser
from numbers import Real
from typing import Optional
from zope.interface.exceptions import DoesNotImplement
from zope.interface import providedBy
from stoqdrivers.interfaces import IChequePrinter
from stoqdrivers.exceptions import ConfigError
from stoqdrivers.printers.base import BasePrinter
from stoqdrivers.utils import encode_text
from stoqdrivers.translation import stoqdrivers_gettext
import datetime
import pkg_resources



class BaseChequePrinter:
    """ A base class for all printers that implements IChequePrinter interface.
    This class knows how to deal with the configuration file, that contains
    all the configuration of all supported cheques by the printer.

    @cvar CHEQUE_CONFIGFILE: This constant must be redefined in subclass and
                             must specify the filename where the cheque printer
                             configuration can be found.
    """
    CHEQUE_CONFIGFILE = None

    def __init__(self):
        self._banks = {}

    def get_banks(self):
        configfile = self.__module__.split('.')[-2] + '.ini'

        config = ConfigParser()
        resource_name = 'conf/%s' % configfile
        filename = pkg_resources.resource_filename('stoqdrivers', resource_name)
        if not config.read(filename):
            return None
        for section in config.sections():
            # With this, we'll have a dictionary in this format:
            # CONFIG_NAME: "Y,X"
            items = dict(config.items(section))
            try:
                bank = self._parse_bank(items)

            except ConfigError as errmsg: