/*
 * Copyright (C) 2008 Martin Hostettler
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 */

// Manager of a queue for alert popup dialogs (like can't connect to Server,
// connection errors, etc) the user has to attend to

#include <algorithm>
#include <QDebug>
#include <QMessageBox>

#include "alertmanager.h"


static bool itemCompare(AlertManager::Item* a, AlertManager::Item* b) {
    return a->priority > b->priority;
}

QWidget* AlertManager::findDialog(const QMetaObject& mo) const {
    foreach(Item* i, list_) {
        if (mo.cast(i->widget)) {
            return i->widget;
        }
    }
    return 0;
}

void AlertManager::findDialogs(const QMetaObject& mo, QList<void*>* list) const
{
    foreach(Item* i, list_) {
        if (mo.cast(i->widget)) {
            list->append(i->widget);
        }
    }
}

void AlertManager::dialogRegister(QWidget* w, int prio)
{
    qDebug() << "registered dialog";
    connect(w, SIGNAL(destroyed(QObject*)), SLOT(forceDialogUnregister(QObject*)));
    Item* i = new Item();
    i->widget = w;
    i->priority = prio;
    list_.append(i);
    std::push_heap(list_.begin(), list_.end(), itemCompare);

}

void AlertManager::dialogUnregister(QWidget* w)
{
    if (list_.at(0)->widget == w) {
        std::pop_heap(list_.begin(), list_.end(), itemCompare);
        list_.removeLast();
        if (!list_.isEmpty()) {
            list_.at(0)->widget->show();
        }
        return;
    }

    foreach(Item* i, list_) {
        if (i->widget == w) {
            list_.removeAll(i);
            delete i;
            break;
        }
    }
    std::make_heap(list_.begin(), list_.end(), itemCompare);

}

void AlertManager::forceDialogUnregister(QObject* obj)
{
    dialogUnregister(static_cast<QWidget*>(obj));
}


void AlertManager::deleteDialogList()
{
    while (!list_.isEmpty()) {
        Item* i = list_.takeLast();
        i->widget->disconnect(); // ensure forceDialogUnregister won't be called
        delete i->widget;
        delete i;
    }
}



bool AlertManager::raiseDialog(QWidget* w, int prio) {
    dialogRegister(w, prio);
    if (list_.at(0)->widget == w) {
        w->show();
        return true;
    }
    return false;
}

void AlertManager::raiseMessageBox(int prio, QMessageBox::Icon icon, const QString& title,
                                   const QString& text)
{
    QMessageBox* msgBox = new QMessageBox(icon, title, text, QMessageBox::Ok);
    msgBox->setAttribute(Qt::WA_DeleteOnClose);
    msgBox->setModal(false);

    raiseDialog(msgBox, prio);
}






AlertManager::AlertManager(PsiCon *psi) {
    psi_ = psi;
}


AlertManager::~AlertManager() {
    deleteDialogList();
}
