/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#ifndef CommandSet_DEFINED
#define CommandSet_DEFINED

#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkTArray.h"
#include "tools/skui/InputState.h"
#include "tools/skui/Key.h"
#include "tools/skui/ModifierKey.h"

#include <functional>
#include <vector>

class SkCanvas;

namespace sk_app {
class Window;

/**
 * Helper class used by applications that want to hook keypresses to trigger events.
 *
 * An app can simply store an instance of CommandSet and then use it as follows:
 * 1) Attach to the Window at initialization time.
 * 2) Register commands to be executed for characters or keys. Each command needs a Group and a
 *    description (both just strings). Commands attached to Keys (rather than characters) also need
 *    a displayable name for the Key. Finally, a function to execute when the key or character is
 *    pressed must be supplied. The easiest option to is pass in a lambda that captures [this]
 *    (your application object), and performs whatever action is desired.
 * 3) Register key and char handlers with the Window, and - depending on your state - forward those
 *    events to the CommandSet's onKey, onChar, and onSoftKey.
 * 4) At the end of your onPaint, call drawHelp, and pass in the application's canvas.

 * The CommandSet always binds 'h' to cycle through two different help screens. The first shows
 * all commands, organized by Group (with headings for each Group). The second shows all commands
 * alphabetically by key/character.
 */
class CommandSet {
public:
    CommandSet();

    void attach(Window* window);
    bool onKey(skui::Key key, skui::InputState state, skui::ModifierKey modifiers);
    bool onChar(SkUnichar, skui::ModifierKey modifiers);
    bool onSoftkey(const SkString& softkey);

    void addCommand(SkUnichar c, const char* group, const char* description,
                    std::function<void(void)> function);
    void addCommand(skui::Key k, const char* keyName, const char* group, const char* description,
                    std::function<void(void)> function);

    void drawHelp(SkCanvas* canvas);

    std::vector<SkString> getCommandsAsSoftkeys() const;

private:
    struct Command {
        enum CommandType {
            kChar_CommandType,
            kKey_CommandType,
        };

        Command(SkUnichar c, const char* group, const char* description,
                std::function<void(void)> function)
            : fType(kChar_CommandType)
            , fChar(c)
            , fKeyName(' ' == c ? SkString("Space") : SkStringPrintf("%c", c))
            , fGroup(group)
            , fDescription(description)
            , fFunction(function) {}

        Command(skui::Key k, const char* keyName, const char* group, const char* description,
                std::function<void(void)> function)
            : fType(kKey_CommandType)
            , fKey(k)
            , fKeyName(keyName)
            , fGroup(group)
            , fDescription(description)
            , fFunction(function) {}

        CommandType fType;

        // For kChar_CommandType
        SkUnichar fChar;

        // For kKey_CommandType
        skui::Key fKey;

        // Common to all command types
        SkString fKeyName;
        SkString fGroup;
        SkString fDescription;
        std::function<void(void)> fFunction;

        SkString getSoftkeyString() const {
            return SkStringPrintf("%s (%s)", fKeyName.c_str(), fDescription.c_str());
        }
    };

    static bool compareCommandKey(const Command& first, const Command& second);
    static bool compareCommandGroup(const Command& first, const Command& second);

    enum HelpMode {
        kNone_HelpMode,
        kGrouped_HelpMode,
        kAlphabetical_HelpMode,
    };

    Window*           fWindow;
    SkTArray<Command> fCommands;
    HelpMode          fHelpMode;
};

}   // namespace sk_app

#endif
