lab 5
diff --git a/src/sample/ArtRico.java b/src/sample/ArtRico.java
index 3a1b778..2ed17b0 100644
--- a/src/sample/ArtRico.java
+++ b/src/sample/ArtRico.java
@@ -20,7 +20,7 @@
    */
   @Override
   public void start(Stage primaryStage) {
-    primaryStage.setTitle("ArtRik");
+    primaryStage.setTitle("ArtRico");
     showMenu(primaryStage);
   }
 
diff --git a/src/sample/Ball.java b/src/sample/Ball.java
index 50604a1..daeb83c 100644
--- a/src/sample/Ball.java
+++ b/src/sample/Ball.java
@@ -30,8 +30,8 @@
   boolean topCover;
   boolean bottomCover;
   int score;
+
   /**
-   *
    * @param x
    * @param y
    * @param w
@@ -245,16 +245,15 @@
   }
 
   /**
-   *
    * @param bricks
    */
   public void setBricks(ArrayList<SimpleObject> bricks) {
     this.bricks.clear();
+    score = 0;
     this.bricks.addAll(bricks);
   }
 
   /**
-   *
    * @param player
    */
   public void setPlayer(Player player) {
@@ -262,7 +261,6 @@
   }
 
   /**
-   *
    * @return
    */
   public boolean isGameOver() {
@@ -270,7 +268,6 @@
   }
 
   /**
-   *
    * @return
    */
   public boolean isGameWon() {
diff --git a/src/sample/Client.java b/src/sample/Client.java
index 1e6998b..074f648 100644
--- a/src/sample/Client.java
+++ b/src/sample/Client.java
@@ -20,7 +20,6 @@
   SimpleObject rightWall;
   SimpleObject top;
   SimpleObject bottom;
-  Rectangle background;
   Label scoreLabel;
   Server server;
   Game game;
@@ -31,9 +30,9 @@
 
   public Client(char gameMode, Game game) {
     super();
+    this.game = game;
     server = new Server(gameMode, this);
     this.bricks = new ArrayList<>();
-    this.game = game;
     working = true;
     start();
   }
@@ -59,12 +58,10 @@
   private Pane initGame() {
     gameRoot = new Pane();
     gameRoot.setPrefSize(SCENE_WIDTH, SCENE_HEIGHT);
-    background = new Rectangle(SCENE_WIDTH, SCENE_HEIGHT, Color.GREY);
     scoreLabel = new Label();
     scoreLabel.setLayoutX(40);
-    scoreLabel.setLayoutY(0);
+    scoreLabel.setLayoutY(3);
     scoreLabel.setFont(javafx.scene.text.Font.font(20));
-    gameRoot.getChildren().add(background);
     gameRoot.getChildren().addAll(bricks);
     gameRoot.getChildren().addAll(player, ball, leftWall, rightWall, top, bottom);
     gameRoot.getChildren().add(scoreLabel);
@@ -127,4 +124,8 @@
   public char getDirection() {
     return direction;
   }
+
+  public String getReplayFile(){
+    return game.getReplayFile();
+  }
 }
diff --git a/src/sample/Constants.java b/src/sample/Constants.java
index c21a2b9..7960fba 100644
--- a/src/sample/Constants.java
+++ b/src/sample/Constants.java
@@ -11,11 +11,14 @@
   int TOP_HEIGHT = 30;
   int BOTTOM_HEIGHT = 10;
   int PLAYER_HEIGHT = 20;
+  int GRID_INDENTS = 20;
+  int GRID_LABEL_HEIGHT = 30;
   int PLAYER_POS_Y = 570;
   char EASY_MODE = 'e';
   char MEDIUM_MODE = 'm';
   char HARD_MODE = 'h';
   char REPLAY_MODE = 'r';
+  int ITER_COUNT = 10000;
   int PLAYER_WIDTH_EASY = 280;
   int PLAYER_WIDTH_MEDIUM = 200;
   int PLAYER_WIDTH_HARD = 200;
@@ -35,5 +38,6 @@
   int BUTTON_BORDER = 20;
   int MENU_SIZE = 5;
   int NEW_GAME_MENU_SIZE = 4;
-  String REPLAY_FILE = "last_replay";
+  String[] TOP_LABEL_CONTENT = {"REPLAY", "MODE", "PLAYED", "MOVED LEFT", "MOVED RIGHT"};
+  String RESOURSE_FOLDER = "Resource\\";
 }
diff --git a/src/sample/Game.java b/src/sample/Game.java
index 90ae4ff..20675dc 100644
--- a/src/sample/Game.java
+++ b/src/sample/Game.java
@@ -2,13 +2,22 @@
 
 import javafx.application.Application;
 import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Pane;
 import javafx.stage.Stage;
 
-public class Game extends Application {
+import java.io.File;
+import java.util.ArrayList;
+
+public class Game extends Application implements Constants {
+  Pane menuRoot;
   char gameMode;
   Stage gameStage;
   Scene scene;
   Client client;
+  String replayFile;
+  ArrayList<ReplayInfo> replays;
 
   public Game(char gameMode) {
     this.gameMode = gameMode;
@@ -17,15 +26,145 @@
   }
 
   public void start(Stage gameStage) {
+    if (gameMode == REPLAY_MODE) {
+      replays = new ArrayList<>();
+      showReplayMenu();
+    } else {
+      startGame();
+    }
+  }
+
+  public void startGame() {
     client = new Client(gameMode, this);
     try {
       Thread.sleep(500);
     } catch (InterruptedException e) {
     }
     scene = client.scene;
+    scene.getStylesheets().add(Game.class.getResource("style.css").toExternalForm());
     gameStage.setScene(scene);
     gameStage.show();
+  }
 
+  private void showReplayMenu() {
+    menuRoot = new Pane();
+    menuRoot.setPrefSize(SCENE_WIDTH, SCENE_HEIGHT);
+    File folder = new File(RESOURSE_FOLDER);
+    String[] fileNames = folder.list();
+    if(fileNames == null) {
+      return;
+    }
+    for (int i = 0; i < fileNames.length; i++) {
+      ReplayInfo replayInfo = new ReplayInfo(fileNames[i]);
+      replays.add(replayInfo);
+    }
+
+    GridPane gridPane = new GridPane();
+    gridPane.setLayoutX(GRID_INDENTS);
+    gridPane.setLayoutY(GRID_INDENTS);
+    gridPane.setGridLinesVisible(true);
+    menuRoot.getChildren().add(gridPane);
+    addLabels(gridPane);
+    scene = new Scene(menuRoot);
+    scene.getStylesheets().add(Game.class.getResource("style.css").toExternalForm());
+
+    gridPane.setOnMouseClicked(e -> {
+      int fileNumber = ((int) e.getY()) / GRID_LABEL_HEIGHT - 1;
+      if (fileNumber != -1 && fileNumber < fileNames.length) {
+        menuRoot.getChildren().remove(gridPane);
+        replayFile = RESOURSE_FOLDER + fileNames[fileNumber];
+        startGame();
+      } else if (fileNumber == -1) {
+        ReplayInfo.sortBy = (int) e.getX() * 5 / (SCENE_WIDTH - GRID_INDENTS * 2);
+        replays.sort(ReplayInfo::compareTo);
+        addLabels(gridPane);
+      }
+    });
+    scene.setOnKeyPressed(event -> {
+      if (event.getCode().toString() == "ESCAPE") {
+        gameStage.close();
+      } else if(event.getCode().toString() == "T") {
+        sortTest();
+      }
+    });
+    gameStage.setScene(scene);
+    gameStage.show();
+  }
+
+  public String getReplayFile() {
+    return replayFile;
+  }
+
+  public void addLabels(GridPane gridPane) {
+    gridPane.getChildren().clear();
+
+    for (int i = 0; i < 5; i++) {
+      Label topLabel = new Label();
+      topLabel.setText(TOP_LABEL_CONTENT[i]);
+      topLabel.setPrefWidth((SCENE_WIDTH - GRID_INDENTS * 2) / 5);
+      topLabel.setPrefHeight(GRID_LABEL_HEIGHT);
+      gridPane.add(topLabel, i, 0);
+    }
+
+    for (int i = 0; i < replays.size(); i++) {
+      Label replayNameLabel = new Label();
+      replayNameLabel.setText(replays.get(i).getReplayName());
+      replayNameLabel.setPrefWidth((SCENE_WIDTH - GRID_INDENTS * 2) / 5);
+      replayNameLabel.setPrefHeight(GRID_LABEL_HEIGHT);
+      gridPane.add(replayNameLabel, 0, i + 1);
+
+      Label replayModeLabel = new Label();
+      replayModeLabel.setText(replays.get(i).getReplayMode());
+      replayModeLabel.setPrefWidth((SCENE_WIDTH - GRID_INDENTS * 2) / 5);
+      replayModeLabel.setPrefHeight(GRID_LABEL_HEIGHT);
+      gridPane.add(replayModeLabel, 1, i + 1);
+
+      Label gameTimeLabel = new Label();
+      gameTimeLabel.setText(Integer.toString(replays.get(i).getGameTime()));
+      gameTimeLabel.setPrefWidth((SCENE_WIDTH - GRID_INDENTS * 2) / 5);
+      gameTimeLabel.setPrefHeight(GRID_LABEL_HEIGHT);
+      gridPane.add(gameTimeLabel, 2, i + 1);
+
+      Label leftMovingTimeLabel = new Label();
+      leftMovingTimeLabel.setText(Integer.toString(replays.get(i).getLeftMovingTime()));
+      leftMovingTimeLabel.setPrefWidth((SCENE_WIDTH - GRID_INDENTS * 2) / 5);
+      leftMovingTimeLabel.setPrefHeight(GRID_LABEL_HEIGHT);
+      gridPane.add(leftMovingTimeLabel, 3, i + 1);
+
+      Label rightMovingTimeLabel = new Label();
+      rightMovingTimeLabel.setText(Integer.toString(replays.get(i).getRightMovingTime()));
+      rightMovingTimeLabel.setPrefWidth((SCENE_WIDTH - GRID_INDENTS * 2) / 5);
+      rightMovingTimeLabel.setPrefHeight(GRID_LABEL_HEIGHT);
+      gridPane.add(rightMovingTimeLabel, 4, i + 1);
+    }
+  }
+
+  void sortTest() {
+    long start;
+    long end;
+    long traceTime;
+    Sorting sorting = new Sorting();
+    JavaSort javaSort = new JavaSort();
+    int [] array = new int[replays.size()];
+    for(int i = 0; i < replays.size(); i++){
+      array[i] = replays.get(i).getGameTime();
+    }
+    System.out.println("Time of sorting:");
+    start = System.nanoTime();
+    for(int i = 0; i < ITER_COUNT; i++){
+      sorting.sort(array);
+    }
+    end = System.nanoTime();
+    traceTime = end-start;
+    System.out.println("Scala: " + traceTime);
+
+    start = System.nanoTime();
+    for(int i = 0; i < ITER_COUNT; i++) {
+      javaSort.sort(array);
+    }
+    end = System.nanoTime();
+    traceTime = end-start;
+    System.out.println("Java:  " + traceTime);
   }
 
   public void exit() {
diff --git a/src/sample/JavaSort.java b/src/sample/JavaSort.java
new file mode 100644
index 0000000..00302aa
--- /dev/null
+++ b/src/sample/JavaSort.java
@@ -0,0 +1,34 @@
+package sample;
+
+public class JavaSort {
+  void sort(int[] xs) {
+    sort(xs, 0, xs.length - 1);
+  }
+
+  void sort(int[] xs, int l, int r) {
+    int pivot = xs[(l + r) / 2];
+    int a = l;
+    int b = r;
+    while (a <= b) {
+      while (xs[a] < pivot) {
+        a = a + 1;
+      }
+      while (xs[b] > pivot) {
+        b = b - 1;
+      }
+      if (a <= b) {
+        swap(xs, a, b);
+        a = a + 1;
+        b = b - 1;
+      }
+    }
+    if (l < b) sort(xs, l, b);
+    if (b < r) sort(xs, a, r);
+  }
+
+  void swap(int[] arr, int i, int j) {
+    int t = arr[i];
+    arr[i] = arr[j];
+    arr[j] = t;
+  }
+}
diff --git a/src/sample/Player.java b/src/sample/Player.java
index ae85004..db28268 100644
--- a/src/sample/Player.java
+++ b/src/sample/Player.java
@@ -12,7 +12,6 @@
   double rightBorder;
 
   /**
-   *
    * @param x
    * @param y
    * @param w
diff --git a/src/sample/ReplayInfo.java b/src/sample/ReplayInfo.java
new file mode 100644
index 0000000..db587d2
--- /dev/null
+++ b/src/sample/ReplayInfo.java
@@ -0,0 +1,85 @@
+package sample;
+
+public class ReplayInfo implements Constants, Comparable<ReplayInfo> {
+  String replayName;
+  String replay;
+  String replayMode;
+  int rightMovingTime;
+  int leftMovingTime;
+  int gameTime;
+  static int sortBy;
+
+  ReplayInfo(String replayName) {
+    this.replayName = replayName;
+    replay = Serializer.loadReplay(RESOURSE_FOLDER + replayName);
+    switch (replay.toCharArray()[0]) {
+      case 'e':
+        replayMode = "EASY";
+        break;
+      case 'm':
+        replayMode = "MEDIUM";
+        break;
+      case 'h':
+        replayMode = "HARD";
+        break;
+    }
+    rightMovingTime = 0;
+    leftMovingTime = 0;
+    gameTime = replay.length() - 1;
+    for (int i = 1; i <= gameTime; i++) {
+      char currentSymbol = replay.toCharArray()[i];
+      switch (currentSymbol) {
+        case 'l':
+          leftMovingTime++;
+          break;
+        case 'r':
+          rightMovingTime++;
+          break;
+      }
+    }
+  }
+
+  @Override
+  public int compareTo(ReplayInfo o) {
+    int result = 0;
+    switch (sortBy) {
+      case 0:
+        result = Integer.compare(new Integer(replayName), new Integer(o.replayName));
+        break;
+      case 1:
+        result = replayMode.compareTo(o.replayMode);
+        break;
+      case 2:
+        result = Integer.compare(gameTime, o.gameTime);
+        break;
+      case 3:
+        result = Integer.compare(leftMovingTime, o.leftMovingTime);
+        break;
+      case 4:
+        result = Integer.compare(rightMovingTime, o.rightMovingTime);
+        break;
+    }
+    return result;
+  }
+
+  public int getRightMovingTime() {
+    return rightMovingTime;
+  }
+
+  public String getReplayMode() {
+    return replayMode;
+  }
+
+  public int getLeftMovingTime() {
+    return leftMovingTime;
+  }
+
+  public int getGameTime() {
+    return gameTime;
+  }
+
+  public String getReplayName() {
+    return replayName;
+  }
+
+}
diff --git a/src/sample/Serializer.java b/src/sample/Serializer.java
index b1e3c43..5e967de 100644
--- a/src/sample/Serializer.java
+++ b/src/sample/Serializer.java
@@ -1,16 +1,36 @@
 package sample;
 
 import java.io.*;
+import java.util.Date;
 
 /**
  *
  */
-public class Serializer {
+public class Serializer implements Constants {
   /**
-   * @param fileName
    * @param string
    */
-  public static void saveReplay(String fileName, String string) {
+  public static void saveReplay(String string) {
+    File folder = new File(RESOURSE_FOLDER);
+    String[] fileNames = folder.list();
+    int max = 0;
+    if (fileNames != null) {
+      try {
+        for (int i = 0; i < fileNames.length; i++) {
+          Integer temp = new Integer(fileNames[i]);
+          if (temp > max) {
+            max = temp;
+          }
+        }
+        max++;
+      } catch (NumberFormatException e) {
+      }
+    }
+    else {
+      max = 1;
+    }
+
+    String fileName = RESOURSE_FOLDER + Integer.toString(max);
     File file = new File(fileName);
     try (FileWriter writer = new FileWriter(file, false)) {
       writer.write(string);
diff --git a/src/sample/Server.java b/src/sample/Server.java
index 0b0624a..895176c 100644
--- a/src/sample/Server.java
+++ b/src/sample/Server.java
@@ -18,7 +18,6 @@
   boolean pause;
   Bot bot;
   boolean working;
-
   String replay;
   boolean replayNow;
   int replayIterator;
@@ -30,7 +29,7 @@
     super();
     working = true;
     if (gameMode == REPLAY_MODE) {
-      replay = Serializer.loadReplay(REPLAY_FILE);
+      replay = Serializer.loadReplay(client.getReplayFile());
       if (!replay.isEmpty()) {
         replayNow = true;
         this.gameMode = replay.toCharArray()[0];
@@ -57,10 +56,9 @@
       timer = new AnimationTimer() {
         @Override
         public void handle(long now) {
-          if(working) {
+          if (working) {
             update();
-          }
-          else {
+          } else {
             timer.stop();
           }
         }
@@ -72,22 +70,22 @@
 
   private void createContent() {
     leftWall = new SimpleObject(0, 0, WALL_WIDTH, SCENE_HEIGHT,
-        STROKE_WIDTH, Color.ORANGE, Color.BEIGE);
+        STROKE_WIDTH, Color.ORANGERED, Color.BEIGE);
     rightWall = new SimpleObject(SCENE_WIDTH - WALL_WIDTH, 0, WALL_WIDTH,
-        SCENE_WIDTH, STROKE_WIDTH, Color.ORANGE, Color.BEIGE);
+        SCENE_WIDTH, STROKE_WIDTH, Color.ORANGERED, Color.BEIGE);
     bottom = new SimpleObject(0, SCENE_HEIGHT, SCENE_WIDTH, BOTTOM_HEIGHT,
-        STROKE_WIDTH, Color.ORANGE, Color.BEIGE);
+        STROKE_WIDTH, Color.ORANGERED, Color.BEIGE);
     top = new SimpleObject(0, 0, SCENE_WIDTH, TOP_HEIGHT,
-        STROKE_WIDTH, Color.ORANGE, Color.BEIGE);
+        STROKE_WIDTH, Color.ORANGERED, Color.BEIGE);
 
     switch (gameMode) {
       case EASY_MODE: {
         player = new Player(SCENE_WIDTH / 2 - PLAYER_WIDTH_EASY / 2,
             PLAYER_POS_Y, PLAYER_WIDTH_EASY, PLAYER_HEIGHT,
-            STROKE_WIDTH, Color.ORANGE, Color.BEIGE,
+            STROKE_WIDTH, Color.ORANGERED, Color.BEIGE,
             WALL_WIDTH, SCENE_WIDTH - WALL_WIDTH, PLAYER_SPEED_EASY);
         ball = new Ball(SCENE_WIDTH / 2 - BALL_SIZE / 2, PLAYER_POS_Y - BALL_SIZE,
-            BALL_SIZE, BALL_SIZE, STROKE_WIDTH, Color.ORANGE,
+            BALL_SIZE, BALL_SIZE, STROKE_WIDTH, Color.ORANGERED,
             Color.BEIGE, WALL_WIDTH, SCENE_WIDTH - WALL_WIDTH,
             TOP_HEIGHT, SCENE_HEIGHT, BALL_SPEED_EASY);
         break;
@@ -95,10 +93,10 @@
       case MEDIUM_MODE: {
         player = new Player(SCENE_WIDTH / 2 - PLAYER_WIDTH_MEDIUM / 2,
             PLAYER_POS_Y, PLAYER_WIDTH_MEDIUM,
-            PLAYER_HEIGHT, STROKE_WIDTH, Color.ORANGE, Color.BEIGE,
+            PLAYER_HEIGHT, STROKE_WIDTH, Color.ORANGERED, Color.BEIGE,
             WALL_WIDTH, SCENE_WIDTH - WALL_WIDTH, PLAYER_SPEED_MEDIUM);
         ball = new Ball(SCENE_WIDTH / 2 - BALL_SIZE / 2, PLAYER_POS_Y - BALL_SIZE,
-            BALL_SIZE, BALL_SIZE, STROKE_WIDTH, Color.ORANGE,
+            BALL_SIZE, BALL_SIZE, STROKE_WIDTH, Color.ORANGERED,
             Color.BEIGE, WALL_WIDTH, SCENE_WIDTH - WALL_WIDTH,
             TOP_HEIGHT, SCENE_HEIGHT, BALL_SPEED_MEDIUM);
         break;
@@ -106,11 +104,11 @@
       case HARD_MODE: {
         player = new Player(SCENE_WIDTH / 2 - PLAYER_WIDTH_HARD / 2,
             PLAYER_POS_Y, PLAYER_WIDTH_HARD, PLAYER_HEIGHT,
-            STROKE_WIDTH, Color.ORANGE, Color.BEIGE,
+            STROKE_WIDTH, Color.ORANGERED, Color.BEIGE,
             WALL_WIDTH, SCENE_WIDTH - WALL_WIDTH, PLAYER_SPEED_HARD);
         ball = new Ball(SCENE_WIDTH / 2 - BALL_SIZE / 2,
             PLAYER_POS_Y - BALL_SIZE, BALL_SIZE,
-            BALL_SIZE, STROKE_WIDTH, Color.ORANGE,
+            BALL_SIZE, STROKE_WIDTH, Color.ORANGERED,
             Color.BEIGE, WALL_WIDTH, SCENE_WIDTH - WALL_WIDTH,
             TOP_HEIGHT, SCENE_HEIGHT, BALL_SPEED_HARD);
         break;
@@ -135,7 +133,7 @@
     for (int i = 0; i < raw; i++) {
       for (int j = 0; j < colomn; j++) {
         SimpleObject brick = new SimpleObject(j * width + 40, i * height + 75,
-            width, height, STROKE_WIDTH, Color.ORANGE, Color.BEIGE);
+            width, height, STROKE_WIDTH, Color.ORANGERED, Color.BEIGE);
         bricks.add(brick);
 
       }
@@ -173,7 +171,7 @@
     if (replayNow) {
       replayIterator = 1;
     } else {
-      Serializer.saveReplay(REPLAY_FILE, replay);
+      Serializer.saveReplay(replay);
       replay = "" + gameMode;
     }
     client.resetBricks();
diff --git a/src/sample/SimpleObject.java b/src/sample/SimpleObject.java
index 1306633..35d6a8f 100644
--- a/src/sample/SimpleObject.java
+++ b/src/sample/SimpleObject.java
@@ -11,7 +11,6 @@
   Rectangle rect;
 
   /**
-   *
    * @param x
    * @param y
    * @param w
diff --git a/src/sample/Sorting.scala b/src/sample/Sorting.scala
new file mode 100644
index 0000000..0168170
--- /dev/null
+++ b/src/sample/Sorting.scala
@@ -0,0 +1,13 @@
+package sample
+
+class Sorting {
+  def sort(xs: Array[Int]): Array[Int] =
+    if (xs.length <= 1) xs
+    else {
+      val pivot = xs(xs.length / 2)
+      Array.concat(
+        sort(xs filter (pivot >)),
+        xs filter (pivot ==),
+        sort(xs filter (pivot <)))
+    }
+}
diff --git a/src/sample/brick.jpg b/src/sample/brick.jpg
new file mode 100644
index 0000000..836d3c6
--- /dev/null
+++ b/src/sample/brick.jpg
Binary files differ
diff --git a/src/sample/metal.jpg b/src/sample/metal.jpg
new file mode 100644
index 0000000..15b0bf2
--- /dev/null
+++ b/src/sample/metal.jpg
Binary files differ
diff --git a/src/sample/style.css b/src/sample/style.css
index cdaf5f5..3811225 100644
--- a/src/sample/style.css
+++ b/src/sample/style.css
@@ -1,5 +1,14 @@
 .root {
-    -fx-background-color: gray;
+    -fx-background-image: url("metal.jpg");
+}
+
+.label {
+    -fx-text-fill: white;
+        -fx-font-family: "Arial Narrow";
+        -fx-font-size: 20;
+        -fx-font-weight: bold;
+        -fx-background-image: url("brick.jpg");
+        -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
 }
 
 .button {
@@ -7,10 +16,6 @@
     -fx-font-family: "Arial Narrow";
     -fx-font-size: 20;
     -fx-font-weight: bold;
-    -fx-background-color: orange;
+    -fx-background-image: url("brick.jpg");
     -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
-}
-
-.player {
-    -fx-fill: orange;
 }
\ No newline at end of file