#!/usr/bin/python
# header2py.py - Convert OpenGL ES 2.0 header to Python
# This creates a ctypes-based wrapper around libGLESv2
# Copyright (c) 2011 Thomas Perl <thp.io/about>
# usage: python header2py.py < ~/pkg/QtSDK/Madde/sysroots/harmattan-nokia-meego-arm-sysroot-1122-slim/usr/include/GLES2/gl2.h > gles2.py

import sys
import re

TYPEDEF_RE = re.compile(r'^typedef (.*)\s+(.*);$')

TYPE_MAP = {
    'short': 'c_short',
    'int': 'c_int',
    'void': None,
    'float': 'c_float',
    'unsigned short': 'c_ushort',
    'signed char': 'c_byte',
    'unsigned char': 'c_ubyte',
    'unsigned int': 'c_uint',
}

COMMENT_RE = re.compile(r'/[*](.*)[*]/$')

DEFINE_RE = re.compile(r'^#define\s+([^ ]*)\s+([^ ]*)(.*)$')

APICALL_RE = re.compile(r'^GL_APICALL(.*)GL_APIENTRY([^(]*)[(](.*)[)];$')

print """
# Automatically generated from gl2.h
# Generator: header2py.py by Thomas Perl <thp.io/about>

from ctypes import *

glesv2 = cdll.LoadLibrary('libGLESv2.so')

"""

def convert_arg(argname, argtype):
    if argtype in ('GLfloat', 'GLclampf'):
        return '%s(%s)' % (argtype, argname)

    return argname


for line in sys.stdin:
    line = line.rstrip('\n')

    if not line:
        print ''
        continue

    typedef = TYPEDEF_RE.match(line)
    if typedef:
        ctype, name = typedef.groups()
        ctype = TYPE_MAP[ctype.strip()]
        if ctype is None:
            print '# ignored typedef:', name
        else:
            print '%s = %s' % (name, ctype)

    comment = COMMENT_RE.match(line)
    if comment:
        print '#', comment.group(1).strip()
        continue

    line = COMMENT_RE.sub(r'# \1', line)

    define = DEFINE_RE.match(line)
    if define:
        name, value, rest = define.groups()

        if '/*' in value or '/*' in name:
            print '->', repr(value)

        print '%s = %s%s' % (name.strip(), value.strip(), rest.rstrip())

    apicall = APICALL_RE.match(line)
    if apicall:
        rettype, funcname, signature = (x.strip() for x in apicall.groups())
        args = []
        for arg in signature.split(','):
            try:
                argtype, argname = [x.strip() for x in arg.rsplit(' ', 1)]
                args.append((argname, argtype))
            except:
                assert arg.strip() == 'void'

        convargs = ', '.join(convert_arg(argname, argtype) for argname, argtype in args)
        args = ', '.join(argname for argname, argtype in args)
        print 'def %s(%s):\n    return glesv2.%s(%s)\n' % (funcname, args, funcname, convargs)

