/** @file nativeui.cpp Native GUI functionality. 
 * @ingroup base
 *
 * @authors Copyright © 2012-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
 * @authors Copyright © 2013 Daniel Swanson <danij@dengine.net>
 *
 * @par License
 * GPL: http://www.gnu.org/licenses/gpl.html
 *
 * <small>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 St, Fifth Floor, Boston, MA
 * 02110-1301 USA</small>
 */

#include <QMessageBox>
#include <QFile>
#include <QString>
#include <stdarg.h>
#include "dd_share.h"
#include "sys_system.h"
#include <QLayout>
#include <QLabel>
#include <QVBoxLayout>
#include <QDebug>

#include <de/App>
#include <de/ByteArrayFile>

#include "ui/nativeui.h"
#include "ui/clientwindow.h"

void Sys_MessageBox(messageboxtype_t type, const char* title, const char* msg, const char* detailedMsg)
{
    Sys_MessageBox2(type, title, msg, 0, detailedMsg);
}

void Sys_MessageBox2(messageboxtype_t type, const char* title, const char* msg, const char* informativeMsg, const char* detailedMsg)
{
    Sys_MessageBox3(type, title, msg, informativeMsg, detailedMsg, 0);
}

int Sys_MessageBox3(messageboxtype_t type, const char* title, const char* msg, const char* informativeMsg, const char* detailedMsg,
                    const char** buttons)
{
    if(novideo)
    {
        // There's no GUI...
        qWarning("%s", msg);
        return 0;
    }

    if(ClientWindow::mainExists())
    {
        ClientWindow::main().hide();
    }

    QMessageBox box;
    box.setWindowTitle(title);
    box.setText(msg);
    switch(type)
    {
    case MBT_INFORMATION: box.setIcon(QMessageBox::Information); break;
    case MBT_QUESTION:    box.setIcon(QMessageBox::Question);    break;
    case MBT_WARNING:     box.setIcon(QMessageBox::Warning);     break;
    case MBT_ERROR:       box.setIcon(QMessageBox::Critical);    break;
    default:
        break;
    }
    if(detailedMsg)
    {
        /// @todo Making the dialog a bit wider would be nice, but it seems one has to
        /// derive a new message box class for that -- the default one has a fixed size.

        box.setDetailedText(detailedMsg);
    }
    if(informativeMsg)
    {
        box.setInformativeText(informativeMsg);
    }
    if(buttons)
    {
        for(int i = 0; buttons[i]; ++i)
        {
            box.addButton(buttons[i],
                          i == 0? QMessageBox::AcceptRole :
                          i == 1? QMessageBox::RejectRole :
                                  QMessageBox::ActionRole);
        }
    }
    return box.exec();
}

void Sys_MessageBoxf(messageboxtype_t type, const char* title, const char* format, ...)
{
    char buffer[1024];
    va_list args;

    va_start(args, format);
    dd_vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    Sys_MessageBox(type, title, buffer, 0);
}

int Sys_MessageBoxWithButtons(messageboxtype_t type, const char* title, const char* msg,
                              const char* informativeMsg, const char** buttons)
{
    return Sys_MessageBox3(type, title, msg, informativeMsg, 0, buttons);
}

void Sys_MessageBoxWithDetailsFromFile(messageboxtype_t type, const char* title, const char* msg,
                                       const char* informativeMsg, const char* detailsFileName)
{
    try
    {
        de::Block details;
        de::ByteArrayFile const &file = de::App::rootFolder().locate<de::ByteArrayFile>(detailsFileName);
        file >> details;

        // This will be used as a null-terminated string.
        details.append('\0');

        Sys_MessageBox2(type, title, msg, informativeMsg, details.constData());
    }
    catch(de::Error const &er)
    {
        qWarning() << "Could not read" << detailsFileName << ":" << er.asText().toLatin1().constData();

        // Show it without the details, then.
        Sys_MessageBox2(type, title, msg, informativeMsg, 0);
    }
}
