/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.view;

import static com.android.internal.util.Preconditions.checkArgument;

import static java.lang.Character.MIN_VALUE;

import android.annotation.Nullable;
import android.graphics.drawable.Icon;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * Information about a Keyboard Shortcut.
 */
public final class KeyboardShortcutInfo implements Parcelable {
    private final CharSequence mLabel;
    private final Icon mIcon;
    private final char mBaseCharacter;
    private final int mKeycode;
    private final int mModifiers;

    /**
     * @param label The label that identifies the action performed by this shortcut.
     * @param icon An icon that identifies the action performed by this shortcut.
     * @param keycode The keycode that triggers the shortcut. This should be a valid constant
     *     defined in {@link KeyEvent}.
     * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
     *     These should be a combination of {@link KeyEvent#META_CTRL_ON},
     *     {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON},
     *     {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_FUNCTION_ON} and
     *     {@link KeyEvent#META_SYM_ON}.
     *
     * @hide
     */
    public KeyboardShortcutInfo(
            @Nullable CharSequence label, @Nullable Icon icon, int keycode, int modifiers) {
        mLabel = label;
        mIcon = icon;
        mBaseCharacter = MIN_VALUE;
        checkArgument(keycode >= KeyEvent.KEYCODE_UNKNOWN && keycode <= KeyEvent.getMaxKeyCode());
        mKeycode = keycode;
        mModifiers = modifiers;
    }

    /**
     * @param label The label that identifies the action performed by this shortcut.
     * @param keycode The keycode that triggers the shortcut. This should be a valid constant
     *     defined in {@link KeyEvent}.
     * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
     *     These should be a combination of {@link KeyEvent#META_CTRL_ON},
     *     {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON},
     *     {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_FUNCTION_ON} and
     *     {@link KeyEvent#META_SYM_ON}.
     */
    public KeyboardShortcutInfo(CharSequence label, int keycode, int modifiers) {
        this(label, null, keycode, modifiers);
    }

    /**
     * @param label The label that identifies the action performed by this shortcut.
     * @param baseCharacter The character that triggers the shortcut.
     * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
     *     These should be a combination of {@link KeyEvent#META_CTRL_ON},
     *     {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON},
     *     {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_FUNCTION_ON} and
     *     {@link KeyEvent#META_SYM_ON}.
     */
    public KeyboardShortcutInfo(CharSequence label, char baseCharacter, int modifiers) {
        mLabel = label;
        checkArgument(baseCharacter != MIN_VALUE);
        mBaseCharacter = baseCharacter;
        mKeycode = KeyEvent.KEYCODE_UNKNOWN;
        mModifiers = modifiers;
        mIcon = null;
    }

    private KeyboardShortcutInfo(Parcel source) {
        mLabel = source.readCharSequence();
        mIcon = source.readParcelable(null, android.graphics.drawable.Icon.class);
        mBaseCharacter = (char) source.readInt();
        mKeycode = source.readInt();
        mModifiers = source.readInt();
    }

    /**
     * Returns the label to be used to describe this shortcut.
     */
    @Nullable
    public CharSequence getLabel() {
        return mLabel;
    }

    /**
     * Returns the icon to be used to describe this shortcut.
     *
     * @hide
     */
    @Nullable
    public Icon getIcon() {
        return mIcon;
    }

    /**
     * Returns the base keycode that, combined with the modifiers, triggers this shortcut. If the
     * base character was set instead, returns {@link KeyEvent#KEYCODE_UNKNOWN}. Valid keycodes are
     * defined as constants in {@link KeyEvent}.
     */
    public int getKeycode() {
        return mKeycode;
    }

    /**
     * Returns the base character that, combined with the modifiers, triggers this shortcut. If the
     * keycode was set instead, returns {@link Character#MIN_VALUE}.
     */
    public char getBaseCharacter() {
        return mBaseCharacter;
    }

    /**
     * Returns the set of modifiers that, combined with the key, trigger this shortcut. These can
     * be a combination of {@link KeyEvent#META_CTRL_ON}, {@link KeyEvent#META_SHIFT_ON},
     * {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_ALT_ON},
     * {@link KeyEvent#META_FUNCTION_ON} and {@link KeyEvent#META_SYM_ON}.
     */
    public int getModifiers() {
        return mModifiers;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeCharSequence(mLabel);
        dest.writeParcelable(mIcon, 0);
        dest.writeInt(mBaseCharacter);
        dest.writeInt(mKeycode);
        dest.writeInt(mModifiers);
    }

    public static final @android.annotation.NonNull Creator<KeyboardShortcutInfo> CREATOR =
            new Creator<KeyboardShortcutInfo>() {
        public KeyboardShortcutInfo createFromParcel(Parcel source) {
            return new KeyboardShortcutInfo(source);
        }
        public KeyboardShortcutInfo[] newArray(int size) {
            return new KeyboardShortcutInfo[size];
        }
    };
}