diff --git a/README.md b/README.md
index 8715d4d91..26d67c65f 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,61 @@
-# Duke project template
-
-This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it.
-
-## Setting up in Intellij
-
-Prerequisites: JDK 11, update Intellij to the most recent version.
-
-1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first)
-1. Open the project into Intellij as follows:
- 1. Click `Open`.
- 1. Select the project directory, and click `OK`.
- 1. If there are any further prompts, accept the defaults.
-1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
- In the same dialog, set the **Project language level** field to the `SDK default` option.
-3. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output:
- ```
- Hello from
- ____ _
- | _ \ _ _| | _____
- | | | | | | | |/ / _ \
- | |_| | |_| | < __/
- |____/ \__,_|_|\_\___|
- ```
+# Nocturne v0.2
+
+Welcome to the User Guide for Nocturne.
+
+
+
+## Setting up the ChatBot
+
+Ensure that you have the ip.jar file downloaded. Take note of which directory this file is located. A convenient location would be in Downloads, or the Desktop.
+
+Now, open up the command prompt. You can do this by pressing the Windows key and searching 'Command Prompt'. For Mac users, you can press 'Command + Space' to open up the search bar. From there you can open the Terminal by searching for it on the search bar.
+
+Once in the terminal, type in *cd Downloads* or *cd Desktop*. This will place you in the directory where you placed Nocturne. Now, simply type
+> java -jar ip.jar
+
+And this will initialize Nocturne.
+
+## Nocturne's Features
+
+Primarily, Nocturne is there to help you record tasks you need to do, as well as their completion status. To utilize them, you will need to enter the commands below. In particular, keep the commands in lowercase, and as much as possible, do not deviate from the command structure. Error messages will be thrown at you if you mess up, but not to worry, Nocturne will usually tell you what you did wrong.
+
+For the features below, Words in UPPER_CASE are the parameters to be supplied by the user.
+e.g. in *todo TASK*, *TASK* is a parameter which can be used as *todo pay the bills*.
+
+### Adding a Todo task: **todo STRING**
+Adds a Todo task to the list.
+For example: >*todo do the laundry*
+
+### Adding a deadline task: **deadline STRING /by TIME**
+Adds a deadline to the list.
+For example: >*deadline return books /by Friday 5pm*
+
+### Adding an event task: **event STRING /from START /to END**
+Adds an event to the list.
+For example: >*event Brian's birthday /from Saturday 2pm /to Saturday 10pm
+
+### Marking a task as complete: **mark NUMBER**
+Marks a task as complete.
+For example: >*mark 2*
+
+### Marking a task as incomplete: **unmark NUMBER**
+Marks a task as incomplete.
+For example: >*unmark 2*
+
+### Deleting a task: **delete NUMBER**
+Deletes a task already on the list.
+For example: >*delete 1*
+
+### Finding a task: **find KEYWORD**
+Finds any tasks that have your keyword and shows them to you. Does not include the TIME, START or END inputs from deadline or event.
+For example: >*find swim*
+
+### Listing all tasks: **list**
+Lists all the tasks you have accummulated thus far, showing them in a numbered list, displaying their type (T for Todo, D for deadline and E for event) as well as their completion status.
+
+### Closing the bot: **bye**
+Causes the bot to exit.
+
+Be aware that running the bot in the first place creates a text file, nocturne.txt, within the directory that your ip.jar file is placed in. This holds all of the tasks that you have inputted, which Nocturne will remember on startup once again. There is no need for manual saving, as Nocturne updates it every time you add, delete or mark tasks.
+
+Thank you for using Nocturne.
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
index 8077118eb..2f566823f 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,29 +1,61 @@
-# User Guide
+# Nocturne v0.2
-## Features
+Welcome to the User Guide for Nocturne.
-### Feature-ABC
+
-Description of the feature.
+## Setting up the ChatBot
-### Feature-XYZ
+Ensure that you have the ip.jar file downloaded. Take note of which directory this file is located. A convenient location would be in Downloads, or the Desktop.
-Description of the feature.
+Now, open up the command prompt. You can do this by pressing the Windows key and searching 'Command Prompt'. For Mac users, you can press 'Command + Space' to open up the search bar. From there you can open the Terminal by searching for it on the search bar.
-## Usage
+Once in the terminal, type in *cd Downloads* or *cd Desktop*. This will place you in the directory where you placed Nocturne. Now, simply type
+> java -jar ip.jar
-### `Keyword` - Describe action
+And this will initialize Nocturne.
-Describe the action and its outcome.
+## Nocturne's Features
-Example of usage:
+Primarily, Nocturne is there to help you record tasks you need to do, as well as their completion status. To utilize them, you will need to enter the commands below. In particular, keep the commands in lowercase, and as much as possible, do not deviate from the command structure. Error messages will be thrown at you if you mess up, but not to worry, Nocturne will usually tell you what you did wrong.
-`keyword (optional arguments)`
+For the features below, Words in UPPER_CASE are the parameters to be supplied by the user.
+e.g. in *todo TASK*, *TASK* is a parameter which can be used as *todo pay the bills*.
-Expected outcome:
+### Adding a Todo task: **todo STRING**
+Adds a Todo task to the list.
+For example: >*todo do the laundry*
-Description of the outcome.
+### Adding a deadline task: **deadline STRING /by TIME**
+Adds a deadline to the list.
+For example: >*deadline return books /by Friday 5pm*
-```
-expected output
-```
+### Adding an event task: **event STRING /from START /to END**
+Adds an event to the list.
+For example: >*event Brian's birthday /from Saturday 2pm /to Saturday 10pm
+
+### Marking a task as complete: **mark NUMBER**
+Marks a task as complete.
+For example: >*mark 2*
+
+### Marking a task as incomplete: **unmark NUMBER**
+Marks a task as incomplete.
+For example: >*unmark 2*
+
+### Deleting a task: **delete NUMBER**
+Deletes a task already on the list.
+For example: >*delete 1*
+
+### Finding a task: **find KEYWORD**
+Finds any tasks that have your keyword and shows them to you. Does not include the TIME, START or END inputs from deadline or event.
+For example: >*find swim*
+
+### Listing all tasks: **list**
+Lists all the tasks you have accummulated thus far, showing them in a numbered list, displaying their type (T for Todo, D for deadline and E for event) as well as their completion status.
+
+### Closing the bot: **bye**
+Causes the bot to exit.
+
+Be aware that running the bot in the first place creates a text file, nocturne.txt, within the directory that your ip.jar file is placed in. This holds all of the tasks that you have inputted, which Nocturne will remember on startup once again. There is no need for manual saving, as Nocturne updates it every time you add, delete or mark tasks.
+
+Thank you for using Nocturne.
\ No newline at end of file
diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java
deleted file mode 100644
index 5d313334c..000000000
--- a/src/main/java/Duke.java
+++ /dev/null
@@ -1,10 +0,0 @@
-public class Duke {
- public static void main(String[] args) {
- String logo = " ____ _ \n"
- + "| _ \\ _ _| | _____ \n"
- + "| | | | | | | |/ / _ \\\n"
- + "| |_| | |_| | < __/\n"
- + "|____/ \\__,_|_|\\_\\___|\n";
- System.out.println("Hello from\n" + logo);
- }
-}
diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..a4f239d2c
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: Nocturne
+
diff --git a/src/main/java/Nocturne.java b/src/main/java/Nocturne.java
new file mode 100644
index 000000000..299fb4496
--- /dev/null
+++ b/src/main/java/Nocturne.java
@@ -0,0 +1,17 @@
+import exceptions.NocturneException;
+import util.Parser;
+import util.TaskList;
+import util.Ui;
+
+public class Nocturne {
+
+ /**
+ * The main function of the Chatbot, Nocturne.
+ */
+ public static void main(String[] args) {
+ TaskList list = new TaskList();
+ Ui.greetingMessage();
+ Parser.getInput(list);
+ Ui.farewellMessage();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/exceptions/NocturneException.java b/src/main/java/exceptions/NocturneException.java
new file mode 100644
index 000000000..df6a10730
--- /dev/null
+++ b/src/main/java/exceptions/NocturneException.java
@@ -0,0 +1,7 @@
+package exceptions;
+
+public class NocturneException extends Exception {
+ public NocturneException(String s) {
+ super(s);
+ }
+}
diff --git a/src/main/java/tasks/Deadline.java b/src/main/java/tasks/Deadline.java
new file mode 100644
index 000000000..7f859a7ca
--- /dev/null
+++ b/src/main/java/tasks/Deadline.java
@@ -0,0 +1,45 @@
+package tasks;
+
+/**
+ * Deadline subclass of Task. Requiring a by input.
+ */
+public class Deadline extends Task {
+ protected String by;
+
+ /**
+ * Constructor for the deadline object.
+ *
+ * @param description The description of the deadline.
+ * @param by The due date of the deadline.
+ */
+ public Deadline(String description, String by) {
+ super(description);
+ this.by = by;
+ }
+
+ /**
+ * Constructor for the deadline object when reconstructing the list
+ * from nocturne.txt, which includes the completion status of the deadline.
+ *
+ * @param description The description of the deadline.
+ * @param by The due date of the deadline.
+ * @param isDone The boolean variable of whether the deadline is done or not.
+ */
+ public Deadline(String description, String by, boolean isDone) {
+ super(description);
+ this.by = by;
+ this.isDone = isDone;
+ }
+
+ /**
+ * Override of the deadline class when it is printed,
+ * resulting in the format shown in the list.
+ *
+ * @return The string that will be printed.
+ */
+ @Override
+ public String toString() {
+ return "[D]" + "[" + super.getStatusIcon() + "] " + this.description + " (by: " + by + ")";
+ }
+}
+
diff --git a/src/main/java/tasks/Event.java b/src/main/java/tasks/Event.java
new file mode 100644
index 000000000..89ccdce68
--- /dev/null
+++ b/src/main/java/tasks/Event.java
@@ -0,0 +1,51 @@
+package tasks;
+
+/**
+ * Event subclass of Task. Requires a from and to input.
+ */
+public class Event extends Task {
+ protected String from;
+ protected String to;
+
+ /**
+ * Constructor for the event object.
+ *
+ * @param description The description of the event.
+ * @param from The start time of the event.
+ * @param to The end time of the event.
+ */
+ public Event(String description, String from, String to) {
+ super(description);
+ this.from = from;
+ this.to = to;
+ }
+
+ /**
+ * Constructor for event when restructuring the list from
+ * nocturne.txt, which includes the completion status of the event.
+ *
+ * @param description The description of the event.
+ * @param from The start time of the event.
+ * @param to The end time of the event.
+ * @param isDone The boolean variable of whether the event is done or not.
+ */
+ public Event(String description, String from, String to, boolean isDone) {
+ super(description);
+ this.from = from;
+ this.to = to;
+ this.isDone = isDone;
+ }
+
+ /**
+ * Override of the event class when printed,
+ * resulting in the format shown in the list.
+ *
+ * @return The string that will be printed.
+ */
+ @Override
+ public String toString() {
+ return "[E][" + super.getStatusIcon() +
+ "] " + this.description +
+ " (from: " + this.from + " to: " + this.to + ")";
+ }
+}
diff --git a/src/main/java/tasks/Task.java b/src/main/java/tasks/Task.java
new file mode 100644
index 000000000..2efac36f1
--- /dev/null
+++ b/src/main/java/tasks/Task.java
@@ -0,0 +1,51 @@
+package tasks;
+
+/**
+ * The base class of deadline, event and todo.
+ */
+public class Task {
+ protected String description;
+ protected boolean isDone;
+
+ /**
+ * Constructor for the task object.
+ *
+ * @param description The description of the task.
+ */
+ public Task(String description) {
+ this.description = description;
+ this.isDone = false;
+ }
+
+ /**
+ * The string showing the completion status of the task.
+ *
+ * @return X when the task is completed, one blank space otherwise.
+ */
+ public String getStatusIcon() {
+ return (isDone ? "X" : " ");
+ }
+
+ /**
+ * Marks a task as done.
+ */
+ public void markAsDone() {
+ this.isDone = true;
+ }
+
+ /**
+ * Marks a task as not done.
+ */
+ public void markAsUndone() {
+ this.isDone = false;
+ }
+
+ /**
+ * Gets the description of a task.
+ *
+ * @return The description of a task.
+ */
+ public String getDescription() {
+ return this.description;
+ }
+}
diff --git a/src/main/java/tasks/Todo.java b/src/main/java/tasks/Todo.java
new file mode 100644
index 000000000..e13407359
--- /dev/null
+++ b/src/main/java/tasks/Todo.java
@@ -0,0 +1,41 @@
+package tasks;
+
+/**
+ * The Todo subclass of Task. Requires no additional inputs.
+ */
+public class Todo extends Task {
+
+ /**
+ * Constructor for the todo object.
+ *
+ * @param description The description of the todo.
+ */
+ public Todo(String description) {
+ super(description);
+ this.isDone = false;
+ }
+
+ /**
+ * Constructor for the todo object when restructuring the list
+ * from nocturne.txt, which includes the completion status of the todo.
+ *
+ * @param description The description of the todo.
+ * @param isDone The boolean variable of whether the todo is done or not.
+ */
+ public Todo(String description, boolean isDone) {
+ super(description);
+ this.isDone = isDone;
+ }
+
+ /**
+ * Override of the todo class when it is printed,
+ * resulting in the format shown in the list.
+ *
+ * @return The string that will be printed.
+ */
+ @Override
+ public String toString() {
+ return "[T]" + "[" + super.getStatusIcon() + "] " + description;
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/util/Parser.java b/src/main/java/util/Parser.java
new file mode 100644
index 000000000..d7f331b74
--- /dev/null
+++ b/src/main/java/util/Parser.java
@@ -0,0 +1,101 @@
+package util;
+
+import tasks.Deadline;
+import tasks.Event;
+import tasks.Todo;
+import java.util.Scanner;
+
+/**
+ * The class that handles user input and processes for the commands.
+ */
+public class Parser {
+
+ /**
+ * Takes the first word of any input as the command.
+ *
+ * @param input The user's line input.
+ * @return Command string.
+ */
+ public static String getCommand(String input) {
+ return input.split(" ")[0].toLowerCase();
+ }
+
+ /**
+ * Obtains the non-command part of the input, which contains both
+ * the description and the timings for deadline and event.
+ *
+ * @param input The user's line input.
+ * @return Non-command string.
+ */
+ public static String getTask(String input) {
+ String[] splitInput = input.split(" ", 2);
+ return splitInput.length > 1 ? splitInput[1] : "";
+ }
+
+ /**
+ * Generates a response based on the user's input.
+ *
+ * @param input The user's line input.
+ * @param tasks The array list of tasks that will be modified
+ * based on the command.
+ */
+ private static void getResponse(String input, TaskList tasks) {
+ String command = getCommand(input);
+ String task = getTask(input);
+ try {
+ switch (command) {
+ case "list":
+ tasks.listTasks();
+ break;
+ case "mark":
+ tasks.markTask(Integer.parseInt(task));
+ break;
+ case "unmark":
+ tasks.unmarkTask(Integer.parseInt(task));
+ break;
+ case "todo":
+ tasks.addTask(new Todo(task.trim()));
+ break;
+ case "deadline":
+ String[] deadlineSplit = task.split("/");
+ tasks.addTask(new Deadline(deadlineSplit[0].trim(),
+ deadlineSplit[1].substring(3).trim()));
+ break;
+ case "event":
+ String[] eventSplit = task.split("/");
+ tasks.addTask(new Event(eventSplit[0].trim(),
+ eventSplit[1].substring(5).trim(),
+ eventSplit[2].substring(3).trim()));
+ break;
+ case "find":
+ tasks.findTask(task);
+ break;
+ case "delete":
+ tasks.deleteTask(Integer.parseInt(task));
+ break;
+ default:
+ System.out.println("Your command is invalid, invalid. Try again.");
+ }
+ } catch (IndexOutOfBoundsException e) {
+
+ Ui.missingSlashMessage();
+ } catch (NumberFormatException e) {
+ System.out.println("Ensure that you include a number after your delete/find/mark command.");
+ }
+ }
+
+ /**
+ * Takes in the user's input from the command line interface,
+ * running it through the response method.
+ *
+ * @param tasks The array list of tasks that will be modified.
+ */
+ public static void getInput(TaskList tasks) {
+ Scanner in = new Scanner(System.in);
+ String line = in.nextLine();
+ while (!line.equals("bye")) {
+ getResponse(line, tasks);
+ line = in.nextLine();
+ }
+ }
+}
diff --git a/src/main/java/util/Storage.java b/src/main/java/util/Storage.java
new file mode 100644
index 000000000..84c898762
--- /dev/null
+++ b/src/main/java/util/Storage.java
@@ -0,0 +1,99 @@
+package util;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Scanner;
+import tasks.Deadline;
+import tasks.Event;
+import tasks.Task;
+import tasks.Todo;
+
+public class Storage {
+ /**
+ * Directory constant.
+ */
+ private final String PATH = "./data/nocturne.txt";
+ private File f;
+
+ /**
+ * Constructor for the Storage, creating the directory and file that
+ * Nocturne will read and write to.
+ */
+ public Storage() {
+ File dir = new File("./data");
+ if (!dir.exists()) {
+ dir.mkdir();
+ }
+ this.f = new File(PATH);
+ try {
+ f.createNewFile();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Writes to the file specified above.
+ *
+ * @param taskList The list of tasks that will be updated on call.
+ * @throws IOException if the file cannot be access or written to.
+ */
+ public void saveToFile(TaskList taskList) {
+ try {
+ FileWriter fileWriter = new FileWriter(this.f);
+ fileWriter.write("");
+ for (Task task : taskList.tasks) {
+ fileWriter.append(task.toString()).append("\n");
+ }
+ fileWriter.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Reads from the file in the directory specified above.
+ *
+ * @param tasks The new instance of the list of tasks that will be shown when
+ * list is called.
+ */
+ public void readFromFile(TaskList tasks) {
+ try {
+ Scanner sc = new Scanner(this.f);
+
+ while(sc.hasNextLine()) {
+ String data = sc.nextLine();
+
+ //Deserialization of the strings in the file occur here.
+
+ String task = data.substring(6);
+ task = task.replace('(', ' ');
+ task = task.replace(')', ' ');
+ boolean isDone = data.charAt(4) == 'X';
+ switch (data.charAt(1)) {
+ case 'D':
+ String[] deadlineSplit = task.split("by:");
+ tasks.addTaskStealth(new Deadline(deadlineSplit[0].trim(),
+ deadlineSplit[1].trim(),
+ isDone));
+ break;
+ case 'E':
+ String[] eventSplit = task.split(":");
+ tasks.addTaskStealth(new Event(eventSplit[0].substring(0,
+ eventSplit[0].length() - 4).trim(),
+ eventSplit[1].substring(0, eventSplit[1].length() - 2).trim(),
+ eventSplit[2].trim(),
+ isDone));
+ break;
+ case 'T':
+ tasks.addTaskStealth(new Todo(task.trim(), isDone));
+ }
+ }
+ sc.close();
+ } catch (IndexOutOfBoundsException | FileNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/main/java/util/TaskList.java b/src/main/java/util/TaskList.java
new file mode 100644
index 000000000..69c27ab7e
--- /dev/null
+++ b/src/main/java/util/TaskList.java
@@ -0,0 +1,135 @@
+package util;
+
+import java.util.ArrayList;
+import tasks.Task;
+
+/**
+ * This class handles the array list of tasks.
+ *
+ */
+public class TaskList {
+ /**
+ * ArrayList is initialised here. Storage is also initialised at the same time.
+ */
+ protected ArrayList tasks = new ArrayList<>();
+ protected Storage storage = new Storage();
+
+ /**
+ * Storage reading is done along with the constructor.
+ */
+ public TaskList() {
+ this.storage.readFromFile(this);
+ }
+
+ /**
+ * Adds a task to the array list, while updating nocturne.txt.
+ *
+ * @param task A task that will be added. Can be of type deadline, event or todo.
+ */
+ public void addTask(Task task) {
+ System.out.println("A task I see. I have added it.");
+ Ui.printTask(task);
+ this.tasks.add(task);
+ this.storage.saveToFile(this);
+ }
+
+ /**
+ * Adds a task without printing a message, which is done
+ * on initialisation when reading from nocturne.txt file,
+ * while updating nocturne.txt.
+ *
+ * @param task The task that will be added to the array list.
+ */
+ public void addTaskStealth(Task task) {
+ this.tasks.add(task);
+ this.storage.saveToFile(this);
+ }
+
+ /**
+ * Deletes a task in the array list, while updating nocturne.txt.
+ *
+ * @param index The index of the entry that will get deleted.
+ * Starts from 1 to be more intuitive, requiring -1
+ * in the accessing.
+ */
+ public void deleteTask(int index) {
+ try {
+ System.out.println("Should all acquaintance be forgot...");
+ Ui.printTask(this.tasks.get(index - 1));
+ this.tasks.remove(index - 1);
+ System.out.println(this.tasks.size() + " task(s) remain.");
+ } catch (IndexOutOfBoundsException e) {
+ Ui.indexOutOfBoundsMessage();
+ }
+ this.storage.saveToFile(this);
+ }
+
+ /**
+ * Lists out all the tasks recorded in the array list thus far.
+ */
+ public void listTasks() {
+ if (this.tasks.isEmpty()) {
+ Ui.emptyListMessage();
+ }
+
+ for(int i = 0; i < this.tasks.size(); ++i) {
+ System.out.print(i + 1 + ".");
+ System.out.println(this.tasks.get(i));
+ }
+
+ }
+
+ /**
+ * Marks a task as done, while updating nocturne.txt.
+ *
+ * @param index The index of the task that will be updated as done.
+ */
+ public void markTask(int index) {
+ try {
+ (this.tasks.get(index - 1)).markAsDone();
+ System.out.println("Congratulations. I have marked this task as finished:");
+ Ui.printTask(this.tasks.get(index - 1));
+ } catch (IndexOutOfBoundsException var3) {
+ Ui.indexOutOfBoundsMessage();
+ }
+
+ this.storage.saveToFile(this);
+ }
+
+ /**
+ * Marks a task as undone, while updating nocturne.txt.
+ *
+ * @param index The index of the task that will be updated as undone.
+ */
+ public void unmarkTask(int index) {
+ try {
+ (this.tasks.get(index - 1)).markAsUndone();
+ System.out.println("Do not neglect your duties. I have marked this task as unfinished:");
+ Ui.printTask(this.tasks.get(index - 1));
+ } catch (IndexOutOfBoundsException e) {
+ Ui.indexOutOfBoundsMessage();
+ }
+
+ this.storage.saveToFile(this);
+ }
+
+ /**
+ * Finds tasks that contain the keyword and prints out any matches.
+ *
+ * @param keyFind The string that will be used to find matches.
+ */
+ public void findTask(String keyFind) {
+ try {
+ System.out.println("Here is what you are looking for: ");
+ int count = 1;
+ for (Task task : this.tasks) {
+ if (task.getDescription().contains(keyFind)) {
+ System.out.println(count + ". " + task);
+ ++count;
+ }
+ }
+ } catch (IndexOutOfBoundsException e) {
+ Ui.indexOutOfBoundsMessage();
+ }
+ }
+}
diff --git a/src/main/java/util/Ui.java b/src/main/java/util/Ui.java
new file mode 100644
index 000000000..616a11b0a
--- /dev/null
+++ b/src/main/java/util/Ui.java
@@ -0,0 +1,56 @@
+package util;
+
+import tasks.Task;
+
+/**
+ * The class that interacts with the user. General messages are placed here.
+ */
+public class Ui {
+
+ /**
+ * Prints on initialisation.
+ */
+ public static void greetingMessage() {
+ System.out.println("Good evening. I'm Nocturne.");
+ System.out.println("What ails you on this fine day?");
+ }
+
+ /**
+ * Prints on exit.
+ */
+ public static void farewellMessage() {
+ System.out.println("Farewell. And may the fortunes be ever in your favour.");
+ }
+
+ /**
+ * Prints to let the user know that they are accessing and index that is out of
+ * bounds, through the mark, unmark or delete methods.
+ */
+ public static void indexOutOfBoundsMessage() {
+ System.out.println("You are trying to access forbidden territory. Tread carefully.");
+ }
+
+ /**
+ * Prints a message to let the user know that their list is empty.
+ */
+ public static void emptyListMessage() {
+ System.out.println("Your list is empty. Try again, when you have become more productive.");
+ }
+
+ /**
+ * Prints to let the user know that they are missing / in the deadline and
+ * event inputs.
+ */
+ public static void missingSlashMessage() {
+ System.out.println("You are missing a /. Do not let this happen again.");
+ }
+
+ /**
+ * Prints out a task with indentation.
+ *
+ * @param task: a singular task that can be printed, T, D or E.
+ */
+ public static void printTask(Task task) {
+ System.out.println(" " + task);
+ }
+}