#!/usr/bin/env python

import string
import re

words = {
    'WS' : '_ws',
    'EOL' : '_eol',
    'AutoC' : 'autoc',
    'KeyWords' : 'Keywords',
    'BackSpace' : 'Backspace',
    'UnIndents' : 'Unindents',
    'TargetRE' : 'TargetRe'
}

dont_render = [
    'add_text',
    'set_text',
    'get_text',
    'get_line',
    'get_sel_text'
]

sci_defs = open('gtkscintilla.defs', 'w')
sci_mod = open('gtkscintilla.py', 'w')
#sci_vals = open('GTKSCINTILLA.py', 'w')

def fix_name(name):
    str = ''
    
    for word in words.keys():
        if string.find(name, word) >= 0:
            name = string.replace(name, word, words[word])
    
    for i in range(len(name)):
        if name[i] in string.uppercase:
            if i > 0:
                str = str + '_%c' % string.lower(name[i])
            else:
                str = str + string.lower(name[i])
        else:
            str = str + name[i]
    return str

def write_fun(dict):
    def_full = '''
(define-func gtk_scintilla_%(fun_name)s
    %(ret_type)s
    ((GtkScintilla sci)
     (%(first_type)s %(first_name)s)
     (%(second_type)s %(second_name)s)))
'''
    def_first = '''
(define-func gtk_scintilla_%(fun_name)s
    %(ret_type)s
    ((GtkScintilla sci)
     (%(first_type)s %(first_name)s)))
'''
    def_second = '''
(define-func gtk_scintilla_%(fun_name)s
    %(ret_type)s
    ((GtkScintilla sci)
     (%(second_type)s %(second_name)s)))
'''
    def_none = '''
(define-func gtk_scintilla_%(fun_name)s
    %(ret_type)s
    ((GtkScintilla sci)))
'''

    mod_full = '''
    def %(fun_name)s(self, %(first_name)s, %(second_name)s):
        %(return)s_gtkscintilla.gtk_scintilla_%(fun_name)s(self._o, %(first_name)s, %(second_name)s)
'''
    mod_first = '''
    def %(fun_name)s(self, %(first_name)s):
        %(return)s_gtkscintilla.gtk_scintilla_%(fun_name)s(self._o, %(first_name)s)
'''
    mod_second = '''
    def %(fun_name)s(self, %(second_name)s):
        %(return)s_gtkscintilla.gtk_scintilla_%(fun_name)s(self._o, %(second_name)s)
'''
    mod_none = '''
    def %(fun_name)s(self):
        %(return)s_gtkscintilla.gtk_scintilla_%(fun_name)s(self._o)
'''

    dict['fun_name'] = fix_name(dict['fun_name'])
    if dict['fun_name'] in dont_render:
        return
    
    for key in dict.keys():
        if string.find(key, 'type') > 0:
            if dict[key] == 'void':
                dict[key] = 'none'
            elif dict[key] == 'int':
                pass
            elif dict[key] == 'bool':
                pass
            elif dict[key] == 'position':
                dict[key] = 'int'
            elif dict[key] == 'colour':
                dict[key] = 'int'
            elif dict[key] == 'string':
                pass
            elif dict[key] == 'stringresult':
                dict[key] = 'string'
            elif dict[key] is None:
                pass
            else:
                return
    
    if dict['ret_type'] == 'none':
        dict['return'] = ''
    else:
        dict['return'] = 'return '
    
    if dict['first_name'] is not None:
        dict['first_name'] = fix_name(dict['first_name'])
    if dict['second_name'] is not None:
        dict['second_name'] = fix_name(dict['second_name'])
    
    if dict['first_type'] is None and dict['second_type'] is None:
        fun_def = def_none % dict
        fun_mod = mod_none % dict
    elif dict['second_type'] is None:
        fun_def = def_first % dict
        fun_mod = mod_first % dict
    elif dict['first_type'] is None:
        fun_def = def_second % dict
        fun_mod = mod_second % dict
    else:
        fun_def = def_full % dict
        fun_mod = mod_full % dict
    
    sci_defs.write(fun_def)
    sci_mod.write(fun_mod)

def write_val(dict):
    val_template = '%(name)s=%(value)s'
    dict['name'] = string.upper(dict['name'])
#    sci_vals.write(val_template % dict + '\n')

def main():
    sci_defs.write('''(define-object GtkScintilla (GtkBin))

(define-func gtk_scintilla_new
    GtkWidget
    ())
''')
    sci_mod.write('''
import _gtkscintilla
import gtk; _gtk = gtk; del gtk

import GTKSCINTILLA

class GtkScintilla(_gtk.GtkBin):
    get_type = _gtkscintilla.gtk_scintilla_get_type
    def __init__(self, _obj=None):
        if _obj: self._o = _obj; return
        self._o = _gtkscintilla.gtk_scintilla_new()

    def add_text(self, length, text):
        _gtkscintilla.gtk_scintilla_add_text(self._o, length, text)
    
    def set_text(self, text):
        _gtkscintilla.gtk_scintilla_set_text(self._o, text)
    
    def get_line(self, line):
        return _gtkscintilla.gtk_scintilla_get_line(self._o, line)
    
    def get_text(self):
        return _gtkscintilla.gtk_scintilla_get_text(self._o)

    def get_sel_text(self):
        return _gtkscintilla.gtk_scintilla_get_sel_text(self._o)
    
    def find_text(self, flags, string, chrg):
        return _gtkscintilla.gtk_scintilla_find_text(self._o, flags, string, chrg)
''')

    iface = open('Scintilla.iface', 'r')
    
    fun_re = '^(fun|get|set)\s+(?P<ret_type>\S+)\s+(?P<fun_name>\S+)=(?P<msg_num>\d+)?\(((?P<first_type>\w+)\s+(?P<first_name>\w+)\s*)?,(\s*(?P<second_type>\w+)\s+(?P<second_name>\w+))?\)'
    val_re = '^val\s+(?P<name>\S+)\s*=\s*(?P<value>\S+)'
    
    line = iface.readline()
    while line != '':
        if string.find(line, 'cat') == 0 and \
           string.split(string.strip(line))[1] == 'Deprecated':
            break
        
        if re.match(fun_re, line):
            write_fun(re.match(fun_re, line).groupdict())
        elif re.match(val_re, line):
            write_val(re.match(val_re, line).groupdict())
        
        line = iface.readline()
    
    sci_mod.write('''
_gtk._name2cls['GtkScintilla'] = GtkScintilla
''')

    iface.close()
    sci_defs.close()
    sci_mod.close()
#    sci_vals.close()

if __name__ == '__main__':
    main()
