diff --git a/README.md b/README.md
index 303bc3d19..67d7bb3bd 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Duke project template
+# duke.main.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.
@@ -14,7 +14,7 @@ Prerequisites: JDK 11, update IntelliJ to the most recent version.
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).
-1. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()`. If the setup is correct, you should see something like the output below.
+1. After that, locate the `src/main/java/duke.main.Duke.java` file, right-click it, and choose `Run duke.main.Duke.main()`. If the setup is correct, you should see something like the output below.
```
Hello from
diff --git a/docs/README.md b/docs/README.md
index fd4406959..6609b183f 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,20 +1,306 @@
# User Guide
+- [Introduction](#2)
+- [Setup](#3)
+- [Notes](#1)
+- [Features](#a)
+ - [Adding tasks](#a)
+ - [todo](#a)
+ - [deadline](#b)
+ - [event](#c)
+ - [Listing all tasks](#d)
+ - [Completing a task](#e)
+ - [Find](#f)
+ - [Description](#f)
+ - [Date](#g)
+ - [Save and exit](#i)
-## Features
+***
+# Introduction
-### Feature 1
-Description of feature.
+Your very own application to manage your to-do list!
-## Usage
+# Setup
-### `Keyword` - Describe action
+ 1. Copy the jar file
-Describe action and its outcome.
+ 2. Launch the jar file using the following command in `CMD`
-Example of usage:
+ `java -jar [path to your runnable jar file]`
-`keyword (optional arguments)`
+
+ In the event that some characters are not properly printed in the terminal, use the following commands:
-Expected outcome:
+ `chcp 65001`
+
+ `java -jar -Dfile.encoding=UTF-8 [path to your runnable jar file]`
+
+
+***
+
+# Notes
+
+**General Formatting:**
+
+ Description - Describes the functionality of the feature
+
+ Formatting - Describes the code formatting to use a feature
+
+ Examples - Examples of how to use a feature
+
+ Example output - Snapshot of how the usage of a feature will appear in the application
+
+
+**Additional notes:**
+
+ The square brackets specifies that user input is required
+
+ `command [variable input]`
+
+***
+
+# Features
+***
+## Adding tasks: Todo
+**Description:**
+
+ Adding a simple task using the `todo` command
+
+**Formatting:**
+
+ `todo` [task description]
+
+**Examples:**
+
+ Adding the task "read shakespeare"
+
+ `todo read shakespeare`
+
+ Adding the task "finish java quiz"
+
+ `todo finish java quiz`
+
+**Example output:**
+```
+todo read shakespeare
+____________________________________________________________
+Got it. I've added this task:
+ [T][✘] read shakespeare
+Now you have 1 tasks in the list.
+____________________________________________________________
+```
+
+***
+## Adding tasks: Deadline
+
+**Description:**
+
+ Adding a deadline task using the `deadline` command.
+
+ A deadline consist of a **description** and a **date**.
+
+**Formatting:**
+
+ `deadline [task description] /by [date in format YYYY-MM-DD]`
+
+**Examples**
+
+ Adding the deadline "read shakespeare by 8 Mar 2021"
+
+ `deadline read shakespeare /by 2021-03-08`
+
+ Adding the deadline "finish java quiz by 16 Nov 2021"
+
+ `deadline finish java quiz /by 2021-11-16`
+
+**Example output**
+```
+deadline read shakespeare /by 2021-03-08
+____________________________________________________________
+Got it. I've added this task:
+ [D][✘] read shakespeare (by: Mar-08-2021 )
+Now you have 1 tasks in the list.
+____________________________________________________________
+```
+***
+
+## Adding tasks: Event
+**Description:**
+
+ Adding an event task using the `event` command.
+
+ An event consist of a **description** and a **date**.
+
+**Formatting:**
+
+ `event [task description] /at [date in format YYYY-MM-DD]`
+
+**Examples**
+
+ Adding the event "read shakespeare by 8 Mar 2021"
+
+ `event shakespeare's play /at 2021-03-08`
+
+ Adding the event "java quiz by 16 Nov 2021"
+
+ `event java quiz /at 2021-11-16`
+
+**Example output**
+```
+event shakespeare's play /at 2021-03-08
+____________________________________________________________
+Got it. I've added this task:
+ [E][✘] shakespeare's play (by: Mar-08-2021 )
+Now you have 1 tasks in the list.
+____________________________________________________________
+```
+
+
+## Listing all tasks
+**Description:**
+
+ List all tasks (todo, deadline, event)
+
+**Formatting:**
+
+ `list`
+
+**Example output**
+```
+list
+____________________________________________________________
+Here are the tasks in your list:
+1.[T][✘] read shakespeare
+2.[D][✘] read shakespeare (by: Mar-08-2021 )
+3.[E][✘] shakespeare's play (at: Mar-08-2021 )
+____________________________________________________________
+```
+***
+
+## Completing a task
+**Description:**
+
+ Set the task to be done.
+
+**Formatting:**
+
+ `done [index]`
+
+**Examples**
+
+ `done 1`
+
+**Example output**
+```
+Here are the tasks in your list:
+1.[T][✘] read shakespeare
+2.[D][✘] read shakespeare (by: Mar-08-2021 )
+3.[E][✘] shakespeare's play (at: Mar-08-2021 )
+____________________________________________________________
+done 1
+____________________________________________________________
+Nice! I've marked this task as done:
+[✓] read shakespeare
+____________________________________________________________
+list
+____________________________________________________________
+Here are the tasks in your list:
+1.[T][✓] read shakespeare
+2.[D][✘] read shakespeare (by: Mar-08-2021 )
+3.[E][✘] shakespeare's play (at: Mar-08-2021 )
+____________________________________________________________
+```
+
+## Find tasks: Description
+**Description:**
+
+ Find specific tasks based on similar descriptions.
+
+**Formatting:**
+
+ `find [task description]`
+
+**Examples**
+
+ Find any tasks with the phrase "read shakespeare" in description
+
+ `find read shakespeare`
+
+ Find any tasks with the word book description
+
+ `find book`
+
+**Example output**
+```
+find read shakespeare
+____________________________________________________________
+Here are the matching tasks in your list:
+1.[T][✓] read shakespeare
+2.[D][✘] read shakespeare (by: Mar-08-2021 )
+____________________________________________________________
+```
+
+## Find tasks: Date
+**Description:**
+
+ Find specific tasks based on date input.
+
+**Formatting:**
+
+ Find all events that occur on a specific date
+
+ `findAt [Date with format YYYY-MM-DD]`
+
+ Find all deadlines that occurs before a specific date
+
+ `findBy [Date with format YYYY-MM-DD]`
+
+**Examples**
+
+ Find events happening on 10 March 2021
+
+ `findAt 2021-03-10`
+
+ Find all deadlines that occurs before a 10 March 2021
+
+ `findBy 2021-03-10`
+
+**Example output**
+```
+Here are the tasks in your list:
+1.[T][✓] read shakespeare
+2.[D][✘] read shakespeare (by: Mar-08-2021 )
+3.[E][✘] shakespeare's play (at: Mar-08-2021 )
+4.[D][✘] watch wandaVision (by: Mar-10-2021 )
+5.[E][✘] homework submission (at: Mar-08-2021 )
+____________________________________________________________
+findAt 2021-03-08
+____________________________________________________________
+Here are the matching tasks in your list:
+1.[E][✘] shakespeare's play (at: Mar-08-2021 )
+2.[E][✘] homework submission (at: Mar-08-2021 )
+____________________________________________________
+findBy 2021-03-10
+____________________________________________________________
+Here are the matching tasks in your list:
+1.[D][✘] read shakespeare (by: Mar-08-2021 )
+2.[D][✘] watch wandaVision (by: Mar-10-2021 )
+```
+
+## Save and exit
+**Description:**
+
+ Save all tasks in file and exits
+
+**Formatting:**
+
+ `bye`
+
+**Example output**
+```
+bye
+____________________________________________________________
+File is overwritten.
+Bye. Hope to see you again soon!
+____________________________________________________________
+```
-`outcome`
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 000000000..fc24e7a62
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-hacker
\ No newline at end of file
diff --git a/list.txt b/list.txt
new file mode 100644
index 000000000..d45343e60
--- /dev/null
+++ b/list.txt
@@ -0,0 +1,6 @@
+D false owennsdck Oct-10-2020
+D false ppp Oct-11-2020
+D false qqq Oct-12-2020
+D false eee Oct-13-2020
+E true party Sep-09-2020
+T false owen
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..2c6354be6
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: duke.main.Duke
+
diff --git a/src/main/java/duke/exceptions/DeadlineParameterExceptions.java b/src/main/java/duke/exceptions/DeadlineParameterExceptions.java
new file mode 100644
index 000000000..11e3a8861
--- /dev/null
+++ b/src/main/java/duke/exceptions/DeadlineParameterExceptions.java
@@ -0,0 +1,5 @@
+package duke.exceptions;
+
+/** DeadlineParameterExceptions class to handle deadline parameter exception. */
+public class DeadlineParameterExceptions extends Exception{
+}
diff --git a/src/main/java/duke/exceptions/EventParameterExceptions.java b/src/main/java/duke/exceptions/EventParameterExceptions.java
new file mode 100644
index 000000000..2aa23cd18
--- /dev/null
+++ b/src/main/java/duke/exceptions/EventParameterExceptions.java
@@ -0,0 +1,5 @@
+package duke.exceptions;
+
+/** EventParameterExceptions class to handle Event parameter exception. */
+public class EventParameterExceptions extends Exception{
+}
diff --git a/src/main/java/duke/exceptions/InvalidCommandExceptions.java b/src/main/java/duke/exceptions/InvalidCommandExceptions.java
new file mode 100644
index 000000000..6d616a497
--- /dev/null
+++ b/src/main/java/duke/exceptions/InvalidCommandExceptions.java
@@ -0,0 +1,5 @@
+package duke.exceptions;
+
+/** InvalidCommandExceptions class to handle invalid commands exception. */
+public class InvalidCommandExceptions extends Exception{
+}
diff --git a/src/main/java/duke/exceptions/InvalidIndexExceptions.java b/src/main/java/duke/exceptions/InvalidIndexExceptions.java
new file mode 100644
index 000000000..5914bceba
--- /dev/null
+++ b/src/main/java/duke/exceptions/InvalidIndexExceptions.java
@@ -0,0 +1,5 @@
+package duke.exceptions;
+
+/** InvalidIndexExceptions class to handle invalid index exception. */
+public class InvalidIndexExceptions extends Exception{
+}
diff --git a/src/main/java/duke/exceptions/InvalidParameterLengthExceptions.java b/src/main/java/duke/exceptions/InvalidParameterLengthExceptions.java
new file mode 100644
index 000000000..2a4f127ef
--- /dev/null
+++ b/src/main/java/duke/exceptions/InvalidParameterLengthExceptions.java
@@ -0,0 +1,5 @@
+package duke.exceptions;
+
+/** InvalidParameterLengthExceptions class to handle insufficient parameters exception. */
+public class InvalidParameterLengthExceptions extends Exception{
+}
diff --git a/src/main/java/duke/items/Deadline.java b/src/main/java/duke/items/Deadline.java
new file mode 100644
index 000000000..bccae4982
--- /dev/null
+++ b/src/main/java/duke/items/Deadline.java
@@ -0,0 +1,61 @@
+package duke.items;
+
+import static duke.main.UI.convertDateToStringFormat;
+
+/**
+ * Deadline class
+ */
+public class Deadline extends Task {
+ protected String by;
+
+ /**
+ * Deadline constructor
+ *
+ * @param description Description of the task
+ * @param byInput input String of date
+ */
+ public Deadline(String description, String byInput) {
+ super(description);
+ this.by = byInput;
+ }
+
+ /**
+ * Change the by attribute of Deadline
+ *
+ * @param byInput new String of date
+ */
+ public void setBy(String byInput) {
+ this.by = byInput;
+ }
+
+ /**
+ * Returns the by attribute of Deadline object
+ *
+ * @return this.by
+ */
+ public String getBy() {
+ return this.by;
+ }
+
+ /**
+ * Returns the Type of Deadline object
+ *
+ * @return String "D"
+ */
+ @Override
+ public String getType() {
+ return "D";
+ }
+
+ /**
+ * Prints the Deadline object in a certain format
+ */
+ @Override
+ public void print(){
+ if (this.isDone) {
+ System.out.println("[D][√] " + description + " (by: " + by + ")");
+ } else {
+ System.out.println("[D][X] " + description + " (by: " + by + ")");
+ }
+ }
+}
diff --git a/src/main/java/duke/items/Event.java b/src/main/java/duke/items/Event.java
new file mode 100644
index 000000000..6494cca50
--- /dev/null
+++ b/src/main/java/duke/items/Event.java
@@ -0,0 +1,60 @@
+package duke.items;
+
+
+/**
+ * Event class
+ */
+public class Event extends Task {
+ private String at;
+
+ /**
+ * Event constructor
+ *
+ * @param description Description of the task
+ * @param atInput input String of date
+ */
+ public Event(String description, String atInput) {
+ super(description);
+ this.at = atInput;
+ }
+
+ /**
+ * Change the by attribute of Event
+ *
+ * @param atInput new String of date
+ */
+ public void setAt(String atInput) {
+ this.at = atInput;
+ }
+
+ /**
+ * Returns the at attribute of Event object
+ *
+ * @return this.at
+ */
+ public String getAt() {
+ return this.at;
+ }
+
+ /**
+ * Returns the Type of Event object
+ *
+ * @return String "E"
+ */
+ @Override
+ public String getType() {
+ return "E";
+ }
+
+ /**
+ * Prints the Event object in a certain format
+ */
+ @Override
+ public void print(){
+ if (this.isDone) {
+ System.out.println("[E][√] " + description + " (at: " + at + ")" );
+ } else {
+ System.out.println("[E][X] " + description + " (at: " + at + ")" );
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/items/Task.java b/src/main/java/duke/items/Task.java
new file mode 100644
index 000000000..71f25f487
--- /dev/null
+++ b/src/main/java/duke/items/Task.java
@@ -0,0 +1,255 @@
+package duke.items;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import duke.exceptions.*;
+import duke.main.UI;
+
+import static duke.main.Parser.*;
+import static duke.main.UI.convertDateToStringFormat;
+import static duke.main.UI.convertStringFormatToDate;
+
+/** Parent class for other classes (todo, deadline, event) */
+public class Task {
+ private static int numOfTasks = 0;
+ protected String description;
+ protected boolean isDone;
+ protected static ArrayList list = new ArrayList<>();
+
+ /**
+ * Returns the ArrayList from Task
+ *
+ * @return ArrayList
+ */
+ public static ArrayList getList(){
+ return list;
+ }
+
+ /**
+ * Returns the number of Tasks that are in the ArrayList list
+ *
+ * @return numOfTasks
+ */
+ public static int getNumOfTasks() {
+ return numOfTasks;
+ }
+
+ /**
+ * Prints each Task in the list using print() function
+ */
+ public static void printList(){
+ for (int i =0; i= numOfTasks){
+ throw new InvalidIndexExceptions();
+ }
+ list.get(index).isDone = true;
+ System.out.println("Nice! I've marked this task as done: ");
+ System.out.println("[√] " + list.get(index).getDescription());
+ }
+
+ /**
+ * Task object initialisation
+ *
+ * @param description Description of the Task
+ */
+ public Task(String description) {
+ this.description = description;
+ this.isDone = false;
+ }
+
+ /**
+ * Prints the Task in a fixed format
+ */
+ public void print(){
+ if (this.isDone) {
+ System.out.println("[T][√] " + description );
+ } else {
+ System.out.println("[T][X] " + description );
+ }
+ }
+
+ /**
+ * Returns Description of the given Task object
+ *
+ * @return Description
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Changes the description attribute of Task
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * Returns Type of the given Task object
+ *
+ * @return Type
+ */
+ public String getType() {
+ return "T";
+ }
+
+ /**
+ * Returns whether the Task is done
+ *
+ * @return boolean of isDone
+ */
+ public boolean isDone() {
+ return this.isDone;
+ }
+
+ /**
+ * Changes the isDone attribute of Task
+ */
+ public void setDone() {
+ this.isDone = true;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/items/Todo.java b/src/main/java/duke/items/Todo.java
new file mode 100644
index 000000000..7d369bf1c
--- /dev/null
+++ b/src/main/java/duke/items/Todo.java
@@ -0,0 +1,16 @@
+package duke.items;
+
+/**
+ * Todo class
+ */
+public class Todo extends Task {
+
+ /**
+ * Todo constructor
+ *
+ * @param description Description of the task
+ */
+ public Todo(String description) {
+ super(description);
+ }
+}
diff --git a/src/main/java/duke/main/Duke.java b/src/main/java/duke/main/Duke.java
new file mode 100644
index 000000000..eaf3de660
--- /dev/null
+++ b/src/main/java/duke/main/Duke.java
@@ -0,0 +1,18 @@
+package duke.main;
+
+
+public class Duke {
+ /**
+ * Prints welcome and goodbye message
+ * Calls fileHandling
+ * Calls run function from parser
+ * Main function that combines all functions from other files
+ */
+ public static void main(String[] args) {
+ UI.displayWelcomeMessage();
+ UI.printLine();
+ Storage.fileHandling();
+ Parser.run();
+ UI.displayByeMessage();
+ }
+}
diff --git a/src/main/java/duke/main/Parser.java b/src/main/java/duke/main/Parser.java
new file mode 100644
index 000000000..57b8c1326
--- /dev/null
+++ b/src/main/java/duke/main/Parser.java
@@ -0,0 +1,211 @@
+package duke.main;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.time.format.DateTimeParseException;
+import java.util.Scanner;
+
+import duke.exceptions.*;
+import duke.items.Task;
+
+import static duke.main.UI.convertDateToStringFormat;
+
+/** Class in charge of understanding input commands */
+public class Parser {
+
+ /**
+ * Check number of parameters in input command is valid
+ *
+ * @param line entire input command
+ * @throws InvalidParameterLengthExceptions If length of entire todo command is < 2
+ */
+ public static void validateTodoCommand(String line) throws InvalidParameterLengthExceptions {
+ if (line.split(" ").length < 2){
+ throw new InvalidParameterLengthExceptions();
+ }
+ }
+
+ /**
+ * Returns the index of the character "/" in the input command
+ * while checking for the validity of the command
+ *
+ * @param line entire input command
+ * @return index of "/" in the /by indicator
+ * @throws DeadlineParameterExceptions If /by is missing
+ * @throws InvalidParameterLengthExceptions If number of parameters < 4
+ */
+ public static int validateDeadlineCommand(String line) throws DeadlineParameterExceptions, InvalidParameterLengthExceptions {
+ int indexOfSlash;
+ if (line.split(" ").length < 4){
+ throw new InvalidParameterLengthExceptions();
+ }
+ indexOfSlash = line.indexOf("/by");
+ if (indexOfSlash == -1) {
+ throw new DeadlineParameterExceptions();
+ }
+ return indexOfSlash;
+ }
+
+ /**
+ * Returns the index of the character "/" in the input command
+ * while checking for the validity of the command
+ *
+ * @param line entire input command
+ * @return index of "/" in the /at indicator
+ * @throws EventParameterExceptions If /at is missing
+ * @throws InvalidParameterLengthExceptions If number of parameters < 4
+ */
+ public static int validateEventCommand(String line) throws EventParameterExceptions, InvalidParameterLengthExceptions {
+ int indexOfSlash;
+ if (line.split(" ").length < 4){
+ throw new InvalidParameterLengthExceptions();
+ }
+ indexOfSlash = line.indexOf("/at");
+ if (indexOfSlash == -1){
+ throw new EventParameterExceptions();
+ }
+ return indexOfSlash;
+ }
+
+ /**
+ * Returns the command keyword of a an input line
+ *
+ * @param line entire input command
+ * @return command keyword
+ */
+ public static String getCommand(String line) {
+ return line.split(" ")[0];
+ }
+
+ /**
+ * Returns the description of a todo task input
+ *
+ * @param line entire input command
+ * @return String description of the todo task
+ */
+ public static String extractTodo(String line) {
+ return line.substring(line.indexOf(" ") + 1);
+ }
+
+ /**
+ * Returns the description and date of an Deadline/Event task input
+ *
+ * @param line entire input command
+ * @return String array containing description and date of the Deadline/Event task
+ * @throws DeadlineParameterExceptions If /by is missing for deadline task
+ * @throws EventParameterExceptions If /at is missing for event task
+ * @throws InvalidParameterLengthExceptions If number of parameters < 4
+ */
+ public static String[] extractDeadlineAndEvent(String line) throws InvalidParameterLengthExceptions,
+ DeadlineParameterExceptions, EventParameterExceptions {
+
+ int indexOfSlash;
+ if (getCommand(line).equals("deadline")) {
+ indexOfSlash = validateDeadlineCommand(line);
+ } else {
+ indexOfSlash = validateEventCommand(line);
+ }
+ String[] returnList = new String[2];
+ returnList[0] = line.substring(line.indexOf(" ") + 1, indexOfSlash - 1);
+ returnList[1] = line.substring(indexOfSlash + 4);
+ return returnList;
+ }
+
+ /**
+ * Decides which functions to run based on the input command
+ *
+ * @param line entire input command
+ * @return integer -1 when input request to exit, else 1
+ * @throws InvalidCommandExceptions If unrecognised command is used.
+ * @throws InvalidParameterLengthExceptions If number of parameters does not match command used.
+ * @throws DeadlineParameterExceptions If Deadline command format is not adhered to.
+ * @throws EventParameterExceptions If Event command format is not adhered to.
+ * @throws InvalidIndexExceptions If index out of range.
+ * @throws IOException If input output error occurs.
+ * @throws ParseException If date conversion error occurs
+ */
+ public static int commandHandler(String line) throws InvalidCommandExceptions, InvalidParameterLengthExceptions,
+ DeadlineParameterExceptions, EventParameterExceptions, InvalidIndexExceptions, IOException, ParseException {
+
+ switch (getCommand(line)) {
+ case ("bye"):
+ Storage.writeToFile();
+ return -1;
+
+ case ("list"):
+ UI.displayListPreamble();
+ Task.printList();
+ break;
+ case ("done"):
+ Task.setDone(Integer.parseInt(line.split(" ")[1]) - 1);
+ break;
+ case ("delete"):
+ int indexToDelete = Integer.parseInt(line.split(" ")[1]) - 1;
+ if (indexToDelete >= Task.getNumOfTasks()){
+ throw new InvalidIndexExceptions();
+ }
+ Task.deleteTask(indexToDelete);
+ UI.displayListUpdate();
+ break;
+ case ("find"):
+ UI.displayFindPreamble();
+ Task.findTask(line.split(" ")[1]);
+ break;
+ case ("findAt"):
+ UI.displayFindPreamble();
+ Task.findAt(convertDateToStringFormat(line.split(" ")[1]));
+ break;
+ case ("findBy"):
+ UI.displayFindPreamble();
+ Task.findBy(line.split(" ")[1]);
+ break;
+ case ("todo"):
+ Task.addTodo(line);
+ break;
+ case ("deadline"):
+ Task.addDeadline(line);
+ break;
+ case ("event"):
+ Task.addEvent(line);
+ break;
+ default:
+ throw new InvalidCommandExceptions();
+ }
+ return 1;
+ }
+
+ /**
+ * Runs loop that repeatedly calls for input command
+ * Runs commandHandler for each input command
+ * Catches error and decides error message
+ */
+ public static void run(){
+ Scanner in = new Scanner(System.in);
+ while (true) {
+ String line;
+ line = in.nextLine();
+ UI.printLine();
+ try {
+ if (commandHandler(line) == -1) {
+ break;
+ }
+ } catch (InvalidCommandExceptions e) {
+ UI.InvalidCommandErrorMessage();
+ } catch (InvalidParameterLengthExceptions e){
+ UI.InvalidParameterLengthErrorMessage(line);
+ } catch (EventParameterExceptions e){
+ UI.EventParameterErrorMessage();
+ } catch (DeadlineParameterExceptions e){
+ UI.DeadlineParameterErrorMessage();
+ } catch (InvalidIndexExceptions e){
+ UI.InvalidIndexErrorMessage();
+ } catch (DateTimeParseException e){
+ UI.InvalidDateErrorMessage(line);
+ } catch (ParseException | IOException e){
+ e.printStackTrace();
+ }
+ UI.printLine();
+ }
+ }
+}
+
diff --git a/src/main/java/duke/main/Storage.java b/src/main/java/duke/main/Storage.java
new file mode 100644
index 000000000..5fd1a51fd
--- /dev/null
+++ b/src/main/java/duke/main/Storage.java
@@ -0,0 +1,131 @@
+package duke.main;
+
+import duke.items.Deadline;
+import duke.items.Event;
+import duke.items.Task;
+import duke.items.Todo;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.Scanner;
+
+/**
+ * Class in charge of file IO
+ */
+public class Storage {
+
+ /**
+ * Handles the file IO process
+ */
+ public static void fileHandling(){
+ try {
+ loadFile();
+ } catch (FileNotFoundException e) {
+ createFile();
+ }
+ }
+
+ /**
+ * Loads data into current list of tasks
+ *
+ * @param line Each line (1 line represents 1 task) in saved records (list.txt)
+ */
+ public static void loadTask(String line){
+ String[] arr = line.split("\t");
+ switch(arr[0]){
+ case ("T"):
+ Todo todo = new Todo(arr[2]);
+ if (arr[1].equals("true")) {
+ todo.setDone();
+ }
+ Task.addTask(todo);
+ break;
+ case ("D"):
+ Deadline deadline = new Deadline(arr[2], arr[3]);
+ if (arr[1].equals("true")) {
+ deadline.setDone();
+ }
+ Task.addTask(deadline);
+ break;
+ case ("E"):
+ Event event = new Event(arr[2], arr[3]);
+ if (arr[1].equals("true")) {
+ event.setDone();
+ }
+ Task.addTask(event);
+ break;
+ }
+ }
+
+ /**
+ * Reads input from the file list.txt
+ *
+ * @throws FileNotFoundException If file does not exist
+ */
+ public static void loadFile() throws FileNotFoundException {
+ File f = new File("list.txt"); // create a File for the given file path
+ Scanner s = new Scanner(f); // create a Scanner using the File as the source
+ while (s.hasNext()) {
+ loadTask(s.nextLine());
+ }
+ }
+
+ /**
+ * Writes every task that exists within the Task list into the given format in list.txt
+ *
+ * @throws IOException If write errors occurs
+ */
+ public static void writeToFile() throws IOException {
+ createFile();
+ FileWriter fw = new FileWriter("list.txt");
+ for (int i=0; i buffer = Task.getList();
+ fw.write(formWriteData(buffer.get(i)));
+ }
+ fw.close();
+ }
+
+
+ /**
+ * Returns the formatted String (of a task), to be stored in a .txt file
+ *
+ * @param task Current task to be formatted into String
+ * @return Formatted String
+ */
+ public static String formWriteData(Task task) {
+
+ switch (task.getType()) {
+ case ("T"):
+ return (task.getType() + "\t" + task.isDone() + "\t" + task.getDescription() + "\n");
+ case ("D"):
+ Deadline temp1 = (Deadline) (task);
+ return (temp1.getType() + "\t" + temp1.isDone() + "\t" + temp1.getDescription() + "\t" + temp1.getBy() + "\n");
+ default:
+ Event temp2 = (Event) (task);
+ return (temp2.getType() + "\t" + temp2.isDone() + "\t" + temp2.getDescription() + "\t" + temp2.getAt() + "\n");
+ }
+ }
+
+ /**
+ * Creates file if file does not exist
+ *
+ * @throws IllegalArgumentException If input errors occur
+ */
+ public static void createFile(){
+ try {
+ File myObj = new File("list.txt");
+ if (myObj.createNewFile()) {
+ System.out.println("File created: " + myObj.getName());
+ } else {
+ System.out.println("File is overwritten.");
+ }
+ } catch (IOException e) {
+ System.out.println("An error occurred.");
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/main/UI.java b/src/main/java/duke/main/UI.java
new file mode 100644
index 000000000..6a9c50869
--- /dev/null
+++ b/src/main/java/duke/main/UI.java
@@ -0,0 +1,156 @@
+package duke.main;
+
+import duke.items.Task;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+import static duke.main.Parser.getCommand;
+
+/** Class in charge of UI printing */
+public class UI {
+ private static final String DEADLINE_TEMPLATE = "deadline /by ";
+ private static final String EVENT_TEMPLATE = "event /at ";
+ private static final String TODO_TEMPLATE = "todo read book";
+ private static final String DATE_TEMPLATE = "";
+ public static void printLine() {
+ System.out.println("____________________________________________________________");
+ }
+
+ /**
+ * Prints the welcome message.
+ */
+ public static void displayWelcomeMessage(){
+ String logo = " ____ _ \n"
+ + "| _ \\ _ _| | _____ \n"
+ + "| | | | | | | |/ / _ \\\n"
+ + "| |_| | |_| | < __/\n"
+ + "|____/ \\__,_|_|\\_\\___|\n";
+ System.out.println("Hello from\n" + logo);
+ System.out.println("Hello! I'm duke.main.Duke\nWhat can I do for you?");
+ }
+
+ /**
+ * Prints the goodbye message
+ */
+ public static void displayByeMessage(){
+ System.out.println("Bye. Hope to see you again soon!");
+ UI.printLine();
+ }
+
+ /**
+ * Printing the output when using the list function
+ */
+ public static void displayListPreamble() {
+ if (Task.getNumOfTasks() != 0){
+ System.out.println("Here are the tasks in your list:");
+ }
+ }
+
+ /**
+ * Printing the output when using the find function
+ */
+ public static void displayFindPreamble() {
+ if (Task.getNumOfTasks() != 0){
+ System.out.println("Here are the matching tasks in your list:");
+ }
+ else {
+ System.out.println("There are no matching task in your list:");
+ }
+ }
+
+ /**
+ * Prints the updated number of tasks in list
+ */
+ public static void displayListUpdate() {
+ if (Task.getNumOfTasks() == 0){
+ System.out.println("There are no tasks in your list");
+ }
+ else {
+ System.out.println("Now you have " + Task.getNumOfTasks() + " tasks in the list.");
+ }
+ }
+
+ /**
+ * Error message for invalid commands
+ */
+ public static void InvalidCommandErrorMessage(){
+ System.out.println(" ☹ OOPS!!! Invalid Command :-(");
+ }
+
+ /**
+ * Error message for too little input parameters
+ */
+ public static void InvalidParameterLengthErrorMessage(String line){
+ System.out.println(" ☹ OOPS!!! Insufficient number of inputs for command: " + getCommand(line));
+ System.out.println(" Example inputs:");
+ switch (getCommand(line)){
+
+ case ("deadline"):
+ System.out.println(" \t " + DEADLINE_TEMPLATE);
+ break;
+ case ("event"):
+ System.out.println(" \t " + EVENT_TEMPLATE);
+ break;
+ case ("todo"):
+ System.out.println(" \t " + TODO_TEMPLATE);
+ break;
+ }
+ }
+
+ /**
+ * Error message for invalid date format
+ */
+ public static void InvalidDateErrorMessage(String line){
+ String[] arr = line.split(" ");
+ System.out.println(" ☹ OOPS!!! Invalid format for date: " + arr[arr.length-1]);
+ System.out.println(" Input format:");
+ System.out.println(" \t " + DATE_TEMPLATE);
+ }
+
+ /**
+ * Error message when the /at indicator is not present when event command is used
+ */
+ public static void EventParameterErrorMessage(){
+ System.out.println(" ☹ OOPS!!! For \"event\" command please input \"/at\"");
+ }
+
+ /**
+ * Error message when the /by indicator is not present when deadline command is used
+ */
+ public static void DeadlineParameterErrorMessage(){
+ System.out.println(" ☹ OOPS!!! For \"deadline\" command please input \"/by\"");
+ }
+
+ /**
+ * Error message when the the integer parameter is out of range
+ */
+ public static void InvalidIndexErrorMessage(){
+ System.out.println(" ☹ OOPS!!! Index is out of range");
+ }
+
+
+ /**
+ * Returns a String in the formatted version of the date input
+ *
+ * @param date date in the YYYY-MM-DD format
+ * @return String in the MMM-DD-YYYY date format
+ */
+ public static String convertDateToStringFormat(String date){
+ LocalDate myDateObj = LocalDate.parse(date);
+ DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("MMM-dd-yyyy ");
+ return myDateObj.format(myFormatObj);
+ }
+
+ /**
+ * Returns a LocalDate object based on the String input
+ *
+ * @param input date in the MMM-DD-YYYY format
+ * @return LocalDate object
+ */
+ public static LocalDate convertStringFormatToDate(String input){
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM-d-yyyy ");
+ return LocalDate.parse(input, formatter);
+ }
+
+}
diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat
index 087374464..2de2c0f7d 100644
--- a/text-ui-test/runtest.bat
+++ b/text-ui-test/runtest.bat
@@ -15,7 +15,7 @@ IF ERRORLEVEL 1 (
REM no error here, errorlevel == 0
REM run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT
-java -classpath ..\bin Duke < input.txt > ACTUAL.TXT
+java -classpath ..\bin duke.main.Duke < input.txt > ACTUAL.TXT
REM compare the output to the expected output
FC ACTUAL.TXT EXPECTED.TXT