diff --git a/docs/README.md b/docs/README.md
index fd4406959..ce68dc5aa 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,20 +1,154 @@
# User Guide
-## Features
+Welcome! Come and plan your tasks with Duke! :)
-### Feature 1
-Description of feature.
+#### Types of tasks:
-## Usage
+1. ToDo
+2. Event
+3. Deadline
-### `Keyword` - Describe action
+* [Quick Start](#quick-Start)
+* [Features](#features)
+ * [List all Tasks : `list`](#list-all-tasks--list)
+ * [Add Todo : `todo`](#add-todo--todo)
+ * [Add Event : `event`](#add-event--event)
+ * [Add Deadline : `deadline`](#add-deadline--deadline)
+ * [Delete Task : `delete`](#delete-task--delete)
+ * [Mark Task as Done : `done`](#mark-task-as-done--done)
+ * [Find by Keyword : `find`](#find-by-keyword--find)
+ * [Exit : `bye`](#exit--bye)
+* [Command Summary](#command-summary)
-Describe action and its outcome.
+
-Example of usage:
+## Quick Start
-`keyword (optional arguments)`
+Download `Duke.jar` from
+here: https://github.com/beaniestanley/ip/releases/tag/A-Release
-Expected outcome:
+**Requirements:**
-`outcome`
+Ensure you have Java 11 or above installed.
+
+**Usage:**
+
+1. Store the .jar file in a folder
+2. Run the .jar file
+3. Enter your command!
+
+
+
+## Features
+
+### List all Tasks : `list`
+
+Displays all the tasks currently in your task list.
+
+> `[T]` Todo
+> `[E]` Event
+> `[D]` Deadline
+
+> `[X]` Done
+> `[ ]` Not done
+
+**Format:** `list`
+
+| | Example |
+| --------- | ------------------------------------------------------- |
+| Input | `list` |
+| Output | `Here are the tasks in your list: `
`1.[T][ ] Exercise`
`2.[E][X] Meet friends (at: May 22nd 5pm)`
`3.[D][ ] Watch lecture (by: Sunday 3pm)` |
+
+
+
+### Add ToDo : `todo`
+
+Adds a Todo with description.
+**Format:** `todo `
+
+| | Example |
+| --------- | ------------------------------------------------------- |
+| Input | `todo eat apple` |
+| Output | `Got it. I've added this task:`
`[T][ ] eat apple`
`Now you have 4 tasks in the list.` |
+
+
+
+### Add Event : `event`
+
+Adds an event with description and datetime.
+**Format:** `event /at `
+
+| | Example |
+| --------- | ------------------------------------------------------- |
+| Input | `Celebrate May's birthday /at 05/06/2021 1900` |
+| Output | `Got it. I've added this task:`
`[E][ ] party (at: 05/06/2021 1900)`
`Now you have 5 tasks in the list.` |`
+
+
+
+### Add Deadline : `deadline`
+
+Adds a deadline with description and datetime.
+**Format:** `deadline /by `
+
+| | Example |
+| --------- | ------------------------------------------------------- |
+| Input | `deadline Finish iP /by Sunday 3pm` |
+| Output | `Got it. I've added this task:`
`[D][ ] Finish iP (by: Sunday 3pm)`
`Now you have 6 tasks in the list.` |
+
+
+
+### Delete Task : `delete`
+
+Deletes a task using specified index.
+**Format:** `delete `
+
+| | Example |
+| --------- | ------------------------------------------------------- |
+| Input | `delete 6` |
+| Output | `Noted, I've removed this task:`
`[D][ ] Finish iP (by: Sunday 3pm)` |
+
+
+
+### Mark Task As Done : `done`
+
+Marks task as done.
+**Format:** `done `
+
+| | Example |
+| --------- | ------------------------------------------------------- |
+| Input | `done 5` |
+| Output | `Great job! I've marked this task as done:`
`[X] party` |
+
+
+
+### Find by Keyword : `find`
+
+Displays all tasks containing the keyword.
+**Format:** `find `
+
+| | Example |
+| --------- | ------------------------------------------------------- |
+| Input | `find project` |
+| Output | `Here are the matching tasks in your list:`
`1. [T][ ] do project` |
+
+
+
+### Exit : `bye`
+
+Exits Application.
+**Format:** `bye`
+
+
+
+## Command summary
+
+| Command | Format |
+| --------- | ------------------------------------------------------- |
+| list | `list` |
+| todo | `todo ` |
+| event | `event /at ` |
+| deadline | `deadline /by ` |
+| delete | `delete ` |
+| done | `done ` |
+| find | `find ` |
+| bye | `bye` |
\ No newline at end of file
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 000000000..c4192631f
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-cayman
\ No newline at end of file
diff --git a/src/main/java/Classes/Deadline.java b/src/main/java/Classes/Deadline.java
new file mode 100644
index 000000000..da70759a4
--- /dev/null
+++ b/src/main/java/Classes/Deadline.java
@@ -0,0 +1,26 @@
+package Classes;
+
+public class Deadline extends Task {
+ protected String by;
+
+ public Deadline(String description, boolean isDone, String by) {
+ super(description, isDone);
+ this.by = by;
+ }
+
+ /**
+ * @return String containing description of Deadline task
+ */
+ @Override
+ public String toString() {
+ return "[D]" + super.toString() + "(by: " + this.by + ")";
+ }
+
+ /**
+ * @return String of formatted data to be written into the text file
+ */
+ public String formatString() {
+ int done = (isDone ? 1 : 0);
+ return "D-" + done + "-" + description + "-" + by + "\n";
+ }
+}
diff --git a/src/main/java/Classes/Event.java b/src/main/java/Classes/Event.java
new file mode 100644
index 000000000..4e6f0c326
--- /dev/null
+++ b/src/main/java/Classes/Event.java
@@ -0,0 +1,27 @@
+package Classes;
+
+public class Event extends Task {
+ protected String at;
+
+ public Event(String description, boolean isDone, String at) {
+ super(description, isDone);
+ this.at= at;
+ }
+
+ /**
+ * @return String String containing description of Event task
+ */
+ @Override
+ public String toString() {
+ return "[E]" + super.toString() + "(at: " + this.at + ")";
+ }
+
+ /**
+ * @return String of formatted data to be written into the text file
+ */
+ public String formatString() {
+ int done = (isDone ? 1 : 0);
+ return "E-" + done + "-" + description + "-" + at + "\n";
+ }
+}
+
diff --git a/src/main/java/Classes/Task.java b/src/main/java/Classes/Task.java
new file mode 100644
index 000000000..c4d4d414a
--- /dev/null
+++ b/src/main/java/Classes/Task.java
@@ -0,0 +1,49 @@
+package Classes;
+
+public abstract class Task {
+ protected String description;
+ protected boolean isDone;
+
+ public Task(String description) {
+ this.description = description;
+ this.isDone = false;
+ }
+
+ public Task(String description, boolean isDone) {
+ this.description = description;
+ this.isDone = isDone;
+ }
+
+ /**
+ * @return String with a cross sign if a Task is done, else no cross
+ */
+ public String getStatusIcon() {
+ return (isDone ? "X" : " ");
+ }
+
+ /**
+ * @return String with description of Task
+ */
+ public String getDescription() {
+ return this.description;
+ }
+
+ /**
+ * Marks a Task as done
+ */
+ public void markAsDone() {
+ this.isDone = true;
+ }
+
+ /**
+ * @return String contains whether the Task is done and its description
+ */
+ public String toString() {
+ return "[" + getStatusIcon() + "] " + getDescription();
+ }
+
+ /**
+ * @return String of formatted data to be written into the text file
+ */
+ public abstract String formatString();
+}
\ No newline at end of file
diff --git a/src/main/java/Classes/Todo.java b/src/main/java/Classes/Todo.java
new file mode 100644
index 000000000..670c92457
--- /dev/null
+++ b/src/main/java/Classes/Todo.java
@@ -0,0 +1,24 @@
+package Classes;
+
+public class Todo extends Task {
+
+ public Todo(String description, boolean isDone) {
+ super(description, isDone);
+ }
+
+ /**
+ * @return String containing description of Todo task
+ */
+ @Override
+ public String toString() {
+ return "[T]" + super.toString();
+ }
+
+ /**
+ * @return String of formatted data to be written into the text file
+ */
+ public String formatString() {
+ int done = (isDone ? 1 : 0);
+ return "T-" + done + "-" + description + "\n";
+ }
+}
diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java
index 5d313334c..fc77a2dac 100644
--- a/src/main/java/Duke.java
+++ b/src/main/java/Duke.java
@@ -1,4 +1,19 @@
+import Classes.Deadline;
+import Classes.Event;
+import Classes.Task;
+import Classes.Todo;
+
+import java.util.ArrayList;
+import java.util.Scanner;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+
public class Duke {
+ public static final ArrayList tasks = new ArrayList<>();
+
public static void main(String[] args) {
String logo = " ____ _ \n"
+ "| _ \\ _ _| | _____ \n"
@@ -6,5 +21,319 @@ public static void main(String[] args) {
+ "| |_| | |_| | < __/\n"
+ "|____/ \\__,_|_|\\_\\___|\n";
System.out.println("Hello from\n" + logo);
+
+ Scanner sc = new Scanner(System.in);
+
+ try {
+ loadFile();
+ System.out.println("Save file loaded!");
+ } catch (Exception e) {
+ System.out.println("No save files found.");
+ }
+
+ System.out.println("\t------------------------------------------");
+ System.out.println("\tHello there! I'm Duke.");
+ System.out.println("\tWhat can I help you with?");
+ System.out.println("\t__________________________________________\n");
+
+ String userInput;
+ do {
+ userInput = sc.nextLine();
+ dukeManager(userInput, tasks);
+ } while (!userInput.equals("bye"));
+ }
+
+ /**
+ * Manager to handle logic
+ * @param input User's Input
+ * @param tasks Array List of Task
+ */
+ public static void dukeManager(String input, ArrayList tasks) {
+ String [] subString = input.split(" ");
+ String command = subString[0];
+
+ switch (command) {
+ case "bye":
+ exitProgram();
+ try {
+ saveFile();
+ } catch (Exception e) {
+ System.out.println("Failed to save file.");
+ }
+ break;
+ case "list":
+ listTasks(tasks);
+ break;
+ case "done":
+ markTask(input, tasks);
+ break;
+ case "delete":
+ deleteTask(input, tasks);
+ break;
+ case "find":
+ findTasks(input, tasks);
+ break;
+ default:
+ addTask(input, tasks);
+ }
+ }
+
+ /**
+ * Parses the data written in the text file into Task objects
+ * @param line String of data written in the text time
+ */
+ public static void parseData(String line) {
+ String[] tokens = line.split("-");
+
+ boolean isDone = Integer.parseInt(tokens[1]) == 1;
+
+ switch (tokens[0]) {
+ case "T":
+ try {
+ Todo todo = new Todo(tokens[2], isDone);
+ tasks.add(todo);
+ } catch (NumberFormatException e) {
+ return;
+ }
+ break;
+ case "D":
+ try {
+ Deadline deadline = new Deadline(tokens[2], isDone, tokens[3]);
+ tasks.add(deadline);
+ } catch (NumberFormatException e) {
+ return;
+ }
+ break;
+ case "E":
+ try {
+ Event event = new Event(tokens[2], isDone, tokens[3]);
+ tasks.add(event);
+ } catch (NumberFormatException e) {
+ return;
+ }
+ break;
+ default:
+ System.out.println("Invalid data!");
+ break;
+ }
+ }
+
+ /**
+ * Saves the current list of Tasks and writes them into a text file
+ * @throws IOException Exception while trying to create a new file
+ */
+ public static void saveFile() throws IOException {
+ File path = new File("tasks.txt");
+ if (!path.exists()) {
+ if (!path.createNewFile()) {
+ throw new IOException();
+ }
+ }
+ FileWriter fileWriter = new FileWriter(path);
+ for (Task task : tasks) {
+ fileWriter.write(task.formatString());
+ }
+ fileWriter.close();
+ }
+
+ /**
+ * Loads the list of Tasks written in the text file
+ * @throws FileNotFoundException Exception when the text file does not exist
+ */
+ public static void loadFile() throws FileNotFoundException {
+ File path = new File("tasks.txt");
+ if (!path.exists()) {
+ throw new FileNotFoundException();
+ }
+ Scanner sc = new Scanner(path);
+ try {
+ while (sc.hasNext()) {
+ String fileInput = sc.nextLine();
+ parseData(fileInput);
+ }
+ } catch (Exception e) {
+ System.out.println("Load failed.");
+ tasks.clear();
+ }
+ }
+
+ /**
+ * Exits the program
+ */
+ public static void exitProgram() {
+ // exits the program
+ System.out.println("\t------------------------------------------");
+ System.out.println("\tSee you soon! Goodbye! ^.^");
+ System.out.println("\t__________________________________________\n");
+ }
+
+ /**
+ * Displays all the tasks stored in the Array List
+ * @param tasks Array List of Task
+ */
+ public static void listTasks(ArrayList tasks) {
+ System.out.println("\t------------------------------------------");
+ if (tasks.size() == 0) {
+ // if list is empty
+ System.out.println("\tYour list is empty!");
+ }
+ else {
+ // displays the list of tasks
+ System.out.println("\tHere are the tasks in your list: ");
+ int i = 1;
+ for (Task task : tasks) {
+ System.out.println("\t" + i++ + "." + task.toString());
+ }
+ }
+ System.out.println("\t__________________________________________\n");
+ }
+
+ /**
+ * Marks the specific task as done and notifies user the task is marked done
+ * @param userInput User's input
+ * @param tasks Array List of Task
+ * @throws NumberFormatException Exception when an integer is not given in the command
+ * @throws IndexOutOfBoundsException Exception when the input integer is out of bounds in the Array List
+ */
+ public static void markTask(String userInput, ArrayList tasks) throws NumberFormatException,
+ IndexOutOfBoundsException {
+ // check if task exists
+ System.out.println("\t------------------------------------------");
+ try {
+ int taskIndex = Integer.parseInt(userInput.split(" ")[1]) - 1;
+ if (taskIndex > tasks.size()-1) {
+ System.out.println("\tTask " + ++taskIndex + " does not exist! Please try again.");
+ }
+ else {
+ // sets a task as done
+ Task task = tasks.get(taskIndex);
+ task.markAsDone();
+ System.out.println("\tGreat job! I've marked this task as done: ");
+ System.out.println("\t" + task.toString());
+ }
+ }
+ catch (NumberFormatException e) {
+ System.out.println("\tOOPS!! To mark task, you have to enter an integer following the work done " +
+ "in this format e.g. 'done 3'.");
+ }
+ catch (IndexOutOfBoundsException e) {
+ System.out.println("\tOOPS!! Invalid task input!");
+ }
+ System.out.println("\t__________________________________________\n");
+ }
+
+ /**
+ * Adds a new task to the list of Task
+ * @param userInput User's input
+ * @param tasks Array List of Task
+ * @throws StringIndexOutOfBoundsException Exception when wrong description format is entered
+ */
+ public static void addTask(String userInput, ArrayList tasks) throws StringIndexOutOfBoundsException {
+ // adds a task to the list
+ System.out.println("\t------------------------------------------");
+ switch (userInput.split(" ")[0].toLowerCase()) {
+ case "todo":
+ // adds to-do tasks
+ try {
+ Task todo = new Todo(userInput.substring(5), false);
+ tasks.add(todo);
+ System.out.println("\tGot it. I've added this task: ");
+ System.out.println("\t" + todo.toString());
+ System.out.println("\tNow you have " + tasks.size() + " tasks in the list.");
+ }
+ catch (StringIndexOutOfBoundsException e) {
+ System.out.println("\tOOPS!!! The description of a todo cannot be empty! It must be in the following" +
+ " format e.g. 'todo Homework");
+ }
+ break;
+ case "deadline":
+ // adds tasks with deadline
+ try {
+ Task deadline = new Deadline(userInput.substring(9, userInput.indexOf("/by")), false,
+ userInput.substring(userInput.indexOf("/by")+4));
+ tasks.add(deadline);
+ System.out.println("\tGot it. I've added this task: ");
+ System.out.println("\t" + deadline.toString());
+ System.out.println("\tNow you have " + tasks.size() + " tasks in the list.");
+ }
+ catch (StringIndexOutOfBoundsException e) {
+ System.out.println("\tOOPS!!! The description of a deadline is required in the following format e.g." +
+ " 'deadline CS2113 Project /by Thursday 9pm'.");
+ }
+ break;
+ case "event":
+ // adds event tasks
+ try {
+ Task event = new Event(userInput.substring(6, userInput.indexOf("/at")), false,
+ userInput.substring(userInput.indexOf("/at")+4));
+ tasks.add(event);
+ System.out.println("\tGot it. I've added this task: ");
+ System.out.println("\t" + event.toString());
+ System.out.println("\tNow you have " + tasks.size() + " tasks in the list.");
+ }
+ catch (StringIndexOutOfBoundsException e) {
+ System.out.println("\tOOPS!!! The description of an event is required in the following format e.g." +
+ " 'event CS2113 Meeting /at Monday 1pm'.");
+ }
+ break;
+ default:
+ // invalid command
+ System.out.println("\tOOPS! I'm sorry, but I don't know what that means! :-(");
+ }
+ System.out.println("\t__________________________________________\n");
+ }
+
+ /**
+ * Deletes a task from the list of Task
+ * @param userInput User's input
+ * @param tasks Array List of Task
+ * @throws StringIndexOutOfBoundsException Exception when wrong description format is entered
+ */
+ public static void deleteTask(String userInput, ArrayList tasks) throws StringIndexOutOfBoundsException {
+ System.out.println("\t------------------------------------------");
+ try {
+ int taskIndex = Integer.parseInt(userInput.split(" ")[1]) - 1;
+ if (taskIndex > tasks.size()-1) {
+ System.out.println("\tTask " + ++taskIndex + " does not exist! Please try again.");
+ }
+ else {
+ // sets a task as done
+ Task task = tasks.get(taskIndex);
+ System.out.println("\tNoted, I've removed this task: ");
+ System.out.println("\t" + task.toString());
+ tasks.remove(task);
+ System.out.println("\tNow you have " + tasks.size() + " tasks in the list.");
+ }
+ }
+ catch (NumberFormatException e) {
+ System.out.println("\tOOPS!! To delete task, you have to enter an integer following the work delete " +
+ "in this format e.g. 'delete 3'.");
+ }
+ catch (IndexOutOfBoundsException e) {
+ System.out.println("\tOOPS!! Invalid task input!");
+ }
+ System.out.println("\t__________________________________________\n");
+ }
+
+ /**
+ * Search for a specific task via user's input
+ * @param userInput User's input
+ * @param tasks Array List of Task
+ */
+ public static void findTasks(String userInput, ArrayList tasks) {
+ System.out.println("\t------------------------------------------");
+ System.out.println("\tHere are the matching tasks in your list:");
+ String taskInput = userInput.split(" ")[1];
+ ArrayList matchedTasks = new ArrayList<>();
+ for (Task task : tasks) {
+ if (task.getDescription().contains(taskInput)) {
+ matchedTasks.add(task);
+ }
+ }
+ int i = 1;
+ for (Task task : matchedTasks) {
+ System.out.println("\t"+ i++ + ". " + task.toString());
+ }
+ System.out.println("\t_________________________________________\n");
}
}
diff --git a/tasks.txt b/tasks.txt
new file mode 100644
index 000000000..a3d7a19ed
--- /dev/null
+++ b/tasks.txt
@@ -0,0 +1,3 @@
+T-1-do homework
+D-0-upload videos -Sunday 3pm
+E-1-project meeting -May 22nd
diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT
index 657e74f6e..95cfa3805 100644
--- a/text-ui-test/EXPECTED.TXT
+++ b/text-ui-test/EXPECTED.TXT
@@ -5,3 +5,46 @@ Hello from
| |_| | |_| | < __/
|____/ \__,_|_|\_\___|
+ ------------------------------------------
+ Hello there! I'm Duke.
+ What can I help you with?
+ __________________________________________
+
+ ------------------------------------------
+ Got it. I've added this task:
+ [T][ ] read book
+ Now you have 1 tasks in the list.
+ __________________________________________
+
+ ------------------------------------------
+ Here are the tasks in your list:
+ 1.[T][ ] read book
+ __________________________________________
+
+ ------------------------------------------
+ Got it. I've added this task:
+ [D][ ] finish homeowork (by: Saturday)
+ Now you have 2 tasks in the list.
+ __________________________________________
+
+ ------------------------------------------
+ Great job! I've marked this task as done:
+ [T][X] read book
+ __________________________________________
+
+ ------------------------------------------
+ Got it. I've added this task:
+ [E][ ] dance (at: Thurday 6-8pm)
+ Now you have 3 tasks in the list.
+ __________________________________________
+
+ ------------------------------------------
+ Here are the tasks in your list:
+ 1.[T][X] read book
+ 2.[D][ ] finish homeowork (by: Saturday)
+ 3.[E][ ] dance (at: Thurday 6-8pm)
+ __________________________________________
+
+ ------------------------------------------
+ See you soon! Goodbye! ^.^
+ __________________________________________
diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt
index e69de29bb..8dcc526e9 100644
--- a/text-ui-test/input.txt
+++ b/text-ui-test/input.txt
@@ -0,0 +1,7 @@
+todo read book
+list
+deadline finish homeowork /by Saturday
+done 1
+event dance /at Thursday 6-8pm
+list
+bye
\ No newline at end of file