From ac5cb0896811406cb3d458fdb96ef73e19760aea Mon Sep 17 00:00:00 2001
From: Simon Jensen <simonje@stud.ntnu.no>
Date: Mon, 13 Apr 2020 17:25:51 +0200
Subject: [PATCH] Upload page

---
 .../IDATT1002/controllers/UploadedSingle.html |   2 +-
 pom.xml                                       |   7 +
 .../IDATT1002/controllers/DataExchange.java   |   1 -
 .../NTNU/IDATT1002/controllers/Upload.java    |  30 +-
 .../IDATT1002/controllers/UploadImages.java   | 365 ++++++++++++++++++
 .../controllers/UploadedMultiple.java         | 119 ------
 .../IDATT1002/controllers/UploadedSingle.java | 152 --------
 .../NTNU/IDATT1002/controllers/ViewAlbum.java |  95 ++---
 .../repository/AbstractRepository.java        |  29 ++
 .../NTNU/IDATT1002/repository/Repository.java |   8 +
 .../NTNU/IDATT1002/service/AlbumService.java  |   5 +
 .../IDATT1002/utils/MetaDataExtractor.java    |  31 +-
 .../NTNU/IDATT1002/upload_images.fxml         |  70 ++++
 .../NTNU/IDATT1002/uploaded_multiple.fxml     | 185 ---------
 .../NTNU/IDATT1002/uploaded_single.fxml       |  84 ----
 .../resources/NTNU/IDATT1002/view_album.fxml  |   8 +-
 16 files changed, 545 insertions(+), 646 deletions(-)
 create mode 100644 src/main/java/NTNU/IDATT1002/controllers/UploadImages.java
 delete mode 100644 src/main/java/NTNU/IDATT1002/controllers/UploadedMultiple.java
 delete mode 100644 src/main/java/NTNU/IDATT1002/controllers/UploadedSingle.java
 create mode 100644 src/main/resources/NTNU/IDATT1002/upload_images.fxml
 delete mode 100644 src/main/resources/NTNU/IDATT1002/uploaded_multiple.fxml
 delete mode 100644 src/main/resources/NTNU/IDATT1002/uploaded_single.fxml

diff --git a/javadoc/NTNU/IDATT1002/controllers/UploadedSingle.html b/javadoc/NTNU/IDATT1002/controllers/UploadedSingle.html
index 38271fad..272d6088 100644
--- a/javadoc/NTNU/IDATT1002/controllers/UploadedSingle.html
+++ b/javadoc/NTNU/IDATT1002/controllers/UploadedSingle.html
@@ -124,7 +124,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
 <li>java.lang.Object</li>
 <li>
 <ul class="inheritance">
-<li>NTNU.IDATT1002.controllers.UploadedSingle</li>
+<li>NTNU.IDATT1002.controllers.UploadImages</li>
 </ul>
 </li>
 </ul>
diff --git a/pom.xml b/pom.xml
index a1559a29..f409895e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,13 @@
             <type>pom</type>
         </dependency>
 
+        <!-- Controlsfx https://mvnrepository.com/artifact/org.controlsfx/controlsfx -->
+        <dependency>
+            <groupId>org.controlsfx</groupId>
+            <artifactId>controlsfx</artifactId>
+            <version>11.0.1</version>
+        </dependency>
+
         <!-- MySQL Driver -->
         <dependency>
             <groupId>mysql</groupId>
diff --git a/src/main/java/NTNU/IDATT1002/controllers/DataExchange.java b/src/main/java/NTNU/IDATT1002/controllers/DataExchange.java
index 6a6c90cc..a05ec283 100644
--- a/src/main/java/NTNU/IDATT1002/controllers/DataExchange.java
+++ b/src/main/java/NTNU/IDATT1002/controllers/DataExchange.java
@@ -72,6 +72,5 @@ public class DataExchange {
     public void setChosenImg(Long chosenImg) {
         this.chosenImg = chosenImg;
     }
-
 }
 
diff --git a/src/main/java/NTNU/IDATT1002/controllers/Upload.java b/src/main/java/NTNU/IDATT1002/controllers/Upload.java
index 10156152..8f51a659 100644
--- a/src/main/java/NTNU/IDATT1002/controllers/Upload.java
+++ b/src/main/java/NTNU/IDATT1002/controllers/Upload.java
@@ -103,22 +103,10 @@ public class Upload {
      * If the user has chosen 1 image this method is called
      * @throws IOException
      */
-    private void switchToUploadedSingle() throws IOException {
-        App.setRoot("uploaded_single");
+    private void switchToUploadImages() throws IOException {
+        App.setRoot("upload_images");
     }
 
-    /**
-     * Method that changs scene to Uploaded Multiple page
-     * If the user has chosen multiple images this method is called
-     * @throws IOException
-     */
-    private void switchToUploadedMultiple() throws IOException {
-        App.setRoot("uploaded_multiple");
-    }
-
-
-
-
     /**
      * Method that opens file browser with an image filter
      * The user will choose what files to upload
@@ -134,12 +122,7 @@ public class Upload {
         if(!list.isEmpty()){
             //Store files in DataExchange
             App.ex.setUploadedFiles(list);
-            if (list.size() == 1){
-                switchToUploadedSingle();
-            }
-            else {
-                switchToUploadedMultiple();
-            }
+            switchToUploadImages();
         }
     }
 
@@ -193,12 +176,7 @@ public class Upload {
         if(!list.isEmpty()){
             //Stores files to DataExchange
             App.ex.setUploadedFiles(list);
-            if (list.size() == 1){
-                switchToUploadedSingle();
-            }
-            else {
-                switchToUploadedMultiple();
-            }
+            switchToUploadImages();
         }
     }
 }
diff --git a/src/main/java/NTNU/IDATT1002/controllers/UploadImages.java b/src/main/java/NTNU/IDATT1002/controllers/UploadImages.java
new file mode 100644
index 00000000..305b37fe
--- /dev/null
+++ b/src/main/java/NTNU/IDATT1002/controllers/UploadImages.java
@@ -0,0 +1,365 @@
+package NTNU.IDATT1002.controllers;
+
+import NTNU.IDATT1002.App;
+import NTNU.IDATT1002.ApplicationState;
+import NTNU.IDATT1002.models.Album;
+import NTNU.IDATT1002.models.Tag;
+import NTNU.IDATT1002.service.AlbumService;
+import NTNU.IDATT1002.service.ImageService;
+import NTNU.IDATT1002.service.TagService;
+import NTNU.IDATT1002.utils.MetaDataExtractor;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.fxml.Initializable;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.control.*;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.scene.text.Text;
+
+import org.controlsfx.control.CheckComboBox;
+
+import javax.persistence.EntityManager;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Controls the buttons and changeable elements on upload_single.fxml,
+ * a page where you add descriptions to your selected image
+ *
+ * @version 1.0 22.03.2020
+ */
+public class UploadImages implements Initializable {
+
+  public VBox uploadContainer;
+
+  public ImageView tbar_logo;
+  public TextField tbar_search;
+  public Button tbar_searchBtn;
+  public Button tbar_explore;
+  public Button tbar_map;
+  public Button tbar_upload;
+
+  public Button tbar_albums;
+  public VBox root;
+
+  private AlbumService albumService;
+  private ImageService imageService;
+
+  public UploadImages(){
+    EntityManager entityManager = App.ex.getEntityManager();
+    albumService = new AlbumService(entityManager);
+    imageService = new ImageService(entityManager);
+  }
+  /**
+   * Method that runs when the controller is loaded
+   * Sets the image url on the page to be the uploaded images url
+   *
+   * @param location
+   * @param resources
+   */
+  public void initialize(URL location, ResourceBundle resources) {
+    uploadContainer.getChildren().clear();
+    List<File> files = App.ex.getUploadedFiles();
+    int maxPerPage = Math.min(files.size(), 25);
+    for (int i = 0; i < maxPerPage; i ++){
+      //A container for image and text
+      HBox imageContainer = new HBox();
+      imageContainer.setPrefWidth(1520);
+      imageContainer.setPrefHeight(300);
+
+      insertImageToContainer(files.get(i), imageContainer);
+      insertImageTextToContainer(files.get(i), imageContainer);
+      uploadContainer.getChildren().add(imageContainer);
+    }
+    if (uploadContainer.getChildren().size() > 0){
+      Button accept = new Button("Accept");
+      accept.setOnAction(actionEvent -> {
+        try {
+          upload();
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
+      });
+      uploadContainer.setAlignment(Pos.TOP_CENTER);
+      uploadContainer.getChildren().add(accept);
+    }
+  }
+
+
+  /**
+   * Format and insert the first image in the given album to the given container.
+   *
+   * @param file the chosen file
+   * @param imageContainer a container for the image
+   */
+  private void insertImageToContainer(File file, HBox imageContainer){
+    ImageView imageView = new ImageView();
+    imageView.setFitHeight(300.0);
+    imageView.setFitWidth(533.0);
+    imageView.setPickOnBounds(true);
+    imageView.setPreserveRatio(true);
+    imageView.setImage(new Image(file.toURI().toString()));
+
+    HBox container = new HBox();
+    container.setPrefWidth(533);
+    container.setPrefHeight(300);
+    container.setAlignment(Pos.TOP_CENTER);
+    container.getChildren().add(imageView);
+
+    imageContainer.getChildren().add(container);
+  }
+
+  /**
+   * Att text elements from album to the container
+   *
+   * @param file the album to display
+   * @param imageContainer the container for each separate album
+   */
+  private void insertImageTextToContainer(File file, HBox imageContainer) {
+    //Creates a vbox so that nodes is aligned in a column
+    VBox textContainer = new VBox();
+    textContainer.setSpacing(5);
+    textContainer.setPadding(new Insets(0, 0, 0, 25));
+    textContainer.setPrefHeight(300);
+    textContainer.setPrefWidth(987);
+
+    insertImageTitle(file, textContainer);
+    insertImageTags(file, textContainer);
+    insertImageMetadata(file, textContainer);
+    insertCheckedChoiceBox(textContainer);
+
+    imageContainer.getChildren().add(textContainer);
+  }
+
+  /**
+   * Insert title of the given album to the given container
+   * It is clickable, and switches to View Album page of that album
+   *
+   * @param file
+   * @param textContainer container for text elements of an album
+   */
+  private void insertImageTitle(File file, VBox textContainer) {
+    HBox titleContainer = new HBox();
+
+    Text titleLabel = new Text("Title: ");
+    titleLabel.setFont(Font.font("System", FontWeight.BOLD, 24));
+
+    TextField title = new TextField();
+    title.setId("title");
+    title.setFont(Font.font("System",24));
+
+    titleContainer.getChildren().addAll(titleLabel, title);
+
+    textContainer.getChildren().add(titleContainer);
+  }
+
+  /**
+   * Insert tags of the given album to the given container
+   *
+   * @param file
+   * @param textContainer container for text elements of an image
+   */
+  private void insertImageTags(File file, VBox textContainer) {
+    HBox tagContainer = new HBox();
+
+    Text tagLabel = new Text("Tags: ");
+    tagLabel.setFont(Font.font("System", FontWeight.BOLD, 24));
+
+    TextField tags = new TextField();
+    tags.setId("tags");
+    tags.setFont(Font.font("System",24));
+
+    tagContainer.getChildren().addAll(tagLabel, tags);
+
+    textContainer.getChildren().add(tagContainer);
+  }
+
+
+  /**
+   * Insert description of the given album to the given container
+   *
+   * @param file
+   * @param textContainer container for text elements of an image
+   */
+  private void insertImageMetadata(File file, VBox textContainer) {
+    Text metadataLabel = new Text("Metadata: ");
+    metadataLabel.setFont(Font.font("System", FontWeight.BOLD, 16));
+
+    MetaDataExtractor metaDataExtractor = new MetaDataExtractor();
+    String metadataSting = MetaDataExtractor.getMetadata(file);
+    TextArea metadata = new TextArea(metadataSting);
+
+    metadata.setEditable(false);
+    metadata.setPrefWidth(500);
+    metadata.setFont(Font.font("System",16));
+
+
+    textContainer.getChildren().addAll(metadataLabel, metadata);
+  }
+
+  /**
+   * Method that generates a dropdown with checkable albums
+   * The image is added to the following albums after it is created
+   * @param textContainer container for text elements of an image
+   */
+  private void insertCheckedChoiceBox(VBox textContainer){
+    ObservableList<String> options = FXCollections.observableArrayList();
+    albumService.getAllAlbums().stream()
+            //Filters the current users albums
+            .filter(album -> album.getUser() == ApplicationState.getCurrentUser())
+            //Adds a checkbox with albums title and id
+            .forEach(album -> options.add(album.getTitle() + " #" + album.getId()));
+    CheckComboBox<String> checkComboBox = new CheckComboBox<>(options);
+    checkComboBox.setId("checkbox");
+    checkComboBox.setTitle("Add to albums");
+    textContainer.getChildren().add(checkComboBox);
+  }
+
+  /**
+   * Method that changes stage to Main page
+   *
+   * @param mouseEvent
+   * @throws IOException
+   */
+  public void switchToMain(MouseEvent mouseEvent) throws IOException {
+    App.setRoot("main");
+  }
+
+  /**
+   * Method that changes stage to Search page. It reads the value of the search
+   * field and if not empty it is passed to dataexchange
+   *
+   * @param actionEvent
+   * @throws IOException
+   */
+  public void switchToSearch(ActionEvent actionEvent) throws IOException {
+    if (!tbar_search.getText().isEmpty()) {
+      App.ex.setSearchField(tbar_search.getText());
+    }
+    App.setRoot("search");
+  }
+
+  /**
+   * Method that changes stage to Explore page
+   *
+   * @param actionEvent
+   * @throws IOException
+   */
+  public void switchToExplore(ActionEvent actionEvent) throws IOException {
+    App.setRoot("explore");
+  }
+
+  /**
+   * Method that changes stage to Albums page
+   *
+   * @param actionEvent
+   * @throws IOException
+   */
+  public void switchToAlbums(ActionEvent actionEvent) throws IOException {
+    App.setRoot("explore_albums");
+  }
+
+  /**
+   * Method that changes stage to Map page
+   *
+   * @param actionEvent
+   * @throws IOException
+   */
+  public void switchToMap(ActionEvent actionEvent) throws IOException {
+    App.setRoot("map");
+  }
+
+  /**
+   * Method that changes stage to Upload page
+   *
+   * @param actionEvent
+   * @throws IOException
+   */
+  public void switchToUpload(ActionEvent actionEvent) throws IOException {
+    App.setRoot("upload");
+  }
+
+  /**
+   * Method for uploading image to database with tags
+   * Image itself is not stored but URL is
+   *
+   * @throws IOException
+   */
+  public void upload() throws IOException {
+    //List of containers for each selected image
+    List<Node> imageContainers = uploadContainer.getChildren().stream()
+            .filter(child -> child instanceof HBox)
+            .collect(Collectors.toList());
+    for(int i = 0; i < imageContainers.size(); i++){
+      Node imageContainer = imageContainers.get(i);
+      //Getting all child nodes and sorts out those with correct id
+      List<Node> childNodes = getAllNodes((Parent) imageContainer).stream()
+              .filter(n -> n.getId() != null && (n.getId().equals("title") || n.getId().equals("tags") || n.getId().equals("checkbox")))
+              .collect(Collectors.toList());
+
+      //Todo: make title apply to images
+      Node titleField = childNodes.get(0);
+      Node tagsField = childNodes.get(1);
+      Node comboBox = childNodes.get(2);
+
+      //List of the albums checked on the dropdown list
+      ObservableList<String> chosenAlbums = ((CheckComboBox<String>) comboBox).getCheckModel().getCheckedItems();
+      ArrayList<String> albumsId = new ArrayList<>();
+      //Splits the id so we can find albums by id afterwards
+      chosenAlbums.forEach(album -> albumsId.add(album.substring(album.lastIndexOf('#')+1)));
+
+      //Each of the uploaded images in DataExchange index match on each container displaying it on the page
+      File file = App.ex.getUploadedFiles().get(i);
+      String tagsString = ((TextField) tagsField).getText();
+      List<Tag> tags = TagService.getTagsFromString(tagsString);
+
+      //Try creating image with the tags entered
+      Optional<NTNU.IDATT1002.models.Image> createdImage = imageService.createImage(ApplicationState.getCurrentUser(), file, tags);
+      createdImage.ifPresent(image -> {
+        //For each chosen album checked the image is added
+        for (String id : albumsId) {
+          Optional<Album> findAlbum = albumService.getAlbumById(Long.parseLong(id));
+          findAlbum.ifPresent(album -> albumService.addImage(album, image));
+
+        }
+        //Removes container if it was uploaded from data exchange
+        uploadContainer.getChildren().remove(imageContainer);
+      });
+    }
+    //If only element in container is button we change to main page
+    if (uploadContainer.getChildren().size() == 1) {
+      App.setRoot("main");
+    }
+    else {
+      Alert alert = new Alert(Alert.AlertType.INFORMATION, "Could not upload some of your images. Please try again.");
+      alert.show();
+    }
+  }
+
+  public static ArrayList<Node> getAllNodes(Parent root) {
+    ArrayList<Node> nodes = new ArrayList<Node>();
+    addAllDescendents(root, nodes);
+    return nodes;
+  }
+
+  private static void addAllDescendents(Parent parent, ArrayList<Node> nodes) {
+    for (Node node : parent.getChildrenUnmodifiable()) {
+      nodes.add(node);
+      if (node instanceof Parent)
+        addAllDescendents((Parent)node, nodes);
+    }
+  }
+}
diff --git a/src/main/java/NTNU/IDATT1002/controllers/UploadedMultiple.java b/src/main/java/NTNU/IDATT1002/controllers/UploadedMultiple.java
deleted file mode 100644
index 9fdbacf2..00000000
--- a/src/main/java/NTNU/IDATT1002/controllers/UploadedMultiple.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package NTNU.IDATT1002.controllers;
-
-import NTNU.IDATT1002.App;
-import javafx.event.ActionEvent;
-import javafx.scene.control.Button;
-import javafx.scene.control.TextArea;
-import javafx.scene.control.TextField;
-import javafx.scene.image.ImageView;
-import javafx.scene.input.MouseEvent;
-
-import java.io.IOException;
-
-/**
- * Controls the buttons and changeable elements on upload_multiple.fxml,
- * a page where you add descriptions to your selected images
- * @version 1.0 22.03.2020
- */
-public class UploadedMultiple {
-
-
-    public ImageView tbar_logo;
-    public TextField tbar_search;
-    public Button tbar_searchBtn;
-    public Button tbar_explore;
-    public Button tbar_map;
-    public Button tbar_upload;
-
-    public TextField photo_title;
-    public TextField photo_tag;
-    public TextArea photo_desc;
-    public ImageView photo_image;
-
-    public TextField photo_title2;
-    public TextField photo_tag2;
-    public TextArea photo_desc2;
-    public ImageView photo_image2;
-
-    public TextField photo_title3;
-    public TextField photo_tag3;
-    public TextArea photo_desc3;
-    public ImageView photo_image3;
-
-    public TextField photo_title4;
-    public TextField photo_tag4;
-    public TextArea photo_desc4;
-    public ImageView photo_image4;
-
-    public Button acceptBtn;
-    public Button tbar_albums;
-
-    /**
-     * Method that changes scene to Main page
-     * @param mouseEvent
-     * @throws IOException
-     */
-    public void switchToMain(MouseEvent mouseEvent) throws IOException {
-        App.setRoot("main");
-    }
-
-    /**
-     * Method that changes scene to Search page. It reads the value of the search
-     * field and if not empty it is passed to dataexchange
-     * @param actionEvent
-     * @throws IOException
-     */
-    public void switchToSearch(ActionEvent actionEvent) throws IOException {
-        if (!tbar_search.getText().isEmpty()){
-            App.ex.setSearchField(tbar_search.getText());
-        }
-        App.setRoot("search");
-    }
-
-    /**
-     * Method that changes scene to Explore page
-     * @param actionEvent
-     * @throws IOException
-     */
-    public void switchToExplore(ActionEvent actionEvent) throws IOException {
-        App.setRoot("explore");
-    }
-
-    /**
-     * Method that changes scene to Albums page
-     * @param actionEvent
-     * @throws IOException
-     */
-    public void switchToAlbums(ActionEvent actionEvent) throws IOException {
-        App.setRoot("explore_albums");
-    }
-
-    /**
-     * Method that changes scene to Map page
-     * @param actionEvent
-     * @throws IOException
-     */
-    public void switchToMap(ActionEvent actionEvent) throws IOException {
-        App.setRoot("map");
-    }
-
-    /**
-     * Method that changes scene to Upload page
-     * @param actionEvent
-     * @throws IOException
-     */
-    public void switchToUpload(ActionEvent actionEvent) throws IOException {
-        App.setRoot("upload");
-    }
-
-    /**
-     * Method for uploading several images to database with title, tags and description
-     * Image itself is not stored but URL is
-     * @param actionEvent
-     * @throws IOException
-     */
-    public void uploadMultiple(ActionEvent actionEvent) throws IOException {
-        //TODO: write method to accept and upload the photo with chosen settings, titles..
-        App.setRoot("main");
-    }
-}
diff --git a/src/main/java/NTNU/IDATT1002/controllers/UploadedSingle.java b/src/main/java/NTNU/IDATT1002/controllers/UploadedSingle.java
deleted file mode 100644
index 9321eba6..00000000
--- a/src/main/java/NTNU/IDATT1002/controllers/UploadedSingle.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package NTNU.IDATT1002.controllers;
-
-import NTNU.IDATT1002.App;
-import NTNU.IDATT1002.ApplicationState;
-import NTNU.IDATT1002.models.Tag;
-import NTNU.IDATT1002.repository.TagRepository;
-import NTNU.IDATT1002.service.ImageService;
-import NTNU.IDATT1002.service.TagService;
-import javafx.event.ActionEvent;
-import javafx.fxml.Initializable;
-import javafx.scene.control.Button;
-import javafx.scene.control.TextArea;
-import javafx.scene.control.TextField;
-import javafx.scene.image.Image;
-import javafx.scene.image.ImageView;
-import javafx.scene.input.MouseEvent;
-
-import javax.persistence.EntityManager;
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.ResourceBundle;
-
-/**
- * Controls the buttons and changeable elements on upload_single.fxml,
- * a page where you add descriptions to your selected image
- *
- * @version 1.0 22.03.2020
- */
-public class UploadedSingle implements Initializable {
-
-  ImageService imageService;
-
-  public ImageView tbar_logo;
-  public TextField tbar_search;
-  public Button tbar_searchBtn;
-  public Button tbar_explore;
-  public Button tbar_map;
-  public Button tbar_upload;
-
-  public TextField photo_title;
-  public TextField photo_tag;
-  public TextArea photo_desc;
-  public ImageView photo_image;
-
-  public Button acceptBtn;
-  public Button tbar_albums;
-
-
-  /**
-   * Method that runs when the controller is loaded
-   * Sets the image url on the page to be the uploaded images url
-   *
-   * @param location
-   * @param resources
-   */
-  public void initialize(URL location, ResourceBundle resources) {
-    photo_image.setImage(new Image(App.ex.getUploadedFiles()
-            .get(0)
-            .toURI()
-            .toString()));
-
-    EntityManager entityManager = App.ex.getEntityManager();
-    imageService = new ImageService(entityManager);
-  }
-
-  /**
-   * Method that changes stage to Main page
-   *
-   * @param mouseEvent
-   * @throws IOException
-   */
-  public void switchToMain(MouseEvent mouseEvent) throws IOException {
-    App.setRoot("main");
-  }
-
-  /**
-   * Method that changes stage to Search page. It reads the value of the search
-   * field and if not empty it is passed to dataexchange
-   *
-   * @param actionEvent
-   * @throws IOException
-   */
-  public void switchToSearch(ActionEvent actionEvent) throws IOException {
-    if (!tbar_search.getText().isEmpty()) {
-      App.ex.setSearchField(tbar_search.getText());
-    }
-    App.setRoot("search");
-  }
-
-  /**
-   * Method that changes stage to Explore page
-   *
-   * @param actionEvent
-   * @throws IOException
-   */
-  public void switchToExplore(ActionEvent actionEvent) throws IOException {
-    App.setRoot("explore");
-  }
-
-  /**
-   * Method that changes stage to Albums page
-   *
-   * @param actionEvent
-   * @throws IOException
-   */
-  public void switchToAlbums(ActionEvent actionEvent) throws IOException {
-    App.setRoot("explore_albums");
-  }
-
-  /**
-   * Method that changes stage to Map page
-   *
-   * @param actionEvent
-   * @throws IOException
-   */
-  public void switchToMap(ActionEvent actionEvent) throws IOException {
-    App.setRoot("map");
-  }
-
-  /**
-   * Method that changes stage to Upload page
-   *
-   * @param actionEvent
-   * @throws IOException
-   */
-  public void switchToUpload(ActionEvent actionEvent) throws IOException {
-    App.setRoot("upload");
-  }
-
-  /**
-   * Method for uploading image to database with tags
-   * Image itself is not stored but URL is
-   *
-   * @author Lars ØStby
-   * @param actionEvent
-   * @throws IOException
-   */
-
-  public void uploadSingle(ActionEvent actionEvent) throws IOException {
-    List<File> list = App.ex.getUploadedFiles();
-    File file = list.get(0);
-    List<Tag> tags = TagService.getTagsFromString(photo_tag.getText());
-    imageService.createImage(ApplicationState.getCurrentUser(), file, tags);
-    App.setRoot("main");
-  }
-
-
-}
diff --git a/src/main/java/NTNU/IDATT1002/controllers/ViewAlbum.java b/src/main/java/NTNU/IDATT1002/controllers/ViewAlbum.java
index 7d855c76..c099421e 100644
--- a/src/main/java/NTNU/IDATT1002/controllers/ViewAlbum.java
+++ b/src/main/java/NTNU/IDATT1002/controllers/ViewAlbum.java
@@ -10,8 +10,7 @@ import NTNU.IDATT1002.utils.ImageUtil;
 import java.io.File;
 import java.io.IOException;
 import java.net.URL;
-import java.util.Optional;
-import java.util.ResourceBundle;
+import java.util.*;
 import java.util.logging.Logger;
 import javafx.application.HostServices;
 import javafx.event.ActionEvent;
@@ -57,14 +56,14 @@ public class ViewAlbum implements Initializable {
     public Button tbar_albums;
     public Pane metadataPane;
     public Button createAlbumPdf;
-    public ImageView mainPicture;
-    public Text pictureTitleField;
-    public Text pictureTagsField;
+    public ImageView mainImageContainer;
+    public Text mainImageTitle;
+    public Text mainImageTags;
 
     @FXML
     public VBox albumTextContainer;
-    public HBox albumImages;
     public Button viewOnMapBtn;
+    public HBox albumImagesContainer;
 
     private AlbumService albumService;
     private Album currentAlbum;
@@ -86,25 +85,29 @@ public class ViewAlbum implements Initializable {
         Optional<Album> foundAlbum = albumService.getAlbumById(currentAlbumId);
         foundAlbum.ifPresent(album -> {
             currentAlbum = album;
-            NTNU.IDATT1002.models.Image titleImage = album.getImages().get(0);
-            Image image = ImageUtil.convertToFXImage(titleImage);
-            mainPicture.setImage(image);
-            pictureTitleField.setText(album.getTitle());
-            pictureTagsField.setText(TagService.getTagsAsString(album.getTags()));
-            insertAlbumTextToContainer(album);
-            for (NTNU.IDATT1002.models.Image i: album.getImages()) {
-                ImageView iV = new ImageView();
-                iV.setFitHeight(64);
-                iV.setFitWidth(114);
-                iV.setPreserveRatio(true);
-                iV.setId(i.getId().toString());
-                iV.setImage(ImageUtil.convertToFXImage(i));
-                albumImages.getChildren().add(iV);
-                iV.setOnMouseClicked(new EventHandler<MouseEvent>() {
-                    @Override public void handle(MouseEvent mouseEvent) {
-                        setActiveImage(mouseEvent);
-                    }
-                });
+            List<NTNU.IDATT1002.models.Image> albumImages = album.getImages();
+            //If album has an image
+            if (albumImages.size() > 0) {
+                NTNU.IDATT1002.models.Image mainImage = albumImages.get(0);
+                mainImageContainer.setImage(ImageUtil.convertToFXImage(mainImage));
+                mainImageTitle.setText("ADD IMAGE TITLE");
+                mainImageTags.setText(TagService.getTagsAsString(mainImage.getTags()));
+                insertAlbumTextToContainer(album);
+                for (NTNU.IDATT1002.models.Image image : albumImages) {
+                    ImageView imageView = new ImageView();
+                    imageView.setFitHeight(64);
+                    imageView.setFitWidth(114);
+                    imageView.setPreserveRatio(true);
+                    imageView.setId(image.getId().toString());
+                    imageView.setImage(ImageUtil.convertToFXImage(image));
+                    albumImagesContainer.getChildren().add(imageView);
+                    imageView.setOnMouseClicked(new EventHandler<MouseEvent>() {
+                        @Override
+                        public void handle(MouseEvent mouseEvent) {
+                            setActiveImage(mouseEvent);
+                        }
+                    });
+                }
             }
         });
     }
@@ -119,10 +122,12 @@ public class ViewAlbum implements Initializable {
         if (clickedObject instanceof ImageView) {
             ImageView clickedImageView = (ImageView) mouseEvent.getSource();
             Long clickedImageId = Long.parseLong(clickedImageView.getId());
-            Optional<NTNU.IDATT1002.models.Image> newImage = currentAlbum.getImages().stream().filter(img -> img.getId().equals(clickedImageId)).findFirst();
-            newImage.ifPresent(img -> {
-                Image image = ImageUtil.convertToFXImage(img);
-                mainPicture.setImage(image);
+            Optional<NTNU.IDATT1002.models.Image> findImage = currentAlbum.getImages().stream().filter(img -> img.getId().equals(clickedImageId)).findFirst();
+            findImage.ifPresent(newImage -> {
+                Image image = ImageUtil.convertToFXImage(newImage);
+                mainImageTitle.setText("ADD IMAGE TITLE");
+                mainImageTags.setText(TagService.getTagsAsString(newImage.getTags()));
+                mainImageContainer.setImage(image);
             });
         }
     }
@@ -290,38 +295,6 @@ public class ViewAlbum implements Initializable {
         //write method that opens a pop-up view of the main picture
     }
 
-    public void changeMainPicture1(MouseEvent mouseEvent) {
-        //write method that switches to main picture to be picture 1 in the scrollbar-view
-    }
-
-    public void changeMainPicture2(MouseEvent mouseEvent) {
-        //write method that switches to main picture to be picture 2 in the scrollbar-view
-    }
-
-    public void changeMainPicture3(MouseEvent mouseEvent) {
-        //write method that switches to main picture to be picture 3 in the scrollbar-view
-    }
-
-    public void changeMainPicture4(MouseEvent mouseEvent) {
-        //write method that switches to main picture to be picture 4 in the scrollbar-view
-    }
-
-    public void changeMainPicture5(MouseEvent mouseEvent) {
-        //write method that switches to main picture to be picture 5 in the scrollbar-view
-    }
-
-    public void changeMainPicture6(MouseEvent mouseEvent) {
-        //write method that switches to main picture to be picture 6 in the scrollbar-view
-    }
-
-    public void loadPreviousScrollbarView(ActionEvent actionEvent) {
-        //write method that loads the previous 6 images in the album into the scrollbar-view
-    }
-
-    public void loadNextScrollbarView(ActionEvent actionEvent) {
-        //write method that loads the next 6 images in the album into the scrollbar-view
-    }
-
     /**
      * Retrieve and display album document.
      *
diff --git a/src/main/java/NTNU/IDATT1002/repository/AbstractRepository.java b/src/main/java/NTNU/IDATT1002/repository/AbstractRepository.java
index 599cc772..ee20d30b 100644
--- a/src/main/java/NTNU/IDATT1002/repository/AbstractRepository.java
+++ b/src/main/java/NTNU/IDATT1002/repository/AbstractRepository.java
@@ -67,6 +67,24 @@ abstract class AbstractRepository<T, ID> implements Repository<T, ID> {
         return Optional.empty();
     }
 
+    /**
+     * Updates a given entity and returns the updated instance.
+     *
+     * @param entity not null
+     * @return the updates entity
+     */
+    public Optional<T> update(T entity) {
+        try {
+            merge(entity);
+            logger.info("[x] Updated entity {}", entity);
+            return Optional.ofNullable(entity);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return Optional.empty();
+    }
+
     /**
      * Persists the given album.
      *
@@ -78,6 +96,17 @@ abstract class AbstractRepository<T, ID> implements Repository<T, ID> {
         entityManager.getTransaction().commit();
     }
 
+    /**
+     * Merge the given album.
+     *
+     * @param entity  the album to merge
+     */
+    private void merge(T entity) {
+        entityManager.getTransaction().begin();
+        entityManager.merge(entity);
+        entityManager.getTransaction().commit();
+    }
+
     /**
      * Retrieves all instances of the class type.
      *
diff --git a/src/main/java/NTNU/IDATT1002/repository/Repository.java b/src/main/java/NTNU/IDATT1002/repository/Repository.java
index cf1d93c6..20ba935e 100644
--- a/src/main/java/NTNU/IDATT1002/repository/Repository.java
+++ b/src/main/java/NTNU/IDATT1002/repository/Repository.java
@@ -22,6 +22,14 @@ public interface Repository<T, ID> {
      */
     Optional<T> save(T entity);
 
+    /**
+     * Updates a given entity and returns the updated instance.
+     *
+     * @param entity not null
+     * @return the updated entity
+     */
+    Optional<T> update(T entity);
+
     /**
      * Retrieves all instances of the type.
      *
diff --git a/src/main/java/NTNU/IDATT1002/service/AlbumService.java b/src/main/java/NTNU/IDATT1002/service/AlbumService.java
index b9dc9eb2..3f0ed9a8 100644
--- a/src/main/java/NTNU/IDATT1002/service/AlbumService.java
+++ b/src/main/java/NTNU/IDATT1002/service/AlbumService.java
@@ -74,6 +74,11 @@ public class AlbumService {
         return albumRepository.save(album);
     }
 
+    public Optional<Album> addImage(Album album, Image image){
+        album.addImage(image);
+        return albumRepository.update(album);
+    }
+
     /**
      * Retrieves all albums created by the given user by username.
      *
diff --git a/src/main/java/NTNU/IDATT1002/utils/MetaDataExtractor.java b/src/main/java/NTNU/IDATT1002/utils/MetaDataExtractor.java
index 99474019..97c25bee 100644
--- a/src/main/java/NTNU/IDATT1002/utils/MetaDataExtractor.java
+++ b/src/main/java/NTNU/IDATT1002/utils/MetaDataExtractor.java
@@ -42,7 +42,7 @@ public class MetaDataExtractor {
      * Returns a string with the GPS position
      * @return the gelocation of the file
      */
-    public GeoLocation getGeoLocation(File file) {
+    public static GeoLocation getGeoLocation(File file) {
         String gps = "";
         String latitude = "";
         String longitude = "";
@@ -71,7 +71,7 @@ public class MetaDataExtractor {
      * @param file that will be checked for Camera make
      * @return empty string if nothings found
      */
-    public String getCamera(File file) {
+    public static String getCamera(File file) {
         String cameraInformation = "";
         Directory directory;
 
@@ -96,7 +96,7 @@ public class MetaDataExtractor {
      * @param file that will be checked
      * @return empty string if nothing is found
      */
-    public String getLens(File file) {
+    public static String getLens(File file) {
         String lensInformation = "";
         Directory directory;
 
@@ -122,7 +122,7 @@ public class MetaDataExtractor {
      * @param file that will be checked
      * @return empty string if nothing is found
      */
-    public String getAperture(File file) {
+    public static String getAperture(File file) {
         String apertureInformation = "";
         Directory directory;
 
@@ -147,7 +147,7 @@ public class MetaDataExtractor {
      * @param file that will be checked
      * @return empty string if nothing is found
      */
-    public String getShutterSpeed(File file) {
+    public static String getShutterSpeed(File file) {
         String shutterSpeedInformation = "";
         Directory directory;
 
@@ -172,7 +172,7 @@ public class MetaDataExtractor {
      * @param file that will be checked
      * @return empty string if nothing is found
      */
-    public String getIso(File file) {
+    public static String getIso(File file) {
         String isoInformation = "";
         Directory directory;
 
@@ -197,7 +197,7 @@ public class MetaDataExtractor {
      * @param file that will be checked
      * @return empty string if nothing is found
      */
-    public String getFocalLength(File file) {
+    public static String getFocalLength(File file) {
         String focalLengthInformation = "";
         Directory directory;
 
@@ -223,7 +223,7 @@ public class MetaDataExtractor {
      * @param file that will be checked
      * @return empty string if nothing is found
      */
-    public String getFileType(File file) {
+    public static String getFileType(File file) {
         String fileTypeInformation = "";
         Directory directory;
 
@@ -249,7 +249,7 @@ public class MetaDataExtractor {
      * @param file that will be checked
      * @return empty string if nothing is found
      */
-    public String getPhotoDate(File file) {
+    public static String getPhotoDate(File file) {
         String dateInformation = "";
         Directory directory;
 
@@ -281,7 +281,7 @@ public class MetaDataExtractor {
      * @param file that will be checked
      * @return empty string if nothing is found
      */
-    public String getFileSize(File file) {
+    public static String getFileSize(File file) {
         String fileSize = "";
         Directory directory;
 
@@ -307,7 +307,7 @@ public class MetaDataExtractor {
      * @param file that will be checked
      * @return empty string if nothing is found
      */
-    public String getFileDimension(File file) {
+    public static String getFileDimension(File file) {
         String fileDimension = "";
         Directory directory;
 
@@ -327,7 +327,7 @@ public class MetaDataExtractor {
         return fileDimension;
     }
     
-    public void setMetadata(NTNU.IDATT1002.models.Metadata metadata, File file) {
+    public static void setMetadata(NTNU.IDATT1002.models.Metadata metadata, File file) {
         metadata.setCamera(getCamera(file));
         metadata.setLens(getLens(file));
         metadata.setAperture(getAperture(file));
@@ -340,13 +340,18 @@ public class MetaDataExtractor {
         metadata.setFileDimension(getFileDimension(file));
     }
 
+    public static String getMetadata(File file){
+        return getCamera(file) + getLens(file) + getAperture(file) + getShutterSpeed(file) + getFileDimension(file)
+                + getFocalLength(file) + getPhotoDate(file) + getIso(file) + getFileSize(file) + getFileType(file);
+    }
+
     /**
      * Cleans up the tags on a string
      * @param textToClean string that will be cleaned
      * @param directoryToRemove directory that will be removed from string
      * @return cleaned string
      */
-    private String cleanUpTags(String textToClean, Directory directoryToRemove) {
+    private static String cleanUpTags(String textToClean, Directory directoryToRemove) {
         String removingText = directoryToRemove.getName();
         textToClean = textToClean.replace(removingText, "");
         textToClean = textToClean.replace("[", "");
diff --git a/src/main/resources/NTNU/IDATT1002/upload_images.fxml b/src/main/resources/NTNU/IDATT1002/upload_images.fxml
new file mode 100644
index 00000000..6e8ceafe
--- /dev/null
+++ b/src/main/resources/NTNU/IDATT1002/upload_images.fxml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ScrollPane?>
+<?import javafx.scene.control.TextField?>
+<?import javafx.scene.image.Image?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.BorderPane?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.Pane?>
+<?import javafx.scene.layout.VBox?>
+
+<VBox fx:id="root" alignment="CENTER" prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="NTNU.IDATT1002.controllers.UploadImages">
+   <children>
+      <HBox alignment="CENTER" minHeight="100.0" prefHeight="100.0" prefWidth="1920.0" spacing="20.0" style="-fx-background-color: #0c0c0c;">
+         <children>
+            <ImageView fx:id="tbar_logo" fitHeight="69.0" fitWidth="153.0" onMouseClicked="#switchToMain" pickOnBounds="true" preserveRatio="true">
+               <image>
+                  <Image url="@../../Images/PlaceholderLogo.png" />
+               </image>
+            </ImageView>
+            <Pane prefHeight="100.0" prefWidth="343.0" />
+            <TextField fx:id="tbar_search" prefHeight="25.0" prefWidth="358.0" promptText="Search: Tags, Albums, Metadata, etc..." />
+            <Button fx:id="tbar_searchBtn" mnemonicParsing="false" onAction="#switchToSearch" text="SEARCH" />
+            <Button fx:id="tbar_explore" mnemonicParsing="false" onAction="#switchToExplore" text="EXPLORE" />
+            <Button fx:id="tbar_albums" mnemonicParsing="false" onAction="#switchToAlbums" text="ALBUMS" />
+            <Button fx:id="tbar_map" mnemonicParsing="false" onAction="#switchToMap" text="MAP" />
+            <Pane prefHeight="100.0" prefWidth="174.0" />
+            <Button fx:id="tbar_upload" mnemonicParsing="false" onAction="#switchToUpload" prefHeight="25.0" prefWidth="114.0" text="UPLOAD" />
+         </children>
+      </HBox>
+      <HBox alignment="CENTER" prefHeight="982.0" prefWidth="1920.0">
+         <children>
+            <ScrollPane hbarPolicy="NEVER" prefHeight="1080.0" prefWidth="1920.0" HBox.hgrow="ALWAYS">
+               <content>
+                  <BorderPane>
+                     <right>
+                        <Pane minHeight="300.0" prefWidth="200.0" style="-fx-background-color: #6d6d6d;" BorderPane.alignment="CENTER" />
+                     </right>
+                     <bottom>
+                        <Pane prefHeight="250.0" style="-fx-background-color: #6d6d6d;" BorderPane.alignment="CENTER">
+                           <children>
+                              <HBox alignment="CENTER" layoutY="-2.0" prefHeight="84.0" prefWidth="1920.0" spacing="20.0" />
+                           </children>
+                        </Pane>
+                     </bottom>
+                     <center>
+                        <VBox fx:id="uploadContainer" maxHeight="1.7976931348623157E308" maxWidth="Infinity" minHeight="980.0" spacing="10.0" style="-fx-background-color: #555555;" BorderPane.alignment="CENTER" />
+                     </center>
+                     <top>
+                        <VBox prefHeight="250.0" style="-fx-background-color: #6d6d6d;" BorderPane.alignment="CENTER">
+                           <opaqueInsets>
+                              <Insets />
+                           </opaqueInsets>
+                           <padding>
+                              <Insets top="20.0" />
+                           </padding>
+                        </VBox>
+                     </top>
+                     <left>
+                        <Pane minHeight="300.0" prefWidth="200.0" style="-fx-background-color: #6d6d6d;" BorderPane.alignment="CENTER" />
+                     </left>
+                  </BorderPane>
+               </content>
+            </ScrollPane>
+         </children>
+      </HBox>
+   </children>
+</VBox>
\ No newline at end of file
diff --git a/src/main/resources/NTNU/IDATT1002/uploaded_multiple.fxml b/src/main/resources/NTNU/IDATT1002/uploaded_multiple.fxml
deleted file mode 100644
index 34a3c5d0..00000000
--- a/src/main/resources/NTNU/IDATT1002/uploaded_multiple.fxml
+++ /dev/null
@@ -1,185 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.ScrollPane?>
-<?import javafx.scene.control.TextArea?>
-<?import javafx.scene.control.TextField?>
-<?import javafx.scene.image.Image?>
-<?import javafx.scene.image.ImageView?>
-<?import javafx.scene.layout.AnchorPane?>
-<?import javafx.scene.layout.HBox?>
-<?import javafx.scene.layout.Pane?>
-<?import javafx.scene.layout.VBox?>
-<?import javafx.scene.text.Font?>
-<?import javafx.scene.text.Text?>
-
-<AnchorPane prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="NTNU.IDATT1002.controllers.UploadedMultiple">
-    <children>
-        <VBox prefHeight="1080.0" prefWidth="1920.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
-            <children>
-            <HBox alignment="CENTER" minHeight="100.0" prefHeight="100.0" prefWidth="1920.0" spacing="20.0" style="-fx-background-color: #0c0c0c;">
-               <children>
-                  <ImageView fx:id="tbar_logo" fitHeight="69.0" fitWidth="153.0" onMouseClicked="#switchToMain" pickOnBounds="true" preserveRatio="true">
-                     <image>
-                        <Image url="@../../Images/PlaceholderLogo.png" />
-                     </image>
-                  </ImageView>
-                  <Pane prefHeight="100.0" prefWidth="343.0" />
-                  <TextField fx:id="tbar_search" prefHeight="25.0" prefWidth="358.0" promptText="Search: Tags, Albums, Metadata, etc..." />
-                  <Button fx:id="tbar_searchBtn" mnemonicParsing="false" onAction="#switchToSearch" text="SEARCH" />
-                  <Button fx:id="tbar_explore" mnemonicParsing="false" onAction="#switchToExplore" text="EXPLORE" />
-                  <Button fx:id="tbar_albums" mnemonicParsing="false" onAction="#switchToAlbums" text="ALBUMS" />
-                  <Button fx:id="tbar_map" mnemonicParsing="false" onAction="#switchToMap" text="MAP" />
-                  <Pane prefHeight="100.0" prefWidth="174.0" />
-                  <Button fx:id="tbar_upload" mnemonicParsing="false" onAction="#switchToUpload" prefHeight="25.0" prefWidth="114.0" text="UPLOAD" />
-               </children>
-            </HBox>
-                <HBox alignment="CENTER" prefHeight="982.0" prefWidth="1920.0">
-                    <children>
-                  <ScrollPane hbarPolicy="NEVER" prefHeight="1080.0" prefWidth="1920.0" HBox.hgrow="ALWAYS">
-                    <content>
-                      <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="2100.0" prefWidth="1920.0" style="-fx-background-color: #999999;">
-                           <children>
-                                    <Pane prefHeight="981.0" prefWidth="1932.0" style="-fx-background-color: #999999;">
-                                        <children>
-                                            <Text layoutX="238.0" layoutY="142.0" strokeType="OUTSIDE" strokeWidth="0.0" text="ALBUMTITLE:">
-                                                <font>
-                                                    <Font name="System Bold" size="36.0" />
-                                                </font>
-                                            </Text>
-                                            <TextField layoutX="486.0" layoutY="110.0" prefHeight="40.0" prefWidth="488.0" promptText="Insert title here" />
-                                            <Text layoutX="238.0" layoutY="182.0" strokeType="OUTSIDE" strokeWidth="0.0" text="ALBUMTAGS:">
-                                                <font>
-                                                    <Font name="System Bold" size="24.0" />
-                                                </font>
-                                            </Text>
-                                            <TextField layoutX="411.0" layoutY="157.0" prefHeight="32.0" prefWidth="564.0" promptText="#Blue, #water, #summer, etc..." />
-                                            <Text layoutX="239.0" layoutY="224.0" strokeType="OUTSIDE" strokeWidth="0.0" text="ALBUMDESCRIPTION:">
-                                                <font>
-                                                    <Font name="System Bold" size="24.0" />
-                                                </font>
-                                            </Text>
-                                            <TextArea layoutX="238.0" layoutY="239.0" prefHeight="140.0" prefWidth="739.0" promptText="Insert description here" />
-                                            <Text layoutX="1002.0" layoutY="138.0" strokeType="OUTSIDE" strokeWidth="0.0" text="INCLUDED METADATA:">
-                                                <font>
-                                                    <Font name="System Bold" size="24.0" />
-                                                </font>
-                                            </Text>
-                                            <Pane layoutX="1002.0" layoutY="147.0" prefHeight="232.0" prefWidth="684.0" style="-fx-background-color: #ffffff;" />
-                                            <Text layoutX="868.0" layoutY="477.0" strokeType="OUTSIDE" strokeWidth="0.0" text="IMAGES:">
-                                                <font>
-                                                    <Font name="System Bold" size="36.0" />
-                                                </font>
-                                            </Text>
-                                            <Text layoutX="873.0" layoutY="581.0" strokeType="OUTSIDE" strokeWidth="0.0" text="TITLE:">
-                                                <font>
-                                                    <Font name="System Bold" size="36.0" />
-                                                </font>
-                                            </Text>
-                                            <Text layoutX="873.0" layoutY="655.0" strokeType="OUTSIDE" strokeWidth="0.0" text="TAGS:">
-                                                <font>
-                                                    <Font name="System Bold" size="24.0" />
-                                                </font>
-                                            </Text>
-                                            <Text layoutX="873.0" layoutY="719.0" strokeType="OUTSIDE" strokeWidth="0.0" text="DESCRIPTION:">
-                                                <font>
-                                                    <Font name="System Bold" size="24.0" />
-                                                </font>
-                                            </Text>
-                                            <TextField fx:id="photo_title" layoutX="1002.0" layoutY="552.0" prefHeight="32.0" prefWidth="689.0" promptText="Insert title here" />
-                                            <TextField fx:id="photo_tag" layoutX="963.0" layoutY="630.0" prefHeight="32.0" prefWidth="728.0" promptText="#Blue, #water, #summer, etc..." />
-                                            <TextArea fx:id="photo_desc" layoutX="872.0" layoutY="734.0" prefHeight="140.0" prefWidth="822.0" promptText="Insert description here" />
-                                            <ImageView fx:id="photo_image" fitHeight="325.0" fitWidth="608.0" layoutX="238.0" layoutY="549.0" pickOnBounds="true" preserveRatio="true">
-                                                <image>
-                                                    <Image url="@../../Images/placeholder-1920x1080.png" /> <!-- This is the URL to the image in question, needs to change in accordance with the current uploaded picture-->
-                                                </image>
-                                            </ImageView>
-
-                                    <Text layoutX="870.0" layoutY="943.0" strokeType="OUTSIDE" strokeWidth="0.0" text="TITLE:">
-                                       <font>
-                                          <Font name="System Bold" size="36.0" />
-                                       </font>
-                                    </Text>
-                                    <Text layoutX="870.0" layoutY="1017.0" strokeType="OUTSIDE" strokeWidth="0.0" text="TAGS:">
-                                       <font>
-                                          <Font name="System Bold" size="24.0" />
-                                       </font>
-                                    </Text>
-                                    <Text layoutX="870.0" layoutY="1081.0" strokeType="OUTSIDE" strokeWidth="0.0" text="DESCRIPTION:">
-                                       <font>
-                                          <Font name="System Bold" size="24.0" />
-                                       </font>
-                                    </Text>
-                                    <TextField fx:id="photo_title2" layoutX="1002.0" layoutY="914.0" prefHeight="32.0" prefWidth="689.0" promptText="Insert title here" />
-                                    <TextField fx:id="photo_tag2" layoutX="963.0" layoutY="992.0" prefHeight="32.0" prefWidth="728.0" promptText="#Blue, #water, #summer, etc..." />
-                                    <TextArea fx:id="photo_desc2" layoutX="872.0" layoutY="1096.0" prefHeight="140.0" prefWidth="822.0" promptText="Insert description here" />
-                                    <ImageView fx:id="photo_image2" fitHeight="325.0" fitWidth="608.0" layoutX="238.0" layoutY="911.0" pickOnBounds="true" preserveRatio="true">
-                                       <image>
-                                          <Image url="@../../Images/placeholder-1920x1080.png" />
-                                       </image>
-                                    </ImageView>
-
-                                            <Text layoutX="873.0" layoutY="1305.0" strokeType="OUTSIDE" strokeWidth="0.0" text="TITLE:">
-                                                <font>
-                                                    <Font name="System Bold" size="36.0" />
-                                                </font>
-                                            </Text>
-                                            <Text layoutX="873.0" layoutY="1379.0" strokeType="OUTSIDE" strokeWidth="0.0" text="TAGS:">
-                                                <font>
-                                                    <Font name="System Bold" size="24.0" />
-                                                </font>
-                                            </Text>
-                                            <Text layoutX="873.0" layoutY="1443.0" strokeType="OUTSIDE" strokeWidth="0.0" text="DESCRIPTION:">
-                                                <font>
-                                                    <Font name="System Bold" size="24.0" />
-                                                </font>
-                                            </Text>
-                                            <TextField fx:id="photo_title3" layoutX="1002.0" layoutY="1276.0" prefHeight="32.0" prefWidth="689.0" promptText="Insert title here" />
-                                            <TextField fx:id="photo_tag3" layoutX="963.0" layoutY="1354.0" prefHeight="32.0" prefWidth="728.0" promptText="#Blue, #water, #summer, etc..." />
-                                            <TextArea fx:id="photo_desc3" layoutX="872.0" layoutY="1458.0" prefHeight="140.0" prefWidth="822.0" promptText="Insert description here" />
-                                            <ImageView fx:id="photo_image3" fitHeight="325.0" fitWidth="608.0" layoutX="238.0" layoutY="1273.0" pickOnBounds="true" preserveRatio="true">
-                                                <image>
-                                                    <Image url="@../../Images/placeholder-1920x1080.png" /> <!-- This is the URL to the image in question, needs to change in accordance with the current uploaded picture-->
-                                                </image>
-                                            </ImageView>
-
-                                            <Text layoutX="870.0" layoutY="1667.0" strokeType="OUTSIDE" strokeWidth="0.0" text="TITLE:">
-                                                <font>
-                                                    <Font name="System Bold" size="36.0" />
-                                                </font>
-                                            </Text>
-                                            <Text layoutX="870.0" layoutY="1741.0" strokeType="OUTSIDE" strokeWidth="0.0" text="TAGS:">
-                                                <font>
-                                                    <Font name="System Bold" size="24.0" />
-                                                </font>
-                                            </Text>
-                                            <Text layoutX="870.0" layoutY="1805.0" strokeType="OUTSIDE" strokeWidth="0.0" text="DESCRIPTION:">
-                                                <font>
-                                                    <Font name="System Bold" size="24.0" />
-                                                </font>
-                                            </Text>
-                                            <TextField fx:id="photo_title4" layoutX="1002.0" layoutY="1638.0" prefHeight="32.0" prefWidth="689.0" promptText="Insert title here" />
-                                            <TextField fx:id="photo_tag4" layoutX="963.0" layoutY="1716.0" prefHeight="32.0" prefWidth="728.0" promptText="#Blue, #water, #summer, etc..." />
-                                            <TextArea fx:id="photo_desc4" layoutX="872.0" layoutY="1820.0" prefHeight="140.0" prefWidth="822.0" promptText="Insert description here" />
-                                            <ImageView fx:id="photo_image4" fitHeight="325.0" fitWidth="608.0" layoutX="238.0" layoutY="1635.0" pickOnBounds="true" preserveRatio="true">
-                                                <image>
-                                                    <Image url="@../../Images/placeholder-1920x1080.png" />
-                                                </image>
-                                            </ImageView>
-                                    <Button fx:id="acceptBtn" layoutX="880.0" layoutY="2000.0" mnemonicParsing="false" onAction="#uploadMultiple" text="ACCEPT">
-                                       <font>
-                                          <Font name="System Bold" size="24.0" />
-                                       </font>
-                                    </Button>
-                                        </children>
-                                    </Pane>
-                           </children>
-                        </AnchorPane>
-                    </content>
-                  </ScrollPane>
-                    </children>
-                </HBox>
-            </children>
-        </VBox>
-    </children>
-</AnchorPane>
diff --git a/src/main/resources/NTNU/IDATT1002/uploaded_single.fxml b/src/main/resources/NTNU/IDATT1002/uploaded_single.fxml
deleted file mode 100644
index b325c316..00000000
--- a/src/main/resources/NTNU/IDATT1002/uploaded_single.fxml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.TextArea?>
-<?import javafx.scene.control.TextField?>
-<?import javafx.scene.image.Image?>
-<?import javafx.scene.image.ImageView?>
-<?import javafx.scene.layout.HBox?>
-<?import javafx.scene.layout.Pane?>
-<?import javafx.scene.layout.VBox?>
-<?import javafx.scene.text.Font?>
-<?import javafx.scene.text.Text?>
-
-<VBox alignment="CENTER" prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="NTNU.IDATT1002.controllers.UploadedSingle">
-   <children>
-      <HBox alignment="CENTER" minHeight="100.0" prefHeight="100.0" prefWidth="1920.0" spacing="20.0" style="-fx-background-color: #0c0c0c;">
-         <children>
-            <ImageView fx:id="tbar_logo" fitHeight="69.0" fitWidth="153.0" onMouseClicked="#switchToMain" pickOnBounds="true" preserveRatio="true">
-               <image>
-                  <Image url="@../../Images/PlaceholderLogo.png" />
-               </image>
-            </ImageView>
-            <Pane prefHeight="100.0" prefWidth="343.0" />
-            <TextField fx:id="tbar_search" prefHeight="25.0" prefWidth="358.0" promptText="Search: Tags, Albums, Metadata, etc..." />
-            <Button fx:id="tbar_searchBtn" mnemonicParsing="false" onAction="#switchToSearch" text="SEARCH" />
-            <Button fx:id="tbar_explore" mnemonicParsing="false" onAction="#switchToExplore" text="EXPLORE" />
-            <Button fx:id="tbar_albums" mnemonicParsing="false" onAction="#switchToAlbums" text="ALBUMS" />
-            <Button fx:id="tbar_map" mnemonicParsing="false" onAction="#switchToMap" text="MAP" />
-            <Pane prefHeight="100.0" prefWidth="174.0" />
-            <Button fx:id="tbar_upload" mnemonicParsing="false" onAction="#switchToUpload" prefHeight="25.0" prefWidth="114.0" text="UPLOAD" />
-         </children>
-      </HBox>
-      <HBox alignment="CENTER" prefHeight="982.0" prefWidth="1920.0" VBox.vgrow="ALWAYS">
-         <children>
-            <VBox alignment="CENTER" prefHeight="981.0" prefWidth="976.0" style="-fx-background-color: #444444;" HBox.hgrow="ALWAYS">
-               <children>
-                  <ImageView fx:id="photo_image" fitHeight="506.0" fitWidth="900.0" pickOnBounds="true" preserveRatio="true">
-                     <image>
-                        <Image url="@../../Images/placeholder-1920x1080.png" />
-                     </image>
-                  </ImageView>
-               </children>
-            </VBox>
-            <VBox alignment="CENTER" prefHeight="981.0" prefWidth="947.0" style="-fx-background-color: #666666;" HBox.hgrow="ALWAYS">
-               <children>
-                  <VBox alignment="CENTER" maxWidth="799.0" prefHeight="981.0" prefWidth="799.0" spacing="10.0">
-                     <children>
-                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="TITLE:">
-                           <font>
-                              <Font name="System Bold" size="36.0" />
-                           </font>
-                        </Text>
-                        <TextField fx:id="photo_title" prefHeight="32.0" prefWidth="689.0" promptText="Insert title here" />
-                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="TAGS:">
-                           <font>
-                              <Font name="System Bold" size="24.0" />
-                           </font>
-                        </Text>
-                        <TextField fx:id="photo_tag" prefHeight="32.0" prefWidth="728.0" promptText="#Blue, #water, #summer, etc..." />
-                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="DESCRIPTION:">
-                           <font>
-                              <Font name="System Bold" size="24.0" />
-                           </font>
-                        </Text>
-                        <TextArea fx:id="photo_desc" prefHeight="147.0" prefWidth="822.0" promptText="Insert description here" />
-                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="METADATA:">
-                           <font>
-                              <Font name="System Bold" size="24.0" />
-                           </font>
-                        </Text>
-                        <Pane prefHeight="364.0" prefWidth="822.0" style="-fx-background-color: #ffffff;" />
-                        <Button fx:id="acceptBtn" mnemonicParsing="false" onAction="#uploadSingle" text="ACCEPT">
-                           <font>
-                              <Font size="18.0" />
-                           </font>
-                        </Button>
-                     </children>
-                  </VBox>
-               </children>
-            </VBox>
-         </children>
-      </HBox>
-   </children>
-</VBox>
diff --git a/src/main/resources/NTNU/IDATT1002/view_album.fxml b/src/main/resources/NTNU/IDATT1002/view_album.fxml
index 2d190f46..62e88905 100644
--- a/src/main/resources/NTNU/IDATT1002/view_album.fxml
+++ b/src/main/resources/NTNU/IDATT1002/view_album.fxml
@@ -57,24 +57,24 @@
                <children>
                   <VBox maxWidth="839.0" prefHeight="660.0" prefWidth="839.0" spacing="10.0">
                      <children>
-                        <Text fx:id="pictureTitleField" fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="Picturetitle">
+                        <Text fx:id="mainImageTitle" fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="Picturetitle">
                            <font>
                               <Font size="24.0" />
                            </font>
                         </Text>
-                        <Text fx:id="pictureTagsField" fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="#tags">
+                        <Text fx:id="mainImageTags" fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="#tags">
                            <font>
                               <Font size="18.0" />
                            </font>
                         </Text>
-                        <ImageView fx:id="mainPicture" fitWidth="840.0" onMouseClicked="#openPopUpPicture" pickOnBounds="true" preserveRatio="true" style="-fx-max-width: 840" styleClass="viewAlbumImage">
+                        <ImageView fx:id="mainImageContainer" fitWidth="840.0" onMouseClicked="#openPopUpPicture" pickOnBounds="true" preserveRatio="true" style="-fx-max-width: 840" styleClass="viewAlbumImage">
                            <image>
                               <Image url="@../../Images/placeholder-1920x1080.png" />
                            </image>
                         </ImageView>
                         <ScrollPane hbarPolicy="ALWAYS" maxHeight="100.0" prefHeight="110.0" prefWidth="839.0" styleClass="scroll-pane" stylesheets="@style.css" vbarPolicy="NEVER" vmax="0.0" vvalue="1.0" VBox.vgrow="NEVER">
                            <content>
-                              <HBox fx:id="albumImages" alignment="CENTER" maxHeight="100.0" prefHeight="85.0" prefWidth="858.0" spacing="10.0" styleClass="scrollHbox" stylesheets="@style.css">
+                              <HBox fx:id="albumImagesContainer" alignment="CENTER" maxHeight="100.0" prefHeight="85.0" prefWidth="858.0" spacing="10.0" styleClass="scrollHbox" stylesheets="@style.css">
                               </HBox>
                            </content>
                         </ScrollPane>
-- 
GitLab