package cbind

import (
	
	
	

	
)

type eventHandler func(ev *tcell.EventKey) *tcell.EventKey

// Configuration maps keys to event handlers and processes key events.
type Configuration struct {
	handlers map[string]eventHandler
	mutex    *sync.RWMutex
}

// NewConfiguration returns a new input configuration.
func () *Configuration {
	 := Configuration{
		handlers: make(map[string]eventHandler),
		mutex:    new(sync.RWMutex),
	}

	return &
}

// Set sets the handler for a key event string.
func ( *Configuration) ( string,  func( *tcell.EventKey) *tcell.EventKey) error {
	, , ,  := Decode()
	if  != nil {
		return 
	}

	if  == tcell.KeyRune {
		.SetRune(, , )
	} else {
		.SetKey(, , )
	}
	return nil
}

// SetKey sets the handler for a key.
func ( *Configuration) ( tcell.ModMask,  tcell.Key,  func( *tcell.EventKey) *tcell.EventKey) {
	.mutex.Lock()
	defer .mutex.Unlock()

	if &tcell.ModShift != 0 &&  == tcell.KeyTab {
		 ^= tcell.ModShift
		 = tcell.KeyBacktab
	}

	if &tcell.ModCtrl == 0 &&  != tcell.KeyBackspace &&  != tcell.KeyTab &&  != tcell.KeyEnter {
		for ,  := range ctrlKeys {
			if  ==  {
				 |= tcell.ModCtrl
				break
			}
		}
	}

	.handlers[fmt.Sprintf("%d-%d", , )] = 
}

// SetRune sets the handler for a rune.
func ( *Configuration) ( tcell.ModMask,  rune,  func( *tcell.EventKey) *tcell.EventKey) {
	// Some runes are identical to named keys. Set the bind on the matching
	// named key instead.
	switch  {
	case '\t':
		.SetKey(, tcell.KeyTab, )
		return
	case '\n':
		.SetKey(, tcell.KeyEnter, )
		return
	}

	if &tcell.ModCtrl != 0 {
		,  := ctrlKeys[unicode.ToLower()]
		if  {
			.SetKey(, , )
			return
		}
	}

	.mutex.Lock()
	defer .mutex.Unlock()

	.handlers[fmt.Sprintf("%d:%d", , )] = 
}

// Capture handles key events.
func ( *Configuration) ( *tcell.EventKey) *tcell.EventKey {
	.mutex.RLock()
	defer .mutex.RUnlock()

	if  == nil {
		return nil
	}

	var  string
	if .Key() != tcell.KeyRune {
		 = fmt.Sprintf("%d-%d", .Modifiers(), .Key())
	} else {
		 = fmt.Sprintf("%d:%d", .Modifiers(), .Rune())
	}

	 := .handlers[]
	if  != nil {
		return ()
	}
	return 
}

// Clear removes all handlers.
func ( *Configuration) () {
	.mutex.Lock()
	defer .mutex.Unlock()

	.handlers = make(map[string]eventHandler)
}