From 570ea93e7d00d20d202adda3b86d952cec45dfb6 Mon Sep 17 00:00:00 2001
From: c19014407 <rami.chahine@etu.univ-amu.fr>
Date: Fri, 11 Oct 2024 11:46:03 +0200
Subject: [PATCH] TP 5

---
 src/main/TP5/serializer/App.java            | 31 +++++++++++
 src/main/TP5/serializer/DrawerWithSave.java | 52 ++++++++++++++++++
 src/main/TP5/serializer/ShapeReader.java    | 20 +++++++
 src/main/TP5/serializer/ShapeWriter.java    | 15 ++++++
 src/main/TP5/shape/Abstractshape.java       | 40 ++++++++++++++
 src/main/TP5/shape/App.java                 | 35 ++++++++++++
 src/main/TP5/shape/BorderDecorator.java     | 24 +++++++++
 src/main/TP5/shape/CenterDecorator.java     | 27 ++++++++++
 src/main/TP5/shape/Circle.java              | 31 +++++++++++
 src/main/TP5/shape/Decorator.java           | 28 ++++++++++
 src/main/TP5/shape/Polygon.java             | 34 ++++++++++++
 src/main/TP5/shape/Rectangle.java           | 30 +++++++++++
 src/main/TP5/shape/Shape.java               |  9 ++++
 src/main/TP5/shape/ShapeContainer.java      | 20 +++++++
 src/main/TP5/state/App.java                 | 22 ++++++++
 src/main/TP5/state/CircleDrawerState0       | 17 ++++++
 src/main/TP5/state/CircleDrawerState1       | 24 +++++++++
 src/main/TP5/state/Drawer.java              | 36 +++++++++++++
 src/main/TP5/state/DrawerContext.java       | 59 +++++++++++++++++++++
 src/main/TP5/state/DrawerState.java         |  8 +++
 src/main/TP5/state/MoveShapeState           | 33 ++++++++++++
 src/main/TP5/state/NullDrawerState          | 13 +++++
 src/main/TP5/state/RectangleDrawerState0    | 41 ++++++++++++++
 src/main/TP5/state/RectangleDrawerState1    | 25 +++++++++
 src/main/TP5/state/StateCircle0.java        | 13 +++++
 src/main/java/shape/Abstractshape.java      | 40 ++++++++++++++
 src/main/java/shape/BorderDecorator.java    | 24 +++++++++
 src/main/java/shape/CenterDecorator.java    | 27 ++++++++++
 src/main/java/shape/Decorator.java          | 28 ++++++++++
 src/main/java/shape/Polygon.java            | 34 ++++++++++++
 src/main/java/shape/Rectangle.java          | 17 +++---
 src/main/java/shape/ShapeContainer.java     |  6 ++-
 32 files changed, 855 insertions(+), 8 deletions(-)
 create mode 100644 src/main/TP5/serializer/App.java
 create mode 100644 src/main/TP5/serializer/DrawerWithSave.java
 create mode 100644 src/main/TP5/serializer/ShapeReader.java
 create mode 100644 src/main/TP5/serializer/ShapeWriter.java
 create mode 100644 src/main/TP5/shape/Abstractshape.java
 create mode 100644 src/main/TP5/shape/App.java
 create mode 100644 src/main/TP5/shape/BorderDecorator.java
 create mode 100644 src/main/TP5/shape/CenterDecorator.java
 create mode 100644 src/main/TP5/shape/Circle.java
 create mode 100644 src/main/TP5/shape/Decorator.java
 create mode 100644 src/main/TP5/shape/Polygon.java
 create mode 100644 src/main/TP5/shape/Rectangle.java
 create mode 100644 src/main/TP5/shape/Shape.java
 create mode 100644 src/main/TP5/shape/ShapeContainer.java
 create mode 100644 src/main/TP5/state/App.java
 create mode 100644 src/main/TP5/state/CircleDrawerState0
 create mode 100644 src/main/TP5/state/CircleDrawerState1
 create mode 100644 src/main/TP5/state/Drawer.java
 create mode 100644 src/main/TP5/state/DrawerContext.java
 create mode 100644 src/main/TP5/state/DrawerState.java
 create mode 100644 src/main/TP5/state/MoveShapeState
 create mode 100644 src/main/TP5/state/NullDrawerState
 create mode 100644 src/main/TP5/state/RectangleDrawerState0
 create mode 100644 src/main/TP5/state/RectangleDrawerState1
 create mode 100644 src/main/TP5/state/StateCircle0.java
 create mode 100644 src/main/java/shape/Abstractshape.java
 create mode 100644 src/main/java/shape/BorderDecorator.java
 create mode 100644 src/main/java/shape/CenterDecorator.java
 create mode 100644 src/main/java/shape/Decorator.java
 create mode 100644 src/main/java/shape/Polygon.java

diff --git a/src/main/TP5/serializer/App.java b/src/main/TP5/serializer/App.java
new file mode 100644
index 0000000..7fd1281
--- /dev/null
+++ b/src/main/TP5/serializer/App.java
@@ -0,0 +1,31 @@
+package serializer;
+
+import javafx.application.Application;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.stage.Stage;
+
+public class App extends Application {
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    @Override
+    public void start(Stage primaryStage) {
+        Group root = new Group();
+        DrawerWithSave container = new DrawerWithSave(800, 600);
+        root.getChildren().add(container);
+        primaryStage.setScene(new Scene(root));
+        primaryStage.show();
+        Button save = new Button("save");
+        root.getChildren().add(save);
+        save.setLayoutX(0);
+        save.setLayoutY(0);
+        root.setOnKeyPressed(event->container.context.keyPressed(event));
+        //save.setOnKeyPressed(event->container.context.keyPressed(event));
+        save.setOnAction(event -> container.write());
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/TP5/serializer/DrawerWithSave.java b/src/main/TP5/serializer/DrawerWithSave.java
new file mode 100644
index 0000000..2852edf
--- /dev/null
+++ b/src/main/TP5/serializer/DrawerWithSave.java
@@ -0,0 +1,52 @@
+package serializer;
+
+import javafx.scene.canvas.Canvas;
+import javafx.scene.control.Alert;
+import javafx.stage.FileChooser;
+import shape.Shape;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+public class DrawerWithSave extends state.Drawer {
+
+    public DrawerWithSave(int width, int height) {
+        super(width, height);
+    }
+
+    void write(){
+    FileChooser fileChooser = new FileChooser();
+    fileChooser.setTitle("Save");
+    File file = fileChooser.showSaveDialog(getScene().getWindow());
+    if (file == null) return;
+    try {
+        ShapeWriter.write(file, super.shapes);
+    }
+    catch (IOException e) {
+        Alert alert = new Alert(Alert.AlertType.INFORMATION);
+        alert.setTitle("Error Dialog");
+        alert.setHeaderText(null);
+        alert.setContentText("Ooops, there was an error!");
+        alert.showAndWait();
+    }
+    }
+    public void load() {
+        FileChooser fileChooser = new FileChooser();
+        fileChooser.setTitle("Load");
+        File file = fileChooser.showOpenDialog(getScene().getWindow());
+        if (file == null) return;
+        try {
+            super.shapes = ShapeReader.read(file);
+            repaint();
+        } catch (IOException e) {
+            Alert alert = new Alert(Alert.AlertType.INFORMATION);
+            alert.setTitle("Error Dialog");
+            alert.setHeaderText(null);
+            alert.setContentText("Ooops, there was an error!");
+            alert.showAndWait();
+        }
+    }
+}
diff --git a/src/main/TP5/serializer/ShapeReader.java b/src/main/TP5/serializer/ShapeReader.java
new file mode 100644
index 0000000..4905948
--- /dev/null
+++ b/src/main/TP5/serializer/ShapeReader.java
@@ -0,0 +1,20 @@
+package serializer;
+
+import shape.Shape;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collector;
+
+public class ShapeReader {
+    public static List<Shape> read(File file) throws IOException {
+        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
+        /*for(String line : bufferedReader.lines().toList()) {
+            System.out.println(line);
+        }*/
+        return null;
+    }
+}
diff --git a/src/main/TP5/serializer/ShapeWriter.java b/src/main/TP5/serializer/ShapeWriter.java
new file mode 100644
index 0000000..6a76ef8
--- /dev/null
+++ b/src/main/TP5/serializer/ShapeWriter.java
@@ -0,0 +1,15 @@
+package serializer;
+
+import shape.Shape;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+public class ShapeWriter {
+    public static void write (File file, List<Shape> shapes) throws IOException {
+        PrintWriter printWriter = new PrintWriter(file);
+        printWriter.println("Coucou");
+    }
+}
diff --git a/src/main/TP5/shape/Abstractshape.java b/src/main/TP5/shape/Abstractshape.java
new file mode 100644
index 0000000..b6a4e2f
--- /dev/null
+++ b/src/main/TP5/shape/Abstractshape.java
@@ -0,0 +1,40 @@
+package shape;
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import java.util.List;
+
+
+public abstract class Abstractshape implements Shape {
+    private List<Point2D> points;
+
+    public Abstractshape(List<Point2D> points) {
+        this.points = points;
+    }
+    public void addPoints(Point2D... points){
+        for (Point2D point: points)
+            this.points.add(point);
+    }
+    @Override
+    public int pointsCount() {
+        return points.size();
+    }
+
+    @Override
+    public Point2D point(int index) {
+        return index < points.size() ? points.get(index) : null;
+    }
+
+    @Override
+    public void draw(GraphicsContext context) {
+        if (pointsCount()>0){
+            context.beginPath();
+            context.moveTo(point(0).getX(), point(0).getY());
+            for (int i = 1; i<pointsCount(); i++){
+                context.lineTo(point(i).getX(),point(i).getY());
+            }
+            context.closePath();
+            context.stroke();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/TP5/shape/App.java b/src/main/TP5/shape/App.java
new file mode 100644
index 0000000..1a519e1
--- /dev/null
+++ b/src/main/TP5/shape/App.java
@@ -0,0 +1,35 @@
+package shape;
+
+import javafx.application.Application;
+import javafx.geometry.Point2D;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.stage.Stage;
+
+
+
+public class App extends Application {
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    @Override
+    public void start(Stage primaryStage) {
+        Group root = new Group();
+        Canvas canvas = new Canvas(130, 110);
+        GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
+        ShapeContainer shapeContainer = new ShapeContainer();
+        graphicsContext.setFill(Color.AQUAMARINE);
+        graphicsContext.fillOval(10,10,10,10);
+        shapeContainer.addShape(new Rectangle(Color.BLUE,new Point2D(10,10), new Point2D(40,40)));
+        shapeContainer.draw(graphicsContext);
+        root.getChildren().add(canvas);
+        primaryStage.setScene(new Scene(root));
+        primaryStage.show();
+    }
+}
\ No newline at end of file
diff --git a/src/main/TP5/shape/BorderDecorator.java b/src/main/TP5/shape/BorderDecorator.java
new file mode 100644
index 0000000..efdd00a
--- /dev/null
+++ b/src/main/TP5/shape/BorderDecorator.java
@@ -0,0 +1,24 @@
+package shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+
+public class BorderDecorator extends Decorator {
+
+    private double radius;
+
+    public BorderDecorator(Shape decoratedShape ,double radius) {
+        super(decoratedShape);
+        this.radius = radius;
+    }
+    protected void drawDecoration(GraphicsContext context) {
+        context.setStroke(Color.BLACK);
+        context.setLineWidth(2);
+        for (int i=0; i<pointsCount(); i++){
+            Point2D point = point(i);
+            context.strokeOval(point.getX() - radius, point.getY()- radius,radius*2,radius*2);
+        }
+    }
+}
diff --git a/src/main/TP5/shape/CenterDecorator.java b/src/main/TP5/shape/CenterDecorator.java
new file mode 100644
index 0000000..93769c9
--- /dev/null
+++ b/src/main/TP5/shape/CenterDecorator.java
@@ -0,0 +1,27 @@
+package shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+public class CenterDecorator extends Decorator{
+    private double radius;
+    public CenterDecorator(Shape decoratedShape, double radius) {
+        super(decoratedShape);
+        this.radius = radius;
+    }
+    protected void drawDecoration(GraphicsContext context) {
+        double centerX = 0;
+        double centerY = 0;
+        for (int i =0; i<pointsCount(); i++){
+            Point2D point = point(i);
+            centerX += point.getX();
+            centerY += point.getY();
+        }
+        centerX /= pointsCount();
+        centerY /= pointsCount();
+        context.setStroke(Color.RED);
+        context.setLineWidth(2);
+        context.strokeOval(centerX-radius, centerY-radius, radius*2,radius*2);
+    }
+}
\ No newline at end of file
diff --git a/src/main/TP5/shape/Circle.java b/src/main/TP5/shape/Circle.java
new file mode 100644
index 0000000..530a521
--- /dev/null
+++ b/src/main/TP5/shape/Circle.java
@@ -0,0 +1,31 @@
+package shape;
+
+import javafx.scene.canvas.GraphicsContext;
+
+public class Circle implements Shape {
+    private double x, y, radius;
+
+    public Circle(double x, double y, double radius) {
+        this.x = x;
+        this.y = y;
+        this.radius = radius;
+    }
+
+    @Override
+    public void paint(GraphicsContext gc) {
+        gc.strokeOval(x - radius, y - radius, 2 * radius, 2 * radius);
+    }
+
+    @Override
+    public boolean contains(double x, double y) {
+        double dx = x - this.x;
+        double dy = y - this.y;
+        return dx * dx + dy * dy <= radius * radius;
+    }
+
+    @Override
+    public void translate(double dx, double dy) {
+        this.x += dx;
+        this.y += dy;
+    }
+}
diff --git a/src/main/TP5/shape/Decorator.java b/src/main/TP5/shape/Decorator.java
new file mode 100644
index 0000000..5a11efd
--- /dev/null
+++ b/src/main/TP5/shape/Decorator.java
@@ -0,0 +1,28 @@
+package shape;
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+
+public abstract class Decorator implements Shape {
+    protected Shape decoratedshape;
+    public Decorator(Shape decoratedShape) {
+        this.decoratedshape = decoratedShape;
+    }
+    @Override
+    public int pointsCount() {
+        return decoratedshape.pointsCount();
+    }
+
+    @Override
+    public Point2D point(int index) {
+        return decoratedshape.point(index);
+    }
+
+    @Override
+    public void draw(GraphicsContext context) {
+        decoratedshape.draw(context);
+        drawDecoration(context);
+    }
+    protected void drawDecoration(GraphicsContext context) {
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/TP5/shape/Polygon.java b/src/main/TP5/shape/Polygon.java
new file mode 100644
index 0000000..775c7da
--- /dev/null
+++ b/src/main/TP5/shape/Polygon.java
@@ -0,0 +1,34 @@
+package shape;
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+import java.util.List;
+
+public class Polygon extends Abstractshape {
+
+    private Color color;
+
+    public Polygon(Color color, Point2D... points) {
+        super(List.of(points));
+        this.color = color;
+    }
+
+    @Override
+    public int pointsCount() {
+        return super.pointsCount();
+    }
+
+    @Override
+    public Point2D point(int index) {
+        return super.point(index);
+    }
+
+    @Override
+    public void draw(GraphicsContext context) {
+        context.setFill(color);
+        super.draw(context);
+        context.fill();
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/TP5/shape/Rectangle.java b/src/main/TP5/shape/Rectangle.java
new file mode 100644
index 0000000..3e9e4f1
--- /dev/null
+++ b/src/main/TP5/shape/Rectangle.java
@@ -0,0 +1,30 @@
+package shape;
+
+import javafx.scene.canvas.GraphicsContext;
+
+public class Rectangle implements Shape {
+    private double x, y, width, height;
+
+    public Rectangle(double x, double y, double width, double height) {
+        this.x = x;
+        this.y = y;
+        this.width = width;
+        this.height = height;
+    }
+
+    @Override
+    public void paint(GraphicsContext gc) {
+        gc.strokeRect(x, y, width, height);
+    }
+
+    @Override
+    public boolean contains(double x, double y) {
+        return x >= this.x && x <= this.x + width && y >= this.y && y <= this.y + height;
+    }
+
+    @Override
+    public void translate(double dx, double dy) {
+        this.x += dx;
+        this.y += dy;
+    }
+}
diff --git a/src/main/TP5/shape/Shape.java b/src/main/TP5/shape/Shape.java
new file mode 100644
index 0000000..02cf904
--- /dev/null
+++ b/src/main/TP5/shape/Shape.java
@@ -0,0 +1,9 @@
+package shape;
+
+import javafx.scene.canvas.GraphicsContext;
+
+public interface Shape {
+    void paint(GraphicsContext gc);
+    boolean contains(double x, double y);
+    void translate(double dx, double dy);
+}
diff --git a/src/main/TP5/shape/ShapeContainer.java b/src/main/TP5/shape/ShapeContainer.java
new file mode 100644
index 0000000..3ed1776
--- /dev/null
+++ b/src/main/TP5/shape/ShapeContainer.java
@@ -0,0 +1,20 @@
+package shape;
+
+import javafx.scene.canvas.GraphicsContext;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ShapeContainer{
+
+    private List<Shape> shapes = new ArrayList<>();
+
+    public void addShape(Shape shape){
+        shapes.add(shape);
+    }
+
+    public void  draw(GraphicsContext context){
+        for(Shape shape : shapes)
+            shape.draw(context);
+    }
+}
\ No newline at end of file
diff --git a/src/main/TP5/state/App.java b/src/main/TP5/state/App.java
new file mode 100644
index 0000000..09f71cf
--- /dev/null
+++ b/src/main/TP5/state/App.java
@@ -0,0 +1,22 @@
+package state;
+
+import javafx.application.Application;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class App extends Application {
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    @Override
+    public void start(Stage primaryStage) {
+        Group root = new Group();
+        Drawer container = new Drawer(800, 600);
+        root.getChildren().add(container);
+        primaryStage.setScene(new Scene(root));
+        primaryStage.show();
+    }
+}
\ No newline at end of file
diff --git a/src/main/TP5/state/CircleDrawerState0 b/src/main/TP5/state/CircleDrawerState0
new file mode 100644
index 0000000..c488204
--- /dev/null
+++ b/src/main/TP5/state/CircleDrawerState0
@@ -0,0 +1,17 @@
+
+public class CircleDrawerState0 implements DrawerState {
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {
+        context.setState(new CircleDrawerState1(x, y));
+    }
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void paint(GraphicsContext gc) {}
+}
+
diff --git a/src/main/TP5/state/CircleDrawerState1 b/src/main/TP5/state/CircleDrawerState1
new file mode 100644
index 0000000..42f8214
--- /dev/null
+++ b/src/main/TP5/state/CircleDrawerState1
@@ -0,0 +1,24 @@
+public class CircleDrawerState1 implements DrawerState {
+    private double x, y;
+
+    public CircleDrawerState1(double x, double y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        double radius = Math.hypot(this.x - x, this.y - y);
+        context.getDrawer().add(new Circle(this.x, this.y, radius));
+        context.setState(new CircleDrawerState0()); // Reset to initial state
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void paint(GraphicsContext gc) {}
+}
\ No newline at end of file
diff --git a/src/main/TP5/state/Drawer.java b/src/main/TP5/state/Drawer.java
new file mode 100644
index 0000000..5468857
--- /dev/null
+++ b/src/main/TP5/state/Drawer.java
@@ -0,0 +1,36 @@
+package state;
+
+import javafx.scene.canvas.GraphicsContext;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Drawer {
+    private List<Shape> shapes;
+    private double width, height;
+
+    public Drawer(double width, double height) {
+        this.width = width;
+        this.height = height;
+        this.shapes = new ArrayList<>();
+    }
+
+    public void add(Shape shape) {
+        shapes.add(shape);
+    }
+
+    public void repaint(GraphicsContext gc) {
+        gc.clearRect(0, 0, width, height); // Clear canvas
+        for (Shape shape : shapes) {
+            shape.paint(gc);
+        }
+    }
+
+    public Shape shapeContaining(double x, double y) {
+        for (Shape shape : shapes) {
+            if (shape.contains(x, y)) {
+                return shape;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/TP5/state/DrawerContext.java b/src/main/TP5/state/DrawerContext.java
new file mode 100644
index 0000000..74b12cb
--- /dev/null
+++ b/src/main/TP5/state/DrawerContext.java
@@ -0,0 +1,59 @@
+package state;
+
+
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+
+public class DrawerContext {
+    private Drawer drawer;
+    private DrawerState currentState;
+
+    public DrawerContext(Drawer drawer) {
+        this.drawer = drawer;
+        this.currentState = new NullDrawerState(); // Default state
+    }
+
+    public void setState(DrawerState state) {
+        this.currentState = state;
+    }
+
+    public void paint(GraphicsContext gc) {
+        currentState.paint(gc);
+    }
+
+    public void mousePressed(MouseEvent event) {
+        currentState.mousePressed(this, event.getX(), event.getY());
+    }
+
+    public void mouseReleased(MouseEvent event) {
+        currentState.mouseReleased(this, event.getX(), event.getY());
+    }
+
+    public void mouseMoved(MouseEvent event) {
+        currentState.mouseMoved(this, event.getX(), event.getY());
+    }
+
+    public void keyPressed(KeyEvent event) {
+        switch (event.getText()) {
+            case "r":
+                setState(new RectangleDrawerState0());
+                break;
+            case "c":
+                setState(new CircleDrawerState0());
+                break;
+            case "m":
+                Shape shape = getDrawer().shapeContaining(lastMouseX, lastMouseY);
+                if (shape != null) {
+                    setState(new MoveShapeState(shape, lastMouseX, lastMouseY));
+                }
+                break;
+        }
+    }
+
+    public Drawer getDrawer() {
+        return drawer;
+    }
+
+}
+
diff --git a/src/main/TP5/state/DrawerState.java b/src/main/TP5/state/DrawerState.java
new file mode 100644
index 0000000..c185dfe
--- /dev/null
+++ b/src/main/TP5/state/DrawerState.java
@@ -0,0 +1,8 @@
+package state;
+
+interface DrawerState {
+    void mousePressed(DrawerContext context, double x, double y);
+    void mouseReleased(DrawerContext context, double x, double y);
+    void mouseMoved(DrawerContext context, double x, double y);
+    void paint(GraphicsContext gc);
+}
\ No newline at end of file
diff --git a/src/main/TP5/state/MoveShapeState b/src/main/TP5/state/MoveShapeState
new file mode 100644
index 0000000..6069a6e
--- /dev/null
+++ b/src/main/TP5/state/MoveShapeState
@@ -0,0 +1,33 @@
+public class MoveShapeState implements DrawerState {
+    private Shape selectedShape;
+    private double lastX, lastY;
+
+    public MoveShapeState(Shape selectedShape, double x, double y) {
+        this.selectedShape = selectedShape;
+        this.lastX = x;
+        this.lastY = y;
+    }
+
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        context.setState(new NullDrawerState()); // Return to the default state after moving
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+        if (selectedShape != null) {
+            double dx = x - lastX;
+            double dy = y - lastY;
+            selectedShape.translate(dx, dy);
+            lastX = x;
+            lastY = y;
+            context.getDrawer().repaint(context.getDrawer().getGraphicsContext());
+        }
+    }
+
+    @Override
+    public void paint(GraphicsContext gc) {}
+}
diff --git a/src/main/TP5/state/NullDrawerState b/src/main/TP5/state/NullDrawerState
new file mode 100644
index 0000000..8572e06
--- /dev/null
+++ b/src/main/TP5/state/NullDrawerState
@@ -0,0 +1,13 @@
+public class NullDrawerState implements DrawerState {
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void paint(GraphicsContext gc) {}
+}
diff --git a/src/main/TP5/state/RectangleDrawerState0 b/src/main/TP5/state/RectangleDrawerState0
new file mode 100644
index 0000000..3349108
--- /dev/null
+++ b/src/main/TP5/state/RectangleDrawerState0
@@ -0,0 +1,41 @@
+public class RectangleDrawerState0 implements DrawerState {
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {
+        context.setState(new RectangleDrawerState1(x, y));
+    }
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void paint(GraphicsContext gc) {}
+}
+
+public class RectangleDrawerState1 implements DrawerState {
+    private double x, y;
+
+    public RectangleDrawerState1(double x, double y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        double width = Math.abs(this.x - x);
+        double height = Math.abs(this.y - y);
+        context.getDrawer().add(new Rectangle(Math.min(this.x, x), Math.min(this.y, y), width, height));
+        context.setState(new RectangleDrawerState0()); // Reset to initial state
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void paint(GraphicsContext gc) {}
+}
diff --git a/src/main/TP5/state/RectangleDrawerState1 b/src/main/TP5/state/RectangleDrawerState1
new file mode 100644
index 0000000..17a7116
--- /dev/null
+++ b/src/main/TP5/state/RectangleDrawerState1
@@ -0,0 +1,25 @@
+public class RectangleDrawerState1 implements DrawerState {
+    private double x, y;
+
+    public RectangleDrawerState1(double x, double y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        double width = Math.abs(this.x - x);
+        double height = Math.abs(this.y - y);
+        context.getDrawer().add(new Rectangle(Math.min(this.x, x), Math.min(this.y, y), width, height));
+        context.setState(new RectangleDrawerState0()); // Reset to initial state
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void paint(GraphicsContext gc) {}
+}
\ No newline at end of file
diff --git a/src/main/TP5/state/StateCircle0.java b/src/main/TP5/state/StateCircle0.java
new file mode 100644
index 0000000..073c481
--- /dev/null
+++ b/src/main/TP5/state/StateCircle0.java
@@ -0,0 +1,13 @@
+package state;
+
+public class StateCircle0 implements DrawerState {
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {
+
+    }
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+
+    }
+}
diff --git a/src/main/java/shape/Abstractshape.java b/src/main/java/shape/Abstractshape.java
new file mode 100644
index 0000000..b6a4e2f
--- /dev/null
+++ b/src/main/java/shape/Abstractshape.java
@@ -0,0 +1,40 @@
+package shape;
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import java.util.List;
+
+
+public abstract class Abstractshape implements Shape {
+    private List<Point2D> points;
+
+    public Abstractshape(List<Point2D> points) {
+        this.points = points;
+    }
+    public void addPoints(Point2D... points){
+        for (Point2D point: points)
+            this.points.add(point);
+    }
+    @Override
+    public int pointsCount() {
+        return points.size();
+    }
+
+    @Override
+    public Point2D point(int index) {
+        return index < points.size() ? points.get(index) : null;
+    }
+
+    @Override
+    public void draw(GraphicsContext context) {
+        if (pointsCount()>0){
+            context.beginPath();
+            context.moveTo(point(0).getX(), point(0).getY());
+            for (int i = 1; i<pointsCount(); i++){
+                context.lineTo(point(i).getX(),point(i).getY());
+            }
+            context.closePath();
+            context.stroke();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/shape/BorderDecorator.java b/src/main/java/shape/BorderDecorator.java
new file mode 100644
index 0000000..efdd00a
--- /dev/null
+++ b/src/main/java/shape/BorderDecorator.java
@@ -0,0 +1,24 @@
+package shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+
+public class BorderDecorator extends Decorator {
+
+    private double radius;
+
+    public BorderDecorator(Shape decoratedShape ,double radius) {
+        super(decoratedShape);
+        this.radius = radius;
+    }
+    protected void drawDecoration(GraphicsContext context) {
+        context.setStroke(Color.BLACK);
+        context.setLineWidth(2);
+        for (int i=0; i<pointsCount(); i++){
+            Point2D point = point(i);
+            context.strokeOval(point.getX() - radius, point.getY()- radius,radius*2,radius*2);
+        }
+    }
+}
diff --git a/src/main/java/shape/CenterDecorator.java b/src/main/java/shape/CenterDecorator.java
new file mode 100644
index 0000000..93769c9
--- /dev/null
+++ b/src/main/java/shape/CenterDecorator.java
@@ -0,0 +1,27 @@
+package shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+public class CenterDecorator extends Decorator{
+    private double radius;
+    public CenterDecorator(Shape decoratedShape, double radius) {
+        super(decoratedShape);
+        this.radius = radius;
+    }
+    protected void drawDecoration(GraphicsContext context) {
+        double centerX = 0;
+        double centerY = 0;
+        for (int i =0; i<pointsCount(); i++){
+            Point2D point = point(i);
+            centerX += point.getX();
+            centerY += point.getY();
+        }
+        centerX /= pointsCount();
+        centerY /= pointsCount();
+        context.setStroke(Color.RED);
+        context.setLineWidth(2);
+        context.strokeOval(centerX-radius, centerY-radius, radius*2,radius*2);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/shape/Decorator.java b/src/main/java/shape/Decorator.java
new file mode 100644
index 0000000..5a11efd
--- /dev/null
+++ b/src/main/java/shape/Decorator.java
@@ -0,0 +1,28 @@
+package shape;
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+
+public abstract class Decorator implements Shape {
+    protected Shape decoratedshape;
+    public Decorator(Shape decoratedShape) {
+        this.decoratedshape = decoratedShape;
+    }
+    @Override
+    public int pointsCount() {
+        return decoratedshape.pointsCount();
+    }
+
+    @Override
+    public Point2D point(int index) {
+        return decoratedshape.point(index);
+    }
+
+    @Override
+    public void draw(GraphicsContext context) {
+        decoratedshape.draw(context);
+        drawDecoration(context);
+    }
+    protected void drawDecoration(GraphicsContext context) {
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/shape/Polygon.java b/src/main/java/shape/Polygon.java
new file mode 100644
index 0000000..775c7da
--- /dev/null
+++ b/src/main/java/shape/Polygon.java
@@ -0,0 +1,34 @@
+package shape;
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+import java.util.List;
+
+public class Polygon extends Abstractshape {
+
+    private Color color;
+
+    public Polygon(Color color, Point2D... points) {
+        super(List.of(points));
+        this.color = color;
+    }
+
+    @Override
+    public int pointsCount() {
+        return super.pointsCount();
+    }
+
+    @Override
+    public Point2D point(int index) {
+        return super.point(index);
+    }
+
+    @Override
+    public void draw(GraphicsContext context) {
+        context.setFill(color);
+        super.draw(context);
+        context.fill();
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/shape/Rectangle.java b/src/main/java/shape/Rectangle.java
index b0e9062..09df336 100644
--- a/src/main/java/shape/Rectangle.java
+++ b/src/main/java/shape/Rectangle.java
@@ -3,25 +3,30 @@ package shape;
 import javafx.geometry.Point2D;
 import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.paint.Color;
+import java.util.List;
 
-public class Rectangle implements Shape{
-    Color color;
+public class Rectangle extends Abstractshape{
+    private Color color;
     Rectangle(Color color, Point2D point0, Point2D point1){
+        super(List.of(point0, new Point2D(point1.getX(),point0.getY()),
+                point1,new Point2D(point0.getX(),point1.getY())));
         this.color = color;
     }
 
     @Override
     public int pointsCount() {
-        return 0;
+        return super.pointsCount();
     }
 
     @Override
     public Point2D point(int index) {
-        return null;
+        return super.point(index);
     }
 
     @Override
     public void draw(GraphicsContext context) {
-
+        context.setFill(color);
+        super.draw(context);
+        context.fill();
     }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/shape/ShapeContainer.java b/src/main/java/shape/ShapeContainer.java
index 91c7d29..3ed1776 100644
--- a/src/main/java/shape/ShapeContainer.java
+++ b/src/main/java/shape/ShapeContainer.java
@@ -9,10 +9,12 @@ public class ShapeContainer{
 
     private List<Shape> shapes = new ArrayList<>();
 
-    public void addShape(Shape shape){}
+    public void addShape(Shape shape){
+        shapes.add(shape);
+    }
 
     public void  draw(GraphicsContext context){
         for(Shape shape : shapes)
             shape.draw(context);
     }
-}
+}
\ No newline at end of file
-- 
GitLab