From 5775b6555d7c0c724eb72c47faa630f18a6eb528 Mon Sep 17 00:00:00 2001
From: Vincent <vincent.teissier@etu.u-pec.fr>
Date: Fri, 25 Oct 2024 00:28:51 +0200
Subject: [PATCH] =?UTF-8?q?d=C3=A9composition=20en=20MVC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/controller/CameraController.java     | 52 ++++++++++++
 src/main/java/controller/GameContext.java     | 21 +++++
 src/main/java/controller/GameController.java  | 53 +++++++-----
 .../java/controller/HexagonMouseListener.java | 14 +++-
 .../java/controller/MouseDragHandler.java     | 80 +++++++++++++++++++
 .../java/controller/MousePressHandler.java    | 64 +++++++++++++++
 6 files changed, 262 insertions(+), 22 deletions(-)
 create mode 100644 src/main/java/controller/CameraController.java
 create mode 100644 src/main/java/controller/GameContext.java
 create mode 100644 src/main/java/controller/MouseDragHandler.java
 create mode 100644 src/main/java/controller/MousePressHandler.java

diff --git a/src/main/java/controller/CameraController.java b/src/main/java/controller/CameraController.java
new file mode 100644
index 0000000..1879363
--- /dev/null
+++ b/src/main/java/controller/CameraController.java
@@ -0,0 +1,52 @@
+package controller;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class CameraController {
+
+    private Point mouseDragStart = null;  // Stocke la position de départ du clic droit
+    private Point viewOffset = new Point(0, 0); // Stocke le décalage actuel de la vue
+    private JPanel gridPanel;
+    private GameContext context;  // Ajout de GameContext
+
+    public CameraController(JPanel gridPanel, GameContext context) {
+        this.gridPanel = gridPanel;
+        this.context = context;  // Initialisation du contexte
+        setupMouseDragToMove();
+    }
+
+    public Point getViewOffset() {
+        return viewOffset;
+    }
+
+    public void updateViewOffset(int deltaX, int deltaY) {
+        viewOffset.translate(deltaX, deltaY); // Mettre à jour le décalage de la vue
+        gridPanel.setLocation(viewOffset); // Déplacer le panneau en fonction du décalage
+    }
+
+    private void setupMouseDragToMove() {
+        // Utilisation de GameContext dans les gestionnaires de la souris
+        MousePressHandler mousePressHandler = new MousePressHandler(this, context);
+        MouseDragHandler mouseDragHandler = new MouseDragHandler(this, context);
+    
+        gridPanel.addMouseListener(mousePressHandler);
+        gridPanel.addMouseMotionListener(mouseDragHandler);
+    }
+
+    public void setMouseDragStart(Point point) {
+        this.mouseDragStart = point;
+    }
+
+    public Point getMouseDragStart() {
+        return mouseDragStart;
+    }
+
+    public void resetMouseDragStart() {
+        this.mouseDragStart = null;
+    }
+
+    public JPanel getGridPanel() {
+        return gridPanel;
+    }
+}
diff --git a/src/main/java/controller/GameContext.java b/src/main/java/controller/GameContext.java
new file mode 100644
index 0000000..6b7d4d7
--- /dev/null
+++ b/src/main/java/controller/GameContext.java
@@ -0,0 +1,21 @@
+package controller;
+
+import view.HexagonTile;
+import java.awt.*;
+import java.util.Map;
+import java.util.Set;
+
+public class GameContext {
+    public Map<Point, HexagonTile> hexagonMap;
+    public GameController gameController;
+    public Set<Point> availablePositions;
+    public CameraController cameraController;
+
+    public GameContext(Map<Point, HexagonTile> hexagonMap, GameController gameController, 
+                       Set<Point> availablePositions, CameraController cameraController) {
+        this.hexagonMap = hexagonMap;
+        this.gameController = gameController;
+        this.availablePositions = availablePositions;
+        this.cameraController = cameraController;
+    }
+}
diff --git a/src/main/java/controller/GameController.java b/src/main/java/controller/GameController.java
index 086b323..5875e73 100644
--- a/src/main/java/controller/GameController.java
+++ b/src/main/java/controller/GameController.java
@@ -2,7 +2,6 @@ package controller;
 
 import model.Tile;
 import view.HexagonTile;
-import view.GameView;
 
 import java.awt.*;
 import java.util.Map;
@@ -24,62 +23,78 @@ public class GameController {
         this.nextTilePreview = nextTilePreview;
     }
 
-    public void placeInitialTile(Point position) {
-        addHexagonTile(position, gridPanel, 50);
+    public void placeInitialTile(Point position, CameraController cameraController) {
+        addHexagonTile(position, gridPanel, 50, cameraController); // Utilise CameraController
         availablePositions.remove(position);
 
         Point[] adjacentPositions = getAdjacentPositions(position);
         for (Point adj : adjacentPositions) {
             if (!hexagonMap.containsKey(adj)) {
                 availablePositions.add(adj);
-                addHexagonTile(adj, gridPanel, 50);
+                addHexagonTile(adj, gridPanel, 50, cameraController); // Utilise CameraController
             }
         }
     }
 
-    public void placeTile(Point position) {
+    public void placeTile(Point position, CameraController cameraController) {
         if (availablePositions.contains(position)) {
             HexagonTile hexTile = hexagonMap.get(position);
             if (hexTile != null && !hexTile.isFilled()) {
-                // Placer la tuile actuelle
-                hexTile.setTile(nextTile);
-
+                hexTile.setTile(nextTile);  // Placer la tuile
+                gridPanel.revalidate();  // Forcer le rafraîchissement de l'interface graphique
+                gridPanel.repaint();
+                
                 // Générer une nouvelle tuile et mettre à jour la prévisualisation
                 nextTile = generateRandomTile();
                 nextTilePreview.setTile(nextTile);
-
-                updateAdjacentPositions(position);
+                
+                // Mettre à jour les positions adjacentes
+                updateAdjacentPositions(position, cameraController);
+                
+                // Supprimer la position de la liste des positions disponibles
+                availablePositions.remove(position);
             }
         }
     }
 
-    private void addHexagonTile(Point position, JPanel panel, int hexSize) {
-        int xOffset = position.x * (int) (hexSize * 3 / 2);  // Décalage horizontal ajusté
-        int yOffset = position.y * (int) (Math.sqrt(3) * hexSize);  // Décalage vertical ajusté
-
+    public void addHexagonTile(Point position, JPanel panel, int hexSize, CameraController cameraController) {
+        int xOffset = position.x * (int) (hexSize * 3 / 2);
+        int yOffset = position.y * (int) (Math.sqrt(3) * hexSize);
+    
+        Point viewOffset = cameraController.getViewOffset();
+        xOffset += viewOffset.x;
+        yOffset += viewOffset.y;
+    
         if (position.x % 2 != 0) {
             yOffset += (int) (Math.sqrt(3) * hexSize / 2);
         }
-
+    
         HexagonTile hexTile = new HexagonTile(position);
         hexTile.setBounds(xOffset, yOffset, hexSize, hexSize);
-        hexTile.addMouseListener(new HexagonMouseListener(hexTile, this, availablePositions));
-
+    
+        // Ajout de l'écouteur pour gérer le clic sur l'hexagone
+        hexTile.addMouseListener(new HexagonMouseListener(hexTile, this, availablePositions, cameraController));
+    
         hexagonMap.put(position, hexTile);
         panel.add(hexTile);
         panel.revalidate();
         panel.repaint();
     }
+    
+    
+    
+    
 
-    private void updateAdjacentPositions(Point position) {
+    private void updateAdjacentPositions(Point position, CameraController cameraController) {
         Point[] adjacentPositions = getAdjacentPositions(position);
         for (Point adj : adjacentPositions) {
             if (!hexagonMap.containsKey(adj)) {
                 availablePositions.add(adj);
-                addHexagonTile(adj, gridPanel, 50);
+                addHexagonTile(adj, gridPanel, 50, cameraController); // Utilise les nouvelles positions logiques
             }
         }
     }
+    
 
     private Point[] getAdjacentPositions(Point position) {
         return new Point[]{
diff --git a/src/main/java/controller/HexagonMouseListener.java b/src/main/java/controller/HexagonMouseListener.java
index 689da25..728d2fd 100644
--- a/src/main/java/controller/HexagonMouseListener.java
+++ b/src/main/java/controller/HexagonMouseListener.java
@@ -9,20 +9,28 @@ import java.util.Set;
 public class HexagonMouseListener extends MouseAdapter {
 
     private final HexagonTile hexTile;
-    private final GameController gameController;  // Utilise maintenant GameController
+    private final GameController gameController;
     private final Set<Point> availablePositions;
+    private final CameraController cameraController; // Ajouter CameraController
 
-    public HexagonMouseListener(HexagonTile hexTile, GameController gameController, Set<Point> availablePositions) {
+    public HexagonMouseListener(HexagonTile hexTile, GameController gameController, Set<Point> availablePositions, CameraController cameraController) {
         this.hexTile = hexTile;
         this.gameController = gameController;
         this.availablePositions = availablePositions;
+        this.cameraController = cameraController; // Initialiser CameraController
     }
 
     @Override
     public void mouseClicked(MouseEvent e) {
         Point position = hexTile.getPosition();
         if (availablePositions.contains(position)) {
-            gameController.placeTile(position);  // Appelle la méthode placeTile du contrôleur
+            System.out.println("Hexagone cliqué à la position : " + position);
+            gameController.placeTile(position, cameraController);  // Appelle la méthode pour placer une tuile
+        } else {
+            System.out.println("Position non disponible pour le placement");
         }
     }
+
+
+
 }
diff --git a/src/main/java/controller/MouseDragHandler.java b/src/main/java/controller/MouseDragHandler.java
new file mode 100644
index 0000000..64735eb
--- /dev/null
+++ b/src/main/java/controller/MouseDragHandler.java
@@ -0,0 +1,80 @@
+package controller;
+
+import view.HexagonTile;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MouseDragHandler extends MouseAdapter {
+
+    private CameraController controller;
+    private GameContext context;  // Utiliser GameContext pour regrouper les données
+
+    public MouseDragHandler(CameraController controller, GameContext context) {
+        this.controller = controller;
+        this.context = context;
+    }
+
+    @Override
+    public void mouseDragged(MouseEvent e) {
+        if (controller.getMouseDragStart() != null && SwingUtilities.isRightMouseButton(e)) {
+            Point current = e.getPoint();
+            int deltaX = current.x - controller.getMouseDragStart().x;
+            int deltaY = current.y - controller.getMouseDragStart().y;
+
+            // Déplacer uniquement les coordonnées visuelles, pas les coordonnées logiques
+            for (HexagonTile hexTile : context.hexagonMap.values()) {
+                Point currentPos = hexTile.getLocation();
+                hexTile.setLocation(currentPos.x + deltaX, currentPos.y + deltaY);
+            }
+
+            // Mettre à jour la position initiale pour le prochain déplacement
+            controller.setMouseDragStart(current);
+
+            // Rafraîchir la vue
+            controller.getGridPanel().revalidate();
+            controller.getGridPanel().repaint();
+        }
+    }
+
+    @Override
+    public void mouseReleased(MouseEvent e) {
+        if (SwingUtilities.isRightMouseButton(e)) {
+            // Recalculer les positions logiques lorsque la souris est relâchée
+            Map<Point, HexagonTile> newHexagonMap = new HashMap<>();
+            
+            for (Map.Entry<Point, HexagonTile> entry : context.hexagonMap.entrySet()) {
+                HexagonTile hexTile = entry.getValue();
+                Point newLogicalPosition = calculateNewLogicalPosition(hexTile.getLocation());
+
+                // Mettre à jour les écouteurs de la souris
+                hexTile.removeMouseListener(hexTile.getMouseListeners()[0]);  // Supprimer l'ancien écouteur
+                hexTile.addMouseListener(new HexagonMouseListener(hexTile, context.gameController, context.availablePositions, context.cameraController));
+
+                // Ajouter la nouvelle position logique dans la nouvelle carte
+                newHexagonMap.put(newLogicalPosition, hexTile);
+            }
+
+            // Remplacer la carte hexagonMap avec la nouvelle carte
+            context.hexagonMap.clear();
+            context.hexagonMap.putAll(newHexagonMap);
+
+            controller.resetMouseDragStart();
+        }
+    }
+
+    private Point calculateNewLogicalPosition(Point visualPosition) {
+        int logicalX = visualPosition.x / (int) (50 * 3 / 2);  // Ajuste pour la largeur de l'hexagone
+        int logicalY = visualPosition.y / (int) (Math.sqrt(3) * 50);  // Ajuste pour la hauteur de l'hexagone
+    
+        if (logicalX % 2 != 0) {
+            logicalY -= (int) (Math.sqrt(3) * 50 / 2);  // Ajustement pour les colonnes impaires
+        }
+
+        return new Point(logicalX, logicalY);
+    }
+}
diff --git a/src/main/java/controller/MousePressHandler.java b/src/main/java/controller/MousePressHandler.java
new file mode 100644
index 0000000..2dcd855
--- /dev/null
+++ b/src/main/java/controller/MousePressHandler.java
@@ -0,0 +1,64 @@
+package controller;
+
+import view.HexagonTile;
+import java.awt.Point;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.SwingUtilities;
+
+public class MousePressHandler extends MouseAdapter {
+
+    private CameraController controller;
+    private GameContext context;  // Ajout du GameContext
+
+    public MousePressHandler(CameraController controller, GameContext context) {
+        this.controller = controller;
+        this.context = context;  // Utilisation du contexte
+    }
+    
+    @Override
+    public void mousePressed(MouseEvent e) {
+        if (SwingUtilities.isRightMouseButton(e)) {
+            System.out.println("Clic droit détecté");
+            controller.setMouseDragStart(e.getPoint());
+        }
+    }
+
+    @Override
+public void mouseReleased(MouseEvent e) {
+    if (SwingUtilities.isRightMouseButton(e)) {
+        // Créer une nouvelle carte pour stocker les nouvelles positions logiques
+        Map<Point, HexagonTile> newHexagonMap = new HashMap<>();
+        
+        for (Map.Entry<Point, HexagonTile> entry : context.hexagonMap.entrySet()) {
+            HexagonTile hexTile = entry.getValue();
+            Point newLogicalPosition = calculateNewLogicalPosition(hexTile.getLocation());
+
+            // Ajouter la nouvelle position logique dans la nouvelle carte
+            newHexagonMap.put(newLogicalPosition, hexTile);
+        }
+
+        // Remplacer l'ancienne carte après avoir terminé l'itération
+        Map<Point, HexagonTile> oldHexagonMap = context.hexagonMap;  // Sauvegarder l'ancienne référence
+        context.hexagonMap = newHexagonMap;  // Réassigner la nouvelle carte
+
+        oldHexagonMap.clear();  // Vider l'ancienne carte (maintenant non utilisée)
+        controller.resetMouseDragStart();
+    }
+}
+
+
+    private Point calculateNewLogicalPosition(Point visualPosition) {
+        int logicalX = visualPosition.x / (int) (50 * 3 / 2);
+        int logicalY = visualPosition.y / (int) (Math.sqrt(3) * 50);
+
+        if (logicalX % 2 != 0) {
+            logicalY -= (int) (Math.sqrt(3) * 50 / 2);
+        }
+
+        return new Point(logicalX, logicalY);
+    }
+}