diff --git a/README.md b/README.md
index 8715d4d91..900d89b81 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,94 @@
-# Duke project template
+# Duke - User Guide
-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.
+Duke is a personal task manager designed to help you stay organized and on top of your to-do list. With its automated features, Duke streamlines task management and can significantly improve your productivity.
-## Setting up in Intellij
+## Features
-Prerequisites: JDK 11, update Intellij to the most recent version.
+### 3 Types of Tasks
+- `todo` - Adds a simple todo task
+- `deadline` - Adds a deadline task with a due date
+- `event` - Adds an event task with a start time and an end time
-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
- ____ _
- | _ \ _ _| | _____
- | | | | | | | |/ / _ \
- | |_| | |_| | < __/
- |____/ \__,_|_|\_\___|
+### Other Functions
+- `mark` - Mark task as done
+- `unmark` - Mark task as not done
+- `list` - List all tasks
+- `find` - Find task(s) containing certain substring
+- `delete` - Delete a task
+- `bye` - Exit program
+
+## Usage
+
+### todo {Task} - Add a Todo Task
+Example: `todo study`
+Expected outcome:
+ ```
+ Got it. I've added this task:
+ [T][ ] study
+ ```
+
+### deadline {Task} /by {Date/Time} - Add a Deadline Task
+Example: `deadline return book /by Sun`
+Expected outcome:
+ ```
+ Got it. I've added this task:
+ [D][ ] return book (by Sun)
+ ```
+
+### event {Task} /from {Date/Time} /to {Date/Time} - Add a Event Task
+Example: `event party /from Fri 6pm /to 8pm`
+Expected outcome:
+ ```
+ Got it. I've added this task:
+ [E][ ] party (from Fri 6pm to 8pm)
+ ```
+
+### mark {Task Index} - Mark Task as Done
+Example: `mark 1`
+Expected outcome:
+ ```
+ Nice! I've marked this task as done:
+ [T][X] study
+ ```
+
+### unmark {Task Index} - Mark Task as Not Done
+Example: `unmark 2`
+Expected outcome:
+ ```
+ OK, I've marked this task as not done yet:
+ [D][ ] return book (by Sun)
+ ```
+
+### list - List All Tasks
+Example: `list`
+Expected outcome:
+ ```
+ 1. [T][ ] study
+ 2. [D][ ] return book (by Sun)
+ 3. [E][ ] party (from Fri 6pm to 8pm)
+ ```
+
+### find {Keyword} - Find Task(s) Containing Certain Keyword
+Example: `find book`
+Expected outcome:
+ ```
+ Here are the matching tasks in your list:
+ 1. [T][ ] read book
+ 2. [D][ ] return book (by Sun)
+ ```
+
+### delete {Task Index} - Delete Task
+Example: `delete 4`
+Expected outcome:
+ ```
+ Noted. I've removed this task:
+ [T][ ] read book
+ ```
+
+### bye - Leave Program
+Example: `bye`
+Expected outcome:
+ ```
+ Bye. Hope to see you again soon.
```
+
diff --git a/docs/README.md b/docs/README.md
index 8077118eb..900d89b81 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,29 +1,94 @@
-# User Guide
+# Duke - User Guide
-## Features
+Duke is a personal task manager designed to help you stay organized and on top of your to-do list. With its automated features, Duke streamlines task management and can significantly improve your productivity.
-### Feature-ABC
+## Features
-Description of the feature.
+### 3 Types of Tasks
+- `todo` - Adds a simple todo task
+- `deadline` - Adds a deadline task with a due date
+- `event` - Adds an event task with a start time and an end time
-### Feature-XYZ
-
-Description of the feature.
+### Other Functions
+- `mark` - Mark task as done
+- `unmark` - Mark task as not done
+- `list` - List all tasks
+- `find` - Find task(s) containing certain substring
+- `delete` - Delete a task
+- `bye` - Exit program
## Usage
-### `Keyword` - Describe action
-
-Describe the action and its outcome.
-
-Example of usage:
-
-`keyword (optional arguments)`
-
+### todo {Task} - Add a Todo Task
+Example: `todo study`
Expected outcome:
+ ```
+ Got it. I've added this task:
+ [T][ ] study
+ ```
+
+### deadline {Task} /by {Date/Time} - Add a Deadline Task
+Example: `deadline return book /by Sun`
+Expected outcome:
+ ```
+ Got it. I've added this task:
+ [D][ ] return book (by Sun)
+ ```
-Description of the outcome.
-
-```
-expected output
-```
+### event {Task} /from {Date/Time} /to {Date/Time} - Add a Event Task
+Example: `event party /from Fri 6pm /to 8pm`
+Expected outcome:
+ ```
+ Got it. I've added this task:
+ [E][ ] party (from Fri 6pm to 8pm)
+ ```
+
+### mark {Task Index} - Mark Task as Done
+Example: `mark 1`
+Expected outcome:
+ ```
+ Nice! I've marked this task as done:
+ [T][X] study
+ ```
+
+### unmark {Task Index} - Mark Task as Not Done
+Example: `unmark 2`
+Expected outcome:
+ ```
+ OK, I've marked this task as not done yet:
+ [D][ ] return book (by Sun)
+ ```
+
+### list - List All Tasks
+Example: `list`
+Expected outcome:
+ ```
+ 1. [T][ ] study
+ 2. [D][ ] return book (by Sun)
+ 3. [E][ ] party (from Fri 6pm to 8pm)
+ ```
+
+### find {Keyword} - Find Task(s) Containing Certain Keyword
+Example: `find book`
+Expected outcome:
+ ```
+ Here are the matching tasks in your list:
+ 1. [T][ ] read book
+ 2. [D][ ] return book (by Sun)
+ ```
+
+### delete {Task Index} - Delete Task
+Example: `delete 4`
+Expected outcome:
+ ```
+ Noted. I've removed this task:
+ [T][ ] read book
+ ```
+
+### bye - Leave Program
+Example: `bye`
+Expected outcome:
+ ```
+ Bye. Hope to see you again soon.
+ ```
+
diff --git a/src/main/java/Duke.class b/src/main/java/Duke.class
new file mode 100644
index 000000000..2b142ac5e
Binary files /dev/null and b/src/main/java/Duke.class differ
diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java
index 5d313334c..1b300df32 100644
--- a/src/main/java/Duke.java
+++ b/src/main/java/Duke.java
@@ -1,10 +1,124 @@
+import java.io.IOException;
+import java.util.Scanner;
+
+import Exception.DukeException;
+import Parser.Parser;
+import Storage.DukeStorage;
+import Task.Deadline;
+import Task.Event;
+import Task.Task;
+import Task.TaskList;
+import Task.Todo;
+import UI.Ui;
+
public class Duke {
- public static void main(String[] args) {
- String logo = " ____ _ \n"
- + "| _ \\ _ _| | _____ \n"
- + "| | | | | | | |/ / _ \\\n"
- + "| |_| | |_| | < __/\n"
- + "|____/ \\__,_|_|\\_\\___|\n";
- System.out.println("Hello from\n" + logo);
+ /**
+ * Constructor to initiate the program
+ *
+ * @param filePath the path to the file
+ * @throws DukeException
+ * @throws IOException
+ *
+ */
+ public Duke(String filePath) throws DukeException, IOException {
+ Ui.greet();
+ DukeStorage storage = new DukeStorage(filePath);
+ Task.numberOfTasks = 0;
+ TaskList taskList = new TaskList(storage);
+ try (Scanner scan = new Scanner(System.in)) {
+ String input = scan.nextLine();
+ while (!input.equals("bye")) {
+ try {
+ if (input.equals("list")) {
+ Ui.printList(taskList.getTasks());
+
+ } else if (input.startsWith("mark")) {
+ String[] marks = Parser.processInput(input);
+ int index = Parser.checkActionInputValidity(marks);
+ if (index == -1) {
+ throw new Exception();
+ }
+ taskList.getTasks().get(index).markAsDone();
+ Ui.markMessage(taskList.getTasks(), index);
+ } else if (input.startsWith("unmark")) {
+ String[] marks = Parser.processInput(input);
+ int index = Parser.checkActionInputValidity(marks);
+ if (index == -1) {
+ throw new Exception();
+ }
+ taskList.getTasks().get(index).markAsNotDone();
+ Ui.unmarkMessage(taskList.getTasks(), index);
+ } else if (input.startsWith("find")) {
+ String findString = Parser.processFindString(input);
+ if (findString == "") {
+ throw new Exception();
+ }
+ Ui.findTask(taskList.getTasks(), findString);
+ } else if (input.startsWith("todo", 0)) {
+ String toDoDesc = Parser.processTodoString(input);
+ if (toDoDesc == "") {
+ throw new Exception();
+ }
+ Task toDo = new Todo(toDoDesc);
+ taskList.addTask(toDo);
+ Ui.printConfirmation(toDo, "TODO");
+ } else if (input.startsWith("deadline", 0)) {
+ String[] deadlineArray = Parser.processDeadlineString(input);
+ if (deadlineArray.length == 0) {
+ throw new Exception();
+ }
+ String deadlineDesc = deadlineArray[0];
+ String deadlineDay = deadlineArray[1];
+ Task deadline = new Deadline(deadlineDesc, deadlineDay);
+ taskList.addTask(deadline);
+ Ui.printConfirmation(deadline, "DEADLINE");
+ } else if (input.startsWith("event", 0)) {
+ String[] eventArray = Parser.processEventString(input);
+ if (eventArray.length == 0) {
+ throw new Exception();
+ }
+ String eventDesc = eventArray[0];
+ String start = eventArray[1];
+ String end = eventArray[2];
+ Task event = new Event(eventDesc, start, end);
+ taskList.addTask(event);
+ Ui.printConfirmation(event, "EVENT");
+ } else if (input.startsWith("delete")) {
+ String[] deleteStrings = Parser.processInput(input);
+ int toDelete = Parser.checkActionInputValidity(deleteStrings);
+ if (toDelete == -1) {
+ throw new Exception();
+ }
+ Task deleteTask = taskList.getTasks().get(toDelete);
+ taskList.removeTask(deleteTask);
+ Task.decrementNumberOfTasks();
+ Ui.printConfirmation(deleteTask, "DELETE");
+ } else {
+ Ui.printConfirmation(null, "UNRECOGNIZED");
+ ;
+ }
+ } catch (Exception e) {
+ Ui.printIncompleteMessage();
+ }
+
+ input = scan.nextLine();
+ }
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ Ui.bye();
+ storage.saveTaskList(taskList.getTasks());
}
+
+ /**
+ * main function
+ *
+ * @throws DukeException
+ * @throws IOException
+ *
+ */
+ public static void main(String[] args) throws DukeException, IOException {
+ new Duke("data/duke.txt");
+ }
+
}
diff --git a/src/main/java/Exception/DukeException.java b/src/main/java/Exception/DukeException.java
new file mode 100644
index 000000000..790f25ba2
--- /dev/null
+++ b/src/main/java/Exception/DukeException.java
@@ -0,0 +1,12 @@
+package Exception;
+
+public class DukeException extends Exception {
+ /**
+ * This method throws an exception.
+ *
+ * @param message the exception message
+ */
+ public DukeException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/Parser/Parser.java b/src/main/java/Parser/Parser.java
new file mode 100644
index 000000000..262709b92
--- /dev/null
+++ b/src/main/java/Parser/Parser.java
@@ -0,0 +1,141 @@
+package Parser;
+
+import Task.Task;
+
+public class Parser {
+ // Error String
+ public static final String ERROR_MESSAGE = "Invalid input.";
+
+ /**
+ * This method splits the input with spaces.
+ * Maximum length is two.
+ *
+ * @param input the input string
+ * @return the splitted string in a string array
+ */
+ public static String[] processInput(String input) {
+ String[] inputs = input.split(" ", 2);
+ return inputs;
+ }
+
+ /**
+ * This method checks the validity of input.
+ *
+ * @param input the input string array
+ * @return the index of the tasks desired, else -1 if invalid
+ */
+ public static int checkActionInputValidity(String[] input) {
+ try {
+ if (input.length == 1) {
+ System.out.println(ERROR_MESSAGE);
+ return -1;
+ }
+ int taskIndex = Integer.parseInt(input[1]);
+ if (taskIndex > Task.numberOfTasks || taskIndex < 1) {
+ throw new IndexOutOfBoundsException(ERROR_MESSAGE);
+ }
+ return taskIndex - 1;
+ } catch (NumberFormatException nonIntegerIndex) {
+ System.out.println(ERROR_MESSAGE);
+ return -1;
+ } catch (IndexOutOfBoundsException outOfBoundsIndex) {
+ System.out.println(ERROR_MESSAGE);
+ return -1;
+ }
+ }
+
+ /**
+ * This method checks the validity of find input.
+ *
+ * @param input the input string
+ * @return the keyword, else an empty string if invalid
+ */
+ public static String processFindString(String input) {
+ try {
+ String findString = input.split("find")[1].trim();
+ if (findString.equals("")) {
+ System.out.println(ERROR_MESSAGE);
+ return findString;
+ }
+ return findString;
+ } catch (IndexOutOfBoundsException e) {
+ System.out.println(ERROR_MESSAGE);
+ return "";
+ }
+ }
+
+ /**
+ * This method checks the validity of todo input.
+ *
+ * @param input the input string
+ * @return the todo task, else an empty string if invalid
+ */
+ public static String processTodoString(String input) {
+ try {
+ String task = input.split("todo")[1].trim();
+ if (task.equals("")) {
+ System.out.println(ERROR_MESSAGE);
+ return task;
+ }
+ return task;
+ } catch (IndexOutOfBoundsException e) {
+ System.out.println(ERROR_MESSAGE);
+ return "";
+ }
+ }
+
+ /**
+ * This method checks the validity of deadline input.
+ *
+ * @param input the input string
+ * @return the deadline info in string array, else an empty string if invalid
+ */
+ public static String[] processDeadlineString(String input) {
+ try {
+ String deadlineDesc = input.split("/")[0].split("deadline")[1].trim();
+ String deadlineDay = input.split("/")[1].trim();
+
+ String[] deadlineArray = { deadlineDesc, deadlineDay };
+
+ for (int i = 0; i < 2; i++) {
+ deadlineArray[i] = deadlineArray[i].trim();
+ if (deadlineArray[i].equals("")) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+ return deadlineArray;
+ } catch (IndexOutOfBoundsException outOfBoundsException) {
+ System.out.println(ERROR_MESSAGE);
+ return new String[0];
+ }
+ }
+
+ /**
+ * This method checks the validity of event input.
+ *
+ * @param input the input string
+ * @return the event info in string array, else an empty string if invalid
+ */
+ public static String[] processEventString(String input) {
+ try {
+ String eventDesc = input.split("/")[0].split("event")[1].trim();
+ String start = input.split("/")[1].trim();
+ String end = input.split("/")[2].trim();
+
+ String[] eventArray = { eventDesc, start, end };
+
+ for (int i = 0; i < 3; i++) {
+ eventArray[i] = eventArray[i].trim();
+ if (eventArray[i].equals("")) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+ return eventArray;
+ } catch (IndexOutOfBoundsException outOfBoundsException) {
+ System.out.println(ERROR_MESSAGE);
+ return new String[0];
+ }
+
+ }
+
+}
diff --git a/src/main/java/Storage/DukeStorage.java b/src/main/java/Storage/DukeStorage.java
new file mode 100644
index 000000000..aa6d46d16
--- /dev/null
+++ b/src/main/java/Storage/DukeStorage.java
@@ -0,0 +1,85 @@
+package Storage;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Scanner;
+
+import Task.Task;
+import Task.Deadline;
+import Task.Todo;
+import Task.Event;
+
+public class DukeStorage {
+ // filePath of the file
+ private static String filePath;
+
+ /**
+ * Constructor
+ *
+ * @param filePath the path to the file
+ */
+ public DukeStorage(String filePath) {
+ DukeStorage.filePath = filePath;
+ }
+
+ /**
+ * This method save the task list.
+ *
+ * @param tasks the task list
+ *
+ */
+ public void saveTaskList(ArrayList tasks) {
+ try {
+ File file = new File(filePath);
+ if (!file.exists()) {
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ }
+ FileWriter writer = new FileWriter(file);
+ for (Task task : tasks) {
+ writer.write(task.toFileString() + "\n");
+ }
+ writer.close();
+ } catch (IOException e) {
+ System.out.println("Error saving file: " + e.getMessage());
+ }
+ }
+
+ /**
+ * This method loads the task list.
+ *
+ * @return the task list
+ * @throws IOException
+ */
+ public static ArrayList loadTaskList() throws IOException {
+ ArrayList tasks = new ArrayList<>();
+ try {
+ File file = new File(filePath);
+ if (!file.exists()) {
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ }
+ Scanner scanner = new Scanner(file);
+ while (scanner.hasNext()) {
+ String line = scanner.nextLine();
+ if (line.startsWith("T")) {
+ Task task = Todo.fromFileString(line);
+ tasks.add(task);
+ } else if (line.startsWith("D")) {
+ Task task = Deadline.fromFileString(line);
+ tasks.add(task);
+ } else if (line.startsWith("E")) {
+ Task task = Event.fromFileString(line);
+ tasks.add(task);
+ }
+ }
+ scanner.close();
+ } catch (FileNotFoundException e) {
+ System.out.println("Error loading file: " + e.getMessage());
+ }
+ return tasks;
+ }
+}
diff --git a/src/main/java/Task/Deadline.java b/src/main/java/Task/Deadline.java
new file mode 100644
index 000000000..a003f08ee
--- /dev/null
+++ b/src/main/java/Task/Deadline.java
@@ -0,0 +1,70 @@
+package Task;
+
+public class Deadline extends Task {
+ // deadline day
+ protected String deadlineDay;
+
+ /**
+ * Constructor
+ *
+ * @param description deadline description
+ * @param deadlineDay deadline day
+ *
+ */
+ public Deadline(String description, String deadlineDay) {
+ super(description);
+ this.deadlineDay = deadlineDay;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param description deadline description
+ * @param deadlineDay deadline day
+ * @param isDone whether the task is done or not
+ *
+ */
+ public Deadline(String description, String deadlineDay, boolean isDone) {
+ super(description, isDone);
+ this.deadlineDay = deadlineDay;
+ }
+
+ /**
+ * toString method
+ *
+ * @return string description
+ *
+ */
+ @Override
+ public String toString() {
+ return "[D]" + super.toString() + " (" + this.deadlineDay + ")";
+ }
+
+ /**
+ * toString method when saving in file
+ *
+ * @return string description to be saved in file
+ *
+ */
+ @Override
+ public String toFileString() {
+ return "D | " + (isDone ? 1 : 0) + " | " + description + " | "
+ + deadlineDay;
+ }
+
+ /**
+ * toString method
+ *
+ * @param line input string from file
+ * @return deadline item
+ *
+ */
+ public static Deadline fromFileString(String line) {
+ String[] parts = line.split(" \\| ");
+ boolean isDone = Integer.parseInt(parts[1]) == 1;
+ String description = parts[2];
+ String deadlineDay = parts[3];
+ return new Deadline(description, deadlineDay, isDone);
+ }
+
+}
diff --git a/src/main/java/Task/Event.java b/src/main/java/Task/Event.java
new file mode 100644
index 000000000..4d2d2f3d2
--- /dev/null
+++ b/src/main/java/Task/Event.java
@@ -0,0 +1,75 @@
+package Task;
+
+public class Event extends Task {
+ // Attributes of Event instances
+ protected String start;
+ protected String end;
+
+ /**
+ * Constructor
+ *
+ * @param description event description
+ * @param start start of event
+ * @param end end of event
+ *
+ */
+ public Event(String description, String start, String end) {
+ super(description);
+ this.start = start;
+ this.end = end;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param description event description
+ * @param start start of event
+ * @param end end of event
+ * @param isDone whether event is done or not
+ *
+ */
+ public Event(String description, String start, String end, boolean isDone) {
+ super(description, isDone);
+ this.start = start;
+ this.end = end;
+ }
+
+ /**
+ * toString method
+ *
+ * @return string description
+ *
+ */
+ @Override
+ public String toString() {
+ return "[E]" + super.toString() + " (" + start + " " + end + ")";
+ }
+
+ /**
+ * toString method when saving in file
+ *
+ * @return string description to be saved in file
+ *
+ */
+ @Override
+ public String toFileString() {
+ return "E | " + (isDone ? 1 : 0) + " | " + description + " | "
+ + start + " | " + end;
+ }
+
+ /**
+ * toString method
+ *
+ * @param line input string from file
+ * @return deadline item
+ *
+ */
+ public static Event fromFileString(String line) {
+ String[] parts = line.split(" \\| ");
+ boolean isDone = Integer.parseInt(parts[1]) == 1;
+ String description = parts[2];
+ String start = parts[3];
+ String end = parts[4];
+ return new Event(description, start, end, isDone);
+ }
+}
diff --git a/src/main/java/Task/Task.java b/src/main/java/Task/Task.java
new file mode 100644
index 000000000..c1b97c98e
--- /dev/null
+++ b/src/main/java/Task/Task.java
@@ -0,0 +1,100 @@
+package Task;
+
+public class Task {
+ // attributes
+ protected String description;
+ protected boolean isDone;
+ public static int numberOfTasks = 0;
+
+ /**
+ * Constuctor
+ *
+ * @param description task description
+ *
+ */
+ public Task(String description) {
+ this.description = description;
+ this.isDone = false;
+ addNumberOfTasks();
+ }
+
+ /**
+ * Constuctor
+ *
+ * @param description task description
+ * @param isDone whether the task is done or not
+ *
+ */
+ public Task(String description, boolean isDone) {
+ this.description = description;
+ this.isDone = isDone;
+ addNumberOfTasks();
+ }
+
+ /**
+ * increment the number of tasks
+ */
+ public static void addNumberOfTasks() {
+ numberOfTasks++;
+ }
+
+ /**
+ * decrement the number of tasks
+ */
+ public static void decrementNumberOfTasks() {
+ numberOfTasks--;
+ }
+
+ /**
+ * getter for description
+ *
+ * @return description string
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * getter for status icon
+ *
+ * @return status icon
+ */
+ public String getStatusIcon() {
+ return (isDone ? "X" : " ");
+ }
+
+ /**
+ * mark task as done
+ */
+ public void markAsDone() {
+ isDone = true;
+ }
+
+ /**
+ * mark task as not done
+ */
+ public void markAsNotDone() {
+ isDone = false;
+ }
+
+ /**
+ * toString method
+ *
+ * @return string description
+ *
+ */
+ public String toString() {
+ return "[" + this.getStatusIcon() + "]" + "\t" + this.getDescription();
+ }
+
+ /**
+ * toString method when saving in file
+ *
+ * @return string description to be saved in file
+ *
+ */
+ public String toFileString() {
+ return "Task";
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/Task/TaskList.java b/src/main/java/Task/TaskList.java
new file mode 100644
index 000000000..e660dd74c
--- /dev/null
+++ b/src/main/java/Task/TaskList.java
@@ -0,0 +1,91 @@
+package Task;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import Storage.DukeStorage;
+
+public class TaskList {
+ // array list of tasks
+ private ArrayList tasks;
+
+ /**
+ * Constructor
+ *
+ * @param storage the storage file
+ * @throws IOException
+ *
+ */
+ public TaskList(DukeStorage storage) throws IOException {
+ tasks = storage.loadTaskList();
+ }
+
+ /**
+ * add task to the list
+ *
+ * @param task task to be added
+ *
+ */
+ public void addTask(Task task) {
+ tasks.add(task);
+ }
+
+ /**
+ * remove task from the list
+ *
+ * @param task task to be removed
+ *
+ */
+ public void removeTask(Task task) {
+ tasks.remove(task);
+ }
+
+ /**
+ * get the list of tasks
+ *
+ * @return the list of tasks
+ *
+ */
+ public ArrayList getTasks() {
+ return tasks;
+ }
+
+ /**
+ * print the list of tasks
+ *
+ * @param tasks the list of tasks
+ * @return the list of tasks in string format
+ */
+ public static String printTasksList(ArrayList tasks) {
+ String tasksList = new String();
+ int count = 1;
+ for (Task i : tasks) {
+ tasksList += count + ". " + i.toString();
+ if (count < Task.numberOfTasks) {
+ tasksList += System.lineSeparator();
+ }
+ count++;
+ }
+ return tasksList;
+ }
+
+ /**
+ * find all tasks containing a given string
+ *
+ * @param tasks the list of tasks
+ * @param input the string to search
+ * @return the list of tasks containing the given string
+ *
+ */
+ public static String findList(ArrayList tasks, String input) {
+ String findList = new String();
+ int count = 1;
+ for (Task i : tasks) {
+ if (i.toString().contains(input)) {
+ findList += count + ". " + i.toString();
+ findList += System.lineSeparator();
+ count++;
+ }
+ }
+ return findList;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/Task/Todo.java b/src/main/java/Task/Todo.java
new file mode 100644
index 000000000..268a35046
--- /dev/null
+++ b/src/main/java/Task/Todo.java
@@ -0,0 +1,60 @@
+package Task;
+
+public class Todo extends Task{
+ /**
+ * constructor
+ *
+ * @param description description of the task
+ *
+ */
+ public Todo (String description){
+ super(description);
+ }
+
+ /**
+ * constructor
+ *
+ * @param description description of the task\
+ * @param isDone true if the task is done, false otherwise
+ *
+ */
+ public Todo (String description, boolean isDone){
+ super(description, isDone);
+ }
+
+ /**
+ * toString method
+ *
+ * @return string description
+ *
+ */
+ @Override
+ public String toString(){
+ return "[T]"+super.toString();
+ }
+
+ /**
+ * toString method when saving in file
+ *
+ * @return string description to be saved in file
+ *
+ */
+ @Override
+ public String toFileString() {
+ return "T | " + (isDone ? 1 : 0) + " | " + description;
+ }
+
+ /**
+ * toString method
+ *
+ * @param line input string from file
+ * @return deadline item
+ *
+ */
+ public static Todo fromFileString(String line) {
+ String[] parts = line.split(" \\| ");
+ boolean isDone = Integer.parseInt(parts[1]) == 1;
+ String description = parts[2];
+ return new Todo(description, isDone);
+ }
+}
diff --git a/src/main/java/UI/Ui.java b/src/main/java/UI/Ui.java
new file mode 100644
index 000000000..ead99dc7a
--- /dev/null
+++ b/src/main/java/UI/Ui.java
@@ -0,0 +1,148 @@
+package UI;
+
+import java.util.ArrayList;
+
+import Task.Task;
+import Task.TaskList;
+
+public class Ui {
+ // Message strings
+ final static String LINEBREAK = "______________________________________________________";
+ final static String LOGO = " ____ _ \n"
+ + "| _ \\ _ _| | _____ \n"
+ + "| | | | | | | |/ / _ \\\n"
+ + "| |_| | |_| | < __/\n"
+ + "|____/ \\__,_|_|\\_\\___|";
+ final static String WELCOME_MESSAGE = "Hello! I'm Duke\nWhat can I do for you?";
+ final static String EXIT_MESSAGE = "Bye. Hope to see you again soon.";
+ final static String UNRECOGNIZED_ACTION = "OOPS!!! I'm sorry, but I don't know what that means :-(";
+ final static String INCOMPLETE_ACTION = "Please provide the necessary information for the task.";
+
+ final static String LIST = "list";
+ final static String MARK = "mark";
+ final static String UNMARK = "unmark";
+ final static String TODO = "todo";
+ final static String DEADLINE = "deadline";
+ final static String EVENT = "event";
+ final static String DELETE = "delete";
+
+ final static String LIST_MESSAGE = "Here are the tasks in the list:";
+ final static String FIND_MESSAGE = "Here are the matching tasks in your list:";
+ final static String MARK_MESSAGE = "Nice! I've marked this task as done:";
+ final static String UNMARK_MESSAGE = "OK, I've marked this task as not done yet:";
+ final static String ADD_TASK_MESSAGE = "Got it. I've added this task:";
+ final static String DELETE_TASK_MESSAGE = "Noted. I've removed this task:";
+
+ /**
+ * print welcome message
+ *
+ */
+ public final static void greet() {
+ System.out.println(LOGO + "\n" + WELCOME_MESSAGE);
+ }
+
+ /**
+ * print bye message
+ *
+ */
+ public final static void bye() {
+ System.out.println(LINEBREAK + "\n" + EXIT_MESSAGE + "\n" + LINEBREAK);
+ }
+
+ /**
+ * print the list of tasks
+ *
+ * @param tasks list of tasks
+ *
+ */
+ public static void printList(ArrayList tasks) {
+ String output = LIST_MESSAGE + System.lineSeparator()
+ + TaskList.printTasksList(tasks);
+ System.out.println(LINEBREAK);
+ System.out.println(output);
+ System.out.println(LINEBREAK);
+ }
+
+ /**
+ * print the list of tasks containing the given string
+ *
+ * @param tasks list of tasks
+ * @param input the string to check
+ *
+ */
+ public static void findTask(ArrayList tasks, String input) {
+ String output = FIND_MESSAGE + System.lineSeparator()
+ + TaskList.findList(tasks, input);
+ System.out.println(LINEBREAK);
+ System.out.println(output);
+ System.out.println(LINEBREAK);
+ }
+
+ /**
+ * mark task message
+ *
+ * @param tasks the list of tasks
+ * @param index the index of the task
+ *
+ */
+ public static void markMessage(ArrayList tasks, int index) {
+ System.out.println(LINEBREAK);
+ System.out.println(MARK_MESSAGE);
+ System.out.println(tasks.get(index).toString());
+ System.out.println(LINEBREAK);
+ }
+
+ /**
+ * unmark task message
+ *
+ * @param tasks the list of tasks
+ * @param index the index of the task
+ *
+ */
+ public static void unmarkMessage(ArrayList tasks, int index) {
+ System.out.println(LINEBREAK);
+ System.out.println(UNMARK_MESSAGE);
+ System.out.println(tasks.get(index).toString());
+ System.out.println(LINEBREAK);
+ }
+
+ /**
+ * print confirmation message
+ *
+ * @param newTask the relevant task
+ * @param action the action to perform on the task
+ *
+ */
+ public static void printConfirmation(Task newTask, String action) {
+ System.out.println(LINEBREAK);
+ switch (action) {
+ case "TODO":
+ case "DEADLINE":
+ case "EVENT":
+ System.out.println(ADD_TASK_MESSAGE);
+ System.out.println(newTask.toString());
+ break;
+
+ case "DELETE":
+ System.out.println(DELETE_TASK_MESSAGE);
+ System.out.println(newTask.toString());
+ break;
+
+ default:
+ System.out.println(UNRECOGNIZED_ACTION);
+ }
+ System.out.println("Now you have " + Task.numberOfTasks + " tasks in the list");
+ System.out.println(LINEBREAK);
+
+ }
+
+ /**
+ * print incomplete input message
+ *
+ */
+ public static void printIncompleteMessage() {
+ System.out.println(INCOMPLETE_ACTION);
+ System.out.println(LINEBREAK);
+ }
+
+}