/*
    yandexnarodManage

    Copyright (c) 2009 by Alexander Kazarin <boiler@co.ru>
            2011 by Evgeny Khryukin

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

#include <QClipboard>
#include <QFileDialog>
#include <QMimeData>
#include <QListWidgetItem>
#include <QMouseEvent>
#include <QMenu>
#include <QMessageBox>
#include <QDesktopServices>

#include "yandexnarodmanage.h"
#include "uploaddialog.h"
#include "optionaccessinghost.h"
#include "yandexnarodsettings.h"
#include "options.h"
#include "ui_yandexnarodmanage.h"



//------------------------------------------
//-------ListWidgetItem---------------------
//------------------------------------------
class ListWidgetItem : public QListWidgetItem
{
public:
    ListWidgetItem(const QIcon& ico, const yandexnarodNetMan::FileItem& fileitem)
        : QListWidgetItem(ico, fileitem.filename)
        , item_(fileitem)
    {
        QString toolTip = QObject::tr("Name: %1\nSize: %2\nDate prolongate: %3\nURL: %4\nPassword: %5")
                    .arg(fileitem.filename)
                    .arg( QString(fileitem.size).replace("&nbsp;", " ") )
                    .arg(fileitem.date)
                    .arg(fileitem.fileurl)
                    .arg(fileitem.passset ? QObject::tr("Yes") : QObject::tr("No"));
        setToolTip(toolTip);
    }

    const yandexnarodNetMan::FileItem& fileItem() const
    {
        return item_;
    }

private:
    yandexnarodNetMan::FileItem item_;
};




//------------------------------------------
//-------ListWidget-------------------------
//------------------------------------------
ListWidget::ListWidget(QWidget* p)
    : QListWidget(p)
{
}

QStringList ListWidget::mimeTypes() const
{
    return QStringList() << "text/plain";
}

QMimeData* ListWidget::mimeData(const QList<QListWidgetItem *> &items) const
{
    if(items.isEmpty())
        return 0;

    QMimeData* d = new QMimeData();
    QString text;
    foreach(QListWidgetItem *i, items) {
        text += static_cast<ListWidgetItem*>(i)->fileItem().fileurl + "\n";
    }
    d->setText(text);

    return d;
}

void ListWidget::mousePressEvent(QMouseEvent *event)
{
    QListWidget::mousePressEvent(event);
    if(event->button() == Qt::RightButton) {
        QListWidgetItem *lwi = itemAt(event->pos());
        if(lwi) {
            ListWidgetItem *it = static_cast<ListWidgetItem*>(lwi);
            emit menu(it->fileItem());
            event->accept();
        }
    }
}

static QStringList files(const QMimeData *md)
{
    QString str = QFile::decodeName(QByteArray::fromPercentEncoding(md->data("text/uri-list")));
    QRegExp re("file://(.+)");
    QStringList files;
    int index = re.indexIn(str);
    while(index != -1) {
        files.append(re.cap(1).trimmed());
        index = re.indexIn(str, index+1);
    }
    return files;
}

void ListWidget::dragEnterEvent(QDragEnterEvent *event)
{
    const QMimeData *md = event->mimeData();
    QStringList list = files(md);
    bool ok = false;
    if(list.size() == 1) {
        QFile file(list.takeFirst());
        if(file.exists()) {
            ok = true;
        }
    }
    if(ok) {
        event->acceptProposedAction();
    }
}

void ListWidget::dropEvent(QDropEvent *event)
{
    QStringList list = files(event->mimeData());
    if(list.size() == 1) {
        const QString path = list.takeFirst();
        QFile file(path);
        if(file.exists())
            emit uploadFile(path);
    }

    event->setDropAction(Qt::IgnoreAction);
    event->accept();
}


//------------------------------------------
//-------yandexnarodManage------------------
//------------------------------------------
yandexnarodManage::yandexnarodManage(QWidget* p)
    : QDialog(p, Qt::Window)
    , ui_(new Ui::yandexnarodManageClass)
{
    ui_->setupUi(this);
    setWindowTitle(tr("Yandex.Narod file manager"));
    setWindowIcon(QIcon(":/icons/yandexnarodplugin.png"));
    ui_->frameProgress->hide();
    ui_->frameFileActions->hide();
    ui_->listWidget->clear();

    ui_->btnOpenBrowser->setIcon(qApp->style()->standardIcon(QStyle::SP_BrowserReload));

    newNetMan();

    QPixmap iconimage(":/icons/yandexnarod-icons-files.png");
    for (int i=0; i<(iconimage.width()/16); i++) {
        QIcon icon(iconimage.copy((i*16),0,16,16));
        fileicons.append(icon);
    }

    fileiconstyles["b-icon-music"] = 0;
    fileiconstyles["b-icon-video"] = 1;
    fileiconstyles["b-icon-arc"] = 2;
    fileiconstyles["b-icon-doc"] = 3;
    fileiconstyles["b-icon-soft"] = 4;
    fileiconstyles["b-icon-unknown"] = 5;
    fileiconstyles["b-icon-picture"] = 14;

    Options* o = Options::instance();
    int h = o->getOption(CONST_HEIGHT, 200).toInt();
    int w = o->getOption(CONST_WIDTH, 300).toInt();

    resize(w, h);

    setAttribute(Qt::WA_QuitOnClose, false);
    setAttribute(Qt::WA_DeleteOnClose, true);

    connect(ui_->listWidget, SIGNAL(menu(yandexnarodNetMan::FileItem)), SLOT(doMenu(yandexnarodNetMan::FileItem)));
    connect(ui_->listWidget, SIGNAL(uploadFile(QString)), this, SLOT(uploadFile(QString)), Qt::QueuedConnection);
}

yandexnarodManage::~yandexnarodManage()
{
    Options* o = Options::instance();
    o->setOption(CONST_HEIGHT, height());
    o->setOption(CONST_WIDTH, width());

    delete ui_;
}

void yandexnarodManage::newNetMan()
{
    netman = new yandexnarodNetMan(this);
    connect(netman, SIGNAL(statusText(QString)), ui_->labelStatus, SLOT(setText(QString)));
    connect(netman, SIGNAL(newFileItem(yandexnarodNetMan::FileItem)), this, SLOT(newFileItem(yandexnarodNetMan::FileItem)));
    connect(netman, SIGNAL(finished()), this, SLOT(netmanFinished()));
}

void yandexnarodManage::newFileItem(yandexnarodNetMan::FileItem fileitem)
{
    int iconnum = 5;
    QString fileiconname = fileitem.fileicon.replace("-old", "");
    if (fileiconstyles.contains(fileiconname))
        iconnum = fileiconstyles[fileiconname];

    QListWidgetItem *listitem = new ListWidgetItem(fileicons[iconnum], fileitem);
    ui_->listWidget->addItem(listitem);
}

void yandexnarodManage::netmanPrepare()
{
    ui_->frameProgress->show();
    ui_->labelStatus->clear();
    ui_->frameFileActions->hide();
    ui_->btnReload->setEnabled(false);
}

void yandexnarodManage::netmanFinished()
{
    ui_->btnReload->setEnabled(true);
}

void yandexnarodManage::on_btnReload_clicked()
{
    ui_->listWidget->clear();
    netmanPrepare();
    netman->startGetFilelist();
}

void yandexnarodManage::on_btnDelete_clicked()
{
    QList<yandexnarodNetMan::FileItem> out;
    foreach(QListWidgetItem* i, ui_->listWidget->selectedItems()) {
        ListWidgetItem* lwi = static_cast<ListWidgetItem*>(i);
        yandexnarodNetMan::FileItem &f = const_cast<yandexnarodNetMan::FileItem&>(lwi->fileItem());
        if(!f.deleted) {
            out.append(f);
            f.deleted = true;
        }
    }
    if(out.isEmpty())
        return;

    int rez = QMessageBox::question(this, tr("Delete file(s)"), tr("Are you sure?"), QMessageBox::Ok | QMessageBox::Cancel);
    if(rez == QMessageBox::Cancel)
        return;

    foreach(QListWidgetItem* i, ui_->listWidget->selectedItems()) {
        i->setIcon(fileicons[15]);
    }
    netmanPrepare();
    netman->startDelFiles(out);
}

void yandexnarodManage::on_btnProlong_clicked()
{
    netmanPrepare();
    QList<yandexnarodNetMan::FileItem> out;
    foreach(QListWidgetItem* i, ui_->listWidget->selectedItems()) {
        ListWidgetItem* lwi = static_cast<ListWidgetItem*>(i);
        yandexnarodNetMan::FileItem f = lwi->fileItem();
        if(f.prolong() < 45) {
            out.append(f);
        }
    }
    netman->startProlongFiles(out);
}

void yandexnarodManage::on_btnClearCookies_clicked()
{
    netman->disconnect();
    netman->deleteLater();

    Options::instance()->saveCookies(QList<QNetworkCookie>());

    newNetMan();
    ui_->frameProgress->show();
    ui_->labelStatus->setText(O_M(MRemoveCookie));
}

void yandexnarodManage::on_btnOpenBrowser_clicked()
{
    QDesktopServices::openUrl(QUrl("http://narod.yandex.ru/disk/all/"));
}

void yandexnarodManage::on_listWidget_pressed(QModelIndex)
{
    if (ui_->frameFileActions->isHidden())
        ui_->frameFileActions->show();

    bool prolong = false;
    foreach(QListWidgetItem* i, ui_->listWidget->selectedItems()) {
        ListWidgetItem* lwi = static_cast<ListWidgetItem*>(i);
        if(lwi->fileItem().prolong() < 45) {
            prolong = true;
            break;
        }
    }
    ui_->btnProlong->setEnabled(prolong);
}

void yandexnarodManage::on_btnClipboard_clicked()
{
    QStringList text;
    foreach(QListWidgetItem* i, ui_->listWidget->selectedItems()) {
        text << static_cast<ListWidgetItem*>(i)->fileItem().fileurl;
    }
    copyToClipboard(text.join("\n"));
}

void yandexnarodManage::copyToClipboard(const QString &text)
{
    QClipboard *clipboard = QApplication::clipboard();
    clipboard->setText(text);
}

void yandexnarodManage::on_btnUpload_clicked()
{
    QString filePath = QFileDialog::getOpenFileName(this, O_M(MChooseFile), Options::instance()->getOption(CONST_LAST_FOLDER).toString());

    if (!filePath.isEmpty()) {
        QFileInfo fi(filePath);
        Options::instance()->setOption(CONST_LAST_FOLDER, fi.dir().path());

        uploadFile(filePath);
    }
}

void yandexnarodManage::uploadFile(const QString &path)
{
    uploadDialog* uploadwidget = new uploadDialog(this);
    connect(uploadwidget, SIGNAL(canceled()), this, SLOT(netmanFinished()));
    connect(uploadwidget, SIGNAL(finished()), this, SLOT(netmanFinished()));
    uploadwidget->show();
    uploadwidget->start(path);
}

void yandexnarodManage::doMenu(const yandexnarodNetMan::FileItem &it)
{
    QMenu m;
    QList<QAction*> actions;
    QAction *act = new QAction(tr("Set password"), &m);
    act->setVisible(!it.passset);
    act->setData(1);
    actions << act;
    act = new QAction(tr("Remove password"), &m);
    act->setVisible(it.passset);
    act->setData(2);
    actions << act;
    act = new QAction(tr("Copy URL"), &m);
    act->setData(3);
    actions << act;
    act = new QAction(tr("Prolongate"), &m);
    act->setData(4);
    act->setEnabled(it.prolong() < 45);
    actions << act;
    m.addActions(actions);
    QAction* ret = m.exec(QCursor::pos());
    if(ret) {
        switch(ret->data().toInt()) {
        case 1:
            netman->startSetPass(it);
            break;
        case 2:
            netman->startRemovePass(it);
            break;
        case 3:
            copyToClipboard(it.fileurl);
            break;
        case 4:
            netman->startProlongFiles(QList<yandexnarodNetMan::FileItem>() << it);
        default:
            break;
        }
    }
}

