#ifndef SettingsWidget_H
#define SettingsWidget_H

#include <QWidget>
#include <QTimer>
#include <QSettings>
#include <QPropertyAnimation>
#include <QPushButton>
#include <QEvent>
#include <QDebug>
#include <QScrollArea>
#include <QScrollBar>
#include <QWheelEvent>

#include "models/settings.h"
#include "models/lotrodatmanager.h"

namespace Ui {
class SettingsWidget;
}

class PatchList;

namespace SettingsWidgetPrivate {

class ComboboxScrollingDisabler : public QObject {
    Q_OBJECT

protected:
    bool eventFilter(QObject *, QEvent *event) override {
        if (event->type() == QEvent::Wheel) {
            event->ignore();
            return true;
        } else {
            return false;
        }
    }
};

class SettingsTabsScroller : public QObject {
public:
    SettingsTabsScroller(QList<QWidget*> entries, QScrollArea* target_widget) : target_widget_(target_widget), current_entry_id_(0), entries_(std::move(entries)) {
        scroll_entries_animation_ = new QPropertyAnimation(target_widget_->verticalScrollBar(), "value");
        scroll_entries_animation_->setDuration(450);
        scroll_entries_animation_->setEasingCurve(QEasingCurve::InOutQuart);
    }

    ~SettingsTabsScroller() {
        scroll_entries_animation_->deleteLater();
    }

protected:
    bool eventFilter(QObject *, QEvent *event) override {
//        if (obj != target_widget_) {
//            return false;
//        }

        if (event->type() == QEvent::Wheel) {
            event->ignore();
            QWheelEvent *wheel_event = (QWheelEvent*)(event);

            int wheel_angle = wheel_event->angleDelta().y();

            qDebug() << "SCROLL EVENT! " << wheel_event->pixelDelta() << "/" << wheel_event->angleDelta();

            if (scroll_entries_animation_->state() == QPropertyAnimation::Running) {
                return true;
            }

            if (wheel_angle < 0 && current_entry_id_ + 1 < entries_.size()) {
                ++current_entry_id_;
                scroll_entries_animation_->setStartValue(target_widget_->verticalScrollBar()->value());
                scroll_entries_animation_->setEndValue(entries_[current_entry_id_]->y());
                scroll_entries_animation_->start();
                return true;
            }

            if (wheel_angle > 0 && current_entry_id_ - 1 >= 0) {
                 --current_entry_id_;
                 scroll_entries_animation_->setStartValue(target_widget_->verticalScrollBar()->value());
                 scroll_entries_animation_->setEndValue(entries_[current_entry_id_]->y());
                 scroll_entries_animation_->start();
                 return true;
            }

            return true;
        } else {
            return false;
        }
    }

private:
    QScrollArea* target_widget_;
    int current_entry_id_;
    QList<QWidget*> entries_;
    QPropertyAnimation* scroll_entries_animation_;
};
}

class SettingsWidget : public QWidget
{
    Q_OBJECT

public:

    explicit SettingsWidget(PatchList *legacy_patches, QWidget *parent = 0);

    ~SettingsWidget();

signals:
    void SettingsChanged(); // Settings were changed so we should not do any actions until SettingsApplied() signal

    void SettingsApplied(); // Need to re-initialise all environment and start updates check

    void SettingsReset(); // Need to drop updates blockage, but do not re-initialize all environment

public slots:
    void setActualParametersValues();

    void updateFontsSizes();

protected:
    void resizeEvent(QResizeEvent *event) override;

private slots:
    void onLotroManagerProcessChanged(LotroDatManager::Status status);

    void onBackupSettingsInfoChanged();

    void processParameterChange();

    void checkIfParametersWereReset();

    void on_interface_scale_combobox_currentIndexChanged(const QString &arg1);

    void on_change_folder_button_clicked();

    void on_lotro_base_language_combobox_currentIndexChanged(int index);

    void onPatchTotalOperationsStarted();

    void onPatchTotalOperationsFinished();

    void on_skiprawdownload_checkbox_stateChanged(int arg1);

    void on_nosplashscreen_checkbox_stateChanged(int arg1);

    void on_backup_create_button_clicked();

    void on_backup_restore_button_clicked();

    void on_backup_remove_button_clicked();

    void on_patch_texts_checkbox_clicked();

    void on_patch_items_checkbox_clicked();

    void on_patch_emotes_checkbox_clicked();

    void on_patch_maps_checkbox_clicked();

    void on_patch_textures_checkbox_clicked();

    void on_patch_loadscreens_checkbox_clicked();

    void on_patch_sounds_checkbox_clicked();

    void on_patch_video_checkbox_clicked();

    void on_patch_force_apply_button_clicked();

    void on_micropatch_checkbox_clicked();

    void on_apply_changes_button_clicked();


private:
    bool patch_operations_running_ = false;

    Ui::SettingsWidget *ui = nullptr;

    PatchList *legacy_patches_ = nullptr;

    SettingsWidgetPrivate::ComboboxScrollingDisabler* combobox_scrolling_disabler = nullptr;
    SettingsWidgetPrivate::SettingsTabsScroller* scroller = nullptr;

    Settings::SettingsBackup settings_backup_;
    bool settings_changed_ = false;
};

#endif // SettingsWidget_H
