/**
© 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.
**/

/* Gestion des animations de la souris et des Widgets Qt. */

#ifndef ANIMQT_H
#define ANIMQT_H

#include <QPoint>
#include <QDialog>
#include <QWidget>
#include <QScreen>
#include <QComboBox>
#include <QTabWidget>
#include <QMenu>
#include <QAction>
#include <QAudioDeviceInfo>

#include "qAudioWave.h"

QScreen *EcranWidget(const QWidget *w);
/* Renvoi l'écran qui contient le QWidget */

QPoint PositionCurseurWidget(const QWidget *w);
/* Renvoi la position du curseur sur l'écran contenant le widget. */

void PeupleCmb_RAL(QComboBox &cmb);
/* Rempli la liste des RAL (choix de la couleur). */

void RedimHWidgetAnim(QWidget *w, int taille);
/* Etirement horizontal d'un widget version animée. */

class KeyPressFilter : public QObject
{
    Q_OBJECT

    public:
        KeyPressFilter();
        ~KeyPressFilter();

    protected:
        bool eventFilter(QObject *obj, QEvent *event);
};

class AnimationQt
{
    public:
        AnimationQt();
        ~AnimationQt();

        Q_DISABLE_COPY(AnimationQt)

        void ConfigurationTempsReference(int tempo);
        /* Configuration du temps de référence qui sépare chaque actions. */

        void ConfigurationSouris(int vitesse_deplacement_px_s, int temps_clic_ms);
        /* Configuration de la souris : Vitesse de déplacement en pixels par secondes, temps du clic en millisecondes */

        void ConfigurationAudio(bool active_bruitages_audio, qreal volume, QAudioDeviceInfo const * peripherique);
        /* Configuration audio des animations. */

        inline bool Anime() const { return !arret_animation; }
        /* L'animation est elle autorisée ? */

        void InitAnimations();
        /* Autorise le démarrage des animations. */

        void AttendFinAnimation();
        /* Bloque l'appelant jusque à la fin de l'animation en cours (si il y en a une) */

        void ArretAnimations();
        /* Interdit les animations. */

        inline int TempoReference() const { return tempo_reference; }
        inline int TempoDeplacementSouris() const { return tempo_deplacement; }

        bool Sommeil(int ms=-1, bool ignore_etat_animation=false) const;

        /*
         * Les fonctions suivantes prennent en argument une valeur 'sommeil_post', qui est un tempo (en millisecondes) après l'exécution de l'animation.
            - Si la valeur vaut < 0, le tempo de référence sera utilisé.
            - Si ça vaut 0, le tempo est ignoré.
            - Pour tout le reste, le tempo sera utilisé suivant la valeur du paramètre.
        */

        bool CurseurPoint(const QPoint &cible, QScreen *ecran=0, int sommeil_post=-1, bool ignore_etat_animation=false) const;
        /* Déplace le curseur à un point donné de l'écran. */

        void ClicPoint(const QCursor *curseur_original=0, int sommeil_post=-1, bool ignore_etat_animation=false) const;
        /* Anime le curseur de la souris pour mettre en évidence un clic (mais ça ne simule pas un véritable clic !) */

        bool CurseurWidget(const QWidget *w, int sommeil_post=-1, bool ignore_etat_animation=false) const;
        /* Déplace le curseur de la souris au centre du QWidget donné en argument. L'interface sera bloquée jusqu'à arriver à destination. */

        bool CurseurMenu(const QMenu *menu, QAction *action, const QMenu *sous_menu=0, int sommeil_post=-1, bool ignore_etat_animation=false) const;
        /* Déplace le curseur de la souris au centre de l'action du menu donné en argument. L'interface sera bloquée jusqu'à arriver à destination. */

        bool DeplaceWidget(QWidget *w, const QPoint &pos, int sommeil_post=-1, bool ignore_etat_animation=false) const;
        /* Déplace un widget à la position absolue donnée en argument. */

        bool DeplaceWidgetCurseur(QWidget *w, int sommeil_post=-1, bool ignore_etat_animation=false) const;
        /* Déplace le widget pour le placer à proximité du curseur. */

        bool ClicWidget(QWidget *w, int sommeil_post=-1, bool ignore_etat_animation=false) const;
        /* Simule le clic sur un QWidget en déplacant le curseur sur sur centre et en animant le curseur. */

        bool ClicMenu(const QMenu *menu, QAction *action, const QMenu *sous_menu=0, int sommeil_post=-1, bool ignore_etat_animation=false) const;
        /* Simule le clic sur une action dans un menu en déplacant le curseur sur sur centre et en animant le curseur. */

        bool ClicTabBar(QTabWidget *w, int id, int sommeil_post=-1, bool ignore_etat_animation=false) const;

        bool LectureAudio(const QString &fichier, qreal volume=-1., const QAudioDeviceInfo *peripherique=0, bool bloque_exec=false) const;
        /* Lecture d'un bruitage audio (lecture du fichier, qui peut être une ressource QRC (doit commencer par "qrc:/").
            Si l'on laisse volume à -1, le volume de la configuration sera utilisé, sinon on force ce volume.
            Si bloque_exec vaut true, le fil d'execution appelant sera bloqué jusqu'à la fin de la lecture. */

        bool TestAudio(qreal volume=-1., const QAudioDeviceInfo *peripherique=0) const;

        inline void defVolumeAudio(qreal d) { volume_audio=d; }
        inline qreal VolumeAudio() const { return volume_audio; }

        /* *** Les fonctions concernant la diction ne font rien si le support de la diction est désactivé. *** */
        void ConfigurationDiction(bool active, int lang_p3d, qreal volume, const QString &chemin_ressources=QString());
        /* Configuration de la diction. */

        bool ValideDiction() const;
        /* Valide l'initialisation de la diction. */

        bool ExecDiction(const QString &texte, int langue, qreal volume=0.75, bool force=false, QAudioDeviceInfo const * peripherique=0) const;
        /* Exécute la synthèse vocale du texte donné en argument. */

        void AttendFinDiction() const;
        /* Attend la fin de la diction en cours. */

        bool ArretDiction() const;
        /* Arrêt de la diction en cours. */

        QString ErreurDiction() const;
        /* Si la diction foiré, renvoi la dernière erreure. */

        QString ErreurAudio() const;
        /* Si l'audio foiré, renvoi la dernière erreure. */

        QString ErreurTestAudio() const;

        /* *************************************************************************************************** */

    private:
        void ArretAnimationsInterne() const;
        bool DeplaceWidgetPoint(QWidget *w, const QPoint &dest, QScreen *ecran, int sommeil_post=-1, bool ignore_etat_animation=false) const;

        const int pas_deplacement;
        int tempo_reference;
        int tempo_deplacement;
        int tempo_clic_souris;
        mutable bool arret_animation;

        bool active_bruitages;
        qreal volume_audio;
        QAudioDeviceInfo const * peripherique_audio;
};

#endif // ANIMQT_H
