package com.jniwrapper.win32.hook;

import com.jniwrapper.Bool;
import com.jniwrapper.util.FlagSet;

/**
 * Defines low level keyboard event object.
 *
 * @author Serge Piletsky
 */
public class LowLevelKeyboardEvent extends HookEventObject
{
    private KeyboardHookStruct _keyboardData;
    private long _messageID;
    private Bool _consume;

    LowLevelKeyboardEvent(Object source, long message, KeyboardHookStruct keyboardData, Bool consume)
    {
        super(source);
        _keyboardData = keyboardData;
        _messageID = message;
        _consume = consume;
    }

    /**
     * Returns the identifier of the keyboard message.
     *
     * @return keyboard event identifier
     */
    public long getMessageID()
    {
        return _messageID;
    }

    /**
     * Returns a virtual-key code. The code is in the range 1 to 254.
     *
     * @return virtual key code
     */
    public long getVirtualKeyCode()
    {
        return _keyboardData.getVkCode().getValue();
    }

    /**
     * Returns a hardware scan code for the key.
     *
     * @return a hardware scan code.
     */
    public long getScanCode()
    {
        return _keyboardData.getScanCode().getValue();
    }

    /**
     * Specifies whether the key is an extended key, such as a function key or a
     * key on the numeric keypad.
     *
     * @return true, if the key is an extended key; otherwise, it is false
     */
    public boolean isExtendedKey()
    {
        FlagSet flagSet = new FlagSet(_keyboardData.getFlags().getValue());
        return flagSet.getBit(0);
    }

    /**
     * Specifies whether the event was injected.
     *
     * @return The value is true if the event was injected; otherwise, it is false
     */
    public boolean isInjected()
    {
        FlagSet flagSet = new FlagSet(_keyboardData.getFlags().getValue());
        return flagSet.getBit(4);
    }

    /**
     * Specifies the context code.
     *
     * @return The value is true if the <code>ALT</code> key is pressed; otherwise, it is false
     */
    public boolean isAltPressed()
    {
        FlagSet flagSet = new FlagSet(_keyboardData.getFlags().getValue());
        return flagSet.getBit(5);
    }

    /**
     * Specifies the transition state.
     *
     * @return The value is true if the key is pressed and false if it is being released.
     */
    public boolean isPressed()
    {
        FlagSet flagSet = new FlagSet(_keyboardData.getFlags().getValue());
        // The value is 0 if the key is pressed and 1 if it is being released.
        return !flagSet.getBit(7);
    }

    /**
     * Returns the time stamp for this message.
     *
     * @return time stamp
     */
    public long getTime()
    {
        return _keyboardData.getTime().getValue();
    }

    /**
     * Causes the consuming of this event, so another applications will not receive it.
     */
    public void consume()
    {
        _consume.setValue(true);
    }
}