/*
    SPDX-License-Identifier: GPL-2.0-only
    SPDX-FileCopyrightText: 1999-2001 Lubos Lunak <l.lunak@kde.org>
 */

#ifndef _SETTINGS_H_
#define _SETTINGS_H_

#include "action_data/action_data_group.h"
#include "actions/actions.h"
#include <kshortcut.h>

class KConfig;
class KConfigBase;

namespace KHotKeys
{
class ActionDataGroup;

/**
 * How to handle imports.
 */
enum ImportType {
    ImportNone, //!< no import is done
    ImportAsk, //!< if already imported before, ask (called from GUI)
    ImportSilent, //!< if already imported before, ignore (called from the update script)
};

enum ActionState {
    Retain, //!< Keep the current state
    Enabled, //!< Enable all actions
    Disabled, //!< Disable all actions
};

/**
 * Handles KHotKeys Settings.
 *
 * Settings are saved to the khotkeysrc file.
 */
class Q_DECL_EXPORT Settings
{
    Q_DISABLE_COPY(Settings)

public:
    Settings();
    ~Settings();

    /**
     * Get the system group.
     */
    ActionDataGroup *get_system_group(ActionDataGroup::system_group_t group_id);

    /**
     * Read the settings.
     *
     * \param include_disabled_P Load disabled shortcuts?
     */
    bool reread_settings(bool include_disabled = true);

    /**
     * Update the settings.
     *
     * Checks if updates are available and imports them if not yet done.
     */
    bool update();

    /**
     * Write the settings.
     */
    void write();

    /**
     * Export settings to @a config.
     *
     * @param id    use id for the exported file.
     * @param state state to use for exported actions
     */
    void exportTo(ActionDataBase *what, KConfigBase &config, const QString &id, ActionState state, bool allowMerging);

    /**
     * Import settings from \a cfg_P.
     */
    bool import(KConfig &cfg_P, ImportType ask, ActionState state);

    bool importFrom(ActionDataGroup *parent, KConfigBase const &config, ImportType ask, ActionState state);

    /**
     * Get all actions
     */
    ActionDataGroup *actions();
    const ActionDataGroup *actions() const;

    /**
     * Take the actions.
     *
     * \note Ownership is transferred to you. Subsequent calls to action() will
     * return 0
     */
    ActionDataGroup *takeActions();

    /**
     * Set the actions.
     *
     * \note Ownership is taken. The current action list will be deleted. If
     * \@a actions is nullptr the method will create a new ActionDataGroup
     */
    void setActions(ActionDataGroup *actions);

    /**
     * @name KHotkeys Daemon
     */
    //@{
    /**
     * Disable the daemon.
     */
    void disableDaemon();

    /**
     * Enable the daemon.
     */
    void enableDaemon();

    /**
     * Is the daemon disabled?
     */
    bool isDaemonDisabled() const;
    //@}

    /**
     * Load the default settings
     */
    bool loadDefaults();

    /**
     * @name Gestures
     */
    //@{
    void disableGestures();
    void enableGestures();
    bool areGesturesDisabled() const;

    int gestureMouseButton() const;
    void setGestureMouseButton(int);

    int gestureTimeOut() const;
    void setGestureTimeOut(int);

    void setGesturesExclude(Windowdef_list *gestures);
    Windowdef_list *gesturesExclude();
    const Windowdef_list *gesturesExclude() const;
    //@}

    /**
     * @name Voice Commands
     */
    //@{
    void setVoiceShortcut(const QKeySequence &shortcut);
    QKeySequence voiceShortcut() const;
    //@}

    /**
     * Check if the given config file is a valid khotkeys file
     */
    bool isConfigFileValid(KConfigBase const &config, ImportType ask);

    static bool isOutdated;

protected:
    /**
     * Read settings from \a cfg_P.
     *
     * @param root the group to import to
     * @param config config object to read from
     * @param include_disabled should we read disabled actions?
     * @param state enable, disable or keep the actions enabled state
     */
    bool read_settings(ActionDataGroup *root, KConfigBase const &config, bool include_disabled, ActionState state);

    /**
     * Make sure all System Groups exists
     */
    void validate();

private:
    // Reset all values. No defaults are loaded
    void reinitialize();

    /**
     * TODO
     */
    ActionDataGroup *m_actions;

    /**
     * @name Gestures
     */
    //@{
    /**
     * Gestures globally disabled?
     */
    bool gestures_disabled;

    /**
     * Mouse button used for gestures.
     */
    int gesture_mouse_button;

    /**
     * Gesture timeout
     */
    int gesture_timeout;

    /**
     * Windows to exclude from gestures
     */
    Windowdef_list *gestures_exclude;
    //@}

    /**
     * KHotKeys daemon disabled?
     */
    bool daemon_disabled;

    /**
     * The shortcut that triggers a voice command
     */
    QKeySequence voice_shortcut;

    /**
     * List of id's for all imported files.
     */
    QStringList already_imported;

    friend class SettingsWriter;
};

} // namespace KHotKeys

#endif
