diff --git a/README.md b/README.md
index 8715d4d91..0f2208ab6 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Duke project template
+# duke.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.
@@ -13,7 +13,7 @@ Prerequisites: JDK 11, update Intellij to the most recent version.
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:
+3. After that, locate the `src/main/java/duke.Duke.java` file, right-click it, and choose `Run duke.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
____ _
diff --git a/data/duke.txt b/data/duke.txt
new file mode 100644
index 000000000..ffc4d38d1
--- /dev/null
+++ b/data/duke.txt
@@ -0,0 +1,2 @@
+ 1. [D][ ] tP Meeting (by: Friday 16.00pm)
+ 2. [E][ ] CS2113 tP Meeting (from: Friday 16.00pm to: 18.00pm)
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
index 8077118eb..40283667d 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,29 +1,143 @@
# User Guide
-## Features
+Duke is a Command-Line Interface (CLI) task manager. It allows you to keep track of your tasks quickly and navigate
+through those tasks quickly.
-### Feature-ABC
+## Features
-Description of the feature.
+- Adding different types of tasks:
+ - Todo: the most basic type of task
+ - Deadline: type of task which you can assign the due date of it
+ - Event: type of task which has a start and end date
+- Searching based on keyword and listing all tasks are also supported
-### Feature-XYZ
+## Getting started
-Description of the feature.
+> Java 11 is recommended to run `Duke`
-## Usage
+1. Download the latest ip.jar from [here](https://github.com/kristianachwan/ip/releases)
+2. Go to the directory where you downloaded
+3. Run `java -jar ip.jar`
-### `Keyword` - Describe action
+## Add ToDo
-Describe the action and its outcome.
+Adds todo to your list. Format: `todo `
-Example of usage:
+### Adding `ToDo` example:
-`keyword (optional arguments)`
+```
+todo CS2113 tP Meeting
+ ____________________________________________________________
+ Got it. I've added this task:
+ [T][ ] CS2113 tP Meeting
+ ____________________________________________________________
+```
+
+## Add Deadline
+
+Adds deadline to your list. Format: `deadline /`
+
+### Adding `Deadline` example:
+
+```
+deadline tP Meeting /Friday 16.00pm
+ ____________________________________________________________
+ Got it. I've added this task:
+ [D][ ] tP Meeting (by: Friday 16.00pm)
+ ____________________________________________________________
+```
+
+## Add Deadline
+
+Adds event to your list. Format: `event / / `
+
+### Adding `Event` example:
+
+```
+event CS2113 tP Meeting /Friday 16.00pm /18.00pm
+ ____________________________________________________________
+ Got it. I've added this task:
+ [E][ ] CS2113 tP Meeting (from: Friday 16.00pm to: 18.00pm)
+ ____________________________________________________________
+
+```
+
+### Listing all tasks
+
+List all of your tasks. Format: `list`
+
+### Listing all tasks example:
+
+```
+list
+ ____________________________________________________________
+ 1. [T][ ] CS2113 tP Meeting
+ 2. [D][ ] tP Meeting (by: Friday 16.00pm)
+ 3. [E][ ] CS2113 tP Meeting (from: Friday 16.00pm to: 18.00pm)
+ ____________________________________________________________
+```
-Expected outcome:
+## Deleting a task:
-Description of the outcome.
+Delete your task by indicate the index of the task. Format: `delete `
+### Deleting a task example:
+
+```
+delete 1
+ ____________________________________________________________
+ Noted! I've removed this task
+ [T][ ] CS2113 tP Meeting
+ ____________________________________________________________
```
-expected output
+
+## Finding specific tasks
+
+Find your task based on specific keyword. Format: `find `
+
+### Finding specific tasks example
+
+```
+find tP
+ ____________________________________________________________
+ [D][ ] tP Meeting (by: Friday 16.00pm)
+ [E][ ] CS2113 tP Meeting (from: Friday 16.00pm to: 18.00pm)
+ ____________________________________________________________
+```
+
+## Marking task as done
+
+Mark your task as done. It will have `[X]` when it is listed again.
+Format: `mark `
+
+### Marking task as done example
+
+```
+mark 1
+ ____________________________________________________________
+ Nice! I've marked this task as done:
+ [D][X] tP Meeting (by: Friday 16.00pm)
+ ____________________________________________________________
+```
+
+### Marking task as undone
+
+Mark your task as undone (or unmark). It will revert back to `[]`.
+Format: `unmark `
+
+```
+unmark 1
+ ____________________________________________________________
+ Ok, I've marked this task as not done:
+ [D][ ] tP Meeting (by: Friday 16.00pm)
+ ____________________________________________________________
+```
+
+### Exiting the program
+
```
+bye
+ ____________________________________________________________
+ Bye. Hope to see you again soon!
+ ____________________________________________________________
+```
\ No newline at end of file
diff --git a/duke.txt b/duke.txt
new file mode 100644
index 000000000..bf558ed95
--- /dev/null
+++ b/duke.txt
@@ -0,0 +1,5 @@
+ 1. [T][ ] asd1
+ 2. [T][ ] asd23
+ 3. [T][ ] asd33
+ 4. [T][ ] a
+ 5. [D][ ] asd (by: 2pm)
\ 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..6e864153e
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: duke.Duke
+
diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java
new file mode 100644
index 000000000..b5984df6b
--- /dev/null
+++ b/src/main/java/duke/Duke.java
@@ -0,0 +1,32 @@
+package duke;
+
+import duke.boundary.Ui;
+import duke.controller.TaskList;
+import duke.model.Command;
+import duke.utils.Parser;
+import duke.utils.Storage;
+
+import java.util.Scanner;
+
+/**
+ * A class that serves as an entry point to the application
+ */
+public class Duke {
+ public static void main(String[] args) {
+ Storage dataAccess = new Storage("duke.txt");
+ Scanner scanner = new Scanner(System.in);
+ TaskList taskList = new TaskList();
+ Ui ui = new Ui(taskList);
+ ui.printDuke();
+ String input;
+ while (true) {
+ input = scanner.nextLine();
+ Command command = Parser.parse(input);
+ ui.readCommand(command);
+ dataAccess.writeToFile("\t" + taskList.toString());
+ }
+
+ }
+
+
+}
diff --git a/src/main/java/duke/boundary/Ui.java b/src/main/java/duke/boundary/Ui.java
new file mode 100644
index 000000000..f477c5a80
--- /dev/null
+++ b/src/main/java/duke/boundary/Ui.java
@@ -0,0 +1,207 @@
+package duke.boundary;
+
+import duke.controller.TaskList;
+import duke.exception.InvalidCommandException;
+import duke.model.*;
+
+import java.util.ArrayList;
+
+/**
+ * Class that is mainly responsible to display an information to the user
+ */
+public class Ui {
+ /**
+ * Prefix used when the task is added
+ */
+ static final String TASK_ADDED_PREFIX = "Got it. I've added this task:" + System.lineSeparator() + "\t";
+ /**
+ * Prefix used when the task is deleted
+ */
+ static final String TASK_DELETED_PREFIX = "Noted! I've removed this task" + System.lineSeparator() + "\t";
+ /**
+ * Prefix used when the task is marked
+ */
+ static final String TASK_MARKED_PREFIX = "Nice! I've marked this task as done:" + System.lineSeparator() + "\t";
+ /**
+ * Prefix used when the task is unmarked
+ */
+ static final String TASK_UNMARKED_PREFIX = "Ok, I've marked this task as not done:" + System.lineSeparator() + "\t";
+
+ /**
+ * TaskList attached to this Ui object
+ */
+ protected TaskList taskList;
+
+ /**
+ * Constructor that initiates an Ui object
+ *
+ * @param taskList the TaskList object attached to this Ui object
+ */
+ public Ui(TaskList taskList) {
+ setTaskList(taskList);
+ }
+
+ /**
+ * A method that classifies different cases of the command
+ *
+ * @param command The command object represents tokenized user command
+ */
+ public void readCommand(Command command) {
+ Payload payload = command.getPayload();
+ String[] payloadData = payload.getData();
+ Task task;
+ Event event;
+ Deadline deadline;
+ try {
+ switch (command.getType()) {
+ case "find":
+ this.printSearchedTasks(payloadData);
+ break;
+ case "list":
+ this.printTaskList();
+ break;
+ case "mark":
+ task = taskList.handleMarkTask(payloadData);
+ this.printMarkMessage(task);
+ break;
+ case "unmark":
+ task = taskList.handleUnmarkTask(payloadData);
+ this.printUnmarkMessage(task);
+ break;
+ case "task":
+ task = taskList.handleAddTask(payloadData);
+ this.printAddMessage(task);
+ break;
+ case "todo":
+ ToDo todo = taskList.handleAddTodo(payloadData);
+ this.printAddMessage(todo);
+ break;
+ case "deadline":
+ deadline = taskList.handleAddDeadline(payloadData);
+ this.printAddMessage(deadline);
+ break;
+ case "event":
+ event = taskList.handleAddEvent(payloadData);
+ this.printAddMessage(event);
+ break;
+ case "delete":
+ task = taskList.handleDeleteTask(payloadData);
+ this.printDeleteMessage(task);
+ break;
+ case "bye":
+ this.printMessage("Bye. Hope to see you again soon!");
+ System.exit(0);
+ default:
+ throw new InvalidCommandException();
+ }
+ } catch (InvalidCommandException e) {
+ this.printMessage(e.getMessage());
+ }
+ }
+
+ /**
+ * Method to print the searched tasks i.e. if the taskName contains the searched keyword
+ *
+ * @param payloadData The payload data the command object
+ */
+ public void printSearchedTasks(String[] payloadData) {
+ String keyword = payloadData[0];
+ ArrayList searchedTasks = taskList.getSearchedTasks(keyword);
+ this.printHorizontalLine();
+
+ for (int i = 0; i < searchedTasks.size(); i++) {
+ System.out.printf("\t" + "%3d." + searchedTasks.get(i).toString() + System.lineSeparator(), i + 1);
+ }
+ this.printHorizontalLine();
+
+ }
+
+ /**
+ * Method to print message after marking a task
+ *
+ * @param task Task object to be marked
+ */
+ public void printMarkMessage(Task task) {
+ this.printMessage(TASK_MARKED_PREFIX + task.toString());
+ }
+
+ /**
+ * Method to print message after unmarking a task
+ *
+ * @param task Task object to be unmarked
+ */
+ public void printUnmarkMessage(Task task) {
+ this.printMessage(TASK_UNMARKED_PREFIX + task.toString());
+ }
+
+ /**
+ * Method to print a message after adding a task
+ *
+ * @param task Task object to be added
+ */
+ public void printAddMessage(Task task) {
+ this.printMessage(TASK_ADDED_PREFIX + task.toString());
+ }
+
+ /**
+ * Method to print a message after deleting a task
+ *
+ * @param task Task object to be deleted
+ */
+ public void printDeleteMessage(Task task) {
+ this.printMessage(TASK_DELETED_PREFIX + task.toString());
+ }
+
+ /**
+ * Method to print a horizontla line
+ */
+ public void printHorizontalLine() {
+ System.out.println("\t____________________________________________________________");
+ }
+
+ /**
+ * Method to print a formatted message
+ *
+ * @param message The message to be formatted
+ */
+ public void printMessage(String message) {
+ this.printHorizontalLine();
+ System.out.println("\t" + message);
+ this.printHorizontalLine();
+ }
+
+ /**
+ * Method that set the taskList attached to this Ui object
+ *
+ * @param taskList The attached taskList object
+ */
+ public void setTaskList(TaskList taskList) {
+ this.taskList = taskList;
+ }
+
+ /**
+ * Method to pritn a welcome message of Duke
+ */
+ public void printDuke() {
+ String logo = " ____ _" + System.lineSeparator()
+ + "| _ \\ _ _| | _____" + System.lineSeparator()
+ + "| | | | | | | |/ / _ \\" + System.lineSeparator()
+ + "| |_| | |_| | < __/" + System.lineSeparator()
+ + "|____/ \\__,_|_|\\_\\___|" + System.lineSeparator();
+ System.out.println("____________________________________________________________" + System.lineSeparator()
+ + logo
+ + "Hello! I'm duke.Duke!" + System.lineSeparator()
+ + "What I can do for you?" + System.lineSeparator()
+ + "____________________________________________________________" + System.lineSeparator()
+ );
+ }
+
+ /**
+ * Method that prints the TaskList object representation
+ */
+ public void printTaskList() {
+ this.printMessage(taskList.toString());
+ }
+
+
+}
diff --git a/src/main/java/duke/controller/TaskList.java b/src/main/java/duke/controller/TaskList.java
new file mode 100644
index 000000000..118ded2ff
--- /dev/null
+++ b/src/main/java/duke/controller/TaskList.java
@@ -0,0 +1,160 @@
+package duke.controller;
+
+import duke.exception.InvalidCommandException;
+import duke.model.Deadline;
+import duke.model.Event;
+import duke.model.Task;
+import duke.model.ToDo;
+
+import java.util.ArrayList;
+
+/**
+ * A class that manages a collection of tasks
+ */
+public class TaskList {
+ /**
+ * The collection of tasks
+ */
+ protected ArrayList tasks;
+
+ /**
+ * Constructor that initializes the collection of tasks
+ */
+ public TaskList() {
+ tasks = new ArrayList();
+ }
+
+ /**
+ * Method that unmarks a task as done
+ *
+ * @param payloadData The payload data of the command
+ * @return The unmarked task
+ */
+ public Task handleUnmarkTask(String[] payloadData) {
+ int taskIndex = taskIndex = Integer.parseInt(payloadData[0]) - 1;
+ Task unmarkedTask = tasks.get(taskIndex);
+ unmarkedTask.unmarkAsDone();
+ return unmarkedTask;
+ }
+
+ /**
+ * Method that marks a task as done
+ *
+ * @param payloadData The payload data of the command
+ * @return The marked task
+ */
+ public Task handleMarkTask(String[] payloadData) {
+ int taskIndex = Integer.parseInt(payloadData[0]) - 1;
+ Task markedTask = tasks.get(taskIndex);
+ markedTask.markAsDone();
+ return markedTask;
+ }
+
+ /**
+ * Method that returns the number of tasks of a taskList
+ *
+ * @return The number of tasks
+ */
+ public int getTasksNumber() {
+ return tasks.size();
+ }
+
+ /**
+ * A method that deletes a specific task
+ *
+ * @param payloadData THe payload data of the command
+ * @return The deleted task
+ * @throws InvalidCommandException If the information provided is insufficient
+ */
+ public Task handleDeleteTask(String[] payloadData) throws InvalidCommandException {
+ String outputMessage;
+ int removedIndex = Integer.parseInt(payloadData[0]);
+ Task removedTask = tasks.get(removedIndex - 1);
+ tasks.remove(removedIndex - 1);
+ return removedTask;
+ }
+
+ /**
+ * Method that add an event to tasks
+ *
+ * @param payloadData The payload data of the command
+ * @return The added Event
+ * @throws InvalidCommandException If the information provided is insufficient
+ */
+ public Event handleAddEvent(String[] payloadData) throws InvalidCommandException {
+ Event newEvent = new Event(payloadData);
+ tasks.add(newEvent);
+ return newEvent;
+ }
+
+ /**
+ * Method that add a deadline to tasks
+ *
+ * @param payloadData The payload data of the command
+ * @return The added Deadline
+ * @throws InvalidCommandException If the information provided is insufficient
+ */
+ public Deadline handleAddDeadline(String[] payloadData) throws InvalidCommandException {
+ Deadline newDeadline = new Deadline(payloadData);
+ tasks.add(newDeadline);
+ return newDeadline;
+ }
+
+ /**
+ * Method that add a todo to tasks
+ *
+ * @param payloadData The payload data of the command
+ * @return The added ToDo
+ * @throws InvalidCommandException If the information provided is insufficient
+ */
+ public ToDo handleAddTodo(String[] payloadData) throws InvalidCommandException {
+ ToDo newTodo = new ToDo(payloadData);
+ tasks.add(newTodo);
+ return newTodo;
+ }
+
+ /**
+ * Method that add a task to tasks
+ *
+ * @param payloadData The payload data of the command
+ * @return The added Task
+ * @throws InvalidCommandException If the information provided is insufficient
+ */
+ public Task handleAddTask(String[] payloadData) throws InvalidCommandException {
+ String outputMessage;
+ Task newTask = new Task(payloadData);
+ tasks.add(newTask);
+ return newTask;
+ }
+
+ /**
+ * Method that converts a collection of tasks entity into its spring representation
+ *
+ * @return The spring representation of tasks
+ */
+ public String toString() {
+ int size = this.getTasksNumber();
+ if (size == 0) {
+ return "Task is empty...";
+ }
+ String taskListString = "";
+ int numberOfTasks = size;
+ for (int i = 0; i < numberOfTasks; i++) {
+ taskListString += String.format("%3d. ", (i + 1)) + tasks.get(i).toString();
+ if (i < numberOfTasks - 1) {
+ taskListString += System.lineSeparator() + "\t";
+ }
+ }
+ return taskListString;
+ }
+
+ public ArrayList getSearchedTasks(String keyword) {
+ ArrayList searchedTasks = new ArrayList();
+ for (Task task : tasks) {
+ if (task.getTaskName().contains(keyword)) {
+ searchedTasks.add(task);
+ }
+ }
+ return searchedTasks;
+ }
+}
diff --git a/src/main/java/duke/exception/DukeException.java b/src/main/java/duke/exception/DukeException.java
new file mode 100644
index 000000000..17aaf46b0
--- /dev/null
+++ b/src/main/java/duke/exception/DukeException.java
@@ -0,0 +1,23 @@
+package duke.exception;
+
+/**
+ * A class that represents basic custom exception for Duke
+ */
+
+public class DukeException extends Exception {
+ /**
+ * Prefix for exception message
+ */
+ private static final String DUKE_PREFIX = "Duke Error: ";
+
+
+ /**
+ * Constructor that initiates the exception message
+ *
+ * @param message The message corresponding to the exception
+ */
+ public DukeException(String message) {
+ super(DUKE_PREFIX + message);
+ }
+
+}
diff --git a/src/main/java/duke/exception/InvalidCommandException.java b/src/main/java/duke/exception/InvalidCommandException.java
new file mode 100644
index 000000000..bbd7a2b05
--- /dev/null
+++ b/src/main/java/duke/exception/InvalidCommandException.java
@@ -0,0 +1,27 @@
+package duke.exception;
+
+/**
+ * A class that represents custom exception that is thrown when the command is considered invalid
+ */
+public class InvalidCommandException extends DukeException {
+ /**
+ * Default message when message is not specified
+ */
+ private static final String DEFAULT_MESSAGE = "I'm sorry but I couldn't understand you :(";
+
+ /**
+ * Constructor that initializes the message of the exception
+ *
+ * @param message The message related to the exception
+ */
+ public InvalidCommandException(String message) {
+ super(message);
+ }
+
+ /**
+ * Empty constructor that initializes with default message
+ */
+ public InvalidCommandException() {
+ super(DEFAULT_MESSAGE);
+ }
+}
diff --git a/src/main/java/duke/model/Command.java b/src/main/java/duke/model/Command.java
new file mode 100644
index 000000000..7565c4b15
--- /dev/null
+++ b/src/main/java/duke/model/Command.java
@@ -0,0 +1,53 @@
+package duke.model;
+
+/**
+ * A class to represent the command type and the payload of the command
+ */
+public class Command {
+
+ /**
+ * Represents the type of the command
+ */
+ protected String type;
+ /**
+ * Represents the payload of the command
+ */
+ protected Payload payload;
+
+ /**
+ * Method to return the type of the command
+ *
+ * @return The type of the command
+ */
+ public String getType() {
+ return this.type;
+ }
+
+ /**
+ * Method to set the type of the command
+ *
+ * @param type The type of the command
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Method to get the payload of the command
+ *
+ * @return The Payload object corresponding to the command object
+ */
+ public Payload getPayload() {
+ return this.payload;
+ }
+
+ /**
+ * Method to set the payload of the command
+ *
+ * @param payload The payload of the command
+ */
+ public void setPayload(Payload payload) {
+ this.payload = payload;
+ }
+
+}
diff --git a/src/main/java/duke/model/Deadline.java b/src/main/java/duke/model/Deadline.java
new file mode 100644
index 000000000..688c8dacf
--- /dev/null
+++ b/src/main/java/duke/model/Deadline.java
@@ -0,0 +1,40 @@
+package duke.model;
+
+import duke.exception.InvalidCommandException;
+
+/**
+ * A class to store the Deadline entity
+ */
+public class Deadline extends Task {
+ /**
+ * Represents the time when the deadline is due
+ */
+ protected String deadlineBy;
+
+ /**
+ * Constructor that initializes the deadline's deadlineBy and the deadline name
+ *
+ * @param descriptionArray
+ * @throws InvalidCommandException
+ */
+ public Deadline(String[] descriptionArray) throws InvalidCommandException {
+ if (descriptionArray.length < 2) {
+ throw new InvalidCommandException("Incomplete deadline description!");
+ }
+ this.taskName = descriptionArray[0];
+ this.deadlineBy = descriptionArray[1];
+ }
+
+ /**
+ * Method to represent Deadline as a string
+ *
+ * @return String representation of Deadline
+ */
+ @Override
+ public String toString() {
+ String deadlinePrefix = "[D]";
+ String taskString = super.toString();
+ String deadlinePostfix = " (" + "by: " + this.deadlineBy + ")";
+ return deadlinePrefix + taskString + deadlinePostfix;
+ }
+}
diff --git a/src/main/java/duke/model/Event.java b/src/main/java/duke/model/Event.java
new file mode 100644
index 000000000..ad1694c51
--- /dev/null
+++ b/src/main/java/duke/model/Event.java
@@ -0,0 +1,49 @@
+package duke.model;
+
+import duke.exception.InvalidCommandException;
+
+/**
+ * A class to store Event entity
+ */
+public class Event extends Task {
+
+ /**
+ * Represents the start of the event
+ */
+ protected String eventStart;
+
+ /**
+ * Represents the end of the event
+ */
+ protected String eventEnd;
+
+ /**
+ * A constructor that intializes the start and end of the event, along with the name of the event
+ *
+ * @param descriptionArray
+ * @throws InvalidCommandException
+ */
+ public Event(String[] descriptionArray) throws InvalidCommandException {
+ if (descriptionArray.length < 3) {
+ throw new InvalidCommandException("Incomplete description of event!");
+ }
+ System.out.println("test");
+ this.taskName = descriptionArray[0];
+ this.eventStart = descriptionArray[1];
+ this.eventEnd = descriptionArray[2];
+ }
+
+ /**
+ * Method to represent Event as a string
+ *
+ * @return String representation of Event
+ */
+ @Override
+ public String toString() {
+ String deadlinePrefix = "[E]";
+ String taskString = super.toString();
+ String eventPostfix = " (" + "from: " + this.eventStart + " to: " + this.eventEnd + ")";
+ return deadlinePrefix + taskString + eventPostfix;
+ }
+}
+
diff --git a/src/main/java/duke/model/Payload.java b/src/main/java/duke/model/Payload.java
new file mode 100644
index 000000000..c3c8b5493
--- /dev/null
+++ b/src/main/java/duke/model/Payload.java
@@ -0,0 +1,38 @@
+package duke.model;
+
+/**
+ * A class to represent the payload or argument of a Command object
+ */
+public class Payload {
+
+ /**
+ * Represent the data of the payload
+ */
+ protected String[] data;
+
+ /**
+ * Constructor that indicates an empty payload
+ */
+ public Payload() {
+ this.data = new String[0];
+ }
+
+ /**
+ * Constructor that initializes the data of the payload
+ *
+ * @param data
+ */
+ public Payload(String[] data) {
+ this.data = data;
+ }
+
+ /**
+ * Method to return the data of the payload
+ *
+ * @return Array of string that represents multiple tokenized String
+ */
+ public String[] getData() {
+ return data;
+ }
+
+}
diff --git a/src/main/java/duke/model/Task.java b/src/main/java/duke/model/Task.java
new file mode 100644
index 000000000..c89e8e8c1
--- /dev/null
+++ b/src/main/java/duke/model/Task.java
@@ -0,0 +1,88 @@
+package duke.model;
+
+import duke.exception.InvalidCommandException;
+
+/**
+ * A class to store the Task entity
+ */
+public class Task {
+ /**
+ * Represents the name of the task
+ */
+ protected String taskName;
+
+ /**
+ * Represents the state of the task, whether is done or not
+ */
+ protected boolean isDone;
+
+ /**
+ * Empty constructor that does nothing
+ */
+ public Task() {
+ }
+
+
+ /**
+ * Task Constructor that takes an array of String to describe the entity
+ *
+ * @param descriptionArray The array of String of information
+ * @throws InvalidCommandException When it is not given sufficient information
+ */
+ public Task(String[] descriptionArray) throws InvalidCommandException {
+ if (descriptionArray.length < 1) {
+ throw new InvalidCommandException("Description of task cannot be empty!");
+ }
+ this.taskName = descriptionArray[0];
+ this.isDone = false;
+ }
+
+ /**
+ * Task Constructor that takes an array of String to describe the entity and extra argument to initialize the todo whether is done or not.
+ *
+ * @param descriptionArray The array of String of information
+ * @param isDone The state of a Task object
+ * @throws InvalidCommandException When it is not given sufficient information
+ */
+ public Task(String[] descriptionArray, boolean isDone) throws InvalidCommandException {
+ this(descriptionArray);
+ this.isDone = isDone;
+ }
+
+
+ /**
+ * Method to mark as done a task
+ */
+ public void markAsDone() {
+ this.isDone = true;
+ }
+
+ /**
+ * Method to unmark as done a task
+ */
+ public void unmarkAsDone() {
+ this.isDone = false;
+ }
+
+ /**
+ * Method to return the state of a task using string. X means that it is done, while empty space means that it is still not done.
+ *
+ * @return String representation of the state of the task
+ */
+ public String getStatusIcon() {
+ return this.isDone ? "X" : " ";
+ }
+
+ /**
+ * Method to represent Task as a string
+ *
+ * @return String representation of Task
+ */
+ public String toString() {
+ return "[" + this.getStatusIcon() + "]" + "\t" + this.taskName;
+ }
+
+ public String getTaskName() {
+ return this.taskName;
+ }
+}
diff --git a/src/main/java/duke/model/ToDo.java b/src/main/java/duke/model/ToDo.java
new file mode 100644
index 000000000..097a5b7bf
--- /dev/null
+++ b/src/main/java/duke/model/ToDo.java
@@ -0,0 +1,34 @@
+package duke.model;
+
+import duke.exception.InvalidCommandException;
+
+/**
+ * A class to store the ToDo entity
+ */
+public class ToDo extends Task {
+ /**
+ * ToDo Constructor that takes an array of String to describe the entity
+ *
+ * @param descriptionArray The array of String of information
+ * @throws InvalidCommandException When it is not given sufficient information
+ */
+ public ToDo(String[] descriptionArray) throws InvalidCommandException {
+ if (descriptionArray.length < 1) {
+ throw new InvalidCommandException("Incomplete description of ToDo!");
+ }
+ this.taskName = descriptionArray[0];
+ this.isDone = false;
+ }
+
+ /**
+ * Method to represent ToDo as a string
+ *
+ * @return String representation of ToDo
+ */
+ @Override
+ public String toString() {
+ String todoPrefix = "[T]";
+ String taskString = super.toString();
+ return todoPrefix + taskString;
+ }
+}
diff --git a/src/main/java/duke/utils/Parser.java b/src/main/java/duke/utils/Parser.java
new file mode 100644
index 000000000..db7bd61a2
--- /dev/null
+++ b/src/main/java/duke/utils/Parser.java
@@ -0,0 +1,47 @@
+package duke.utils;
+
+import duke.model.Command;
+import duke.model.Payload;
+
+/**
+ * Class that serves as a parser to tokenize the input
+ */
+public class Parser {
+
+ /**
+ * Method to parse the input into command object
+ *
+ * @param input The string input from the user
+ * @return The corresponding command object that is tokenized
+ */
+ public static Command parse(String input) {
+ String trimmedInput = input.trim();
+ Command command = new Command();
+ String[] commandArray = trimmedInput.split(" ");
+ command.setType(commandArray[0].trim());
+ String[] payloadStringArray = trimmedInput.split(command.getType());
+
+ if (payloadStringArray.length > 1) {
+ command.setPayload(new Payload(trimStringArray(payloadStringArray[1].split("/"))));
+ } else {
+ command.setPayload(new Payload());
+ }
+ return command;
+ }
+
+ /**
+ * Method to trim every String inside an array
+ *
+ * @param stringArray The string array about to be trimmed
+ * @return The trimmed stringArray
+ */
+ public static String[] trimStringArray(String[] stringArray) {
+ String[] trimmedStringArray = new String[stringArray.length];
+ for (int i = 0; i < stringArray.length; i++) {
+ trimmedStringArray[i] = stringArray[i].trim();
+ }
+ return trimmedStringArray;
+ }
+
+
+}
diff --git a/src/main/java/duke/utils/Storage.java b/src/main/java/duke/utils/Storage.java
new file mode 100644
index 000000000..22307e757
--- /dev/null
+++ b/src/main/java/duke/utils/Storage.java
@@ -0,0 +1,56 @@
+package duke.utils;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * Class that serves interaction between txt and CLI app
+ */
+public class Storage {
+ /**
+ * The base filepath of the saved txt
+ */
+ String filePath;
+
+
+ /**
+ * Constructor that initializes the Storage object
+ *
+ * @param filePath The filepath of the txt file
+ */
+ public Storage(String filePath) {
+ this.filePath = filePath;
+ }
+
+ /**
+ * Method to write to a file
+ *
+ * @param text Text to be written to a file
+ */
+ public void writeToFile(String text) {
+ try {
+ BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, false));
+ this.emptyFile();
+ bufferedWriter.write(text);
+ bufferedWriter.close();
+ } catch (IOException e) {
+ System.out.println("Error writing to file: " + filePath);
+ }
+ }
+
+ /**
+ * Method to empty the file
+ */
+ public void emptyFile() {
+ try {
+ BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, false));
+ bufferedWriter.write("");
+ bufferedWriter.close();
+ } catch (IOException e) {
+ System.out.println("Cannot empty the file: " + filePath);
+ ;
+ }
+ }
+
+}
diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT
index 657e74f6e..e69de29bb 100644
--- a/text-ui-test/EXPECTED.TXT
+++ b/text-ui-test/EXPECTED.TXT
@@ -1,7 +0,0 @@
-Hello from
- ____ _
-| _ \ _ _| | _____
-| | | | | | | |/ / _ \
-| |_| | |_| | < __/
-|____/ \__,_|_|\_\___|
-
diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt
index e69de29bb..50f6b963e 100644
--- a/text-ui-test/input.txt
+++ b/text-ui-test/input.txt
@@ -0,0 +1,17 @@
+todo borrow book
+deadline return book /by Sunday
+todo
+event /from mon
+deadline
+blah
+test
+list
+event project meeting /from Mon 2pm /to 4pm
+mark 1
+mark 3
+delete 1
+delete 2
+list
+unmark 1
+list
+bye
\ No newline at end of file
diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat
deleted file mode 100644
index 087374464..000000000
--- a/text-ui-test/runtest.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-@ECHO OFF
-
-REM create bin directory if it doesn't exist
-if not exist ..\bin mkdir ..\bin
-
-REM delete output from previous run
-if exist ACTUAL.TXT del ACTUAL.TXT
-
-REM compile the code into the bin folder
-javac -cp ..\src\main\java -Xlint:none -d ..\bin ..\src\main\java\*.java
-IF ERRORLEVEL 1 (
- echo ********** BUILD FAILURE **********
- exit /b 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
-
-REM compare the output to the expected output
-FC ACTUAL.TXT EXPECTED.TXT
diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh
index c9ec87003..fa884c694 100644
--- a/text-ui-test/runtest.sh
+++ b/text-ui-test/runtest.sh
@@ -13,7 +13,7 @@ then
fi
# compile the code into the bin folder, terminates if error occurred
-if ! javac -cp ../src/main/java -Xlint:none -d ../bin ../src/main/java/*.java
+if ! javac -cp ../src/main/java/duke -Xlint:none -d ../bin ../src/main/java/duke/**/*.java
then
echo "********** BUILD FAILURE **********"
exit 1