#include "main_window.hh"

#include <QApplication>
#include <QFile>
#include <QFileDialog>
#include <QJsonDocument>
#include <QStyle>
#include <QDockWidget>


MainWindow::MainWindow(QWidget *parent) {
	(void) parent;
	connect(&glw, &OpenGLWidget::initialized,
			this, &MainWindow::onOpenGLWidgetInitialized);
	// connect(&timer, &QTimer::timeout, this, &MainWindow::step);
	setCentralWidget(&glw);
	addToolBar(Qt::TopToolBarArea, &top_tb);
	open_action = top_tb.addAction("Ouvrir…", [&]() {
		open(QFileDialog::getOpenFileName(this, "Ouvrir un fichier JSON"));
	});
	open_action->setEnabled(false);
	addToolBar(Qt::BottomToolBarArea, &bottom_tb);
	playpause_action = bottom_tb.addAction(style()->standardIcon(QStyle::SP_MediaPlay), "",
										   this, &MainWindow::play);
	playpause_action->setEnabled(false);
	slider = new QSlider(Qt::Horizontal);
	bottom_tb.addWidget(slider);
	slider->setEnabled(false);

	QDockWidget *dock = new QDockWidget("Outils", this);
	dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
	settings_pane = new SettingsPane();
	settings_pane->setEnabled(false);
	dock->setWidget(settings_pane);
	addDockWidget(Qt::RightDockWidgetArea, dock);
}


void MainWindow::play() {
	dc->play();
	playpause_action->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
	disconnect(playpause_action, &QAction::triggered, nullptr, nullptr);
	connect(playpause_action, &QAction::triggered, this, &MainWindow::pause);
}


void MainWindow::pause() {
	dc->pause();
	playpause_action->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
	disconnect(playpause_action, &QAction::triggered, nullptr, nullptr);
	connect(playpause_action, &QAction::triggered, this, &MainWindow::play);
}


void MainWindow::open(const QString &path) {
	QFile file(path);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning("Impossible d’ouvrir le fichier.");
        return;
    }
    QByteArray data = file.readAll();
    QJsonDocument json_doc = QJsonDocument::fromJson(data);
	if (dc) delete dc;
	glw.meshes.clear();
	dc = new DroneController(json_doc.object());

	// Play/Pause button
	connect(dc, &DroneController::playing, this, &MainWindow::play);
	connect(dc, &DroneController::pausing, this, &MainWindow::pause);
	playpause_action->setEnabled(true);

	// Seekbar slider
	slider->setMinimum(0);
	slider->setMaximum(dc->getDuration());
	slider->setValue(0);
	connect(slider, &QSlider::sliderPressed, dc, &DroneController::suspend);
	connect(slider, &QSlider::sliderReleased, dc, &DroneController::resume);
	connect(slider, &QSlider::valueChanged, dc, &DroneController::seek);
	connect(dc, &DroneController::frameChanged, slider, &QSlider::setValue);
	slider->setEnabled(true);

	// Settings pane
	connect(settings_pane, &SettingsPane::collisionClicked,
			slider, &QSlider::setValue);
	connect(dc, &DroneController::collision, settings_pane, &SettingsPane::addCollision);
	connect(settings_pane, &SettingsPane::sphereRadiusChanged,
			[&](double _) { settings_pane->clearCollisions(); });
	connect(settings_pane, &SettingsPane::sphereRadiusChanged,
			dc, &DroneController::computeCollisions);
	connect(settings_pane, &SettingsPane::sphereRadiusChanged,
			dc, &DroneController::displaySpheres);
	connect(settings_pane, &SettingsPane::toggledTrajectories,
			dc, &DroneController::setDrawTrajectories);
	connect(settings_pane, &SettingsPane::toggledGuides,
			dc, &DroneController::setDrawGuides);
	settings_pane->setEnabled(true);

	glw.setPainter(dc);
	pause();
}


void MainWindow::onOpenGLWidgetInitialized() {
	if (qApp->arguments().size() == 2) {
		open(qApp->arguments().at(1));
	}
	open_action->setEnabled(true);
}
