#!/usr/bin/env python

import qrcode, cgi, urllib, sys

script_name='kortti.cgi'

def unknown_handler(form):
    print('Content-type: text/plain\n\nUnknown mode ' + form.getfirst('mode'))

def html_header(title):
    print('Content-type: text/html\n\n<title>%s</title>' % title)

def png_header():
    print('Content-type: image/png\n')

fields = [('nimi', 'FN'), ('puhelin', 'TEL'), ('email', 'EMAIL'),
        ('kotisivu', 'URL'), ('osoite', 'ADR')]

def default_handler(form):
    html_header('Tee oma yhteystietokorttisi')
    print('<p>Kirjoita vain tiedot, jotka haluat mukaan :)')
    print('<form>%s\n%s</form>' %
        (form_elements(f[0] for f in fields), form_submit()))

def form_submit():
    return '<input type=hidden name=mode value="frame">' + \
            '<input type=submit value="Tee kortti">'

def form_elements(elements):
    return '<dl>%s</dl>' % '\n'.join(form_element(e) for e in elements)

def form_element(e):
    return '<dt>%s:</dt><dd><input type=text name="%s"></dd>' % (e.title(), e)

def render_frame_page(form):
    html_header('Yhteystiedot')
    print('<p>Voit tallettaa sivun kirjanmerkiksi tulevaa varten.</p>')
    print('<table border=0><tr><td>')
    print('<p>Kaikki yhteystiedot:<br><img src="%s">' % mode_url('qr', form))
    print('</td><td>')
    print('<p>Linkki sivuun:<br><img src="%s">' % mode_url('linkqr', form))
    print('</td></tr></table>')
    print('<p>Voit <a href="%s">ladata tiedot itsellesi</a>.'
            % mode_url('vcard', form))

def mode_url(new_mode, form, script=script_name):
    params = dict((key, form.getfirst(key)) for key in form.keys())
    params['mode'] = new_mode
    return '%s?%s' % (script, urllib.urlencode(params))

def render_vcard(form):
    print('Content-type: text/vcard\n')
    print(vcard_from_form(form))

def vcard_from_form(form):
    return 'BEGIN:VCARD\nVERSION:3.0\n%s\n%s\nEND:VCARD' % \
            (name_field(form), vcard_fields(form))

def name_field(form):
    names = form.getfirst('nimi', '').split()
    if not names: return 'N:unknown'
    return 'N:%s;%s' % (names[-1], ' '.join(names[:-1]))

def vcard_fields(form):
    return '\n'.join('%s:%s' % (vfld, form.getfirst(field))
            for field, vfld in fields if form.has_key(field))

def make_vcard_qr(form):
    png_header()
    qrcode.make(vcard_from_form(form)).save(sys.stdout)

def make_link_qr(form):
    png_header()
    from os import environ
    qrcode.make('http://' + environ['SERVER_NAME'] + environ['SCRIPT_NAME'] \
            + mode_url('frame', form, '')).save(sys.stdout)

def make_phone_qr(form):
    png_header()
    qrcode.make('tel:' + form.getfirst('puhelin', '')).save(sys.stdout)

def make_mailto_qr(form):
    png_header()
    qrcode.make('mailto:' + form.getfirst('email', '')).save(sys.stdout)

handlers = {'default': default_handler,
        'vcard': render_vcard,
        'qr': make_vcard_qr,
        'linkqr': make_link_qr,
        'telqr': make_phone_qr,
        'mailqr': make_mailto_qr,
        'frame': render_frame_page}

def handle(form):
    handlers.get(form.getfirst('mode', 'default'), unknown_handler)(form)

if __name__ == '__main__':
    handle(cgi.FieldStorage())

