#ifndef FLYINGLABELS_H
#define FLYINGLABELS_H

#include <QMainWindow>
#include <QFont>
#include <QIcon>
#include <QErrorMessage>
#include <memory>
#include "probleminstance.h"
#include "instanceobserver.h"
#include "routenetwork.h"
#include "mousehandler.h"
#include "drawoptions.h"
class LabelModel;
class StaticLabeler;
class DynamicLabeling;

namespace Ui {
    class FlyingLabels;
}

class FlyingLabels : public QMainWindow, public InstanceObserver {
    Q_OBJECT

    void instanceHadRouteAdded() { updateGUIforExtraRoutes(); }

public:
    explicit FlyingLabels(QWidget* parent = nullptr);
    ~FlyingLabels();

    FlyingLabels(FlyingLabels const&) = delete;
    FlyingLabels& operator=(FlyingLabels const&) = delete;

public slots:
    void timerTick();

    void updateDrawnNetworkParts();
    void updateDrawnLabelParts();
    void changeLabelFont();

    void displayedStatisticsChanged();

    void playPausePressed();

    void labelModelChanged();
    void staticLabelingAlgorithmChanged();
    void interpolationMethodChanged();

    void trimmingChanged();
    void timeSliderMoved();
    void timestepChanged();
    void simulationDurationChanged();

    void routeSelectionChanged();
    void labelTemplateChanged();
    void airplaneSpeedChanged();
    void interarrivalTimeChanged();
    void arrivalDistributionChanged();
    void applyParametersToAllRoutes();

    void newClicked();
    void openClicked();
    void saveClicked();
    void saveAsClicked();
    void revertClicked();

private:
    void updatePlayPauseButton();
    void updateGUIforExtraRoutes() { updateGUIforRoutes(false); }
    void updateGUIforReplacedRoutes() { updateGUIforRoutes(true); }
    void updateGUIforRoutes(bool completelyNew);
    void applyLabelTemplateToRoute(AirplaneRoute& route);
    void applyAirplaneSpeedToRoute(AirplaneRoute& route);
    void applyInterarrivalTimeToRoute(AirplaneRoute& route);
    void applyArrivalDistributionToRoute(AirplaneRoute& route);
    void applyParametersToRoute(AirplaneRoute& route);

    qreal currentTime() const;
    void resetTime();
    void advanceTimeByOneTick();
    bool atEndTime() const;

    void changeEvent(QEvent* event);
    void showEvent(QShowEvent* event);

    void replaceProblemInstance(QString const& filePath);
    void alignGraphingAreaWithTimeline();

public:
    void redraw();

    void mousePressEvent(QMouseEvent* event, QPointF const& cursor);
    void mouseMoveEvent(QMouseEvent* event, QPointF const& cursor);
    void mouseReleaseEvent(QMouseEvent* event, QPointF const& cursor);

    void resizeEvent(QResizeEvent* event);

    ProblemInstance const& problemInstance() const { return *_instance; }
    ProblemInstance& problemInstance() { return *_instance; }

private:    
    Ui::FlyingLabels* _ui;
    QErrorMessage _errorDialog;
    QIcon _playIcon, _pauseIcon;
    std::unique_ptr<ProblemInstance> _instance;
    MouseHandler _mouseHandler;
    std::unique_ptr<DynamicLabeling> _labeling;
    DrawOptions _drawOptions;
    bool _isPaused;
};

#endif // FLYINGLABELS_H
