/***********************************************************************
 *                                                                     *
 * Copyright 2016  Lorenzo Porta (Vindex17) <vindex17@outlook.it>      *
 *                                                                     *
 * 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 any later version accepted by the membership of      *
 * KDE e.V. (or its successor approved by the membership of KDE        *
 * e.V.), which shall act as a proxy defined in Section 14 of          *
 * version 3 of the license.                                           *
 *                                                                     *
 * 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/> *
 *                                                                     *
 ***********************************************************************/


#include "urlrequester.hxx"
#include "urlrequester.moc"

#include <KIO/Global>
#include <KLocalizedString>
#include <QFileDialog>
#include <QHeaderView>

#define CHECK_RELATIONSHIP(A,B) if (Q_UNLIKELY(A##_url.isParentOf(B##_url))) if (show_relationship_error_between(A##_string, B##_string) != KMessageBox::Continue) return

#define SETUP_URL(NAME, WINDOW_TITLE) \
    const QUrl &NAME = QFileDialog::getExistingDirectoryUrl(this, WINDOW_TITLE, start_dir_url).adjusted(QUrl::NormalizePathSegments); \
    if (Q_UNLIKELY(NAME.isEmpty())) return; \
    if (NAME.path().endsWith(slash) == false) const_cast<QUrl&>(NAME).setPath(NAME.path() % slash)


UrlRequester::UrlRequester() : QTableWidget(0,2)
{
    horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
    setEditTriggers(QAbstractItemView::NoEditTriggers);
    setHorizontalHeaderLabels({i18nc("title:column", "Source directories"), i18nc("title:column", "Destination directories")});
    setSelectionBehavior(QAbstractItemView::SelectRows);
    setSelectionMode(QAbstractItemView::SingleSelection);
}


void UrlRequester::add()
{
    // Get and check new urls
    const QChar &slash = QChar::fromLatin1('/');
    const QUrl &start_dir_url = QUrl::fromLocalFile(QDir::homePath());
    SETUP_URL(source_url, i18nc("@title:window", "Select the source directory"));
    SETUP_URL(destination_url, i18nc("@title:window", "Select the destination directory"));
    if (Q_UNLIKELY(source_url == destination_url)) {
        KMessageBox::sorry(this, i18nc("@info", "A directory can't be the source and the destination at the same time!"));
        return;
    }
    const auto &source_string = source_url.toDisplayString(URL_DISPLAY_FORMAT);
    const auto &destination_string = destination_url.toDisplayString(URL_DISPLAY_FORMAT);
    CHECK_RELATIONSHIP(source, destination);
    CHECK_RELATIONSHIP(destination, source);

    // Setup the new row
    const auto &new_row_n = rowCount();
    insertRow(new_row_n);
    setItem(new_row_n, 0, init_table_widget_item(source_url, source_string));
    setItem(new_row_n, 1, init_table_widget_item(destination_url, destination_string));

    // Update operation url lists
    operation_url_list.append(std::array<QUrl,2>{{source_url, destination_url}});
}

void UrlRequester::remove()
{
    const auto &i = currentRow();
    if (Q_UNLIKELY(i < 0))
        return;
    removeRow(i);
    operation_url_list.removeAt(i);
}


void UrlRequester::restore(const QList<QUrl> &&source_url_list, const QList<QUrl> &&destination_url_list)
{
    operation_url_list.clear();
    const auto &lists_size = source_url_list.size();
    Q_ASSERT(lists_size == destination_url_list.size());
    setRowCount(lists_size);
    for (std::decay<decltype(lists_size)>::type i = 0; Q_LIKELY(i < lists_size); ++i) {
        const auto &source_url = source_url_list[i];
        const auto &destination_url = destination_url_list[i];
        setItem(i, 0, init_table_widget_item(source_url, source_url.toDisplayString(URL_DISPLAY_FORMAT)));
        setItem(i, 1, init_table_widget_item(destination_url, destination_url.toDisplayString(URL_DISPLAY_FORMAT)));
        operation_url_list.append(std::array<QUrl,2>{{source_url, destination_url}});
    }
}


KMessageBox::ButtonCode UrlRequester::show_relationship_error_between(const QString &parent_string, const QString &child_string)
{
    return KMessageBox::warningContinueCancel(this, xi18nc("@info", "<warning><filename>%1</filename> is parent of <filename>%2</filename>!</warning><nl/><nl/>"
                                                                    "<note>operations between related directories may open Pandora's box...</note><nl/>"
                                                                    "If you choose to continue, you take full responsibility for what you are doing.",
                                                           parent_string, child_string));
}


QTableWidgetItem * UrlRequester::init_table_widget_item(const QUrl &url, const QString &string)
{
    QTableWidgetItem * new_table_widget_item = new QTableWidgetItem(QIcon::fromTheme(url.isLocalFile() ? QStringLiteral("folder") : QStringLiteral("folder-remote")), string);
    new_table_widget_item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemNeverHasChildren);
    return new_table_widget_item;
}
