# -*- coding: utf8 -*-
from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden
from pyramid.response import Response
import cStringIO as StringIO
from pyramid.view import view_config
from .models import DBSession, User
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.units import mm
import qrcode
import subprocess
from .upload import MediaPath
from jm2l.const import CurrentYear
# Create PDF container
EXPIRATION_TIME = 300 # seconds
WIDTH = 85 * mm
HEIGHT = 60 * mm
ICONSIZE = 10 * mm

def JM2L_Logo(canvas, Offset=(0,0)):
    OffX, OffY = Offset
    logoobject = canvas.beginText()
    logoobject.setFont('Logo', 32)
    logoobject.setFillColorRGB(.83,0,.33)
    logoobject.setTextOrigin(OffX+5, OffY+17)
    logoobject.textLines("JM2L")
    canvas.drawText(logoobject)
    
    yearobject = canvas.beginText()
    yearobject.setFont("Helvetica-Bold", 10)
    yearobject.setFillColorRGB(1,1,1)
    yearobject.setTextRenderMode(0)
    yearobject.setTextOrigin(OffX+12 , OffY+35)
    yearobject.setWordSpace(13)
    yearobject.textLines(" ".join(str(CurrentYear)))
    canvas.drawText(yearobject)

def Tiers_Logo(canvas, DispUser, StartPos=None, Offset=(0,0)):
    Border = 0
    OffX, OffY = Offset
    if StartPos is None:
        StartPos = ( 30 * mm, 2 )
    StartX, StartY = StartPos
    MaxX, MaxY = 34*mm, 18*mm
    num = 0
    canvas.setStrokeColorRGB(0.5,0.5,0.5)
    Logos = filter(lambda x:x.ThumbLinks, DispUser.tiers)[:3]
    # Should We compute a better positionning for logos ?
    DicPos = {}
    DicPos[1] = { 0:(1./2, 1./2) }
    DicPos[2] = { 0:(1./3, 1./2),   1:(2./3, 1./2) }
    DicPos[3] = { 0:(1./2, 1./4),   1:(1./3, 3./4),   2:(2./3, 3./4) }
    DicPos[4] = { 0:(1./3, 1./4),   1:(2./3, 1./4),   2:(1./3, 3./4), 
                  3:(2./3, 3./4) }
    DicPos[5] = { 0:(1./3, 1./4),      1:(2./3, 1./4),      2:(1./6, 3./4),
                  3:(3./6, 3./4),      4:(5./6, 3./4) }
    DicPos[6] = { 0:(1./6, 1./4),      1:(3./6, 1./4),      2:(5./6, 1./4),
                  3:(1./6, 3./4),      4:(3./6, 3./4),      5:(5./6, 3./4) }
    DicPos[7] = { 0:(1./6, 1./4),      1:(3./6, 1./4),      2:(5./6, 1./4),
                  3:(1./8, 3./4),      4:(3./8, 3./4),      5:(5./8, 3./4),
                  6:(7./8, 3./4) }
    DicPos[8] = { 0:(1./8, 1./4),      1:(3./8, 1./4),      2:(5./8, 1./4),
                  3:(7./8, 1./4),      4:(1./8, 3./4),      5:(3./8, 3./4),
                  6:(5./8, 3./4),      7:(7./8, 3./4) }
    # draw overall border
    # canvas.roundRect(StartX, StartY, MaxX, MaxY, radius=2, stroke=True)
    for tiers in Logos:
        FileName = tiers.ThumbLinks.pop().split("/")[-1]
        ImagePath = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, FileName)        
        PosX = OffX+StartX + DicPos[len(Logos)][num][0] * MaxX - (ICONSIZE+Border)/2
        PosY = OffY+StartY + DicPos[len(Logos)][num][1] * MaxY - (ICONSIZE+Border)/2
        canvas.setLineWidth(.1)
        if len(Logos)>1:
            size = ICONSIZE
        else:
            size = ICONSIZE*1.5
        canvas.drawImage(ImagePath, 
            PosX, PosY, size, size,\
            preserveAspectRatio=True, 
            anchor='c',
            mask='auto'
            )
        # draw icon border
        # canvas.roundRect(PosX, PosY, ICONSIZE, ICONSIZE, radius=2, stroke=True)
        num+=1

def QRCode(DispUser):
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=2,
    )
    # Data of QR code
    qr.add_data('http://jm2l.linux-azur.org/user/%s' % DispUser.slug)
    qr.make(fit=True)

    return qr.make_image()

def one_badge(c, DispUser, Offset=(0,0)):
    # Logo on Top
    JM2L_Logo(c, Offset)
    OffX, OffY = Offset
    
    c.rect(OffX-3, OffY-3, WIDTH+6, HEIGHT+6, fill=0, stroke=1)
    if DispUser.Staff:
        # Staff
        c.setFillColorRGB(.83,0,.33)
        c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
        c.setFillColorRGB(1,1,1)
        c.setFont('Liberation', 30)
        c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "STAFF")
    elif DispUser.is_Intervenant:
        # Intervenant
        c.setFillColorRGB(.21,.67,.78)
        c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
        c.setFillColorRGB(1,1,1)
        c.setFont('Liberation', 30)
        c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Intervenant")
    elif DispUser.is_crew:
        # Benevole
        c.setFillColorRGB(.18,.76,.23)
        c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
        c.setFillColorRGB(1,1,1)
        c.setFont('Liberation', 30)
        c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Bénévole")
    else:
        # Visiteur
        c.setFillColorRGB(.8,.8,.8)
        c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
        c.setFillColorRGB(1,1,1)
        c.setFont('Liberation', 30)
        c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Visiteur")

    c.restoreState()
    
    c.setFont('Liberation', 18)
    c.setStrokeColorRGB(0,0,0)
    c.setFillColorRGB(0,0,0)
    # Feed Name and SurName
    if DispUser.prenom and DispUser.nom and len(DispUser.prenom) + len(DispUser.nom)>18:
        if DispUser.pseudo:
            c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 0 * mm , "%s" % DispUser.prenom )
            #c.setFont('Courier', 17)
            c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 - 8 * mm , "%s" % DispUser.nom )
        else:
            c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 4 * mm , "%s" % DispUser.prenom )
            #c.setFont('Courier', 17)
            c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 - 8 * mm , "%s" % DispUser.nom )            
    else:
        c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 0 * mm , "%s %s" % (DispUser.prenom, DispUser.nom) )

    if DispUser.pseudo:
        c.setFont("Helvetica-Oblique", 18)
        c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 10 * mm , "%s" % DispUser.pseudo )
    
    # Put QR code to user profile 
    c.drawInlineImage(QRCode(DispUser), \
            OffX+WIDTH - 20 * mm -5, OffY+5, \
            20 * mm, 20 * mm, \
            preserveAspectRatio=True, \
            anchor='s')
    
    Tiers_Logo(c, DispUser, None, Offset)   
    

@view_config(route_name='badge_user', http_cache = (EXPIRATION_TIME, {'public':True}))
def badge_user(request):
    isoutpng = request.params.get('png')
    user_slug = request.matchdict.get('user_slug', None)
    if user_slug is None or len(user_slug)==0:
        raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu")
    # Query database
    DispUser = User.by_slug(user_slug)
    if DispUser is None:
        raise HTTPNotFound()

    # Ok let's generate a PDF Badge
    
    # Register LiberationMono font
    ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
    pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
    # Import font
    ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
    pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))

    pdf = StringIO.StringIO()
    out_img = StringIO.StringIO()
  
    c = canvas.Canvas( pdf, pagesize=(WIDTH, HEIGHT) )
    c.translate(mm, mm)
    
    # Feed some metadata
    c.setCreator("linux-azur.org")
    c.setTitle("Badge")

    c.saveState()
    
    one_badge(c, DispUser)

    c.showPage()
    c.save()
    pdf.seek(0)
    if isoutpng:
        OutPDF = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf')
        OutPNG = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png')
        # Let's generate a png file for website
        with open( OutPDF ,'wb') as pdff:
            pdff.write(pdf.read())
    
        Command = ["convert","-density","150x150", OutPDF, OutPNG]
        subprocess.call(Command)
        
        with open( OutPNG, 'rb') as pngfile:
            out_img.write(pngfile.read())
        
        out_img.seek(0)
        return Response(app_iter=out_img, content_type = 'image/png' )
    else:
        return Response(app_iter=pdf, content_type = 'application/pdf' )


@view_config(route_name='all_badges')
def planche_badge(request):
    if request.user is None:
        # Don't answer to users that aren't logged
        raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
    # Query database about selected Year.
    Users = DBSession.query(User)
    #            .join(User_Event)\
    #            .filter(User_Event.year_uid == year)

    # Register LiberationMono font
    ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
    pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
    # Import font
    ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
    pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))
    
    pdf = StringIO.StringIO()

    FULLWIDTH = 210 * mm
    FULLHEIGHT = 297 * mm

    c = canvas.Canvas( pdf, pagesize=(FULLWIDTH, FULLHEIGHT) )
    c.translate(mm, mm)
    
    # Feed some metadata
    c.setCreator("linux-azur.org")
    c.setTitle("Badge")
    t=0
    ListUser = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users)
    for num, DispUser in enumerate(ListUser):
        c.saveState()
        Offsets = (((num-t)%2)*(WIDTH+40)+40, ((num-t)/2)*(HEIGHT+25)+40)
        one_badge(c, DispUser, Offsets)
        if num%8==7:
            t=num+1
            c.showPage()

    c.showPage()
    c.save()
    pdf.seek(0)
    return Response(app_iter=pdf, content_type = 'application/pdf' )
