#!/usr/bin/python3

import sys

events = [
    ('xproto', 'KeyPressEvent'),
    ('xproto', 'KeyReleaseEvent'),
    ('xproto', 'ButtonPressEvent'),
    ('xproto', 'ButtonReleaseEvent'),
    ('xproto', 'MotionNotifyEvent'),
    ('xproto', 'EnterNotifyEvent'),
    ('xproto', 'LeaveNotifyEvent'),
    ('xproto', 'FocusInEvent'),
    ('xproto', 'FocusOutEvent'),
    ('xproto', 'KeymapNotifyEvent'),
    ('xproto', 'ExposeEvent'),
    ('xproto', 'GraphicsExposureEvent'),
    ('xproto', 'NoExposureEvent'),
    ('xproto', 'VisibilityNotifyEvent'),
    ('xproto', 'CreateNotifyEvent'),
    ('xproto', 'DestroyNotifyEvent'),
    ('xproto', 'UnmapNotifyEvent'),
    ('xproto', 'MapNotifyEvent'),
    ('xproto', 'MapRequestEvent'),
    ('xproto', 'ReparentNotifyEvent'),
    ('xproto', 'ConfigureNotifyEvent'),
    ('xproto', 'ConfigureRequestEvent'),
    ('xproto', 'GravityNotifyEvent'),
    ('xproto', 'ResizeRequestEvent'),
    ('xproto', 'CirculateNotifyEvent'),
    ('xproto', 'CirculateRequestEvent'),
    ('xproto', 'PropertyNotifyEvent'),
    ('xproto', 'SelectionClearEvent'),
    ('xproto', 'SelectionRequestEvent'),
    ('xproto', 'SelectionNotifyEvent'),
    ('xproto', 'ColormapNotifyEvent'),
    ('xproto', 'ClientMessageEvent'),
    ('xproto', 'MappingNotifyEvent'),

    # X Shape extension events
    ('shape', 'NotifyEvent'),
]

assert len(sys.argv) == 2

if sys.argv[1] == 'evtypes':
    print ('package xevent')
    print ('''/*
    Defines event types and their associated methods automatically.
    
    This file is automatically generated using `scripts/write-events evtypes`.

    Edit it at your peril.
*/''')
    print
    print ('import (')
    print ('\t"fmt"')
    print
    print ('\t"github.com/BurntSushi/xgb/shape"')
    print ('\t"github.com/BurntSushi/xgb/xproto"')
    print (')')
    print

    for ext, e in events:
        # Skip ClientMessageEvent and ConfigureNotifyEvent
        # We define these manually in xevents/types_manual.go
        if e in ('ClientMessageEvent', 'ConfigureNotifyEvent'):
            continue

        if ext == 'xproto':
            print ('type %s struct {') % e
            print ('    *%s.%s') % (ext, e)
            print ('}')
            print
            print ('const %s = %s.%s') % (e[:-5], ext, e[:-5])
            print
            print ('func (ev %s) String() string {') % e
            print ('    return fmt.Sprintf("%%v", ev.%s)') % e
            print ('}')
            print
        else:
            print ('type %s%s struct {') % (ext.title(), e)
            print ('    *%s.%s') % (ext, e)
            print ('}')
            print
            print ('const %s%s = %s.%s') % (ext.title(), e[:-5], ext, e[:-5])
            print
            print ('func (ev %s%s) String() string {') % (ext.title(), e)
            print ('    return fmt.Sprintf("%%v", ev.%s)') % e
            print ('}')
            print
elif sys.argv[1] == 'callbacks':
    print ('package xevent')
    print ('''/*
    Does all the plumbing to allow a simple callback interface for users.

    This file is automatically generated using `scripts/write-events callbacks`.

    Edit it at your peril.
*/''')
    print
    print ('import (')
    print ('\t"github.com/BurntSushi/xgb/xproto"')
    print
    print ('\t"github.com/BurntSushi/xgbutil"')
    print (')')
    print

    for ext, e in events:
        e = e[:-5]
        if ext != 'xproto':
            e = '%s%s' % (ext.title(), e)
        print ('type %sFun func(xu *xgbutil.XUtil, event %sEvent)') % (e, e)
        print
        print ('func (callback %sFun) '\
                'Connect(xu *xgbutil.XUtil,\nwin xproto.Window) {') % e
        print ('    attachCallback(xu, %s, win, callback)') % e
        print ('}')
        print
        print ('func (callback %sFun) ' \
                'Run(xu *xgbutil.XUtil, event interface{}) {') % e
        print ('    callback(xu, event.(%sEvent))') % e
        print ('}')
        print

