/*
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                 ┃
┃            Class Name: GammaSmith.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: Display Gamma-/Smith-chart                                                            ┃
┃                                                                                                 ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃                                                                                                 ┃
┃  © Copyright 2025 Michael Krämer, DK8PP                                                         ┃
┃                                                                                                 ┃
┃  This program is free software: you can redistribute it and/or modify it under the terms of     ┃
┃  the GNU Lesser 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 Lesser General Public License for more details.                                    ┃
┃                                                                                                 ┃
┃  You should have received a copy of the GNU Lesser General Public License along with this       ┃
┃  program.   If not, see <http://www.gnu.org/licenses/>.                                         ┃
┃                                                                                                 ┃
┃  ============================================================================================   ┃
┃                                                                                                 ┃
┃  Dieses Programm ist Freie Software: Sie können es unter den Bedingungen der GNU Lesser         ┃
┃  General Public License, wie von der Free Software Foundation, Version 3 der Lizenz oder        ┃
┃  (nach Ihrer Wahl) jeder neueren veröffentlichten Version, weiter verteilen und/oder            ┃
┃  modifizieren.                                                                                  ┃
┃                                                                                                 ┃
┃  Dieses Programm wird in der Hoffnung bereitgestellt, dass es nützlich sein wird, jedoch OHNE   ┃
┃  JEDE GEWÄHR,; sogar ohne die implizite Gewähr der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN        ┃
┃  BESTIMMTEN ZWECK. Siehe die GNU Lesser General Public License für weitere Einzelheiten.        ┃
┃                                                                                                 ┃
┃  Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit diesem Programm      ┃
┃  erhalten haben. Wenn nicht, siehe <https://www.gnu.org/licenses/>.                             ┃
┃                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
*/
#ifndef GAMMASMITH_H
#define GAMMASMITH_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 <complex>
#include "SmithBasics.h"
#include "infodialog.h"

/*
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│       Defines                                                                                   │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯
*/
/* definitions for registry */
#define OrganizationName QString("DK8PP Freeware")
#define ApplicationName QString("GammaSmith")
#define KEY_PGM QString("Program/")
#define KEY_SMITH QString("SmithChart/")

/* program information */
#define PURPOSE "Purpose: Learn how a Smith-Chart works,\n" +\
                "blend between Smith Chart and reflection coefficent Gamma\n\n"
#define PROGRAMVERSION 90               /* will be displayed as n.nn */
#define AUTHOR "Michael Krämer, DK8PP"
#define COPYRIGHT " Copyright © 2024-2025 "
#define COPYRIGHTDETAILS "\nThis program comes with ABSOLUTELY NO WARRANTY;\n" \
                         "This is free software, and you are welcome to redistribute it under certain conditions.\n" \
                         "Press the LGPL button for details.\n\n"
#define VERSION_STRING (" - Version " + QString::number(PROGRAMVERSION/100) + "." + QString::number(PROGRAMVERSION%100).rightJustified(2,'0'))
#define COMPILE_DT (QString("compiled on ") + __DATE__ + ", " + __TIME__)

#define PROGRAM_INFO \
           ApplicationName + VERSION_STRING + ", " + COMPILE_DT + "\n\n" + \
           PURPOSE + ApplicationName + COPYRIGHT + AUTHOR + COPYRIGHTDETAILS + \
           "for updates check: http://freeware.dk8pp.de/ or email to: Michael@dk8pp.de"

#define CHAR_CAP_GAMMA "Γ"      /* capital letter Gamma */
#define CHAR_CAP_OMEGA "Ω"      /* capital letter Omega */

#define MIN_X 1.0e-1    /* minimum impedance for sliders (100 mΩ) */
#define MAX_X 1.0e3     /* maximum impedance for sliders (1 kΩ) */

#define _USE_MATH_DEFINES
constexpr int swr_circle_count = 3 ; /* count of SWR circles */
constexpr int RES_COUNT = 200 ; /* count of resistance values for slider movement */

/* update request for Line Edits and Spin Boxes */
#define UPD_BASE         0x1  /* base for subsequent definitions */
#define UPD_LED_R       (UPD_BASE <<  0)        /* update Impedance R Line Edit */
#define UPD_LED_X       (UPD_BASE <<  1)        /* update Impedance X Line Edit */
#define UPD_LED_G       (UPD_BASE <<  2)        /* update Admittace G Line Edit */
#define UPD_LED_B       (UPD_BASE <<  3)        /* update Admittace B Line Edit */
#define UPD_LED_RP      (UPD_BASE <<  4)        /* update RLC parallel R Line Edit */
#define UPD_LED_XP      (UPD_BASE <<  5)        /* update RLC parallel X Line Edit */
#define UPD_LED_RS      (UPD_BASE <<  6)        /* update RLC serial R Line Edit */
#define UPD_LED_XS      (UPD_BASE <<  7)        /* update RLC serial X Line Edit */
#define UPD_LED_GAMMAR  (UPD_BASE <<  8)        /* update Gamma R Line Edit */
#define UPD_LED_GAMMAI  (UPD_BASE <<  9)        /* update Gamma I Line Edit */
#define UPD_LED_GAMMAM  (UPD_BASE << 10)        /* update Gamma M Line Edit */
#define UPD_LED_GAMMAP  (UPD_BASE << 11)        /* update Gamma P Line Edit */
#define UPD_LED_Z0      (UPD_BASE << 12)        /* update Z0 Line Edit */
#define UPD_LED_FREQ    (UPD_BASE << 13)        /* update Frequency Line Edit */
#define UPD_SPB_SWR1    (UPD_BASE << 14)        /* update SWR1 Spin Box */
#define UPD_SPB_SWR2    (UPD_BASE << 15)        /* update SWR2 Spin Box */
#define UPD_SPB_SWR3    (UPD_BASE << 16)        /* update SWR3 Spin Box */
#define UPD_QS_R        (UPD_BASE << 17)        /* update R Slider */
#define UPD_QS_X        (UPD_BASE << 18)        /* update X Slider */
#define UPD_QS_G        (UPD_BASE << 19)        /* update G Slider */
#define UPD_QS_B        (UPD_BASE << 20)        /* update B Slider */
#define UPD_QS_RP       (UPD_BASE << 21)        /* update RP Slider */
#define UPD_QS_XP       (UPD_BASE << 22)        /* update XP Slider */
#define UPD_QS_RS       (UPD_BASE << 23)        /* update RS Slider */
#define UPD_QS_XS       (UPD_BASE << 24)        /* update XS Slider */
#define UPD_QS_OPACITY  (UPD_BASE << 25)        /* update Opacity Slider */
#define UPD_QS_F        (UPD_BASE << 26)        /* update Frequency Slider */
#define UPD_UI_ALL (UPD_LED_R      | UPD_LED_X      | UPD_LED_G      | UPD_LED_B      \
                  | UPD_LED_RP     | UPD_LED_XP     | UPD_LED_RS     | UPD_LED_XS     \
                  | UPD_LED_GAMMAR | UPD_LED_GAMMAI | UPD_LED_GAMMAM | UPD_LED_GAMMAP \
                  | UPD_LED_Z0     | UPD_LED_FREQ                                     \
                  | UPD_SPB_SWR1   | UPD_SPB_SWR2   | UPD_SPB_SWR3                    \
                  | UPD_QS_R       | UPD_QS_X       | UPD_QS_G       | UPD_QS_B       \
                  | UPD_QS_RP      | UPD_QS_XP      | UPD_QS_RS      | UPD_QS_XS      \
                  | UPD_QS_OPACITY | UPD_QS_F)

/*
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│       structs and enums                                                                         │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯
*/

/* conversion result */
typedef struct conversion
               {QString str ;                   /* string to be decoded and returned */
                QString deflt ;                 /* default if input empty */
                qreal value ;                   /* result value if no error */
                bool required ;                 /* required field, return error if empty */
                bool positive ;                 /* value must be positive */
                bool empty ;                    /* true if input string is empty */
                bool relative ;                 /* true if relative value was specified, e.g. % */
                bool error ;                    /* true on conversion error or missing required input */
               } CONVERSION ;

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

QT_BEGIN_NAMESPACE
namespace Ui {
class GammaSmith;
}
QT_END_NAMESPACE

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

public:
   MainWindow(QWidget *parent = nullptr);
   ~MainWindow();
   void read_spb();
   void open_smith() ;
   void close_smith() ;
   bool useLocale = true ;                              /* use locale */

public slots:

protected:
   void resizeEvent(QResizeEvent *event) override ;
   void closeEvent(QCloseEvent *event) override ;

private slots:
   void on_PUB_Info_clicked();
   void QS_setR(int value);
   void QS_setX(int value) ;
   void QS_setG(int value);
   void QS_setB(int value) ;
   void QS_setRP(int value);
   void QS_setXP(int value);
   void QS_setRS(int value);
   void QS_setXS(int value);
   void QS_setF(int value) ;
   void LED_setZ0();
   void LED_setRX();
   void LED_setGB();
   void LED_setF() ;
   void LED_setRP() ;
   void LED_setRS() ;
   void LED_setXP() ;
   void LED_setXS() ;
   void LED_setGammaR() ;
   void LED_setGammaI() ;
   void LED_setGammaM() ;
   void LED_setGammaP() ;
   void NewGamma(complex_dbl new_gamma) ;

private:
   void updateLE(uint sel) ;
   void updateSlider(uint sel) ;
   std::complex<qreal> z0 = {Z0R_DEFAULT, 0.0} ;       /* complex reference impedance */
   std::complex<qreal> gamma = {0.0, 0.0} ;            /* complex gamma */
   qreal freq = NAN ; /* in Hz */
   qreal r_par = NAN ; /* R for parallel configuration, copy of LED_RP value */
   qreal x_par = NAN ; /* X for parallel configuration, impedance of LED_XP value for current frequency */
   qreal r_ser = NAN ; /* R for serial configuration, copy of LED_RS value */
   qreal x_ser = NAN ; /* X for serial configuration, impedance of LED_XS value for current frequency */
   Ui::GammaSmith *ui;
   bool updating_ZL = false ;
   bool updating_F = false ;
   void loadSettings() ;
   void saveSettings() ;
   void Init_Controls() ;
   void opacity(int value) ;
   std::array <qreal,swr_circle_count> swr = {1.0, 1.0, 1.0} ; /* SWR circles */
   std::array <qreal, RES_COUNT> reslist ;
   QString ProgramInfo = PROGRAM_INFO ;
   QString CapToStr(qreal val) ;
   QString IndToStr(qreal val) ;
   QString ResToStr(qreal val, int prec, bool imag) ;
   QString ResToStr(qreal val, int prec) {return(ResToStr(val,prec,false)) ;}
   QString FrqToStr(qreal val) ;
   void F_setQS() ;
   void zFromGamma(std::complex<qreal> *z, std::complex<qreal> *gamma, std::complex<qreal> *z0)
        {*z = *z0 * (complex_1+*gamma)/(complex_1-*gamma) ;}
   void gammaFromZ(std::complex<qreal> *z, std::complex<qreal> *gamma, std::complex<qreal> *z0)
        {*gamma = (*z - *z0)/(*z + *z0) ;}
   CONVERSION *get_double(CONVERSION *conv) ;
   QString LE_default_style ;
   QString LE_error_style = "color: Red;" ;

} ;

#endif // GAMMASMITH_H
