// Fichier OnSwipeTouchListener.java
/**
 * Listener de vue personnalisé qui détecte les gestes de balayage (swipe)
 * dans les quatre directions cardinales et notifie un listener externe.
 * Utilise {@link GestureDetector} pour l'analyse des gestes.
 */
package legion.muyue.best2048;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;

public class OnSwipeTouchListener implements View.OnTouchListener {

    /** Détecteur de gestes standard d'Android. */
    private final GestureDetector gestureDetector;
    /** Listener externe à notifier lors de la détection d'un swipe. */
    private final SwipeListener listener;

    /**
     * Interface à implémenter par les classes souhaitant réagir aux événements de swipe.
     */
    public interface SwipeListener {
        /** Appelée lorsqu'un swipe vers le haut est détecté. */
        void onSwipeTop();
        /** Appelée lorsqu'un swipe vers le bas est détecté. */
        void onSwipeBottom();
        /** Appelée lorsqu'un swipe vers la gauche est détecté. */
        void onSwipeLeft();
        /** Appelée lorsqu'un swipe vers la droite est détecté. */
        void onSwipeRight();
    }

    /**
     * Constructeur.
     * @param context Contexte applicatif, nécessaire pour `GestureDetector`.
     * @param listener Instance qui recevra les notifications de swipe. Ne doit pas être null.
     */
    public OnSwipeTouchListener(Context context, @NonNull SwipeListener listener) {
        this.gestureDetector = new GestureDetector(context, new GestureListener());
        this.listener = listener;
    }

    /**
     * Intercepte les événements tactiles sur la vue associée et les délègue
     * au {@link GestureDetector} pour analyse.
     * @param v La vue touchée.
     * @param event L'événement tactile.
     * @return true si le geste a été consommé par le détecteur, false sinon.
     */
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // Passe l'événement au GestureDetector. Si ce dernier le gère (ex: détecte un onFling),
        // il retournera true, et l'événement ne sera pas propagé davantage.
        return gestureDetector.onTouchEvent(event);
    }

    /**
     * Classe interne implémentant l'écouteur de gestes pour détecter le 'fling' (balayage rapide).
     */
    private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

        /** Distance minimale (en pixels) pour qu'un mouvement soit considéré comme un swipe. */
        private static final int SWIPE_THRESHOLD = 100;
        /** Vitesse minimale (en pixels/sec) pour qu'un mouvement soit considéré comme un swipe. */
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        /**
         * Toujours retourner true pour onDown garantit que les événements suivants
         * (comme onFling) seront bien reçus par ce listener.
         */
        @Override
        public boolean onDown(@NonNull MotionEvent e) {
            return true;
        }

        /**
         * Appelée quand un geste de 'fling' (balayage rapide) est détecté.
         * Analyse la direction et la vitesse pour déterminer s'il s'agit d'un swipe valide
         * et notifie le {@link SwipeListener} externe.
         */
        @Override
        public boolean onFling(MotionEvent e1, @NonNull MotionEvent e2, float velocityX, float velocityY) {
            if (e1 == null) return false; // Point de départ est nécessaire

            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();

                // Priorité au mouvement le plus ample (horizontal ou vertical)
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    // Mouvement principalement horizontal
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            listener.onSwipeRight();
                        } else {
                            listener.onSwipeLeft();
                        }
                        result = true; // Geste horizontal traité
                    }
                } else {
                    // Mouvement principalement vertical
                    if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            listener.onSwipeBottom();
                        } else {
                            listener.onSwipeTop();
                        }
                        result = true; // Geste vertical traité
                    }
                }
            } catch (Exception exception) {
                // En cas d'erreur inattendue, on logue discrètement.
                System.err.println("Erreur dans OnSwipeTouchListener.onFling: " + exception.getMessage());
                // Ne pas crasher l'application pour une erreur de détection de geste.
            }
            return result;
        }
    }
} // Fin OnSwipeTouchListener