/***************************************************************************
 * Copyright (C) 2015-2016 by Savoir-faire Linux                           *
 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
 *                                                                         *
 * 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       *
 * (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/>.   *
 **************************************************************************/

#include "configurationwidget.h"
#include "ui_configurationwidget.h"

#include <QMessageBox>
#include <QDir>
#include <QStandardPaths>
#include <QFileDialog>
#include <QPropertyAnimation>
#include <QtConcurrent/QtConcurrent>

#include "video/devicemodel.h"
#include "video/channel.h"
#include "video/resolution.h"
#include "video/rate.h"
#include "video/previewmanager.h"

#include "audio/settings.h"
#include "audio/outputdevicemodel.h"
#include "audio/inputdevicemodel.h"

#include "media/recordingmodel.h"

#include "accountserializationadapter.h"
#include "accountstatedelegate.h"
#include "settingskey.h"
#include "utils.h"
#include "pathpassworddialog.h"
#include "photoboothdialog.h"

#include "accountmodel.h"
#include "protocolmodel.h"
#include "accountdetails.h"
#include "callmodel.h"
#include "ringtonemodel.h"
#include "categorizedhistorymodel.h"
#include "profilemodel.h"
#include "profile.h"
#include "person.h"

#ifdef ENABLE_AUTOUPDATE
#include "winsparkle.h"
#endif

ConfigurationWidget::ConfigurationWidget(QWidget *parent) :
    NavWidget(parent),
    ui(new Ui::ConfigurationWidget),
    accountModel_(&AccountModel::instance()),
    deviceModel_(&Video::DeviceModel::instance()),
    accountDetails_(new AccountDetails())
{
    ui->setupUi(this);

    connect(ui->exitSettingsButton, &QPushButton::clicked, this, [=]() {
        if (CallModel::instance().getActiveCalls().size() == 0
                && Video::PreviewManager::instance().isPreviewing()) {
            Video::PreviewManager::instance().stopPreview();
        }
        accountModel_->save();
        accountDetails_->save();
    });

    connect(accountDetails_->getDeleteAccountButton(), &QPushButton::clicked, this, [=]() {
        auto account = accountModel_->getAccountByModelIndex(
                    ui->accountView->currentIndex());
        accountModel_->remove(account);
        accountModel_->save();
    });

    connect(ui->exitSettingsButton, &QPushButton::clicked, this, [=]() {
        emit NavigationRequested(ScreenEnum::CallScreen);
    });

    ui->accountView->setModel(accountModel_);
    accountStateDelegate_ = new AccountStateDelegate();
    ui->accountView->setItemDelegate(accountStateDelegate_);

    isLoading_ = true;
    ui->deviceBox->setModel(deviceModel_);
    connect(deviceModel_, SIGNAL(currentIndexChanged(int)),
            this, SLOT(deviceIndexChanged(int)));

    AccountModel::instance().selectionModel()->clear();
    ui->accountView->setSelectionModel(AccountModel::instance().selectionModel());
    connect(ui->accountView->selectionModel(),
            SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            this, SLOT(accountSelected(QItemSelection)));

    ui->accountView->setCurrentIndex(accountModel_->index(0));
    ui->accountDetailLayout->addWidget(accountDetails_);
    ui->accountTypeBox->setModel(accountModel_->protocolModel());
    ui->startupBox->setChecked(Utils::CheckStartupLink());

    ui->historyDaySettingsSpinBox->setValue(
                CategorizedHistoryModel::instance().historyLimit());
    ui->closeOrMinCheckBox->setChecked(settings_.value(
                                           SettingsKey::closeOrMinimized).toBool());
    connect(ui->stackedWidget, &QStackedWidget::currentChanged, [](int index) {
        if (index == 1
                && CallModel::instance().getActiveCalls().size() == 0) {
            Video::PreviewManager::instance().startPreview();
        } else {
            if (CallModel::instance().getActiveCalls().size() == 0
                    && Video::PreviewManager::instance().isPreviewing()) {
                Video::PreviewManager::instance().stopPreview();
            }
        }
    });

    ui->videoView->setIsFullPreview(true);

    auto recordPath = Media::RecordingModel::instance().recordPath();
    if (recordPath.isEmpty()) {
        recordPath = QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
        Media::RecordingModel::instance().setRecordPath(recordPath);
    }
    ui->recordPath->setText(Media::RecordingModel::instance().recordPath());

    ui->alwaysRecordCheckBox->setChecked(Media::RecordingModel::instance().isAlwaysRecording());
    connect(ui->alwaysRecordCheckBox, &QCheckBox::clicked, [](bool checked){
        Media::RecordingModel::instance().setAlwaysRecording(checked);
    });

    connect(ui->generalTabButton, &QPushButton::toggled, [=] (bool toggled) {
        if (toggled) {
            ui->stackedWidget->setCurrentWidget(ui->generalPage);
            ui->videoTabButton->setChecked(false);
            ui->accountTabButton->setChecked(false);
        }
    });

    connect(ui->videoTabButton, &QPushButton::toggled, [=] (bool toggled) {
        if (toggled) {
            ui->stackedWidget->setCurrentWidget(ui->videoPage);
            ui->accountTabButton->setChecked(false);
            ui->generalTabButton->setChecked(false);
        }
    });

    connect(ui->accountTabButton, &QPushButton::toggled, [=] (bool toggled) {
        if (toggled) {
            ui->stackedWidget->setCurrentWidget(ui->accountPage);
            ui->videoTabButton->setChecked(false);
            ui->generalTabButton->setChecked(false);
        }
    });

    ui->generalTabButton->setChecked(true);

    auto inputModel = Audio::Settings::instance().inputDeviceModel();
    auto outputModel = Audio::Settings::instance().outputDeviceModel();

    ui->outputComboBox->setModel(outputModel);
    ui->inputComboBox->setModel(inputModel);
    ui->outputComboBox->setCurrentIndex(outputModel->selectionModel()->currentIndex().row());
    ui->inputComboBox->setCurrentIndex(inputModel->selectionModel()->currentIndex().row());
    connect(ui->outputComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(outputIndexChanged(int)));
    connect(ui->inputComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(inputIndexChanged(int)));


#ifndef ENABLE_AUTOUPDATE
    ui->checkUpdateButton->hide();
    ui->intervalUpdateCheckSpinBox->hide();
    ui->updateDayLabel->hide();
    ui->autoUpdateCheckBox->hide();
#endif

    auto profile = ProfileModel::instance().selectedProfile();
    ui->avatarButton->setIcon(QPixmap::fromImage(Utils::getCirclePhoto(profile->person()->photo().value<QImage>(), ui->avatarButton->width())));
    ui->profileNameEdit->setText(profile->person()->formattedName());
}

void ConfigurationWidget::showPreview()
{
    if (ui->stackedWidget->currentIndex() == 1
            && CallModel::instance().getActiveCalls().size() == 0) {
        ui->previewUnavailable->hide();
        ui->videoView->show();
        Video::PreviewManager::instance().startPreview();
    } else {
        ui->previewUnavailable->show();
        ui->videoView->hide();
    }
}

void
ConfigurationWidget::showEvent(QShowEvent *event)
{
#ifdef ENABLE_AUTOUPDATE
    if (win_sparkle_get_automatic_check_for_updates()) {
        ui->autoUpdateCheckBox->setChecked(true);
    }
    ui->intervalUpdateCheckSpinBox->setValue(win_sparkle_get_update_check_interval() / 86400);
#endif
    QWidget::showEvent(event);
    showPreview();
}

ConfigurationWidget::~ConfigurationWidget()
{
    delete ui;
    delete accountStateDelegate_;
}

void
ConfigurationWidget::deviceIndexChanged(int index)
{
    ui->deviceBox->setCurrentIndex(index);
}

void
ConfigurationWidget::on_deviceBox_currentIndexChanged(int index)
{
    if (index < 0)
        return;

    if (!isLoading_)
        deviceModel_->setActive(index);

    auto device = deviceModel_->activeDevice();

    ui->sizeBox->clear();

    isLoading_ = true;
    if (device->channelList().size() > 0) {
        for (auto resolution : device->channelList()[0]->validResolutions()) {
            ui->sizeBox->addItem(resolution->name());
        }
    }
    ui->sizeBox->setCurrentIndex(
                device->channelList()[0]->activeResolution()->relativeIndex());
    isLoading_ = false;
}

void
ConfigurationWidget::on_sizeBox_currentIndexChanged(int index)
{
    auto device = deviceModel_->activeDevice();

    if (index < 0)
        return;
    if (!isLoading_)
        device->channelList()[0]->setActiveResolution(
                    device->channelList()[0]->validResolutions()[index]);
}

void
ConfigurationWidget::accountSelected(QItemSelection itemSel)
{
    if (itemSel.size())
        accountDetails_->show();
    else
        accountDetails_->hide();

    if (accountConnection_)
        disconnect(accountConnection_);

    auto account = accountModel_->getAccountByModelIndex(
                ui->accountView->currentIndex());
    accountDetails_->setAccount(account);
    if (account) {
        AccountSerializationAdapter adapter(account, accountDetails_);
        accountConnection_= connect(account,
                                    SIGNAL(propertyChanged(Account*,QString,QString,QString)),
                                    this,
                                    SLOT(accountPropertyChanged(Account*,QString,QString,QString)));
    }
}

void
ConfigurationWidget::accountPropertyChanged(Account* a,
                                            const QString& name,
                                            const QString& newVal,
                                            const QString& oldVal)
{
    Q_UNUSED(name)
    Q_UNUSED(newVal)
    Q_UNUSED(oldVal)
    accountDetails_->setAccount(a);
    AccountSerializationAdapter adapter(a, accountDetails_);
}

void
ConfigurationWidget::on_addAccountButton_clicked()
{
    auto account = accountModel_->add(tr("New Account"),
                                      ui->accountTypeBox->model()->index(
                                          ui->accountTypeBox->currentIndex(), 0));
    account->setRingtonePath(Utils::GetRingtonePath());
    accountModel_->save();
}

void
ConfigurationWidget::on_startupBox_toggled(bool checked)
{
    if (checked)
        Utils::CreateStartupLink();
    else
        Utils::DeleteStartupLink();
}

void
ConfigurationWidget::on_clearHistoryButton_clicked()
{
    QMessageBox confirmationDialog;

    confirmationDialog.setText(tr("Are you sure you want to clear all your history?"));
    confirmationDialog.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
    auto ret = confirmationDialog.exec();

    if (ret == QMessageBox::Ok)
        CategorizedHistoryModel::instance().clearAllCollections();
}

void
ConfigurationWidget::on_historyDaySettingsSpinBox_valueChanged(int limit)
{
    if (CategorizedHistoryModel::instance().historyLimit() != limit)
        CategorizedHistoryModel::instance().setHistoryLimit(limit);
}

void
ConfigurationWidget::on_closeOrMinCheckBox_toggled(bool checked)
{
    settings_.setValue(SettingsKey::closeOrMinimized, checked);
}

void
ConfigurationWidget::on_checkUpdateButton_clicked()
{
#ifdef ENABLE_AUTOUPDATE
    win_sparkle_check_update_with_ui();
#endif
}

void
ConfigurationWidget::on_autoUpdateCheckBox_toggled(bool checked)
{
#ifdef ENABLE_AUTOUPDATE
    win_sparkle_set_automatic_check_for_updates(checked);
#endif
}

void
ConfigurationWidget::on_intervalUpdateCheckSpinBox_valueChanged(int arg1)
{
#ifdef ENABLE_AUTOUPDATE
    win_sparkle_set_update_check_interval(arg1 * 86400);
#endif
}

void
ConfigurationWidget::on_stackedWidget_currentChanged(int index)
{
    Q_UNUSED(index)
    showPreview();
}

void
ConfigurationWidget::on_recordPath_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this, tr("Choose Directory"),
                                                 Media::RecordingModel::instance().recordPath(),
                                                 QFileDialog::ShowDirsOnly
                                                 | QFileDialog::DontResolveSymlinks);
    if (not dir.isEmpty()) {
        Media::RecordingModel::instance().setRecordPath(dir);
        ui->recordPath->setText(dir);
    }
}

void
ConfigurationWidget::outputIndexChanged(int index)
{
    auto outputModel = Audio::Settings::instance().outputDeviceModel();
    outputModel->selectionModel()->setCurrentIndex(outputModel->index(index), QItemSelectionModel::ClearAndSelect);
}

void
ConfigurationWidget::inputIndexChanged(int index)
{
    auto inputModel = Audio::Settings::instance().inputDeviceModel();
    inputModel->selectionModel()->setCurrentIndex(inputModel->index(index), QItemSelectionModel::ClearAndSelect);
}

void
ConfigurationWidget::on_importButton_clicked()
{
    PathPasswordDialog dlg;
    if (dlg.exec() == QDialog::Accepted)
        if (AccountModel::instance().importAccounts(dlg.path_, dlg.password_) > 0)
            errorDlg_.showMessage(tr("An error occured while importing account."));
}

void
ConfigurationWidget::on_exportButton_clicked()
{
    PathPasswordDialog dlg;
    dlg.exportMode = true;
    if (dlg.exec() == QDialog::Accepted) {
        auto func = [](QString path, QString password)
        {
            AccountModel::instance().exportAccounts(
            {AccountModel::instance().selectedAccount()->id()},
                        path,
                        password);
        };
        QtConcurrent::run(func, dlg.path_, dlg.password_);
    }
}

void
ConfigurationWidget::on_avatarButton_clicked()
{
    PhotoBoothDialog dlg;
    dlg.exec();
    if (dlg.result() == QDialog::Accepted) {
        auto image = QImage(dlg.fileName_);
        auto avatar = image.scaled(100, 100, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
        ProfileModel::instance().selectedProfile()->person()->setPhoto(avatar);
        ProfileModel::instance().selectedProfile()->save();
        ui->avatarButton->setIcon(QPixmap::fromImage(Utils::getCirclePhoto(avatar, ui->avatarButton->width())));
    }
}

void
ConfigurationWidget::on_profileNameEdit_textEdited(const QString& name)
{
    ProfileModel::instance().selectedProfile()->person()->setFormattedName(name);
    ProfileModel::instance().selectedProfile()->save();
}
