/*
 *   This file is part of Dianara
 *   Copyright 2012-2016  JanKusanagi JRR <jancoding@gmx.com>
 *
 *   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 2 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, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .
 */

#include "notifications.h"


FDNotifications::FDNotifications(QObject* parent) : QObject(parent)
{
    qDebug() << "Creating FreeDesktop Notifier";
    this->notificationsAvailable = false; // Init as false, detect later

#ifdef QT_DBUS_LIB
    this->bus = new QDBusConnection(QDBusConnection::sessionBus());
    if (bus->isConnected())
    {
        QDBusReply<QStringList> busReply = bus->interface()->registeredServiceNames();
        qDebug() << "Listing D-Bus services...";
        if (busReply.isValid())
        {
            foreach (QString serviceName, busReply.value())
            {
                if (serviceName == "org.freedesktop.Notifications")
                {
                    qDebug() << "org.freedesktop.Notifications D-Bus service found!";
                    this->notificationsAvailable = true;
                }
            }
        }
    }
    else
    {
        qDebug() << "D-Bus unavailable!";
        notificationsAvailable = false;
    }
#endif

    qDebug() << "FreeDesktop Notifier created";
}


FDNotifications::~FDNotifications()
{
#ifdef QT_DBUS_LIB
    delete bus;
#endif
    qDebug() << "FreeDesktop Notifier destroyed";
}




bool FDNotifications::areNotificationsAvailable()
{
    qDebug() << "Are notifications available?" << notificationsAvailable;
    return notificationsAvailable;
}

void FDNotifications::setNotificationOptions(int style,
                                             bool notifyNewTL, bool notifyHLTL,
                                             bool notifyNewMW, bool notifyHLMW,
                                             bool notifyErr)
{
    this->notificationType = style;

    this->notifyNewTimeline  = notifyNewTL;
    this->notifyHLTimeline   = notifyHLTL;
    this->notifyNewMeanwhile = notifyNewMW;
    this->notifyHLMeanwhile  = notifyHLMW;
    this->notifyErrors       = notifyErr;

    qDebug() << "Notification type set to"
             << this->notificationType
             << "-- FD.o/Qt/none";
    qDebug() << this->notifyNewTimeline << this->notifyHLTimeline
             << this->notifyNewMeanwhile << this->notifyHLMeanwhile
             << this->notifyErrors;
}

void FDNotifications::setCurrentUserId(QString newId)
{
    this->currentUserId = newId;
}


bool FDNotifications::getNotifyNewTimeline()
{
    return this->notifyNewTimeline;
}

bool FDNotifications::getNotifyHLTimeline()
{
    return this->notifyHLTimeline;
}

bool FDNotifications::getNotifyNewMeanwhile()
{
    return this->notifyNewMeanwhile;
}

bool FDNotifications::getNotifyHLMeanwhile()
{
    return this->notifyHLMeanwhile;
}

bool FDNotifications::getNotifyErrors()
{
    return this->notifyErrors;
}



///////////////////////////////////////////////////////////////////////
////////////////////////////// SLOTS //////////////////////////////////
///////////////////////////////////////////////////////////////////////



void FDNotifications::showMessage(QString message)
{
    // if notifications are disabled
    if (this->notificationType == FDNotifications::NoNotifications)
    {
        return;
    }

    QString notificationTitle = "Dianara - " + currentUserId;

    // If FD.org notifications are not available, or Qt's Balloon ones are selected
    if (!notificationsAvailable
       || notificationType == FDNotifications::FallbackNotifications)
    {
        qDebug() << "FreeDesktop Notifications are NOT available, "
                    "or balloon notifications selected";

        // Clean up possible HTML, since Qt's balloons don't support it
        message.remove("<b>");
        message.remove("</b>");
        message.remove("<i>");
        message.remove("</i>");
        message.remove("<u>");
        message.remove("</u>");
        message.replace("<br>", "\n");
        // FIXME: remove also <a href=...>
        emit showFallbackNotification(notificationTitle, message);

        return;
    }


    // Only when building with D-Bus support
#ifdef QT_DBUS_LIB
    message.replace("\n", "<br>"); // use HTML newlines
    // HTML newlines break notifications in Xfce; \n works, but is not actually
    // shown as newline in Plasma 4's notifications

    QDBusMessage dBusMessage = QDBusMessage::createMethodCall(
                                 "org.freedesktop.Notifications",
                                 "/org/freedesktop/Notifications",
                                 "",
                                 "Notify");


    // --- D-Bus Notify call ----------------------------------------------
    // method uint org.freedesktop.Notifications.Notify(QString app_name,
    // uint replaces_id, QString app_icon, QString summary, QString body,
    // QStringList actions, QVariantMap hints, int timeout)

    QList<QVariant> arguments;
    arguments << QString("Dianara");   // app_name
    arguments << uint(0);              // replaces_id
    if (QIcon::hasThemeIcon("dianara"))
    {
        arguments << QString("dianara"); // app_icon, if "dianara" icon is in theme
    }
    else
    {
        arguments << QString("dialog-information");   // app_icon otherwise
    }
    arguments << notificationTitle;
    arguments << message;
    arguments << QStringList();        // actions
    arguments << QVariantMap();        // hints
    arguments << 4000;                 // timeout, in milliseconds

    dBusMessage.setArguments(arguments);


    qDebug() << "sending DBUS call to org.freedesktop.Notifications Notify";
    this->bus->asyncCall(dBusMessage);
#endif
}
