/*
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                 ┃
┃            Class Name: GraphTest.h                                                              ┃
┃                Author: Michael Krämer                                                           ┃
┃                 Email: Michael@dk8pp.de                                                         ┃
┃                  Date: 27.11.2024 13:25:54                                                      ┃
┃                  Tool: Qt                                                                       ┃
┃                Device: Windows/Linux                                                            ┃
┃               Version: 0.1                                                                      ┃
┃        Program status: still testing                                                            ┃
┃                                                                                                 ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃                                                                                                 ┃
┃  Purpose: Test Qt Graphics View Framework                                                       ┃
┃                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

/*
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│       Includes                                                                                  │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯
*/
#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsSceneWheelEvent>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsEllipseItem>
#include <QDoubleSpinBox>
#include <QTimer>
#include <QPainter>
#include <QPaintDevice>
#include <QPainterPath>
#include <QQuickWidget>
#include <QGraphicsSimpleTextItem>
#include <QMenu>
#include <QFont>
#include <QSettings>
//#include <cmath>
#include <complex>

/*
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│       Defines                                                                                   │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯
*/
#define OrganizationName QString("DK8PP Freeware")
#define ApplicationName QString("GraphTest") /* for registry */
#define KEY_PGM QString("Program/")
#define _USE_MATH_DEFINES
#define Z0 50.0         /* real part of reference impedance */

/*
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                 ┃
┃  Class definitions                                                                              ┃
┃                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
*/

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

/*
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│       gpItem                                                                                    │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯
*/
class gpItem : public QObject, public QGraphicsPathItem
{
    Q_OBJECT

protected:
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override ;
    void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override ;

signals:
    void markerDragged(QPointF pos) ;
} ;

/*
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│       GraphicsScene                                                                             │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯
*/
class GraphicsScene : public QGraphicsScene
{
    Q_OBJECT

public:
    GraphicsScene() ;
    void drawscene();
    void print(const QString& text, QFont *font, QBrush *brush, qreal posx, qreal posy) ;
    QGraphicsEllipseItem *swr_item = nullptr ;
    QGraphicsView *gview = nullptr ;
    void setSWR(qreal newswr) ;
    qreal getSWR() const ;
    gpItem *markeritem = nullptr ;

protected:

private:
    QPoint mouse_pos = QPoint(0,0) ;
    QPoint curr_pos = QPoint(0,0) ;
    QPoint prev_pos = QPoint(0,0) ;
    QGraphicsItem *selected_item = nullptr ;
    std::complex<double> z0 = {Z0, 0.0} ;          /* complex reference impedance */
    QPainterPath cross;
    QPainterPath marker;
    QPainterPath gridline ;
    QGraphicsSimpleTextItem *item = nullptr ;
    qreal swr = 3.0 ;

} ;

/*
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│       MainWindow                                                                                │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯
*/
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void MyInit();
    void updateMarker();
    void updateZL();
    void updateSlider();
    void updateSWR() const;
    void read_spb();
    GraphicsScene *scene = nullptr;
    QGraphicsView *graphics_view ;

public slots:
    void zoomIn();
    void zoomOut();
    void zoomAll();
    void center();
    void setZLR(int value);
    void setZLX(int value) ;
    void ZLupdated();
    void markerDragged(QPointF pos);

protected:
    void resizeEvent(QResizeEvent *event) override ;
    void paintEvent(QPaintEvent *event) override ;
    void wheelEvent(QWheelEvent *event) override ;

private:
    void calcGamma(std::complex<double> *gamma, std::complex<double> *impedance) ;
    void calcZ(std::complex<double> *impedance, std::complex<double> *gamma) ;
    std::complex<double> z0 = {Z0, 0.0} ;          /* complex reference impedance */
    std::complex<double> zl = {Z0, 0.0} ;          /* complex load impedance */
    std::complex<double> complex_1 = {1.0, 0.0} ;  /* complex constant: 1+i0 */
    std::complex<double> gamma = {0.0, 0.0} ;      /* complex gamma */
    Ui::MainWindow *ui;
    bool updating_ZL = false ;
    QPoint mouse_pos = QPoint(0,0) ;
    QPoint curr_pos = QPoint(0,0) ;
    QPoint prev_pos = QPoint(0,0) ;
    QGraphicsItem *selected_item = nullptr;
    void loadSettings() ;
    void saveSettings() ;
    bool init_completed = false ;
} ;

#endif // MAINWINDOW_H
