// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:generate go run gen.go

// x11key contains X11 numeric codes for the keyboard and mouse.
package x11key // import "golang.org/x/exp/shiny/driver/internal/x11key"

import (
	"unicode"

	"golang.org/x/mobile/event/key"
)

// These constants come from /usr/include/X11/X.h
const (
	ShiftMask   = 1 << 0
	LockMask    = 1 << 1
	ControlMask = 1 << 2
	Mod1Mask    = 1 << 3
	Mod2Mask    = 1 << 4
	Mod3Mask    = 1 << 5
	Mod4Mask    = 1 << 6
	Mod5Mask    = 1 << 7
	Button1Mask = 1 << 8
	Button2Mask = 1 << 9
	Button3Mask = 1 << 10
	Button4Mask = 1 << 11
	Button5Mask = 1 << 12
)

type KeysymTable [256][2]uint32

func (t *KeysymTable) Lookup(detail uint8, state uint16, numLockMod uint16) (rune, key.Code) {
	// The key event's rune depends on whether the shift key is down.
	unshifted := rune(t[detail][0])
	r := unshifted
	if state&numLockMod != 0 && isKeypad(t[detail][1]) {
		if state&ShiftMask == 0 {
			r = rune(t[detail][1])
		}
	} else if state&ShiftMask != 0 {
		r = rune(t[detail][1])
		// In X11, a zero keysym when shift is down means to use what the
		// keysym is when shift is up.
		if r == 0 {
			r = unshifted
		}
	}

	// The key event's code is independent of whether the shift key is down.
	var c key.Code
	if 0 <= unshifted && unshifted < 0x80 {
		c = asciiKeycodes[unshifted]
		if state&LockMask != 0 {
			r = unicode.ToUpper(r)
		}
	} else if kk, isKeypad := keypadKeysyms[r]; isKeypad {
		r, c = kk.rune, kk.code
	} else if nuk := nonUnicodeKeycodes[unshifted]; nuk != key.CodeUnknown {
		r, c = -1, nuk
	} else {
		r = keysymCodePoints[r]
		if state&LockMask != 0 {
			r = unicode.ToUpper(r)
		}
	}

	return r, c
}

func isKeypad(keysym uint32) bool {
	return keysym >= 0xff80 && keysym <= 0xffbd
}

func KeyModifiers(state uint16) (m key.Modifiers) {
	if state&ShiftMask != 0 {
		m |= key.ModShift
	}
	if state&ControlMask != 0 {
		m |= key.ModControl
	}
	if state&Mod1Mask != 0 {
		m |= key.ModAlt
	}
	if state&Mod4Mask != 0 {
		m |= key.ModMeta
	}
	return m
}

// These constants come from /usr/include/X11/{keysymdef,XF86keysym}.h
const (
	xkISOLeftTab = 0xfe20
	xkBackSpace  = 0xff08
	xkTab        = 0xff09
	xkReturn     = 0xff0d
	xkEscape     = 0xff1b
	xkMultiKey   = 0xff20
	xkHome       = 0xff50
	xkLeft       = 0xff51
	xkUp         = 0xff52
	xkRight      = 0xff53
	xkDown       = 0xff54
	xkPageUp     = 0xff55
	xkPageDown   = 0xff56
	xkEnd        = 0xff57
	xkInsert     = 0xff63
	xkMenu       = 0xff67
	xkHelp       = 0xff6a

	xkNumLock        = 0xff7f
	xkKeypadEnter    = 0xff8d
	xkKeypadHome     = 0xff95
	xkKeypadLeft     = 0xff96
	xkKeypadUp       = 0xff97
	xkKeypadRight    = 0xff98
	xkKeypadDown     = 0xff99
	xkKeypadPageUp   = 0xff9a
	xkKeypadPageDown = 0xff9b
	xkKeypadEnd      = 0xff9c
	xkKeypadInsert   = 0xff9e
	xkKeypadDelete   = 0xff9f
	xkKeypadEqual    = 0xffbd
	xkKeypadMultiply = 0xffaa
	xkKeypadAdd      = 0xffab
	xkKeypadSubtract = 0xffad
	xkKeypadDecimal  = 0xffae
	xkKeypadDivide   = 0xffaf
	xkKeypad0        = 0xffb0
	xkKeypad1        = 0xffb1
	xkKeypad2        = 0xffb2
	xkKeypad3        = 0xffb3
	xkKeypad4        = 0xffb4
	xkKeypad5        = 0xffb5
	xkKeypad6        = 0xffb6
	xkKeypad7        = 0xffb7
	xkKeypad8        = 0xffb8
	xkKeypad9        = 0xffb9

	xkF1       = 0xffbe
	xkF2       = 0xffbf
	xkF3       = 0xffc0
	xkF4       = 0xffc1
	xkF5       = 0xffc2
	xkF6       = 0xffc3
	xkF7       = 0xffc4
	xkF8       = 0xffc5
	xkF9       = 0xffc6
	xkF10      = 0xffc7
	xkF11      = 0xffc8
	xkF12      = 0xffc9
	xkShiftL   = 0xffe1
	xkShiftR   = 0xffe2
	xkControlL = 0xffe3
	xkControlR = 0xffe4
	xkCapsLock = 0xffe5
	xkAltL     = 0xffe9
	xkAltR     = 0xffea
	xkSuperL   = 0xffeb
	xkSuperR   = 0xffec
	xkDelete   = 0xffff

	xf86xkAudioLowerVolume = 0x1008ff11
	xf86xkAudioMute        = 0x1008ff12
	xf86xkAudioRaiseVolume = 0x1008ff13
)

// nonUnicodeKeycodes maps from those xproto.Keysym values (converted to runes)
// that do not correspond to a Unicode code point, such as "Page Up", "F1" or
// "Left Shift", to key.Code values.
var nonUnicodeKeycodes = map[rune]key.Code{
	xkISOLeftTab: key.CodeTab,
	xkBackSpace:  key.CodeDeleteBackspace,
	xkTab:        key.CodeTab,
	xkReturn:     key.CodeReturnEnter,
	xkEscape:     key.CodeEscape,
	xkHome:       key.CodeHome,
	xkLeft:       key.CodeLeftArrow,
	xkUp:         key.CodeUpArrow,
	xkRight:      key.CodeRightArrow,
	xkDown:       key.CodeDownArrow,
	xkPageUp:     key.CodePageUp,
	xkPageDown:   key.CodePageDown,
	xkEnd:        key.CodeEnd,
	xkInsert:     key.CodeInsert,
	xkMenu:       key.CodeRightGUI, // TODO: CodeRightGUI or CodeMenu??
	xkHelp:       key.CodeHelp,
	xkNumLock:    key.CodeKeypadNumLock,
	xkMultiKey:   key.CodeCompose,

	xkKeypadEnter:    key.CodeKeypadEnter,
	xkKeypadHome:     key.CodeHome,
	xkKeypadLeft:     key.CodeLeftArrow,
	xkKeypadUp:       key.CodeUpArrow,
	xkKeypadRight:    key.CodeRightArrow,
	xkKeypadDown:     key.CodeDownArrow,
	xkKeypadPageUp:   key.CodePageUp,
	xkKeypadPageDown: key.CodePageDown,
	xkKeypadEnd:      key.CodeEnd,
	xkKeypadInsert:   key.CodeInsert,
	xkKeypadDelete:   key.CodeDeleteForward,

	xkF1:  key.CodeF1,
	xkF2:  key.CodeF2,
	xkF3:  key.CodeF3,
	xkF4:  key.CodeF4,
	xkF5:  key.CodeF5,
	xkF6:  key.CodeF6,
	xkF7:  key.CodeF7,
	xkF8:  key.CodeF8,
	xkF9:  key.CodeF9,
	xkF10: key.CodeF10,
	xkF11: key.CodeF11,
	xkF12: key.CodeF12,

	xkShiftL:   key.CodeLeftShift,
	xkShiftR:   key.CodeRightShift,
	xkControlL: key.CodeLeftControl,
	xkControlR: key.CodeRightControl,
	xkCapsLock: key.CodeCapsLock,
	xkAltL:     key.CodeLeftAlt,
	xkAltR:     key.CodeRightAlt,
	xkSuperL:   key.CodeLeftGUI,
	xkSuperR:   key.CodeRightGUI,

	xkDelete: key.CodeDeleteForward,

	xf86xkAudioRaiseVolume: key.CodeVolumeUp,
	xf86xkAudioLowerVolume: key.CodeVolumeDown,
	xf86xkAudioMute:        key.CodeMute,
}

// asciiKeycodes maps lower-case ASCII runes to key.Code values.
var asciiKeycodes = [0x80]key.Code{
	'a': key.CodeA,
	'b': key.CodeB,
	'c': key.CodeC,
	'd': key.CodeD,
	'e': key.CodeE,
	'f': key.CodeF,
	'g': key.CodeG,
	'h': key.CodeH,
	'i': key.CodeI,
	'j': key.CodeJ,
	'k': key.CodeK,
	'l': key.CodeL,
	'm': key.CodeM,
	'n': key.CodeN,
	'o': key.CodeO,
	'p': key.CodeP,
	'q': key.CodeQ,
	'r': key.CodeR,
	's': key.CodeS,
	't': key.CodeT,
	'u': key.CodeU,
	'v': key.CodeV,
	'w': key.CodeW,
	'x': key.CodeX,
	'y': key.CodeY,
	'z': key.CodeZ,

	'1': key.Code1,
	'2': key.Code2,
	'3': key.Code3,
	'4': key.Code4,
	'5': key.Code5,
	'6': key.Code6,
	'7': key.Code7,
	'8': key.Code8,
	'9': key.Code9,
	'0': key.Code0,

	' ':  key.CodeSpacebar,
	'-':  key.CodeHyphenMinus,
	'=':  key.CodeEqualSign,
	'[':  key.CodeLeftSquareBracket,
	']':  key.CodeRightSquareBracket,
	'\\': key.CodeBackslash,
	';':  key.CodeSemicolon,
	'\'': key.CodeApostrophe,
	'`':  key.CodeGraveAccent,
	',':  key.CodeComma,
	'.':  key.CodeFullStop,
	'/':  key.CodeSlash,
}

type keypadKeysym struct {
	rune rune
	code key.Code
}

var keypadKeysyms = map[rune]keypadKeysym{
	xkKeypadEqual:    {'=', key.CodeKeypadEqualSign},
	xkKeypadMultiply: {'*', key.CodeKeypadAsterisk},
	xkKeypadAdd:      {'+', key.CodeKeypadPlusSign},
	xkKeypadSubtract: {'-', key.CodeKeypadHyphenMinus},
	xkKeypadDecimal:  {'.', key.CodeKeypadFullStop},
	xkKeypadDivide:   {'/', key.CodeKeypadSlash},
	xkKeypad0:        {'0', key.CodeKeypad0},
	xkKeypad1:        {'1', key.CodeKeypad1},
	xkKeypad2:        {'2', key.CodeKeypad2},
	xkKeypad3:        {'3', key.CodeKeypad3},
	xkKeypad4:        {'4', key.CodeKeypad4},
	xkKeypad5:        {'5', key.CodeKeypad5},
	xkKeypad6:        {'6', key.CodeKeypad6},
	xkKeypad7:        {'7', key.CodeKeypad7},
	xkKeypad8:        {'8', key.CodeKeypad8},
	xkKeypad9:        {'9', key.CodeKeypad9},
}
