#Copyright ReportLab Europe Ltd. 2000-2004
#see license.txt for license details
#history www.reportlab.co.uk/rl-cgi/viewcvs.cgi/graphics/barcode/widget.py
__version__=''' $Id: widgets.py 13212 2004-06-28 12:31:48Z rgbecker $ '''
from reportlab.lib.validators import isInt, isNumber, isColor, isString, isColorOrNone, OneOf, isBoolean, EitherOr, isNumberOrNone
from reportlab.lib.attrmap import AttrMap, AttrMapValue
from reportlab.lib.colors import black
from reportlab.graphics.shapes import Line, Rect, Group, NotImplementedError
from reportlab.graphics.charts.areas import PlotArea

'''
#snippet

#first make your Drawing
from reportlab.graphics.shapes import Drawing
d= Drawing(100,50)

#create and set up the widget
from rlextra.graphics.barcode.widgets import BarcodeStandard93
bc = BarcodeStandard93()
bc.value = 'RGB-123456'

#add to the drawing and save
d.add(bc)
#   d.save(formats=['gif','pict'],fnRoot='bc_sample')
'''


class _BarcodeWidget(PlotArea):
    _attrMap = AttrMap(BASE=PlotArea,
        barStrokeColor = AttrMapValue(isColorOrNone, desc='Color of bar borders.'),
        barFillColor = AttrMapValue(isColorOrNone, desc='Color of bar interior areas.'),
        barStrokeWidth = AttrMapValue(isNumber, desc='Width of bar borders.'),
        value = AttrMapValue(EitherOr((isString,isNumber)), desc='Value.'),
        )
    _bcTransMap = {}

    def __init__(self,BCC=None,value=''):
        PlotArea.__init__(self)
        self.barStrokeColor = black
        self.barFillColor = black
        self.barStrokeWidth = 0
        self._BCC = BCC
        self.value = value
        BC = self._BCC(self.value)
        self.value = BC.value
        for a in self._bcAttrs():
            setattr(self,a,getattr(BC,self._bcTrans(a)))

    def _bcTrans(self,a):
        return self._bcTransMap.get(a,a)

    def rect(self,x,y,w,h,**kw):
        self._G.add(Rect(self.x+x,self.y+y,w,h,
                    strokeColor=self.barStrokeColor,strokeWidth=self.barStrokeWidth, fillColor=self.barFillColor))

    def _bcAttrs(self):
        return filter(lambda x,BK=_BarcodeWidget._attrMap.keys(): x not in BK,self._attrMap.keys())

    def draw(self):
        if not self._BCC: raise NotImplementedError("Abstract class %s cannot be drawn" % self.__class__.__name__)
        BC = {}
        for a in self._bcAttrs():
            BC[self._bcTrans(a)]=getattr(self,a)
        BC=self._BCC(self.value,**BC)
        BC.canv = self
        self._G = Group()
        BC.draw()
        G = self._G
        del BC.canv, self._G
        return G

class BarcodeI2of5(_BarcodeWidget):
    _attrMap = AttrMap(BASE=_BarcodeWidget,
        xdim = AttrMapValue(isNumber,'''(float, default .0075):
            X-Dimension, or width of the smallest element
            Minumum is .0075 inch (7.5 mils).'''),
        ratio = AttrMapValue(isNumber,'''(float, default 2.2):
            The ratio of wide elements to narrow elements.
            Must be between 2.0 and 3.0 (or 2.2 and 3.0 if the
            xdim is greater than 20 mils (.02 inch))'''),
        gap = AttrMapValue(isNumberOrNone,'''(float or None, default None):
            width of intercharacter gap. None means "use xdim".'''),
        barHeight = AttrMapValue(isNumber,'''(float, see default below):
            Height of the symbol.  Default is the height of the two
            bearer bars (if they exist) plus the greater of .25 inch
            or .15 times the symbol's length.'''),
        checksum = AttrMapValue(isBoolean,'''(bool, default 1):
            Whether to compute and include the check digit'''),
        bearers = AttrMapValue(isNumber,'''(float, in units of xdim. default 3.0):
            Height of bearer bars (horizontal bars along the top and
            bottom of the barcode). Default is 3 x-dimensions.
            Set to zero for no bearer bars. (Bearer bars help detect
            misscans, so it is suggested to leave them on).'''),
        quiet = AttrMapValue(isBoolean,'''(bool, default 1):
            Whether to include quiet zones in the symbol.'''),

        lquiet = AttrMapValue(isNumber,'''(float, see default below):
            Quiet zone size to left of code, if quiet is true.
            Default is the greater of .25 inch, or .15 times the symbol's
            length.'''),

        rquiet = AttrMapValue(isNumber,'''(float, defaults as above):
            Quiet zone size to right left of code, if quiet is true.'''),
        )
    _bcTransMap = {'barHeight':'height'}

    def __init__(self):
        from rlextra.graphics.barcode.common import I2of5
        _BarcodeWidget.__init__(self,I2of5,1234)

class BarcodeCode128(BarcodeI2of5):
    _attrMap = AttrMap(BASE=BarcodeI2of5,UNWANTED=('bearers','checksum','ratio','checksum'))
    def __init__(self):
        from rlextra.graphics.barcode.code128 import Code128
        _BarcodeWidget.__init__(self,Code128,"AB-12345678")

class BarcodeStandard93(BarcodeCode128):
    def __init__(self):
        from rlextra.graphics.barcode.code93 import Standard93
        _BarcodeWidget.__init__(self,Standard93,"CODE 93")

class BarcodeExtended93(BarcodeCode128):
    def __init__(self):
        from rlextra.graphics.barcode.code93 import Extended93
        _BarcodeWidget.__init__(self,Extended93,"L@@K! Code 93 ;-)")

class BarcodeStandard39(BarcodeI2of5):
    def __init__(self):
        from rlextra.graphics.barcode.code39 import Standard39
        _BarcodeWidget.__init__(self,Standard39,"A012345B%R")

class BarcodeExtended39(BarcodeI2of5):
    def __init__(self):
        from rlextra.graphics.barcode.code39 import Extended39
        _BarcodeWidget.__init__(self,Extended39,"A012345B}")

class BarcodeMSI(BarcodeI2of5):
    def __init__(self):
        from rlextra.graphics.barcode.common import MSI
        _BarcodeWidget.__init__(self,MSI,1234)

class BarcodeCodabar(BarcodeI2of5):
    def __init__(self):
        from rlextra.graphics.barcode.common import Codabar
        _BarcodeWidget.__init__(self,Codabar,"A012345B")

class BarcodeCode11(BarcodeI2of5):
    _attrMap = AttrMap(BASE=BarcodeI2of5,
        checksum = AttrMapValue(isInt,'''(integer, default 2):
            Whether to compute and include the check digit(s).
            (0 none, 1 1-digit, 2 2-digit, -1 auto, default -1):
            How many checksum digits to include. -1 ("auto") means
            1 if the number of digits is 10 or less, else 2.'''),
            )
    def __init__(self):
        from rlextra.graphics.barcode.common import Code11
        _BarcodeWidget.__init__(self,Code11,"01234545634563")

class BarcodeFIM(_BarcodeWidget):
    _attrMap = AttrMap(BASE=_BarcodeWidget,
        barWidth = AttrMapValue(isNumber,'''(float, default 1/32in): the bar width.'''),
        barSpace = AttrMapValue(isNumber,'''(float or None, default 1/16in):
            width of intercharacter gap. None means "use xdim".'''),
        barHeight = AttrMapValue(isNumber,'''(float, default 5/8in): The bar height.'''),
        quiet = AttrMapValue(isBoolean,'''(bool, default 0):
            Whether to include quiet zones in the symbol.'''),
        lquiet = AttrMapValue(isNumber,'''(float, default: 15/32in):
            Quiet zone size to left of code, if quiet is true.'''),
        rquiet = AttrMapValue(isNumber,'''(float, default 1/4in):
            Quiet zone size to right left of code, if quiet is true.'''),
        )
    _bcTransMap = {'barHeight':'height','barWidth': 'barwidth', 'barSpace':'barspace'}
    def __init__(self):
        from rlextra.graphics.barcode.usps import FIM
        _BarcodeWidget.__init__(self,FIM,"A")

class BarcodePOSTNET(_BarcodeWidget):
    _attrMap = AttrMap(BASE=_BarcodeWidget,
        barWidth = AttrMapValue(isNumber,'''(float, default 0.018*in): the bar width.'''),
        barSpace = AttrMapValue(isNumber,'''(float or None, default 0.0275in): width of intercharacter gap.'''),
        sbarHeight = AttrMapValue(isNumber,'''(float, default 0.05in): The short bar height.'''),
        fbarHeight = AttrMapValue(isNumber,'''(float, default 0.125in): The full bar height.'''),
        )
    _bcTransMap = {'sbarHeight':'sbarheight', 'fbarHeight':'fbarheight', 'barWidth':'barwide', 'barSpace':'spacewide'}
    def __init__(self):
        from rlextra.graphics.barcode.usps import POSTNET
        _BarcodeWidget.__init__(self,POSTNET,"78247-1043")

if __name__=='__main__':
    import os, sys, glob
    from reportlab.graphics.shapes import Drawing
    os.chdir(os.path.dirname(sys.argv[0]))
    if not os.path.isdir('out'):
        os.mkdir('out')
    map(os.remove,glob.glob(os.path.join('out','*')))
    html = ['<html><head></head><body>']
    a = html.append
    for C in (BarcodeI2of5,
            BarcodeCode128,
            BarcodeStandard93,
            BarcodeExtended93,
            BarcodeStandard39,
            BarcodeExtended39,
            BarcodeMSI,
            BarcodeCodabar,
            BarcodeCode11,
            BarcodeFIM,
            BarcodePOSTNET,
            ):
        name = C.__name__
        i = C()
        D = Drawing(100,50)
        D.add(i)
        D.save(formats=['gif','pict'],outDir='out',fnRoot=name)
        a('<h2>%s</h2><img src="%s.gif"><br>' % (name, name))
    a('</body></html>')
    open(os.path.join('out','index.html'),'w').write('\n'.join(html))
