/**
© Florian Joncour, 2013-2018 florian@zetta-sys.com

Ce logiciel est un programme informatique faisant interface à la bibliothèque
Perspective3D, un outil de modélisation 3D à partir de vues orthographiques 2D.

Ce logiciel est régi par la licence CeCILL-C soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL-C telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".

En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée.  Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme,  le
titulaire des droits patrimoniaux et les concédants successifs.

A cet égard  l'attention de l'utilisateur est attirée sur les risques
associés au chargement,  à l'utilisation,  à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant  des  connaissances  informatiques approfondies.  Les
utilisateurs sont donc invités à charger  et  tester  l'adéquation  du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.

Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL-C, et que vous en avez accepté les
termes.
**/

/* Objet: Fenêtre de configuration et gestion de l'enregistrement des paramètres. */

#ifndef PARAMETRES_H
#define PARAMETRES_H

#include <QFileDialog>
#include <QDialog>
#include <QCheckBox>
#include <QSettings>
#include <QDir>
#include <QString>
#include <QAbstractButton>
#include <QThread>
#include <QList>

#ifdef SUPPORT_VISION2D
#include "configvision.h"
#endif

#include "interface_texte.h"
#include "qSelectCouleur.h"
#include "documentation.h"

#include "animeQt.h"
#include "API/perspective_api.h"
#include "GL/perspective_gl.h"

//#define PARAMETRES_DOCK /* Si commenté, la configuration sera dans une fenêtre séparée (QDialog). */

namespace Ui { class Parametres; }

enum { TYPE_FICHIER=0, TYPE_DOSSIER, TYPE_DOSSIER_ENREG };
enum { RIEN_FAIRE_DEMARRAGE=0, OUVRIR_PRECEDENT_DEMARRAGE, DIALOGUE_OUVRIR_DEMARRAGE };
enum { EXPORT_DXF_SOLIDE_NUL = 0, EXPORT_DXF_SOLIDE_MESH, EXPORT_DXF_SOLIDE_MESH_GROUPE, EXPORT_DXF_SOLIDE_FACES};

enum { PONGLET_ERGONOMIE=0, PONGLET_DESSIN,
   #ifdef SUPPORT_VISION2D
       PONGLET_VISION2D,
   #endif
       PONGLET_SOLIDE3D, PONGLET_AFFICHAGE3D, PONGLET_EXPORT, PONGLET_PRODUIT };

enum { CONTEXTE_GLSL_MODELE=0, CONTEXTE_GLSL_POST };
enum { COULEUR_3D_FOND, COULEUR_3D_SOMMETS, COULEUR_3D_SEGMENTS, COULEUR_3D_IMPRIMANTE, COULEUR_3D_REPERES_SOMMETS, COULEUR_3D_REPERES_SEGMENTS, COULEUR_3D_REPERES_SURFACES };

class MainWindow;
class QPrinter;

/* Thread pour remplir une QComboBox de la liste des périphériques (ne bloque pas l'interface si le merdier prend un peu de temps). */
class ListePeripheriquesAudio_th : public QThread
{
        Q_OBJECT
    public:
        inline ListePeripheriquesAudio_th(QComboBox *cmb, QList<QAudioDeviceInfo> *liste_perpheriques, const QString &sectionne_peripherique=QString()) :
            selection_perif(sectionne_peripherique), etat_exec(false), cmb_liste_perifs(cmb), liste_perifs(liste_perpheriques)
        {
            ;
        }

        int SelectionPeripheriqueDefaut();
        void run();

        inline void stop() { etat_exec = false; }
        inline bool enCours() const { return etat_exec; }

    signals:
        void Termine();

    private:
        QString selection_perif;
        bool etat_exec;
        QComboBox *cmb_liste_perifs;
        QList<QAudioDeviceInfo> *liste_perifs;
};

#ifdef PARAMETRES_DOCK
class Parametres : public QDockWidget
#else
class Parametres : public QDialog
#endif
{
        Q_OBJECT
    public:

#ifdef PARAMETRES_DOCK
        explicit Parametres(const AnimationQt &anim, Documentation *doc=0, Perspective3D::i18n::lang_p3d_t langue=Perspective3D::i18n::lang_p3d_t::P3D_LANG_EN, QWidget *parent = 0);
#else
        explicit Parametres(const AnimationQt &anim, Documentation *doc=0, Perspective3D::i18n::lang_p3d_t langue=Perspective3D::i18n::lang_p3d_t::P3D_LANG_EN, MainWindow *parent = 0);
#endif

        ~Parametres();

        Q_DISABLE_COPY(Parametres)

        bool LicenceValideP3D();
#ifdef SUPPORT_VISION2D
        bool LicenceValideV2D();
#endif // SUPPORT_VISION2D
        void ParamsPerspective(Perspective3D::ParametresPerspective &parametres_p3d) const;
        bool ForceConfigP3D(const Perspective3D::ParametresPerspective &parametres_p3d);

        void AfficheAide();

        void AssigneParametresGL(PGL::Params_GL &params_gl);
        void AssigneParametresPerspectiveGL(PGL::Params_Perspective_GL &params, const Perspective3D::Perspective &perspective, bool mode_2d=false);
        void AssigneParametresPerspectiveGL(PGL::Params_Perspective_GL &params);

#ifdef SUPPORT_VISION2D
        QRgb R_CouleurTraceVision2D() const;
        double R_TailleGrilleTraceVision2D() const;
        bool AssigneParametresVision2D(Perspective3D::ParametresVision &parametres, int domaine_configuration=ConfigVision::DOMAINE_IMPORT);
        int R_DernierDomaineVision2D() const;
        bool R_AffichageMatriceVision() const;
#endif // SUPPORT_VISION2D

        inline QRgb R_CouleurTrace2D() const
        {
#ifdef SUPPORT_VISION2D
            return R_CouleurTraceVision2D();
#else
            return qRgb(250, 250, 250);
#endif // SUPPORT_VISION
        }

        bool R_AutoriseControleMAJ() const;

        bool R_AutoriseAnimationScripts() const;
        unsigned int R_TempsReferenceAnimation() const;
        unsigned int R_VitesseClicAnimation() const;
        unsigned int R_VitesseCurseurAnimation() const;

        void ForceOnglet(unsigned int id, bool force_animation=false);
        void ForceSousOngletAffichage(int id, bool force_animation=false);
        void AnimeLicence();

        bool R_PremierLancement() const;
        void R_Onglet_Parametres() const;
        void R_TypeConfigAffichage_Parametres() const;
        bool R_AutoriseExport3DAutomate() const;
        bool R_ActiveGLSL() const;
        bool R_ActiveGLSLPost() const;
        bool R_Gen3DVuesAuto() const;
        unsigned int R_IdentRAL3D() const;
        QRgb R_CouleurFond3D() const;
        QRgb R_CouleurFond2D() const;
        QRgb R_CouleurSommets3D() const;
        QRgb R_CouleurSegments3D() const;
        QRgb R_CouleurImprimante3D() const;
        QRgb R_CouleurReperesSommets3D() const;
        QRgb R_CouleurReperesSegments3D() const;
        QRgb R_CouleurReperesFaces3D() const;
        double R_ToleranceDessin() const;
        QString R_CheminExport() const;
        void defNomDernierScript(const QString &n);
        QString R_NomDernierScript() const;
        void defNiveauTolerance(int niveau, int niveau_max); /* Assigne un niveau de tolérance (un entier multiplié par un coefficient prédéfini) */
        int R_ArrondiEntites() const;
        int R_ZoneDessin() const;
        void defEtatApplication(const QByteArray &etat);
        void defGeometrieApplication(const QByteArray &etat);
        QByteArray R_EtatApplication() const;
        QByteArray R_GeometrieApplication() const;
        void defPageDocumentation();
        bool R_PageDocumentation() const;
        int R_TypeInterface() const;
        bool R_InterfaceStandard() const;
        bool R_InterfacePanoramique() const;
        bool R_InterfacePetitEcran() const;
        bool R_ReductionBarreOnglets2D() const;
        bool R_MenuContextuel2D() const;
        unsigned int R_TailleIconesOutils2D() const;
        int R_DivisionsCourbes() const;
        QRectF R_RectSelection(QString nfichier, const char *nom_rect);
        void defRectSelection(QString nfichier, const char *nom_rect, double x, double y, double lg, double ht);
        void SupprRectSelection(QString nfichier, const char *nom_vue);
        void DefPointOrigine(QString nfichier, const char *nom_vue, double x, double y);
        QPointF R_PointOrigine(QString nfichier, const char *nom_vue);
        void SupprPointOrigine(QString nfichier, const char *nom_vue);
        void defFichier_Precedent(const QString &d);
        QString R_Fichier_Precedent() const;
        int R_TailleHistorique() const;
        QStringList R_Historique(int type) const;
        void defAnnule_PremierLancement();
        void defVersion();
        bool ControleVersions() const;
        void defDernierDossier_Ouverture(const QString &d);
        void defDernierDossier_SauvegardeMod(const QString &d);
        QString R_DernierDossier_Ouverture() const;
        QString R_DernierDossier_SauvegardeMod() const;
        Perspective3D::vues2D_t R_Projections() const;
        Perspective3D::infos3d_t R_Informations() const;
        int R_TailleTexte3D() const;
        bool R_PleinEcran() const;
        bool R_IgnoreNonImprimableDXF() const;
        bool R_GenereModeleAuto() const;
        double R_HauteurExtrusion() const;
        double R_ExtrusionFixe() const;
        void defAngleRevolution(double angle);
        double R_AngleRevolution() const;
        double R_RevolutionFixe() const;

        QByteArray R_VertexShader_Courant(unsigned int contexte) const;
        QByteArray R_PixelShader_Courant(unsigned int contexte) const;

        void defTypeExport2DDefaut(const char *nom);
        QString R_TypeExport2DDefaut() const;

        QString R_CreditExport(bool ajout_date=false) const;

        int R_ActionDemarrage() const;
        bool R_RegenModeles_MAJ() const;
        void defHauteurExtrusion(double ht);
        bool R_FilaireUniquement() const;
        void defFilaireUniquement(bool etat);
        void defMultiThreading(bool etat);
        Perspective3D::params_gen3d_t R_ParametresGen3D() const;
        unsigned int R_TailleSurfaces() const;

        void defAfficheProprietes3D(bool etat);
        bool R_AfficheProprietes3D() const;

        unsigned int R_ValeurEchelleUniforme() const;
        bool R_ActiveEchelleUniforme() const;

        const QCheckBox *Chk_FilaireUniquement();
        int R_OpaciteSolide() const;

        bool R_EclairageDeuxFaces() const;

        bool R_AfficheAccrochage3D() const;

        Perspective3D::params_export_dxf_t R_ParametresExportDXF() const;

        bool R_ExportCouleurCollada() const;
        bool R_GroupeSolidesOBJ() const;
        bool R_CompressionZIPAMF() const;

        QString R_TypeExport3DDefaut() const;
        bool R_Export3DFilaireDXF() const;
        int R_TypeExportSolideDXF() const;

        bool R_MultiThreading() const;

        bool R_ExportConfig3DScripts() const;

        QString R_CleeActivationQStr();
        const pint8 *R_CleeActivation();
        puint64 R_SalageActivation();
        void GenCodeBarreCle();
        Perspective3D::normevues_t R_NormeVues2D() const;

        bool R_EclairageScene() const;

        bool R_AffichageOrthographique() const;
        bool R_LissageAffichage3D() const;

        bool R_AfficheZoneImpression3D() const;
        unsigned int R_TailleZoneImpression3D_X() const;
        unsigned int R_TailleZoneImpression3D_Y() const;
        unsigned int R_TailleZoneImpression3D_Z() const;

        bool R_Export2DVignette() const;
        unsigned int R_TailleVignetteExport2D() const;

        void DefSepareSolidesSTL();
        bool R_SepareSolidesSTL() const;

        void defAfficheAccrochage3D();
        void defTypeInterface(int force_etat);

        QFileDialog::ViewMode R_TypeAffichageOuvrir() const;
        void defTypeAffichageOuvrir(QFileDialog::ViewMode);

        void defConfigurationImprimante(const QPrinter *imprimante);
        void ConfigurationImprimante(QPrinter *imprimante) const;

        unsigned int R_IndexRAL() const;
        unsigned int R_TypeAffichage3D();

        bool R_ActiveBruitagesAudio() const;
        bool R_ActiveSyntheseVocale() const;
        int R_LangueAudio() const;
        int R_VolumeAudio() const; /* Volume audio 0 -> 100 */
        qreal R_VolumeAudioD() const; /* Volume audio 0.0 -> 1.0 */
        QString R_NomPeripheriqueAudio(bool fin_thread=false) const;
        const QAudioDeviceInfo *R_PeripheriqueAudio();

        int R_TempoShadersPost() const;

        bool R_SavGeometrieFenetre();

        void defPleinEcran(int force_valeur=-1);
        void defGeometrie(const QString &nom, const QWidget *w);
        bool R_Geometrie(const QString &nom, QWidget *w);

    private:
        void InitVals(); /* Chargement de la configuration */
        void ValideVals(); /* Enregistrement d'une nouvelle configuration */
        void ReinitVals(bool general=false); /* Restauration des paramètres par défaut. */
        bool FermetureDocumentation();
        void PeupleCmbContexteGLSL(unsigned int contexte);

        void defAutoriseControleMAJ();

#ifdef SUPPORT_VISION2D
        void defDernierDomaineVision2D();
        int R_DernierParamV2D() const;
        void defDernierParamV2D();
        void InitParametresVision(int domaine=ConfigVision::DOMAINE_NUL);
        bool ReinitParametresVision(int domaine, int id_page_parametres);
        void ValideParametresVision();
#endif // SUPPORT_VISION2D

        Perspective3D::params_gen3d_t GenIdentifiantParams3d() const;
        void MiseAJourIdsParams3D();

        bool ControleLicenceValide(bool reinit_params=false);

        void defAnimationScript();
        void defTempsReferenceAnimation();
        void defVitesseClicAnimation();
        void defVitesseCurseurAnimation();

        void defActiveBruitagesAudio();
        void defActiveSyntheseVocale();
        void defLangueAudio();
        void defVolumeAudio();
        void defNomPeripheriqueAudio();

        void defTempoShaderPost();

        void defSavGeometrieFenetre();

        void defPositionParametres();
        void R_PositionParametres();

        int R_IdShader_Courant(unsigned int contexte) const;
        int R_ContexteShader_Courant() const;

        void defCheminExport(const QString &ch);
        void defToleranceDessin(double d);
        void defZoneDessin(int i);
        void defOnglet_Parametres();
        void defTypeConfigAffichage_Parametres();
        void defActiveGLSL();
        void defIdShader_Courant(unsigned int contexte);
        void defContexteShader_Courant();
        void defIdentRAL3D(int force_valeur = -1);
        void defCouleurFond3D(QRgb couleur);
        void defCouleurSommets3D(QRgb couleur);
        void defCouleurSegments3D(QRgb couleur);
        void defCouleurImprimante3D(QRgb couleur);
        void defCouleurReperesSommets3D(QRgb couleur);
        void defCouleurReperesSegments3D(QRgb couleur);
        void defCouleurReperesFaces3D(QRgb couleur);
        void defTypeAffichage3D();
        void defGen3DVuesAuto();
        void defDivisionsCourbes(int force_valeur = -1);
        void defProjections(int force_valeur = -1);
        void defInformations(int force_valeur = -1);
        void defTailleTexte3D(int force_valeur = -1);
        void defParametresGen3D(int force_valeur = -1);
        void defTailleSurfaces(int force_valeur = -1);
        void defNormeVues2D(int force_valeur = -1);
        void defValeurEchelleUniforme(int force_valeur = -1);
        void defActiveEchelleUniforme(int force_valeur = -1);
        void defExtrusionFixe();
        void defRevolutionFixe();
        void defActionDemarrage();
        void defRegenModele_MAJ();
        void defOpaciteSolide();
        void defTypeExport3DDefaut();
        void defExport3DFilaireDXF();
        void defTypeExportSolideDXF();
        void defExportCouleurCollada();
        void defGroupeSolidesOBJ();
        void defCompressionZIPAMF();
        void defCleeActivation(const pint8 *cle);
        void defSalageActivation();
        void defIgnoreNonImprimableDXF();
        void defTypeInterface();

        void defExportConfig3DScripts();
        void defCreditExport();

        void defExport2DVignette();
        void defTailleVignetteExport2D();

        void defFilaireUniquement();
        void defMultiThreading();

        void defArrondiEntites(int i);

        void defEclairageDeuxFaces();
        void defEclairageScene();
        void defAffichageOrthographique();
        void defLissageAffichage3D();
        void defZoneParamsImprimable3D();

        void defVertexShader_Perso();
        void defPixelShader_Perso();

        QByteArray R_VertexShader_Perso(int id, unsigned int contexte) const;
        QByteArray R_PixelShader_Perso(int id, unsigned int contexte) const;

        QByteArray VertexShader_Id(int id, unsigned int contexte) const;
        QByteArray PixelShader_Id(int id, unsigned int contexte) const;

        void defHistorique(const QString &a, int type);

        /* Cas particuliers, non configurables depuis la fenêtre de configuration... */
        void defGenereModeleAuto(bool etat=false);
        void defTailleHistorique(int n);
#ifdef SUPPORT_VISION2D
        void defAffichageMatriceVision(bool etat);
#endif // SUPPORT_VISION2D
        /* ************************************************************************* */

    private slots:
        void NouvelleCouleur3D(QRgb couleur);
        void closeEvent(QCloseEvent * ev);
        void showEvent(QShowEvent *ev);
        void moveEvent(QMoveEvent *ev);

        void on_buttonBox_clicked(QAbstractButton *button);
        void on_spb_arrondi_valueChanged(int arg1);
        void on_chk_exportfilaire_toggled(bool checked);
        void on_pb_chemin_export_clicked();
        void on_chk_fixe_extrusion_clicked(bool checked);
        void on_chk_fixe_revolution_clicked(bool checked);
        void on_spb_divisionsellipses_valueChanged(int arg1);
        void on_spb_divisionsellipses_editingFinished();
        void on_cmb_norme_vues_currentIndexChanged(int index);
        void on_pb_aboutqt_clicked();
        void on_pb_detail_licence_clicked();
        void on_pb_licenceP3D_clicked();
        void on_pb_licenceCeCILL_C_clicked();
        void on_buttonBox_helpRequested();
        void on_pb_entree_cle_clicked();
        void on_chk_zone_impression3d_clicked();
        void on_tabWidget_currentChanged(int index);
        void on_cmb_typeexport_currentIndexChanged(const QString &arg1);
        void on_chk_projections_vues_clicked(bool checked);
        void on_chk_proj_face_clicked();
        void on_chk_proj_cote_clicked();
        void on_chk_proj_haut_clicked();
        void on_chk_autorise_anim_scripts_stateChanged(int arg1);

#ifdef SUPPORT_VISION2D
        void SelectionDomaineParametresV2D(int);
#endif // SUPPORT_VISION2D

        void on_dspb_animation_temps_reference_valueChanged(double arg1);
        void on_dspb_animation_duree_clic_valueChanged(double arg1);
        void on_chk_mode_vignette_stateChanged(int arg1);
        void on_chk_echelle_uniforme_clicked(bool checked);

        void on_cmb_langue_synthese_vocale_activated(int index);
        void on_pb_test_audio_clicked();
        void on_vslide_volume_audio_valueChanged(int value);
        void on_cmb_type_config_affichage_currentIndexChanged(int index);

        void on_chk_glsl_toggled(bool checked);
        void on_lw_liste_progs_glsl_currentRowChanged(int currentRow);
        void on_pted_glsl_vertex_cursorPositionChanged();
        void on_pted_glsl_frag_cursorPositionChanged();
        void on_pb_enregistre_shader_clicked();
        void on_pb_reinit_shaders_clicked();
        void on_cmb_contexte_glsl_currentIndexChanged(int index);

        void on_lw_couleurs_3d_currentRowChanged(int currentRow);
        void on_led_ids_params_textEdited(const QString &arg1);

        void on_chk_suppr_lignes_orphelines_clicked();
        void on_chk_suppr_segments_alignes_clicked();
        void on_chk_suppr_lignes_croisement_plan_clicked();
        void on_chk_suppr_chevauchement_lignes_clicked();
        void on_chk_suppr_croisement_lignes_clicked();
        void on_chk_conservation_ents_clicked();
        void on_chk_division_surfaces_clicked();
        void on_chk_controle_coherence_clicked();
        void on_chk_suppr_surfaces_meme_plan_clicked();
        void on_chk_suppr_surfaces_col_lignes_clicked();
        void on_cmb_type_interface_currentIndexChanged(int index);

        void on_pted_glsl_frag_textChanged();
        void on_pted_glsl_vertex_textChanged();

    signals:
        void FermetureParametres();
        void ValideParametres(bool nouveaux_shaders);
        void NouvelleLicence();

    private:
        inline void ForgeBoutonAide(QHBoxLayout *conteneur, const char *url)
        {
            BoutonAide *bt_aide_x = new BoutonAide(documentation, url);
            bt_aide_x->setObjectName("aide");
            conteneur->insertWidget(0, bt_aide_x);
            BoutonsAide.push_back(bt_aide_x);
        }

        Ui::Parametres *ui;
#ifdef SUPPORT_VISION2D
        ConfigVision conf_vision;
#endif // SUPPORT_VISION2D

        bool ignore_etat_onglets;
        bool etat_init;
        const AnimationQt &animation;
        Documentation *documentation;
        std::vector<BoutonAide*> BoutonsAide;

#ifdef PARAMETRES_DOCK
        QWidget *MainApp;
#else
        MainWindow *MainApp;
#endif
        ListePeripheriquesAudio_th *th_liste_peripheriques;
        QList<QAudioDeviceInfo> liste_peripheriques_audio;
        QAudioDeviceInfo peripherique_audio;

        QSelectCouleur select_couleurs;

        bool change_shader;

        InterfaceTexte *liste_licences, *detail_licence_cecill_c ,*detail_licence_p3d;
        QSettings *Settings;
        int MaxArrondi;
        bool InitLicence_P3D;
        bool InitLicence_V2D;
        bool LicenceValide_P3D;
        bool LicenceValide_V2D;
        pint8 Licence[64]; /* Clé d'activation chiffrée. */
};

#endif // PARAMETRES_H
