/*
  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.
*/

/*
  Shows the content of a log file
  begin:     Fri Dec 5 2003
  copyright: (C) 2003 by Dario Abatianni
  email:     eisfuchs@tigress.com
*/

#include "logfilereader.h"
#include "application.h"
#include "ircview.h"
#include "ircviewbox.h"

#include <QFile>
#include <QPushButton>
#include <QLabel>
#include <QSpinBox>
#include <QTextCodec>
#include <QKeyEvent>

#include <KToolBar>
#include <KMessageBox>
#include <QFileDialog>
#include <KLocalizedString>
#include <KIO/CopyJob>
#include <KJobUiDelegate>


LogfileReader::LogfileReader(QWidget* parent, const QString& log, const QString& caption) : ChatWindow(parent)
{
    setType(ChatWindow::LogFileReader);
    setName(i18n("Logfile of %1", caption));

    fileName = log;

    setSpacing(0);

    toolBar = new KToolBar(this, true, true);
    toolBar->setObjectName("logfile_toolbar");
    toolBar->addAction(QIcon::fromTheme("document-save-as"), i18n("Save As..."), this, SLOT(saveLog()));
    toolBar->addAction(QIcon::fromTheme("view-refresh"), i18n("Reload"), this, SLOT(updateView()));
    toolBar->addAction(QIcon::fromTheme("edit-delete"), i18n("Clear Logfile"), this, SLOT(clearLog()));

    toolBar->addWidget(new QLabel(i18n("Show last:"),toolBar));
    sizeSpin = new QSpinBox(toolBar);
    sizeSpin->setMinimum(10);
    sizeSpin->setMaximum(1000);
    sizeSpin->setSingleStep(10);
    sizeSpin->setObjectName("logfile_size_spinbox");
    sizeSpin->setWhatsThis(i18n("Use this box to set the maximum size of the log file. This setting does not take effect until you restart Konversation. Each log file may have a separate setting."));
    sizeSpin->setValue(Preferences::self()->logfileBufferSize());
    sizeSpin->setSuffix(i18n(" KB"));
    sizeSpin->installEventFilter(this);
    toolBar->addWidget(sizeSpin);
    connect(sizeSpin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &LogfileReader::storeBufferSize);

    IRCViewBox* ircBox = new IRCViewBox(this);
    setTextView(ircBox->ircView());
    getTextView()->setWhatsThis(i18n("The messages in the log file are displayed here. The oldest messages are at the top and the most recent are at the bottom."));

    updateView();
    ircBox->ircView()->setFocusPolicy(Qt::StrongFocus);
    setFocusPolicy(Qt::StrongFocus);
    setFocusProxy(ircBox->ircView());

    updateAppearance();

    connect(getTextView(), SIGNAL(gotFocus()), getTextView(), SLOT(setFocus()));
}

LogfileReader::~LogfileReader()
{
}

bool LogfileReader::eventFilter(QObject* /* watched */, QEvent* e)
{
    if (e->type() == QEvent::KeyPress)
    {
        QKeyEvent* ke = static_cast<QKeyEvent*>(e);

        if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter)
        {
            updateView();

            return true;
        }
        else
            return false;
    }

    return false;
}

void LogfileReader::storeBufferSize(int kb)
{
    Preferences::self()->setLogfileBufferSize(kb);
}

void LogfileReader::updateView()
{
    // get maximum size of logfile to display
    qint64 pos = Q_INT64_C(1024) * sizeSpin->value();
    getTextView()->clear();

    QFile file(fileName);

    if(file.open(QIODevice::ReadOnly))
    {
        QTextStream stream(&file);
        stream.setCodec(QTextCodec::codecForName("UTF-8"));
        stream.setAutoDetectUnicode(true);

        // Set file pointer to <pos> bytes from the end
        if(stream.device()->size() > pos)
        {
            stream.device()->seek(stream.device()->size() - pos);
        }
        // Skip first line, since it may be incomplete
        // NOTE: we always skip the first line(in the log), but the
        //       first line is just a '\n', so it's ok
        stream.readLine();
        QString str;

        while(!stream.atEnd())
        {
            str = stream.readLine().toHtmlEscaped();
            getTextView()->appendLog(str);
        }

        stream.setDevice(0);
        file.close();
    }
}

void LogfileReader::clearLog()
{
    if(KMessageBox::warningContinueCancel(this,
        i18n("Do you really want to permanently discard all log information of this file?"),
        i18n("Clear Logfile"),
        KStandardGuiItem::del(),
        KStandardGuiItem::cancel(),
        "ClearLogfileQuestion")==KMessageBox::Continue)
    {
        QFile::remove(fileName);
        updateView();
    }
}

void LogfileReader::saveLog()
{
    KMessageBox::information(this,
        i18n("Note: By saving the logfile you will save all data in the file, not only the part you can see in this viewer."),
        i18n("Save Logfile"),
        "SaveLogfileNote");

    QUrl logUrl = QUrl::fromLocalFile(fileName);
    QUrl destination = QFileDialog::getSaveFileUrl(this, i18n("Choose Destination Folder"), logUrl);
    if(!destination.isEmpty())
    {
        KIO::Job* job = KIO::copy(logUrl, destination);

        connect(job, &KIO::Job::result, this, &LogfileReader::copyResult);
    }
}

void LogfileReader::copyResult(KJob* job)
{
    if(job->error()) job->uiDelegate()->showErrorMessage();

    job->deleteLater();
}

void LogfileReader::closeLog()
{
    delete this;
}

void LogfileReader::childAdjustFocus()
{
  getTextView()->setFocus();
}

int LogfileReader::margin()
{
    return style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
}

int LogfileReader::spacing()
{
    return style()->layoutSpacing(QSizePolicy::DefaultType, QSizePolicy::DefaultType, Qt::Horizontal);
}

bool LogfileReader::searchView() { return true; }
