/*
 * Copyright (c) KylinSoft Co., Ltd. 2025.All rights reserved.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 */
#ifndef _FCITX_MODULES_INPUTMODE_H_
#define _FCITX_MODULES_INPUTMODE_H_

#include "fcitx-config/iniparser.h"
#include "fcitx-utils/dbus/servicewatcher.h"
#include "fcitx-utils/i18n.h"
#include "fcitx/addonfactory.h"
#include "fcitx/addoninstance.h"
#include "fcitx/addonmanager.h"
#include "fcitx/event.h"
#include "fcitx/instance.h"
#include "fcitx/userinterfacemanager.h"

namespace fcitx {

/**
 * Implement configurable functions on the configuration interface
 */
FCITX_CONFIG_ENUM_NAME_WITH_I18N(
    InputMethodModeStrategy, N_("Always On Physical Keyboard"),
    N_("Always On Screen Keyboard"),
    N_("On Screen Keyboard When Keyboard Is Disconnection"))

FCITX_CONFIG_ENUM_NAME_WITH_I18N(VirtualKeyboardShowHideStrategy,
                                 N_("Automatically show and hide"),
                                 N_("Do not automatically show and hide"))

/**
 * Default configuration ：OnScreenKeyboardWhenKeyboardIsDisconnect、DoNotAutoShowAndHide
 */
FCITX_CONFIGURATION(
    InputModeConfig,
    OptionWithAnnotation<InputMethodModeStrategy,
                         InputMethodModeStrategyI18NAnnotation>
        inputModeStrategySelect{
            this, "InputMethodMode", _("select input mode strategy"),
            InputMethodModeStrategy::OnScreenKeyboardWhenKeyboardIsDisconnect};
    OptionWithAnnotation<VirtualKeyboardShowHideStrategy,
                         VirtualKeyboardShowHideStrategyI18NAnnotation>
        showHideStrategySelect{
            this, "ShowHideStrategy",
            _("select virtual keyboard show hide strategy"),
            VirtualKeyboardShowHideStrategy::DoNotAutoShowAndHide};)

class InputModeManager : public AddonInstance {
public:
    explicit InputModeManager(Instance *instance);
    ~InputModeManager() override = default;

protected:
    /**
     * Save input mode
     */
    void reloadConfig() override;
    const Configuration *getConfig() const override;
    void setConfig(const RawConfig &config) override;

private:
    /**
     * Update input mode based on configuration file.
     */
    void updateInputModeStrategy();

    /**
     * Update auto show && hide based on configuration file.
     */
    void updateShowHideStrategy();

    /**
     * Update input mode based on keyboard status.
     */
    void updateInputMode();

    void connectKeyboardSignals();
    int callDBusToGetKeyboardStatus();

    FCITX_ADDON_DEPENDENCY_LOADER(dbus, instance_->addonManager());

private:
    Instance *instance_;
    InputModeConfig inputModeConfig_;
    dbus::Bus *bus_ = nullptr;
    dbus::ServiceWatcher *watcher_ = nullptr;
    std::unique_ptr<dbus::ServiceWatcherEntry> entry_;
    std::unique_ptr<dbus::Slot> slot_;
    int keyboardNum = 1;
};
} // namespace fcitx
#endif