diff --git a/src/main/java/Graph1/serializer/App.java b/src/main/java/Graph1/serializer/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..de2390b06553373d5143bbfc42625e5688007f4b
--- /dev/null
+++ b/src/main/java/Graph1/serializer/App.java
@@ -0,0 +1,31 @@
+package Graph1.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/java/Graph1/serializer/DrawerWithSave.java b/src/main/java/Graph1/serializer/DrawerWithSave.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f5fc3412f7ed021da0ffce96aae90827e0cd1a6
--- /dev/null
+++ b/src/main/java/Graph1/serializer/DrawerWithSave.java
@@ -0,0 +1,52 @@
+package Graph1.serializer;
+
+import javafx.scene.canvas.Canvas;
+import javafx.scene.control.Alert;
+import javafx.stage.FileChooser;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+public class DrawerWithSave extends Graph1.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/java/Graph1/serializer/ShapeReader.java b/src/main/java/Graph1/serializer/ShapeReader.java
new file mode 100644
index 0000000000000000000000000000000000000000..27320d4121b0b4a570c6fda01e81677995d10e8b
--- /dev/null
+++ b/src/main/java/Graph1/serializer/ShapeReader.java
@@ -0,0 +1,20 @@
+package Graph1.serializer;
+
+import Graph1.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/java/Graph1/serializer/ShapeWriter.java b/src/main/java/Graph1/serializer/ShapeWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..3203d2f63ee95d638d450084d4246cb208a7f0aa
--- /dev/null
+++ b/src/main/java/Graph1/serializer/ShapeWriter.java
@@ -0,0 +1,15 @@
+package Graph1.serializer;
+
+import Graph1.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/java/Graph1/shape/Abstractshape.java b/src/main/java/Graph1/shape/Abstractshape.java
new file mode 100644
index 0000000000000000000000000000000000000000..e458aa1de3d634e2c369993149d2316a806402bc
--- /dev/null
+++ b/src/main/java/Graph1/shape/Abstractshape.java
@@ -0,0 +1,40 @@
+package Graph1.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/Graph1/shape/App.java b/src/main/java/Graph1/shape/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..107341ccdc2079008f5cdba8a6083121db31b58c
--- /dev/null
+++ b/src/main/java/Graph1/shape/App.java
@@ -0,0 +1,35 @@
+package Graph1.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/java/Graph1/shape/BorderDecorator.java b/src/main/java/Graph1/shape/BorderDecorator.java
new file mode 100644
index 0000000000000000000000000000000000000000..04a32c276418de0cc35db5c94063956abda8928e
--- /dev/null
+++ b/src/main/java/Graph1/shape/BorderDecorator.java
@@ -0,0 +1,24 @@
+package Graph1.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/Graph1/shape/CenterDecorator.java b/src/main/java/Graph1/shape/CenterDecorator.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6d1c0b7f4e749a50a686c1eafd78e27d53381e8
--- /dev/null
+++ b/src/main/java/Graph1/shape/CenterDecorator.java
@@ -0,0 +1,27 @@
+package Graph1.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/Graph1/shape/Circle.java b/src/main/java/Graph1/shape/Circle.java
new file mode 100644
index 0000000000000000000000000000000000000000..e73276310325c80d5f5d2151176873ffb215ddc9
--- /dev/null
+++ b/src/main/java/Graph1/shape/Circle.java
@@ -0,0 +1,25 @@
+package Graph1.shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+
+public class Circle implements Shape {
+
+    public Circle(double x, double y, double sqrt) {
+    }
+
+    @Override
+    public int pointsCount() {
+        return 0;
+    }
+
+    @Override
+    public Point2D point(int index) {
+        return null;
+    }
+
+    @Override
+    public void draw(GraphicsContext context) {
+
+    }
+}
diff --git a/src/main/java/Graph1/shape/Decorator.java b/src/main/java/Graph1/shape/Decorator.java
new file mode 100644
index 0000000000000000000000000000000000000000..a806739421574fb76c6738209b5b5c432c791b3e
--- /dev/null
+++ b/src/main/java/Graph1/shape/Decorator.java
@@ -0,0 +1,28 @@
+package Graph1.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/Graph1/shape/Polygon.java b/src/main/java/Graph1/shape/Polygon.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b45e5bd30847f0d1729b5cf831f75e7a0832b48
--- /dev/null
+++ b/src/main/java/Graph1/shape/Polygon.java
@@ -0,0 +1,34 @@
+package Graph1.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/Graph1/shape/Rectangle.java b/src/main/java/Graph1/shape/Rectangle.java
new file mode 100644
index 0000000000000000000000000000000000000000..958d31d230efe65c2262dc3901760a860c119564
--- /dev/null
+++ b/src/main/java/Graph1/shape/Rectangle.java
@@ -0,0 +1,32 @@
+package Graph1.shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+import java.util.List;
+
+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 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/Graph1/shape/Shape.java b/src/main/java/Graph1/shape/Shape.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca81871943b7c430bb64172fb83d75cf2f572fc6
--- /dev/null
+++ b/src/main/java/Graph1/shape/Shape.java
@@ -0,0 +1,10 @@
+package Graph1.shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+
+public interface Shape {
+    int pointsCount();
+    Point2D point(int index);
+    void draw(GraphicsContext context);
+}
diff --git a/src/main/java/Graph1/shape/ShapeContainer.java b/src/main/java/Graph1/shape/ShapeContainer.java
new file mode 100644
index 0000000000000000000000000000000000000000..09ad98af5d5ea8a672d100c5e3949a0e6271f332
--- /dev/null
+++ b/src/main/java/Graph1/shape/ShapeContainer.java
@@ -0,0 +1,20 @@
+package Graph1.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/java/Graph1/state/App.java b/src/main/java/Graph1/state/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..597da8a30f41cd0019bfbaeaaaa044e1f3e5152f
--- /dev/null
+++ b/src/main/java/Graph1/state/App.java
@@ -0,0 +1,22 @@
+package Graph1.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/java/Graph1/state/Drawer.java b/src/main/java/Graph1/state/Drawer.java
new file mode 100644
index 0000000000000000000000000000000000000000..61faf4e508374d25e8be6e1270f4b1118cb43d0e
--- /dev/null
+++ b/src/main/java/Graph1/state/Drawer.java
@@ -0,0 +1,28 @@
+package Graph1.state;
+
+import javafx.scene.canvas.Canvas;
+import Graph1.shape.Circle;
+import Graph1.shape.Shape;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Drawer extends Canvas {
+    protected List<Shape> shapes = new ArrayList<>();
+    public DrawerContext context = new DrawerContext(this);
+
+    public Drawer(int width, int height) {
+        super(width,height);
+        setFocusTraversable(true);
+        setOnMousePressed(event->context.mousePressed(event));
+        setOnMouseReleased(event->context.mouseReleased(event));
+        setOnMouseMoved(event->context.mouseMoved(event));
+        setOnMouseDragged(event->context.mouseMoved(event));
+        //setOnKeyPressed(event -> context.keyPressed(event));
+    }
+
+    public void repaint(){
+        this.getGraphicsContext2D().clearRect(0,0,this.getWidth(),this.getHeight());
+    }
+}
diff --git a/src/main/java/Graph1/state/DrawerContext.java b/src/main/java/Graph1/state/DrawerContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..c90a1b8fac22555b136a75ba331440dbbead79aa
--- /dev/null
+++ b/src/main/java/Graph1/state/DrawerContext.java
@@ -0,0 +1,33 @@
+package Graph1.state;
+
+
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+
+public class DrawerContext {
+
+    Drawer drawer;
+    DrawerState currentState;
+
+    public DrawerContext(Drawer drawer) {
+        this.drawer = drawer;
+    }
+
+    void mousePressed(MouseEvent event){
+        currentState.mousePressed(this,event.getX(),event.getY());
+
+    }
+
+    void mouseReleased(MouseEvent event){
+        currentState.mouseReleased(this,event.getX(),event.getY());
+    }
+
+    void mouseMoved(MouseEvent event){}
+
+    public void keyPressed(KeyEvent event) {
+        switch (event.getText()) {
+            case "c":
+                currentState = new StateCircle0();
+        }
+    }
+}
diff --git a/src/main/java/Graph1/state/DrawerState.java b/src/main/java/Graph1/state/DrawerState.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d0a302047aa9fa0dc318f1ab72a1349a1e2dda5
--- /dev/null
+++ b/src/main/java/Graph1/state/DrawerState.java
@@ -0,0 +1,6 @@
+package Graph1.state;
+
+public interface DrawerState {
+    void mousePressed(DrawerContext context, double x, double y);
+    void mouseReleased(DrawerContext context, double x, double y);
+}
diff --git a/src/main/java/Graph1/state/StateCircle0.java b/src/main/java/Graph1/state/StateCircle0.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9a2b91b6674c08cd74c42c4f423c6dcacefc624
--- /dev/null
+++ b/src/main/java/Graph1/state/StateCircle0.java
@@ -0,0 +1,13 @@
+package Graph1.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/TP5/serializer/App.java b/src/main/java/TP5/serializer/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9f667be0266d06bcd6a0022adef0cc5124ea3ad
--- /dev/null
+++ b/src/main/java/TP5/serializer/App.java
@@ -0,0 +1,31 @@
+package TP5.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/java/TP5/serializer/DrawerWithSave.java b/src/main/java/TP5/serializer/DrawerWithSave.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0e3d7cb0ea331d883eba458c0312796cd235873
--- /dev/null
+++ b/src/main/java/TP5/serializer/DrawerWithSave.java
@@ -0,0 +1,48 @@
+package TP5.serializer;
+
+import javafx.scene.control.Alert;
+import javafx.stage.FileChooser;
+
+import java.io.File;
+import java.io.IOException;
+
+
+public class DrawerWithSave extends TP5.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/java/TP5/serializer/ShapeReader.java b/src/main/java/TP5/serializer/ShapeReader.java
new file mode 100644
index 0000000000000000000000000000000000000000..740f15ad6c76cfa708e71ac89dab81b45c90581d
--- /dev/null
+++ b/src/main/java/TP5/serializer/ShapeReader.java
@@ -0,0 +1,19 @@
+package TP5.serializer;
+
+import TP5.shape.Shape;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+
+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/java/TP5/serializer/ShapeWriter.java b/src/main/java/TP5/serializer/ShapeWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb9f9fef6f48a0e9abde07e34ee50d73c7102f2e
--- /dev/null
+++ b/src/main/java/TP5/serializer/ShapeWriter.java
@@ -0,0 +1,15 @@
+package TP5.serializer;
+
+import TP5.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/java/TP5/shape/App.java b/src/main/java/TP5/shape/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..5df6b0a49950741028a5949ab1594a777e241486
--- /dev/null
+++ b/src/main/java/TP5/shape/App.java
@@ -0,0 +1,27 @@
+package TP5.shape;
+
+import javafx.application.Application;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+
+public class App extends Application {
+
+    @Override
+    public void start(Stage primaryStage) {
+        Drawer drawer = new Drawer(600, 400);
+
+        Group root = new Group();
+        root.getChildren().add(drawer.getCanvas());
+
+        Scene scene = new Scene(root, 600, 400);
+
+        primaryStage.setTitle("JavaFX Drawer");
+        primaryStage.setScene(scene);
+        primaryStage.show();
+    }
+    public static void main(String[] args) {
+        launch(args);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/TP5/shape/Circle.java b/src/main/java/TP5/shape/Circle.java
new file mode 100644
index 0000000000000000000000000000000000000000..0cef5337718a032fb4e6bc7920886abf309c7e97
--- /dev/null
+++ b/src/main/java/TP5/shape/Circle.java
@@ -0,0 +1,78 @@
+package TP5.shape;
+
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+public class Circle implements Shape {
+
+    private double radius, x, y;
+    private boolean isFinished;
+
+    public Circle(double x, double y, double radius) {
+        this.x = x;
+        this.y = y;
+        this.radius = radius;
+        this.isFinished = true;
+    }
+
+
+    @Override
+    public void paint(GraphicsContext graphicsContext) {
+        graphicsContext.setStroke(Color.BLACK);
+        graphicsContext.setLineWidth(2);
+        if (isFinished) {
+            graphicsContext.setFill(Color.GREEN.deriveColor(0,1,1,0.5));
+            graphicsContext.fillOval(x - radius, y - radius, 2 * radius, 2 * radius);
+        }
+        graphicsContext.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 Math.sqrt(dx * dx + dy * dy) <= radius;
+    }
+
+    @Override
+    public void translate(double dx, double dy) {
+        this.x += dx;
+        this.y += dy;
+    }
+
+    @Override
+    public boolean isFinished() {
+        return isFinished;
+    }
+
+    public void setX(double x) {
+        this.x = x;
+    }
+
+    public void setY(double y) {
+        this.y = y;
+    }
+
+    public void setFinished(boolean finished) {
+        isFinished = finished;
+    }
+
+    public void updateRadius(double newX, double newY) {
+       this.radius = Math.sqrt(Math.pow(newX - this.x, 2) + Math.pow(newY - this.y, 2));
+    }
+
+    public double getX() {
+        return x;
+    }
+
+    public double getY() {
+        return y;
+    }
+
+    public void setDimensions(double x, double y, double width, double height){
+        this.x = x;
+        this.y = y;
+        this.radius = width/2;
+    }
+
+}
diff --git a/src/main/java/TP5/shape/Drawer.java b/src/main/java/TP5/shape/Drawer.java
new file mode 100644
index 0000000000000000000000000000000000000000..914e859a9b5c73c8076c5fb74f024b630b3e3d29
--- /dev/null
+++ b/src/main/java/TP5/shape/Drawer.java
@@ -0,0 +1,120 @@
+package TP5.shape;
+
+
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.MouseButton;
+import TP5.state.DrawerContext;
+import TP5.state.StateMoveShape;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Drawer {
+    private List<Shape> shapes;
+//    private double width;
+//    private double height;
+    private Canvas canvas;
+    private GraphicsContext gc;
+
+    private  String currentShapeType = "rectangle";
+    private Shape tempShape = null;
+    private boolean isFinished = false;
+    public DrawerContext context;
+
+
+    public Drawer(double width, double height) {
+//        this.width = width;
+//        this.height = height;
+        shapes = new ArrayList<>();
+        canvas = new Canvas(width,height);
+        gc = canvas.getGraphicsContext2D();
+        setupMouseHandlers();
+        setupKeyHandlers();
+    }
+
+    public void add(Shape shape) {
+        shapes.add(shape);
+    }
+    public void repaint(){
+        gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
+        for(Shape shape : shapes){
+            shape.paint(gc);
+        }
+        if (tempShape != null){
+            tempShape.paint(gc);
+        }
+    }
+
+    private void setupMouseHandlers(){
+        canvas.setOnMousePressed(event -> {
+            if(event.getButton() == MouseButton.PRIMARY){
+                double x = event.getX();
+                double y = event.getY();
+             //   tempShape = new Rectangle(x, y, 0, 0);
+                System.out.println(currentShapeType);
+                if (currentShapeType.equals("rectangle")) {
+                    tempShape = new Rectangle(x, y, 0, 0);
+                }else if (currentShapeType.equals("circle")) {
+                    tempShape = new Circle(x, y, 0);
+                }
+            }
+        });
+
+        canvas.setOnMouseDragged(event ->{
+            if (tempShape != null) {
+                double x = event.getX();
+                double y = event.getY();
+                if (tempShape instanceof Rectangle){
+                    ((Rectangle) tempShape).updateSize(x,y);
+                }else if (tempShape instanceof Circle){
+                    ((Circle) tempShape).updateRadius(x,y);
+                }
+                repaint();
+            }
+        });
+
+        canvas.setOnMouseReleased(event -> {
+            if(event.getButton() == MouseButton.PRIMARY && tempShape != null){
+                shapes.add(tempShape);
+                if (tempShape instanceof Rectangle){
+                    ((Rectangle) tempShape).setFinished(true);
+                }else if (tempShape instanceof Circle){
+
+                    ((Circle) tempShape).setFinished(true);
+                }
+                repaint();
+                tempShape = null;
+            }
+        });
+    }
+    private void setupKeyHandlers(){
+        canvas.setFocusTraversable(true);
+        canvas.setOnKeyPressed(event -> {
+            if (event.getCode() == KeyCode.R){
+                currentShapeType = "rectangle";
+                System.out.println("Current shape type is: " + currentShapeType);
+            }else if (event.getCode() == KeyCode.C){
+                currentShapeType = "circle";
+                System.out.println("Current shape type is: " + currentShapeType);
+            } else if (event.getCode() == KeyCode.M) {
+                currentShapeType = null ;
+            }
+        });
+    }
+
+   /* public Shape shapeContaining(double x, double y){
+        for(Shape shape : shapes){
+            if (shape.contains(x, y)){
+                return shape;
+            }
+        }
+        return null;
+    }*/
+
+
+    public Canvas getCanvas() {
+        return canvas;
+    }
+}
diff --git a/src/main/java/TP5/shape/Rectangle.java b/src/main/java/TP5/shape/Rectangle.java
new file mode 100644
index 0000000000000000000000000000000000000000..a702075705a0294d9c0e60b82bbb4dac6263e0d5
--- /dev/null
+++ b/src/main/java/TP5/shape/Rectangle.java
@@ -0,0 +1,88 @@
+package TP5.shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+public class Rectangle implements Shape{
+
+    private double x,y,width, height;
+    private boolean isFinished;
+    public Color fillColor;
+
+    public Rectangle(double x, double y, double width, double height) {
+        this.x = x;
+        this.y = y;
+        this.width = width;
+        this.height = height;
+        this.isFinished = true;
+    }
+
+    @Override
+    public void paint(GraphicsContext graphicsContext) {
+        graphicsContext.setStroke(Color.BLACK);
+        graphicsContext.setLineWidth(2);
+        if(isFinished){
+            graphicsContext.setFill(Color.RED.deriveColor(0,1,1,0.5));
+            graphicsContext.fillRect(x, y, width, height);
+        }
+        graphicsContext.strokeRect(x, y, width, height);
+
+    }
+
+    @Override
+    public boolean contains(double x, double y) {
+        return x>= this.x && x<= this.x + this.width
+                && y>= this.y && y<= this.y + this.height;
+    }
+
+    @Override
+    public void translate(double dx, double dy) {
+        x += dx;
+        y += dy;
+    }
+
+    @Override
+    public boolean isFinished() {
+        return isFinished;
+    }
+
+
+    public void updateSize(double newX, double newY) {
+        this.width = Math.abs(newX - this.x);
+        this.height = Math.abs(newY - this.y);
+        if (newX < this.x && newY < this.y) {
+            this.x = newX;
+            this.y = newY;
+        }
+    }
+
+    public Color getFillColor() {
+        return fillColor;
+    }
+
+    public void setFinished(boolean finished) {
+        isFinished = finished;
+    }
+
+    public void setFillColor(Color fillColor) {
+        this.fillColor = fillColor;
+    }
+
+    public double getX() {
+        return x;
+    }
+
+    public double getY() {
+        return y;
+    }
+
+    public void setDimensions(double x, double y, double width, double height) {
+        this.x = x;
+        this.y = y;
+        this.width = Math.abs(width);
+        this.height = Math.abs(height);
+        if(width < 0 ){ this.x += width;}
+        if(height < 0){ this.y += height;}
+    }
+}
diff --git a/src/main/java/TP5/shape/Shape.java b/src/main/java/TP5/shape/Shape.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f01b05615ba44ff6ac77d307df06614e6191fa4
--- /dev/null
+++ b/src/main/java/TP5/shape/Shape.java
@@ -0,0 +1,12 @@
+package TP5.shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+public interface Shape {
+    void paint(GraphicsContext graphicsContext);
+    boolean contains(double x, double y);
+    void translate(double dx, double dy);
+    boolean isFinished();
+}
diff --git a/src/main/java/TP5/state/App.java b/src/main/java/TP5/state/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ed103fa2707647a39d44ef02f388178a38f99ab
--- /dev/null
+++ b/src/main/java/TP5/state/App.java
@@ -0,0 +1,24 @@
+package TP5.state;
+
+import javafx.application.Application;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import TP5.shape.Circle;
+
+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/java/TP5/state/Drawer.java b/src/main/java/TP5/state/Drawer.java
new file mode 100644
index 0000000000000000000000000000000000000000..d89b71308b00d5d83c0979da24927cb787d1bf04
--- /dev/null
+++ b/src/main/java/TP5/state/Drawer.java
@@ -0,0 +1,40 @@
+package TP5.state;
+
+import javafx.scene.canvas.Canvas;
+import TP5.shape.Shape;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Drawer extends Canvas {
+    protected List<Shape> shapes = new ArrayList<>();
+    public DrawerContext context = new DrawerContext(this);
+
+    public Drawer(int width, int height) {
+        super(width,height);
+        setFocusTraversable(true);
+        setOnMousePressed(event->context.mousePressed(event));
+        setOnMouseReleased(event->context.mouseReleased(event));
+        setOnMouseMoved(event->context.mouseMoved(event));
+        setOnMouseDragged(event->context.mouseMoved(event));
+        setOnKeyPressed(event -> context.keyPressed(event));
+    }
+
+    public void repaint(){
+        this.getGraphicsContext2D().clearRect(0,0,this.getWidth(),this.getHeight());
+        for(Shape shape : shapes){
+            shape.paint(this.getGraphicsContext2D());
+        }
+    }
+    public void addShape(Shape shape){
+        shapes.add(shape);
+        repaint();
+    }
+    public Shape shapeContains(double x, double y){
+        for(Shape shape : shapes){
+            if(shape.contains(x,y))  return shape;
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/TP5/state/DrawerContext.java b/src/main/java/TP5/state/DrawerContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..590aa928b8cd05bf978a989d35a7202b7bbb7d04
--- /dev/null
+++ b/src/main/java/TP5/state/DrawerContext.java
@@ -0,0 +1,62 @@
+package TP5.state;
+
+
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+
+public class DrawerContext {
+
+    Drawer drawer;
+    DrawerState currentState;
+
+    public DrawerContext(Drawer drawer) {
+        this.drawer = drawer;
+        this.currentState = new NullDrawerState();
+    }
+    public void paint(GraphicsContext graphicsContext) {
+        drawer.repaint();
+    }
+
+    void mousePressed(MouseEvent event){
+        currentState.mousePressed(this,event.getX(),event.getY());
+
+    }
+
+    void mouseReleased(MouseEvent event){
+        currentState.mouseReleased(this,event.getX(),event.getY());
+    }
+
+    void mouseMoved(MouseEvent event){
+        currentState.mouseMoved(this,event.getX(),event.getY());
+    }
+
+    public void keyPressed(KeyEvent event) {
+        switch (event.getText()) {
+            case "c":
+                setState(new StateCircle0());
+                System.out.println("circle state");
+                break;
+            case "r":
+                setState(new StateRectangle0());
+                break;
+            case "m":
+                setState(new StateMoveShape());
+                System.out.println("state: " + currentState);
+                break;
+            default:
+                setState(new NullDrawerState());
+        }
+    }
+    public Drawer drawer(){
+        return drawer;
+    }
+
+    public Drawer getDrawer() {
+        return drawer;
+    }
+
+    public void setState(DrawerState state) {
+        this.currentState = state;
+    }
+}
diff --git a/src/main/java/TP5/state/DrawerState.java b/src/main/java/TP5/state/DrawerState.java
new file mode 100644
index 0000000000000000000000000000000000000000..c09f08e3a69b9eb0ba27e55e24a19cb0263a4467
--- /dev/null
+++ b/src/main/java/TP5/state/DrawerState.java
@@ -0,0 +1,8 @@
+package TP5.state;
+
+public 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);
+    public void paint(DrawerContext context);
+}
diff --git a/src/main/java/TP5/state/NullDrawerState.java b/src/main/java/TP5/state/NullDrawerState.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee48c3df11fc34c4be5634ea646d1c21417c70f7
--- /dev/null
+++ b/src/main/java/TP5/state/NullDrawerState.java
@@ -0,0 +1,17 @@
+package TP5.state;
+
+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(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP5/state/Shapes.java b/src/main/java/TP5/state/Shapes.java
new file mode 100644
index 0000000000000000000000000000000000000000..17dba3e0810fc02e109798d75114809152efdda1
--- /dev/null
+++ b/src/main/java/TP5/state/Shapes.java
@@ -0,0 +1,6 @@
+package TP5.state;
+
+public enum Shapes {
+    RECTANGLE,
+    CIRCLE,
+}
diff --git a/src/main/java/TP5/state/StateCircle0.java b/src/main/java/TP5/state/StateCircle0.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e52b21830ef9c7b75ea9688cb355474f7721357
--- /dev/null
+++ b/src/main/java/TP5/state/StateCircle0.java
@@ -0,0 +1,29 @@
+package TP5.state;
+
+import TP5.shape.Circle;
+
+public class StateCircle0 implements DrawerState {
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {
+        Circle circle = new Circle(x, y,0);
+        circle.setFinished(false);
+        context.getDrawer().addShape(circle);
+        context.setState(new StateCircle1(circle));
+
+    }
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP5/state/StateCircle1.java b/src/main/java/TP5/state/StateCircle1.java
new file mode 100644
index 0000000000000000000000000000000000000000..8656bafc57f4c1ba04fbd9e0d60fbf99e1e02c2f
--- /dev/null
+++ b/src/main/java/TP5/state/StateCircle1.java
@@ -0,0 +1,32 @@
+package TP5.state;
+
+import TP5.shape.Circle;
+
+public class StateCircle1 implements DrawerState{
+    private Circle circle;
+
+    public StateCircle1(Circle circle) {
+        this.circle = circle;
+    }
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        circle.setFinished(true);
+        context.paint(context.getDrawer().getGraphicsContext2D());
+        context.setState(new StateCircle0());
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+        double radius = Math.sqrt(Math.pow(x - circle.getX(), 2) + Math.pow(y - circle.getY(), 2));
+        circle.setDimensions(circle.getX(), circle.getY(), radius*2, radius*2);
+        context.paint(context.getDrawer().getGraphicsContext2D());
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP5/state/StateMoveShape.java b/src/main/java/TP5/state/StateMoveShape.java
new file mode 100644
index 0000000000000000000000000000000000000000..645c047486cfc4924fe52ab4a8286c684761058c
--- /dev/null
+++ b/src/main/java/TP5/state/StateMoveShape.java
@@ -0,0 +1,41 @@
+package TP5.state;
+
+import TP5.shape.Shape;
+
+public class StateMoveShape implements DrawerState{
+    private Shape selectedShape;
+    private double previousX, previousY;
+
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {
+        selectedShape = context.getDrawer().shapeContains(x,y);
+        System.out.println("selectedShape : " + selectedShape);
+        if(selectedShape != null) {
+            previousX = x;
+            previousY = y;
+        }
+
+    }
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        selectedShape = null;
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+        if(selectedShape != null) {
+            double deltaX = x - previousX;
+            double deltaY = y - previousY;
+            selectedShape.translate(deltaX, deltaY);
+            previousX = x;
+            previousY = y;
+            context.getDrawer().repaint();
+        }
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP5/state/StateRectangle0.java b/src/main/java/TP5/state/StateRectangle0.java
new file mode 100644
index 0000000000000000000000000000000000000000..54166ad7277c66b2da2d5bc5214aebd9fe1b08a8
--- /dev/null
+++ b/src/main/java/TP5/state/StateRectangle0.java
@@ -0,0 +1,30 @@
+package TP5.state;
+
+import TP5.shape.Rectangle;
+
+public class StateRectangle0 implements DrawerState{
+    public StateRectangle0() { }
+
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {
+        Rectangle rectangle = new Rectangle(x, y,0,0);
+        rectangle.setFinished(false);
+        context.getDrawer().addShape(rectangle);
+        context.setState(new StateRectangle1(rectangle));
+    }
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP5/state/StateRectangle1.java b/src/main/java/TP5/state/StateRectangle1.java
new file mode 100644
index 0000000000000000000000000000000000000000..c524e01ec59aa3d55616ac588583440026c77198
--- /dev/null
+++ b/src/main/java/TP5/state/StateRectangle1.java
@@ -0,0 +1,35 @@
+package TP5.state;
+
+import TP5.shape.Rectangle;
+
+public class StateRectangle1 implements DrawerState {
+    private Rectangle rectangle;
+    private double startX, startY;
+    public StateRectangle1(Rectangle rectangle) {
+        this.rectangle = rectangle;
+        this.startX = rectangle.getX();
+        this.startY = rectangle.getY();
+    }
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        rectangle.setFinished(true);
+        context.paint(context.getDrawer().getGraphicsContext2D());
+        context.setState(new StateRectangle0());
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+        double width = x - startX;
+        double height = y - startY;
+        rectangle.setDimensions(startX,startY,width,height);
+        context.paint(context.getDrawer().getGraphicsContext2D());
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP7/serializer/App.java b/src/main/java/TP7/serializer/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b0661778ebd01f95e03ad56bc52df91c3981452
--- /dev/null
+++ b/src/main/java/TP7/serializer/App.java
@@ -0,0 +1,31 @@
+package TP7.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/java/TP7/serializer/CircleSerializer.java b/src/main/java/TP7/serializer/CircleSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc3eb10b459c145125e6bbe3585a082b3266912e
--- /dev/null
+++ b/src/main/java/TP7/serializer/CircleSerializer.java
@@ -0,0 +1,24 @@
+package  TP7.serializer;
+
+import  TP7.shape.Circle;
+
+public class CircleSerializer implements ShapeSerializer<Circle> {
+    @Override
+    public String code() {
+        return "Circle";
+    }
+
+    @Override
+    public String serialize(Circle shape) {
+        return String.format("%f %f %f", shape.getX(), shape.getY(), shape.getRadius());
+    }
+
+    @Override
+    public Circle unserialize(String s) {
+        String[] split = s.split(" ");
+        double x = Double.parseDouble(split[0]);
+        double y = Double.parseDouble(split[1]);
+        double radius = Double.parseDouble(split[2]);
+        return new Circle(x, y, radius);
+    }
+}
diff --git a/src/main/java/TP7/serializer/DrawerWithSave.java b/src/main/java/TP7/serializer/DrawerWithSave.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1bdad54e7806a66d3e7b5034e6f9cab4a577f9a
--- /dev/null
+++ b/src/main/java/TP7/serializer/DrawerWithSave.java
@@ -0,0 +1,48 @@
+package  TP7.serializer;
+
+import javafx.scene.control.Alert;
+import javafx.stage.FileChooser;
+
+import java.io.File;
+import java.io.IOException;
+
+
+public class DrawerWithSave extends TP7.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/java/TP7/serializer/RectangleSerializer.java b/src/main/java/TP7/serializer/RectangleSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..78106956bb6e2fa4c4d7bb83637d193d104e397a
--- /dev/null
+++ b/src/main/java/TP7/serializer/RectangleSerializer.java
@@ -0,0 +1,25 @@
+package  TP7.serializer;
+
+import  TP7.shape.Rectangle;
+
+public class RectangleSerializer implements ShapeSerializer<Rectangle> {
+    @Override
+    public String code() {
+        return "Rectangle";
+    }
+
+    @Override
+    public String serialize(Rectangle shape) {
+        return String.format("%f %f %f %f", shape.getX(), shape.getY(), shape.getWidth(), shape.getHeight());
+    }
+
+    @Override
+    public Rectangle unserialize(String s) {
+        String[] split = s.split(" ");
+        double x = Double.parseDouble(split[0]);
+        double y = Double.parseDouble(split[1]);
+        double width = Double.parseDouble(split[2]);
+        double height = Double.parseDouble(split[3]);
+        return new Rectangle(x, y, width, height);
+    }
+}
diff --git a/src/main/java/TP7/serializer/ShapeReader.java b/src/main/java/TP7/serializer/ShapeReader.java
new file mode 100644
index 0000000000000000000000000000000000000000..5042f8d222081def5653db5dfaef3f1eb6f458f8
--- /dev/null
+++ b/src/main/java/TP7/serializer/ShapeReader.java
@@ -0,0 +1,40 @@
+package  TP7.serializer;
+
+import  TP7.shape.Circle;
+import  TP7.shape.Shape;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ShapeReader {
+
+    private static final Map<String, ShapeSerializer<?>> serializers = new HashMap<>();
+
+    static {
+        serializers.put("circle", new CircleSerializer());
+        serializers.put("rectangle", new RectangleSerializer());
+    }
+    public static List<Shape> read(File file) throws IOException {
+        List<Shape> shapes = new ArrayList<>();
+        try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
+        String line ;
+        while ((line = bufferedReader.readLine()) != null) {
+            String[] parts = line.split(" ",2);
+            String code = parts[0];
+            String data = parts[1];
+            ShapeSerializer<?> serializer = serializers.get(code);
+            if (serializer != null) {
+                Shape shape = serializer.unserialize(data);
+                shapes.add(shape);
+            }
+        }
+            return shapes;
+        }
+    }
+}
diff --git a/src/main/java/TP7/serializer/ShapeSerializer.java b/src/main/java/TP7/serializer/ShapeSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..8db3d2d52254df0b063f8eccc95a5a814996a6de
--- /dev/null
+++ b/src/main/java/TP7/serializer/ShapeSerializer.java
@@ -0,0 +1,9 @@
+package  TP7.serializer;
+
+import  TP7.shape.Shape;
+
+public interface ShapeSerializer<S extends Shape> {
+    String code();
+    String serialize(S shape);
+    S unserialize(String s);
+}
diff --git a/src/main/java/TP7/serializer/ShapeVisitor.java b/src/main/java/TP7/serializer/ShapeVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..b86f765fc55945b1a223fad13b7b270a49cccf57
--- /dev/null
+++ b/src/main/java/TP7/serializer/ShapeVisitor.java
@@ -0,0 +1,10 @@
+package  TP7.serializer;
+
+import  TP7.shape.Circle;
+import  TP7.shape.Rectangle;
+
+
+public interface ShapeVisitor {
+    void visit(Circle circle);
+    void visit(Rectangle rectangle);
+}
diff --git a/src/main/java/TP7/serializer/ShapeWriter.java b/src/main/java/TP7/serializer/ShapeWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..b678767ce9b713138df6c9c101cceb3f3fb81c21
--- /dev/null
+++ b/src/main/java/TP7/serializer/ShapeWriter.java
@@ -0,0 +1,39 @@
+package  TP7.serializer;
+
+import  TP7.shape.Circle;
+import  TP7.shape.Rectangle;
+import  TP7.shape.Shape;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+public class ShapeWriter implements ShapeVisitor {
+
+    private PrintWriter printWriter;
+
+    public ShapeWriter(PrintWriter printWriter) {
+        this.printWriter = printWriter;
+    }
+
+    public static void write (File file, List<Shape> shapes) throws IOException {
+        try(PrintWriter printWriter = new PrintWriter(file)){
+        ShapeWriter shapeWriter = new ShapeWriter(printWriter);
+
+        for (Shape shape : shapes) {
+            shape.accept(shapeWriter);
+        }
+        }
+    }
+
+    @Override
+    public void visit(Circle circle) {
+        printWriter.printf("Circle %f %f %f%n", circle.getX(), circle.getY(), circle.getRadius());
+    }
+
+    @Override
+    public void visit(Rectangle rectangle) {
+        printWriter.printf("Rectangle %f %f %f %f%n", rectangle.getX(), rectangle.getY(), rectangle.getWidth() ,rectangle.getHeight());
+    }
+}
diff --git a/src/main/java/TP7/shape/App.java b/src/main/java/TP7/shape/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d8a8c3ce40c679283d604c6ffd1827ff0acf4bc
--- /dev/null
+++ b/src/main/java/TP7/shape/App.java
@@ -0,0 +1,27 @@
+package  TP7.shape;
+
+import javafx.application.Application;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+
+public class App extends Application {
+
+    @Override
+    public void start(Stage primaryStage) {
+        Drawer drawer = new Drawer(600, 400);
+
+        Group root = new Group();
+        root.getChildren().add(drawer.getCanvas());
+
+        Scene scene = new Scene(root, 600, 400);
+
+        primaryStage.setTitle("JavaFX Drawer");
+        primaryStage.setScene(scene);
+        primaryStage.show();
+    }
+    public static void main(String[] args) {
+        launch(args);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/TP7/shape/Circle.java b/src/main/java/TP7/shape/Circle.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a4eb2156244645b6cd121878a0b00744d90a567
--- /dev/null
+++ b/src/main/java/TP7/shape/Circle.java
@@ -0,0 +1,87 @@
+package  TP7.shape;
+
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+import  TP7.serializer.ShapeVisitor;
+
+public class Circle implements Shape {
+
+    private double radius, x, y;
+    private boolean isFinished;
+
+    public Circle(double x, double y, double radius) {
+        this.x = x;
+        this.y = y;
+        this.radius = radius;
+        this.isFinished = true;
+    }
+
+
+    @Override
+    public void paint(GraphicsContext graphicsContext) {
+        graphicsContext.setStroke(Color.BLACK);
+        graphicsContext.setLineWidth(2);
+        if (isFinished) {
+            graphicsContext.setFill(Color.GREEN.deriveColor(0,1,1,0.5));
+            graphicsContext.fillOval(x - radius, y - radius, 2 * radius, 2 * radius);
+        }
+        graphicsContext.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 Math.sqrt(dx * dx + dy * dy) <= radius;
+    }
+
+    @Override
+    public void translate(double dx, double dy) {
+        this.x += dx;
+        this.y += dy;
+    }
+
+    @Override
+    public boolean isFinished() {
+        return isFinished;
+    }
+
+    @Override
+    public void accept(ShapeVisitor visitor) {
+        visitor.visit(this);
+    }
+
+    public void setX(double x) {
+        this.x = x;
+    }
+
+    public void setY(double y) {
+        this.y = y;
+    }
+
+    public void setFinished(boolean finished) {
+        isFinished = finished;
+    }
+
+    public void updateRadius(double newX, double newY) {
+       this.radius = Math.sqrt(Math.pow(newX - this.x, 2) + Math.pow(newY - this.y, 2));
+    }
+
+    public double getX() {
+        return x;
+    }
+
+    public double getY() {
+        return y;
+    }
+
+    public void setDimensions(double x, double y, double width, double height){
+        this.x = x;
+        this.y = y;
+        this.radius = width/2;
+    }
+
+    public double getRadius() {
+        return radius;
+    }
+}
diff --git a/src/main/java/TP7/shape/Drawer.java b/src/main/java/TP7/shape/Drawer.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc3809103e2415c507d745b5de74aaa93a764096
--- /dev/null
+++ b/src/main/java/TP7/shape/Drawer.java
@@ -0,0 +1,120 @@
+package  TP7.shape;
+
+
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.MouseButton;
+import  TP7.state.DrawerContext;
+import  TP7.state.StateMoveShape;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Drawer {
+    private List<Shape> shapes;
+//    private double width;
+//    private double height;
+    private Canvas canvas;
+    private GraphicsContext gc;
+
+    private  String currentShapeType = "rectangle";
+    private Shape tempShape = null;
+    private boolean isFinished = false;
+    public DrawerContext context;
+
+
+    public Drawer(double width, double height) {
+//        this.width = width;
+//        this.height = height;
+        shapes = new ArrayList<>();
+        canvas = new Canvas(width,height);
+        gc = canvas.getGraphicsContext2D();
+        setupMouseHandlers();
+        setupKeyHandlers();
+    }
+
+    public void add(Shape shape) {
+        shapes.add(shape);
+    }
+    public void repaint(){
+        gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
+        for(Shape shape : shapes){
+            shape.paint(gc);
+        }
+        if (tempShape != null){
+            tempShape.paint(gc);
+        }
+    }
+
+    private void setupMouseHandlers(){
+        canvas.setOnMousePressed(event -> {
+            if(event.getButton() == MouseButton.PRIMARY){
+                double x = event.getX();
+                double y = event.getY();
+             //   tempShape = new Rectangle(x, y, 0, 0);
+                System.out.println(currentShapeType);
+                if (currentShapeType.equals("rectangle")) {
+                    tempShape = new Rectangle(x, y, 0, 0);
+                }else if (currentShapeType.equals("circle")) {
+                    tempShape = new Circle(x, y, 0);
+                }
+            }
+        });
+
+        canvas.setOnMouseDragged(event ->{
+            if (tempShape != null) {
+                double x = event.getX();
+                double y = event.getY();
+                if (tempShape instanceof Rectangle){
+                    ((Rectangle) tempShape).updateSize(x,y);
+                }else if (tempShape instanceof Circle){
+                    ((Circle) tempShape).updateRadius(x,y);
+                }
+                repaint();
+            }
+        });
+
+        canvas.setOnMouseReleased(event -> {
+            if(event.getButton() == MouseButton.PRIMARY && tempShape != null){
+                shapes.add(tempShape);
+                if (tempShape instanceof Rectangle){
+                    ((Rectangle) tempShape).setFinished(true);
+                }else if (tempShape instanceof Circle){
+
+                    ((Circle) tempShape).setFinished(true);
+                }
+                repaint();
+                tempShape = null;
+            }
+        });
+    }
+    private void setupKeyHandlers(){
+        canvas.setFocusTraversable(true);
+        canvas.setOnKeyPressed(event -> {
+            if (event.getCode() == KeyCode.R){
+                currentShapeType = "rectangle";
+                System.out.println("Current shape type is: " + currentShapeType);
+            }else if (event.getCode() == KeyCode.C){
+                currentShapeType = "circle";
+                System.out.println("Current shape type is: " + currentShapeType);
+            } else if (event.getCode() == KeyCode.M) {
+                currentShapeType = null ;
+            }
+        });
+    }
+
+   /* public Shape shapeContaining(double x, double y){
+        for(Shape shape : shapes){
+            if (shape.contains(x, y)){
+                return shape;
+            }
+        }
+        return null;
+    }*/
+
+
+    public Canvas getCanvas() {
+        return canvas;
+    }
+}
diff --git a/src/main/java/TP7/shape/Rectangle.java b/src/main/java/TP7/shape/Rectangle.java
new file mode 100644
index 0000000000000000000000000000000000000000..e0cc3fa49ab05b771e43c8c12b7e97da32a57d1e
--- /dev/null
+++ b/src/main/java/TP7/shape/Rectangle.java
@@ -0,0 +1,102 @@
+package  TP7.shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+import  TP7.serializer.ShapeVisitor;
+
+public class Rectangle implements Shape{
+
+    private double x,y,width, height;
+    private boolean isFinished;
+    public Color fillColor;
+
+    public Rectangle(double x, double y, double width, double height) {
+        this.x = x;
+        this.y = y;
+        this.width = width;
+        this.height = height;
+        this.isFinished = true;
+    }
+
+    @Override
+    public void paint(GraphicsContext graphicsContext) {
+        graphicsContext.setStroke(Color.BLACK);
+        graphicsContext.setLineWidth(2);
+        if(isFinished){
+            graphicsContext.setFill(Color.RED.deriveColor(0,1,1,0.5));
+            graphicsContext.fillRect(x, y, width, height);
+        }
+        graphicsContext.strokeRect(x, y, width, height);
+
+    }
+
+    @Override
+    public boolean contains(double x, double y) {
+        return x>= this.x && x<= this.x + this.width
+                && y>= this.y && y<= this.y + this.height;
+    }
+
+    @Override
+    public void translate(double dx, double dy) {
+        x += dx;
+        y += dy;
+    }
+
+    @Override
+    public boolean isFinished() {
+        return isFinished;
+    }
+
+    @Override
+    public void accept(ShapeVisitor visitor) {
+        visitor.visit(this);
+    }
+
+
+    public void updateSize(double newX, double newY) {
+        this.width = Math.abs(newX - this.x);
+        this.height = Math.abs(newY - this.y);
+        if (newX < this.x && newY < this.y) {
+            this.x = newX;
+            this.y = newY;
+        }
+    }
+
+    public Color getFillColor() {
+        return fillColor;
+    }
+
+    public void setFinished(boolean finished) {
+        isFinished = finished;
+    }
+
+    public void setFillColor(Color fillColor) {
+        this.fillColor = fillColor;
+    }
+
+    public double getX() {
+        return x;
+    }
+
+    public double getY() {
+        return y;
+    }
+
+    public void setDimensions(double x, double y, double width, double height) {
+        this.x = x;
+        this.y = y;
+        this.width = Math.abs(width);
+        this.height = Math.abs(height);
+        if(width < 0 ){ this.x += width;}
+        if(height < 0){ this.y += height;}
+    }
+
+    public double getWidth() {
+        return width;
+    }
+
+    public double getHeight() {
+        return height;
+    }
+}
diff --git a/src/main/java/TP7/shape/Shape.java b/src/main/java/TP7/shape/Shape.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c9f230fd6da34d1a1693e76306dbaa4a13edf66
--- /dev/null
+++ b/src/main/java/TP7/shape/Shape.java
@@ -0,0 +1,14 @@
+package  TP7.shape;
+
+import javafx.geometry.Point2D;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+import  TP7.serializer.ShapeVisitor;
+
+public interface Shape {
+    void paint(GraphicsContext graphicsContext);
+    boolean contains(double x, double y);
+    void translate(double dx, double dy);
+    boolean isFinished();
+    void accept(ShapeVisitor visitor);
+}
diff --git a/src/main/java/TP7/state/App.java b/src/main/java/TP7/state/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..d26870fb1cfa77f40b07401e9ded490cadbd4aca
--- /dev/null
+++ b/src/main/java/TP7/state/App.java
@@ -0,0 +1,24 @@
+package  TP7.state;
+
+import javafx.application.Application;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import  TP7.shape.Circle;
+
+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/java/TP7/state/Drawer.java b/src/main/java/TP7/state/Drawer.java
new file mode 100644
index 0000000000000000000000000000000000000000..dfe52408a0c5d91c1d6cce7b2488d93b938be0a4
--- /dev/null
+++ b/src/main/java/TP7/state/Drawer.java
@@ -0,0 +1,40 @@
+package  TP7.state;
+
+import javafx.scene.canvas.Canvas;
+import  TP7.shape.Shape;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Drawer extends Canvas {
+    protected List<Shape> shapes = new ArrayList<>();
+    public DrawerContext context = new DrawerContext(this);
+
+    public Drawer(int width, int height) {
+        super(width,height);
+        setFocusTraversable(true);
+        setOnMousePressed(event->context.mousePressed(event));
+        setOnMouseReleased(event->context.mouseReleased(event));
+        setOnMouseMoved(event->context.mouseMoved(event));
+        setOnMouseDragged(event->context.mouseMoved(event));
+        setOnKeyPressed(event -> context.keyPressed(event));
+    }
+
+    public void repaint(){
+        this.getGraphicsContext2D().clearRect(0,0,this.getWidth(),this.getHeight());
+        for(Shape shape : shapes){
+            shape.paint(this.getGraphicsContext2D());
+        }
+    }
+    public void addShape(Shape shape){
+        shapes.add(shape);
+        repaint();
+    }
+    public Shape shapeContains(double x, double y){
+        for(Shape shape : shapes){
+            if(shape.contains(x,y))  return shape;
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/TP7/state/DrawerContext.java b/src/main/java/TP7/state/DrawerContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..eff218a47b127d83a8f6d51b23baa67861e76e36
--- /dev/null
+++ b/src/main/java/TP7/state/DrawerContext.java
@@ -0,0 +1,62 @@
+package  TP7.state;
+
+
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+
+public class DrawerContext {
+
+    Drawer drawer;
+    DrawerState currentState;
+
+    public DrawerContext(Drawer drawer) {
+        this.drawer = drawer;
+        this.currentState = new NullDrawerState();
+    }
+    public void paint(GraphicsContext graphicsContext) {
+        drawer.repaint();
+    }
+
+    void mousePressed(MouseEvent event){
+        currentState.mousePressed(this,event.getX(),event.getY());
+
+    }
+
+    void mouseReleased(MouseEvent event){
+        currentState.mouseReleased(this,event.getX(),event.getY());
+    }
+
+    void mouseMoved(MouseEvent event){
+        currentState.mouseMoved(this,event.getX(),event.getY());
+    }
+
+    public void keyPressed(KeyEvent event) {
+        switch (event.getText()) {
+            case "c":
+                setState(new StateCircle0());
+                System.out.println("circle state");
+                break;
+            case "r":
+                setState(new StateRectangle0());
+                break;
+            case "m":
+                setState(new StateMoveShape());
+                System.out.println("state: " + currentState);
+                break;
+            default:
+                setState(new NullDrawerState());
+        }
+    }
+    public Drawer drawer(){
+        return drawer;
+    }
+
+    public Drawer getDrawer() {
+        return drawer;
+    }
+
+    public void setState(DrawerState state) {
+        this.currentState = state;
+    }
+}
diff --git a/src/main/java/TP7/state/DrawerState.java b/src/main/java/TP7/state/DrawerState.java
new file mode 100644
index 0000000000000000000000000000000000000000..2bfb22e97b36274a07b864db84ddb11e9990f2a1
--- /dev/null
+++ b/src/main/java/TP7/state/DrawerState.java
@@ -0,0 +1,8 @@
+package  TP7.state;
+
+public 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);
+    public void paint(DrawerContext context);
+}
diff --git a/src/main/java/TP7/state/NullDrawerState.java b/src/main/java/TP7/state/NullDrawerState.java
new file mode 100644
index 0000000000000000000000000000000000000000..29bbe8a036b39ecc4491e6b04b5b1da8b41ca721
--- /dev/null
+++ b/src/main/java/TP7/state/NullDrawerState.java
@@ -0,0 +1,17 @@
+package  TP7.state;
+
+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(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP7/state/Shapes.java b/src/main/java/TP7/state/Shapes.java
new file mode 100644
index 0000000000000000000000000000000000000000..b872a3c989ea1452a23a8ddffe548b69c08be597
--- /dev/null
+++ b/src/main/java/TP7/state/Shapes.java
@@ -0,0 +1,6 @@
+package  TP7.state;
+
+public enum Shapes {
+    RECTANGLE,
+    CIRCLE,
+}
diff --git a/src/main/java/TP7/state/StateCircle0.java b/src/main/java/TP7/state/StateCircle0.java
new file mode 100644
index 0000000000000000000000000000000000000000..e026c18dcf8fd0b4c62b3c0afbeb5220bbcf79b7
--- /dev/null
+++ b/src/main/java/TP7/state/StateCircle0.java
@@ -0,0 +1,29 @@
+package  TP7.state;
+
+import  TP7.shape.Circle;
+
+public class StateCircle0 implements DrawerState {
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {
+        Circle circle = new Circle(x, y,0);
+        circle.setFinished(false);
+        context.getDrawer().addShape(circle);
+        context.setState(new StateCircle1(circle));
+
+    }
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP7/state/StateCircle1.java b/src/main/java/TP7/state/StateCircle1.java
new file mode 100644
index 0000000000000000000000000000000000000000..88a3364c573b33d17282cd2d8f1c57728de82421
--- /dev/null
+++ b/src/main/java/TP7/state/StateCircle1.java
@@ -0,0 +1,32 @@
+package  TP7.state;
+
+import  TP7.shape.Circle;
+
+public class StateCircle1 implements DrawerState{
+    private Circle circle;
+
+    public StateCircle1(Circle circle) {
+        this.circle = circle;
+    }
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        circle.setFinished(true);
+        context.paint(context.getDrawer().getGraphicsContext2D());
+        context.setState(new StateCircle0());
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+        double radius = Math.sqrt(Math.pow(x - circle.getX(), 2) + Math.pow(y - circle.getY(), 2));
+        circle.setDimensions(circle.getX(), circle.getY(), radius*2, radius*2);
+        context.paint(context.getDrawer().getGraphicsContext2D());
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP7/state/StateMoveShape.java b/src/main/java/TP7/state/StateMoveShape.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1c3994b9bbf772eee5440c7986984888d793e09
--- /dev/null
+++ b/src/main/java/TP7/state/StateMoveShape.java
@@ -0,0 +1,41 @@
+package  TP7.state;
+
+import  TP7.shape.Shape;
+
+public class StateMoveShape implements DrawerState{
+    private Shape selectedShape;
+    private double previousX, previousY;
+
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {
+        selectedShape = context.getDrawer().shapeContains(x,y);
+        System.out.println("selectedShape : " + selectedShape);
+        if(selectedShape != null) {
+            previousX = x;
+            previousY = y;
+        }
+
+    }
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        selectedShape = null;
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+        if(selectedShape != null) {
+            double deltaX = x - previousX;
+            double deltaY = y - previousY;
+            selectedShape.translate(deltaX, deltaY);
+            previousX = x;
+            previousY = y;
+            context.getDrawer().repaint();
+        }
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP7/state/StateRectangle0.java b/src/main/java/TP7/state/StateRectangle0.java
new file mode 100644
index 0000000000000000000000000000000000000000..ead84bb4dbac8e3d62870558e3e8e7f9dbdc82f4
--- /dev/null
+++ b/src/main/java/TP7/state/StateRectangle0.java
@@ -0,0 +1,30 @@
+package  TP7.state;
+
+import  TP7.shape.Rectangle;
+
+public class StateRectangle0 implements DrawerState{
+    public StateRectangle0() { }
+
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {
+        Rectangle rectangle = new Rectangle(x, y,0,0);
+        rectangle.setFinished(false);
+        context.getDrawer().addShape(rectangle);
+        context.setState(new StateRectangle1(rectangle));
+    }
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}
diff --git a/src/main/java/TP7/state/StateRectangle1.java b/src/main/java/TP7/state/StateRectangle1.java
new file mode 100644
index 0000000000000000000000000000000000000000..446afe61d283564950b80d015bedf7d7195eba24
--- /dev/null
+++ b/src/main/java/TP7/state/StateRectangle1.java
@@ -0,0 +1,35 @@
+package  TP7.state;
+
+import  TP7.shape.Rectangle;
+
+public class StateRectangle1 implements DrawerState {
+    private Rectangle rectangle;
+    private double startX, startY;
+    public StateRectangle1(Rectangle rectangle) {
+        this.rectangle = rectangle;
+        this.startX = rectangle.getX();
+        this.startY = rectangle.getY();
+    }
+    @Override
+    public void mousePressed(DrawerContext context, double x, double y) {}
+
+    @Override
+    public void mouseReleased(DrawerContext context, double x, double y) {
+        rectangle.setFinished(true);
+        context.paint(context.getDrawer().getGraphicsContext2D());
+        context.setState(new StateRectangle0());
+    }
+
+    @Override
+    public void mouseMoved(DrawerContext context, double x, double y) {
+        double width = x - startX;
+        double height = y - startY;
+        rectangle.setDimensions(startX,startY,width,height);
+        context.paint(context.getDrawer().getGraphicsContext2D());
+    }
+
+    @Override
+    public void paint(DrawerContext context) {
+
+    }
+}