// Copyright (C) 2014 Rob Caelers <robc@krandor.org>
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "StatusIcon.hh"

#include "ui/GUIConfig.hh"

#include "ToolkitMenu.hh"
#include "UiUtil.hh"

using namespace workrave;

StatusIcon::StatusIcon(std::shared_ptr<IApplicationContext> app)
  : apphold(app->get_toolkit())
{
#if defined(PLATFORM_OS_MACOS)
  // macOS Retina menu bar icons: render from SVG at 22pt; provide both 1x
  // and 2x pixmaps so Qt picks the right one for the display's pixel ratio.
  auto make_tray_icon = [](const QString &svg) -> QIcon {
    QIcon icon;
    icon.addPixmap(UiUtil::create_pixmap(svg, 22));
    QPixmap pm2x = UiUtil::create_pixmap(svg, 44);
    pm2x.setDevicePixelRatio(2.0);
    icon.addPixmap(pm2x);
    return icon;
  };
  mode_icons[workrave::OperationMode::Normal]    = make_tray_icon("workrave-normal.svg");
  mode_icons[workrave::OperationMode::Suspended] = make_tray_icon("workrave-suspended.svg");
  mode_icons[workrave::OperationMode::Quiet]     = make_tray_icon("workrave-quiet.svg");
#else
  mode_icons[workrave::OperationMode::Normal] = UiUtil::create_icon("workrave-icon-medium.png");
  mode_icons[workrave::OperationMode::Suspended] = UiUtil::create_icon("workrave-suspended-icon-medium.png");
  mode_icons[workrave::OperationMode::Quiet] = UiUtil::create_icon("workrave-quiet-icon-medium.png");
#endif

  tray_icon = std::make_shared<QSystemTrayIcon>();

  menu = std::make_shared<ToolkitMenu>(app->get_menu_model());

  tray_icon->setContextMenu(menu->get_menu());

  auto core = app->get_core();
  workrave::utils::connect(core->signal_operation_mode_changed(), this, [this](auto mode) { on_operation_mode_changed(mode); });
  OperationMode mode = core->get_regular_operation_mode();
  tray_icon->setIcon(mode_icons[mode]);

  GUIConfig::trayicon_enabled().attach(this, [&](bool enabled) {
    tray_icon->setVisible(enabled);
    apphold.set_hold(enabled && QSystemTrayIcon::isSystemTrayAvailable());
  });

  QObject::connect(tray_icon.get(), &QSystemTrayIcon::activated, this, &StatusIcon::on_activate);
  QObject::connect(tray_icon.get(), &QSystemTrayIcon::messageClicked, this, &StatusIcon::on_balloon_activate);
}

void
StatusIcon::on_operation_mode_changed(OperationMode m)
{
  tray_icon->setIcon(mode_icons[m]);
}

void
StatusIcon::set_tooltip(const QString &tip)
{
  tray_icon->setToolTip(tip);
}

void
StatusIcon::show_balloon(const QString &id, const QString &title, const QString &balloon)
{
  active_balloon_id = id.toStdString();
  tray_icon->showMessage(title, balloon);
}

void
StatusIcon::on_activate(QSystemTrayIcon::ActivationReason reason)
{
  if (reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::DoubleClick)
    {
      activate_signal();
    }
}

void
StatusIcon::on_balloon_activate()
{
  if (!active_balloon_id.empty())
    {
      balloon_activate_signal(active_balloon_id);
    }
}

auto
StatusIcon::signal_activate() -> boost::signals2::signal<void()> &
{
  return activate_signal;
}

auto
StatusIcon::signal_balloon_activate() -> boost::signals2::signal<void(std::string)> &
{
  return balloon_activate_signal;
}
