package de.renew.propertymanagementgui.gui;

import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JTextField;
import javax.swing.KeyStroke;

import de.renew.propertymanagement.prop.ConfigurableHotkeyProperty;
import de.renew.propertymanagement.prop.ConfigurablePropertyManager;

/**
 * Custom JTextField that is not directly editable, only through the input of hotkeys.
 * Used to allow the user to define custom hotkeys for commands and actions.
 *
 * @author 0schult
 */
public class HotkeyField extends JTextField {
    private KeyStroke _keyStroke;

    /**
     * Creates a HotkeyField that is responsible for updating the hotkey for a given
     * action or command.
     *
     * @param property the property this HotkeyField is responsible for
     */
    public HotkeyField(ConfigurableHotkeyProperty property) {
        setEditable(false);
        setKeyStroke(property.getKeyStroke());

        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();

                // Ignore modifier-only presses (Ctrl, Shift, etc.)
                if (keyCode == KeyEvent.VK_SHIFT || keyCode == KeyEvent.VK_CONTROL
                    || keyCode == KeyEvent.VK_ALT || keyCode == KeyEvent.VK_META) {
                    return;
                }

                int modifiers = e.getModifiersEx();
                setKeyStroke(KeyStroke.getKeyStroke(keyCode, modifiers));
                ConfigurablePropertyManager.getInstance()
                    .changeHotkeyProperty(property.getKey(), _keyStroke);
            }
        });
    }

    /**
     * Sets both the internal and the displayed keystroke
     *
     * @param ks the new keystroke
     */
    private void setKeyStroke(KeyStroke ks) {
        this._keyStroke = ks;
        setText(getFormattedKeyStroke());
    }

    /**
     * Formats the stored keystroke to a more readable format
     *
     * @return the readable String representing the stored keystroke
     */
    private String getFormattedKeyStroke() {
        if (_keyStroke == null)
            return "";

        StringBuilder sb = new StringBuilder();

        int mod = _keyStroke.getModifiers();
        if ((mod & InputEvent.CTRL_DOWN_MASK) != 0)
            sb.append("Ctrl+");
        if ((mod & InputEvent.SHIFT_DOWN_MASK) != 0)
            sb.append("Shift+");
        if ((mod & InputEvent.ALT_DOWN_MASK) != 0)
            sb.append("Alt+");
        if ((mod & InputEvent.META_DOWN_MASK) != 0)
            sb.append("Meta+");

        sb.append(KeyEvent.getKeyText(_keyStroke.getKeyCode()));
        return sb.toString();
    }
}
