diff --git a/README.md b/README.md
index 84755485a7..c57b4a278d 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,68 @@
-# Setting up
+# 1. Introduction
-**Prerequisites**
+**Duke** is a *task management system* that can help you keep track of various tasks. It is a **Command Line Interface(CLI)**.
-* JDK 11
-* Recommended: IntelliJ IDE
-* Fork this repo to your GitHub account and clone the fork to your computer
+# 2. Quick Start
-**Importing the project into IntelliJ**
+1. Ensure you have a Java **`11`** or above installed in your computer
+1. Download the latest **`duke.jar`**
+1. Copy the file to the folder you want to use as the working directory for your Duke
+1. Open Command Prompt(CMD) of your computer and direct to the working directory of **`Duke`**
+1. Type the command **`java -jar duke.jar`** to launch the program
+1. Type the command in CLI to manage your tasks in **`Duke`**
+1. Some example commands you can try:
+ * **`help`**: show a simple user guide
+ * **`list`**: list all tasks in the task list
+ * **`todo read book`**: add a todo task called **`read book`** into the task list
+ * **`delete 3`**: delete the 3rd task in the task list
+ * **`bye`**: exit the software
-1. Open IntelliJ (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project dialog first).
-1. Set up the correct JDK version.
- * Click `Configure` > `Structure for new Projects` (in older versions of Intellij:`Configure` > `Project Defaults` > `Project Structure`).
- * If JDK 11 is listed in the drop down, select it. If it is not, click `New...` and select the directory where you installed JDK 11.
- * Click `OK`.
-1. Click `Import Project`.
-1. Locate the project directory and click `OK`.
-1. Select `Create project from existing sources` and click `Next`.
-1. Rename the project if you want. Click `Next`.
-1. Ensure that your src folder is checked. Keep clicking `Next`.
-1. Click `Finish`.
+# 3. Features
-# Tutorials
+### 3.1 Viewing help: **`help`**
+Format: `help`
-Duke Increment | Tutorial
----------------|---------------
-`A-Gradle` | [Gradle Tutorial](tutorials/gradleTutorial.md)
-`A-TextUiTesting` | [Text UI Testing Tutorial](tutorials/textUiTestingTutorial.md)
-`Level-10` | JavaFX tutorials:
→ [Part 1: Introduction to JavaFX][fx1]
→ [Part 2: Creating a GUI for Duke][fx2]
→ [Part 3: Interacting with the user][fx3]
→ [Part 4: Introduction to FXML][fx4]
+### 3.2 Adding a Todo task: **`todo`**
+Format: `todo [TaskName]`
-[fx1]:
-[fx2]:
-[fx3]:
-[fx4]:
+### 3.3 Adding a Deadline task: **`deadline`**
+Format: `deadline [TaskName] /by [Deadline]`
-# Feedback, Bug Reports
+### 3.4 Adding a Event task: **`event`**
+Format: `event [TaskName] /at [Timeslot]`
-* If you have feedback or bug reports, please post in [se-edu/duke issue tracker](https://github.com/se-edu/duke/issues).
-* We welcome pull requests too.
\ No newline at end of file
+### 3.5 Marking a task as Done: **`done`**
+Format: `done [Task#]`
+
+### 3.6 Deleting a task: **`delete`**
+Format: `delete [Task#]`
+
+### 3.7 Finding tasks by searching for a keyword: **`find`**
+Format: `find [Keyword]`
+
+### 3.8 Listing all tasks: **`list`**
+Format: `list`
+
+### 3.9 Exiting the program: **`bye`**
+Format: `bye`
+
+### 3.10 Saving the data
+The task list is saved in the hard disk automatically after any command that changes the list and saved data will be loaded up when launching the program.
+There is no need to save or load data manually.
+
+# 4. Command Summary
+* **todo**: `todo [TaskName]`
+ e.g. `todo read book`
+* **deadline**: `deadline [TaskName] /by [Deadline]`
+ e.g. `deadline return book /by Sunday`
+* **event**: `event [TaskName] /at [Timeslot]`
+ e.g. `event project meeting /at Monday 2-4pm`
+* **done**: `done [Task#]`
+ e.g. `done 3`
+* **delete**: `delete [Task#]`
+ e.g. `delete 2`
+* **find**: `find [Keyword]`
+ e.g. `find book`
+* **list**: `list`
+* **help**: `help`
+* **bye**: `bye`
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000000..1ffc0fbce3
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,20 @@
+plugins {
+ id 'java'
+ id 'application'
+}
+
+group 'seedu.duke'
+version '0.1.0'
+
+repositories {
+ mavenCentral()
+}
+
+application {
+ // Change this to your main class.
+ mainClassName = "duke.Duke"
+}
+
+run {
+ standardInput = System.in
+}
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
new file mode 100644
index 0000000000..b1a57ba6c0
--- /dev/null
+++ b/config/checkstyle/checkstyle.xml
@@ -0,0 +1,257 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/README.md b/docs/README.md
index fd44069597..c57b4a278d 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,20 +1,68 @@
-# User Guide
+# 1. Introduction
-## Features
+**Duke** is a *task management system* that can help you keep track of various tasks. It is a **Command Line Interface(CLI)**.
-### Feature 1
-Description of feature.
+# 2. Quick Start
-## Usage
+1. Ensure you have a Java **`11`** or above installed in your computer
+1. Download the latest **`duke.jar`**
+1. Copy the file to the folder you want to use as the working directory for your Duke
+1. Open Command Prompt(CMD) of your computer and direct to the working directory of **`Duke`**
+1. Type the command **`java -jar duke.jar`** to launch the program
+1. Type the command in CLI to manage your tasks in **`Duke`**
+1. Some example commands you can try:
+ * **`help`**: show a simple user guide
+ * **`list`**: list all tasks in the task list
+ * **`todo read book`**: add a todo task called **`read book`** into the task list
+ * **`delete 3`**: delete the 3rd task in the task list
+ * **`bye`**: exit the software
-### `Keyword` - Describe action
+# 3. Features
-Describe action and its outcome.
+### 3.1 Viewing help: **`help`**
+Format: `help`
-Example of usage:
+### 3.2 Adding a Todo task: **`todo`**
+Format: `todo [TaskName]`
-`keyword (optional arguments)`
+### 3.3 Adding a Deadline task: **`deadline`**
+Format: `deadline [TaskName] /by [Deadline]`
-Expected outcome:
+### 3.4 Adding a Event task: **`event`**
+Format: `event [TaskName] /at [Timeslot]`
-`outcome`
+### 3.5 Marking a task as Done: **`done`**
+Format: `done [Task#]`
+
+### 3.6 Deleting a task: **`delete`**
+Format: `delete [Task#]`
+
+### 3.7 Finding tasks by searching for a keyword: **`find`**
+Format: `find [Keyword]`
+
+### 3.8 Listing all tasks: **`list`**
+Format: `list`
+
+### 3.9 Exiting the program: **`bye`**
+Format: `bye`
+
+### 3.10 Saving the data
+The task list is saved in the hard disk automatically after any command that changes the list and saved data will be loaded up when launching the program.
+There is no need to save or load data manually.
+
+# 4. Command Summary
+* **todo**: `todo [TaskName]`
+ e.g. `todo read book`
+* **deadline**: `deadline [TaskName] /by [Deadline]`
+ e.g. `deadline return book /by Sunday`
+* **event**: `event [TaskName] /at [Timeslot]`
+ e.g. `event project meeting /at Monday 2-4pm`
+* **done**: `done [Task#]`
+ e.g. `done 3`
+* **delete**: `delete [Task#]`
+ e.g. `delete 2`
+* **find**: `find [Keyword]`
+ e.g. `find book`
+* **list**: `list`
+* **help**: `help`
+* **bye**: `bye`
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..87b738cbd0
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..4b7e1f3d38
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000000..af6708ff22
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000..6d57edc706
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000000..d1e92fe5db
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'duke'
diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java
deleted file mode 100644
index 5d313334cc..0000000000
--- 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 0000000000..2c9a9745c5
--- /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 0000000000..5a9dabc72d
--- /dev/null
+++ b/src/main/java/duke/Duke.java
@@ -0,0 +1,62 @@
+package duke;
+
+import duke.command.Command;
+import duke.command.ExitCommand;
+import duke.command.HelpCommand;
+import duke.command.ListCommand;
+import duke.exception.DukeException;
+
+/**
+ * Duke class (the main class of this Duke project)
+ */
+public class Duke {
+
+ private Storage storage;
+ private TaskList tasks;
+ private Ui ui;
+ private boolean fileHasChanges = false;
+
+ public Duke(String filePath) {
+ ui = new Ui();
+ storage = new Storage(filePath);
+ try {
+ tasks = new TaskList(storage.load());
+ } catch (DukeException e) {
+ ui.showLoadingError(e.getMessage());
+ tasks = new TaskList();
+ }
+ }
+
+ /**
+ * run process method of Duke
+ */
+ public void run() {
+ ui.greet();
+ boolean isExit = false;
+ while (!isExit) {
+ try {
+ String commandLine = ui.parseCommand();
+ Command c = Parser.parse(commandLine);
+ c.execute(tasks, ui);
+ if(!(c instanceof HelpCommand || c instanceof ListCommand || c instanceof ExitCommand)) {
+ fileHasChanges = true;
+ }
+ isExit = c.isExit();
+ } catch (DukeException e) {
+ ui.showLoadingError(e.getMessage());
+ }
+ }
+ if (fileHasChanges) {
+ try {
+ storage.save(tasks.getTaskList());
+ } catch (DukeException e) {
+ ui.showLoadingError(e.getMessage());
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ new Duke("tasks.txt").run();
+ }
+
+}
diff --git a/src/main/java/duke/Parser.java b/src/main/java/duke/Parser.java
new file mode 100644
index 0000000000..ac35ba660f
--- /dev/null
+++ b/src/main/java/duke/Parser.java
@@ -0,0 +1,69 @@
+package duke;
+
+import duke.command.*;
+import duke.exception.DukeException;
+
+/**
+ * parser class that is used to deal with making sense of user commands
+ */
+public class Parser {
+
+ /**
+ * split user command into different parts and decide which operation should be implement on the task list
+ * @param commandLine command entered by user which need to be split
+ * @return a command object
+ * @throws DukeException if the commandLine user entered is invalid
+ * */
+ public static Command parse(String commandLine) throws DukeException {
+ String[] attributes = commandLine.split(" ", 2);
+ attributes[0] = attributes[0].toLowerCase();
+ switch (attributes[0]){
+ case "bye": return new ExitCommand();
+ case "list": return new ListCommand();
+ case "done":
+ try {
+ return new DoneCommand(Integer.parseInt(attributes[1]));
+ } catch (IndexOutOfBoundsException | NumberFormatException e) {
+ throw new DukeException(Ui.INVALID_TASKNO +Ui.DONE_DESCRIPTION);
+ }
+ case "todo":
+ try {
+ return new AddTodoCommand(attributes[1]);
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException(Ui.INVALID_DESCRIPTION+Ui.TODO_DESCRIPTION);
+ }
+ case "deadline":
+ try {
+ int index = attributes[1].indexOf(" /by ");
+ String taskName = attributes[1].substring(0, index);
+ String deadline = attributes[1].substring(index+1).trim().split(" ",2)[1];
+ return new AddDeadlineCommand(taskName, deadline);
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException(Ui.INVALID_DESCRIPTION+Ui.DEADLINE_DESCRIPTION);
+ }
+ case "event":
+ try {
+ int index = attributes[1].indexOf(" /at ");
+ String taskName = attributes[1].substring(0, index);
+ String timeSlot = attributes[1].substring(index+1).trim().split(" ",2)[1];
+ return new AddEventCommand(taskName, timeSlot);
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException(Ui.INVALID_DESCRIPTION+Ui.EVENT_DESCRIPTION);
+ }
+ case "delete":
+ try {
+ return new DeleteCommand(Integer.parseInt(attributes[1]));
+ } catch (IndexOutOfBoundsException | NumberFormatException e) {
+ throw new DukeException(Ui.INVALID_TASKNO +Ui.DELETE_DESCRIPTION);
+ }
+ case "help": return new HelpCommand();
+ case "find":
+ try {
+ return new FindCommand(attributes[1]);
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException(Ui.LACK_KEYWORD+Ui.FIND_DESCRIPTION);
+ }
+ default: throw new DukeException(Ui.INVALID_COMMAND);
+ }
+ }
+}
diff --git a/src/main/java/duke/Storage.java b/src/main/java/duke/Storage.java
new file mode 100644
index 0000000000..5a4bf0a8cd
--- /dev/null
+++ b/src/main/java/duke/Storage.java
@@ -0,0 +1,77 @@
+package duke;
+
+import duke.exception.DukeException;
+import duke.task.Deadline;
+import duke.task.Event;
+import duke.task.Task;
+import duke.task.Todo;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.Scanner;
+
+/**
+ * storage class: deals with loading tasks from the file and saving tasks in the file
+ */
+public class Storage {
+
+ private ArrayList taskList;
+ private String filePath;
+
+ public Storage(String filePath) {
+ this.filePath = filePath;
+ }
+
+ /**
+ * load data from file to initialize task list at the beginning of the launching Duke
+ * @return a ArrayList that contains all task stored in the local file
+ * @throws DukeException if file cannot be found
+ * */
+ public ArrayList load() throws DukeException {
+ File f = new File(filePath);
+ Scanner fileIn;
+ try {
+ fileIn = new Scanner(f);
+ } catch (FileNotFoundException e) {
+ throw new DukeException("Creat a new file called tasks.txt");
+ }
+ taskList = new ArrayList();
+ String record;
+ while (fileIn.hasNextLine()) {
+ record = fileIn.nextLine();
+ String[] attributes = record.split("\\|");
+ switch (attributes[0].trim()) {
+ case "T":
+ taskList.add(new Todo(attributes[2].trim(), attributes[1].trim().equals("1")));
+ break;
+ case "D":
+ taskList.add(new Deadline(attributes[2].trim(), attributes[1].trim().equals("1"), attributes[3].trim()));
+ break;
+ case "E":
+ taskList.add(new Event(attributes[2].trim(), attributes[1].trim().equals("1"), attributes[3].trim()));
+ break;
+ }
+ }
+ return taskList;
+ }
+
+ /**
+ * save data to file if there are some changes made to the task list before exiting from Duke
+ * @param taskList the task list stored in the tasks object
+ * @throws DukeException if the file cannot be written
+ * */
+ public void save(ArrayList taskList) throws DukeException {
+ try {
+ FileWriter fw = new FileWriter(filePath);
+ for(Task task: taskList) {
+ fw.write(task.textToFile());
+ }
+ fw.close();
+ } catch (IOException e) {
+ throw new DukeException("Cannot write to the file!");
+ }
+ }
+}
diff --git a/src/main/java/duke/TaskList.java b/src/main/java/duke/TaskList.java
new file mode 100644
index 0000000000..363ef5da0d
--- /dev/null
+++ b/src/main/java/duke/TaskList.java
@@ -0,0 +1,118 @@
+package duke;
+
+import duke.task.Deadline;
+import duke.task.Event;
+import duke.task.Task;
+import duke.task.Todo;
+
+import java.util.ArrayList;
+
+/**
+ * tasklist class:contains the task list and it can perform operations on task list such as addtask, deletetask etc.)
+ */
+public class TaskList {
+
+ private ArrayList taskList;
+
+ public TaskList(ArrayList taskList) {
+ this.taskList = taskList;
+ }
+
+ public TaskList() {
+ this.taskList = new ArrayList<>();
+ }
+
+ public ArrayList getTaskList() {
+ return taskList;
+ }
+
+ /**
+ * add a todo task into the task list
+ * @param taskName task name of the todo task
+ * @return a description of newly added task
+ */
+ public String addTodo(String taskName) {
+ Todo todo = new Todo(taskName, false);
+ taskList.add(todo);
+ return todo.print();
+ }
+
+ /**
+ * add a deadline task into the task list
+ * @param taskName task name of the deadline task
+ * @param deadLine deadline string of the task
+ * @return a description of this newly added task
+ */
+ public String addDeadline(String taskName, String deadLine) {
+ Deadline deadline = new Deadline(taskName, false, deadLine);
+ taskList.add(deadline);
+ return deadline.print();
+ }
+
+ /**
+ * add a event task into the task list
+ * @param taskName task name of the event task
+ * @param timeSlot timeslot string of this task
+ * @return a description of this newly added tasks
+ */
+ public String addEvent(String taskName, String timeSlot) {
+ Event event = new Event(taskName, false, timeSlot);
+ taskList.add(event);
+ return event.print();
+ }
+
+ /**
+ * list all tasks in the task list
+ * @param ui Ui object that interacts with users
+ */
+ public void listTask(Ui ui) {
+ int i = 1;
+ ui.printFormatLine();
+ ui.printString(Ui.LISTING);
+ for(Task task: taskList) {
+ ui.printString(i++ + "." + task.print());
+ }
+ ui.printString("Now you have " + taskList.size() + (taskList.size() > 1 ? " tasks" : " task") + " in the list");
+ ui.printFormatLine();
+ ui.printString("");
+ }
+
+ /**
+ * mark a task in the task list as done
+ * @param taskNo # of task needed to be marked
+ * @return a description of this newly marked task
+ */
+ public String markTask(int taskNo) {
+ Task task = taskList.get(taskNo-1);
+ task.changeStatus(true);
+ return task.print();
+ }
+
+ /**
+ * delete a task in the task list
+ * @param taskNo # of task needed to be deleted
+ * @return a description of this deleted task
+ */
+ public String deleteTask(int taskNo) {
+ Task task = taskList.get(taskNo-1);
+ String description = task.print();
+ taskList.remove(task);
+ return description;
+ }
+
+ /**
+ * search tasks in the task list in terms of the keyword
+ * @param keyword the key word entered by user
+ * @return array of strings of all matching tasks
+ */
+ public String[] findMatchingTasks(String keyword) {
+ ArrayList matchingTasks = new ArrayList<>();
+ matchingTasks.add(Ui.FINDING);
+ int i = 1;
+ for (Task task : taskList) {
+ String taskDescription = task.print();
+ if (taskDescription.toLowerCase().contains(keyword.toLowerCase())) matchingTasks.add(i++ + "." + taskDescription);
+ }
+ return matchingTasks.toArray(new String[matchingTasks.size()]);
+ }
+}
diff --git a/src/main/java/duke/Ui.java b/src/main/java/duke/Ui.java
new file mode 100644
index 0000000000..d6d30792fa
--- /dev/null
+++ b/src/main/java/duke/Ui.java
@@ -0,0 +1,96 @@
+package duke;
+
+import java.util.Scanner;
+
+/**
+ * UI class: deals with interactions with the user(write to stdout, read from stdin)
+ */
+public class Ui {
+
+ public static final String FORMAT_LINE = "------------------------------------";
+ public static final String GOODBYE = "Bye. Hope to see you again soon!";
+ public static final String ADD_TASK = "Got it! I have added this task into your list:";
+ public static final String DONE_TASK = "Good job! You have done this task:";
+ public static final String GREETING = String.format("%s\n%s", "Hello, I'm Duke!", "What can I do for you?");
+ public static final String DELETE_TASK= "Noted! I have deleted this task from the list:";
+ public static final String LISTING = "Here is the list of all tasks you have:";
+ public static final String HELPING = "Hello, Welcome to Duke!\n" +
+ "This task management software can help you track all your tasks.\n" +
+ "Here are the commands of Duke:";
+ public static final String INVALID_COMMAND = "OOPS!!! This is an invalid command\n" +
+ "Type 'help' to find more commands";
+ public static final String INVALID_TASKNO = "# of the task is invalid\n";
+ public static final String INVALID_DESCRIPTION = "The description of the task is invalid\n";
+ public static final String LACK_KEYWORD = "A keyword is needed\n";
+ public static final String TODO_DESCRIPTION = "[format] todo ";
+ public static final String DEADLINE_DESCRIPTION = "[format] deadline /by ";
+ public static final String DONE_DESCRIPTION = "[format] done (within the range)";
+ public static final String DELETE_DESCRIPTION= "[format] delete (within the range)";
+ public static final String EVENT_DESCRIPTION = "[format] event /at ";
+ public static final String LIST_DESCRIPTION = "[format] list";
+ public static final String HELP_DESCRIPTION = "[format] help";
+ public static final String BYE_DESCRIPTION = "[format] bye";
+ public static final String FIND_DESCRIPTION = "[format] find ";
+ public static final String FINDING = "Here are the matching tasks in your list:";
+
+ private static Scanner in = new Scanner(System.in);
+
+ public void greet() {
+ String logo = " ____ _ \n"
+ + "| _ \\ _ _| | _____ \n"
+ + "| | | | | | | |/ / _ \\\n"
+ + "| |_| | |_| | < __/\n"
+ + "|____/ \\__,_|_|\\_\\___|\n";
+ System.out.println("Welcome to\n" + logo);
+ printFormat(GREETING);
+ }
+
+ public String parseCommand() {
+ return in.nextLine();
+ }
+
+ public void exit() {
+ printFormat(GOODBYE);
+ }
+
+ public void showLoadingError(String errorDescription) {
+ printFormat(errorDescription);
+ }
+
+ /**
+ * a simple printout method that print well-formatted output
+ * @param strs a variable parameter
+ * */
+ public void printFormat(String ...strs) {
+ System.out.println(FORMAT_LINE);
+ for(String str: strs) {
+ System.out.println(str);
+ }
+ System.out.println(FORMAT_LINE);
+ System.out.println();
+ }
+
+ public void printFormatLine() {
+ System.out.println(FORMAT_LINE);
+ }
+
+ public void printString(String str) {
+ System.out.println(str);
+ }
+
+ /**
+ * print user guide out when user types Help command
+ */
+ public void printUserGuide() {
+ printFormat(HELPING,
+ "todo\nadd a todo task to your task list\n"+TODO_DESCRIPTION,
+ "deadline\nadd a deadline task to your task list\n"+DEADLINE_DESCRIPTION,
+ "event\nadd a event task to your task list\n"+EVENT_DESCRIPTION,
+ "delete\ndelete one task in your task list\n"+DELETE_DESCRIPTION,
+ "done\nmark one task as done in your task list\n"+DONE_DESCRIPTION,
+ "find\nfind tasks by searching for a keyword\n" + FIND_DESCRIPTION,
+ "list\nlist all tasks in your task list\n"+ LIST_DESCRIPTION,
+ "help\nlist all commands and corresponding command format of Duke"+ HELP_DESCRIPTION,
+ "exit\nexit from Duke\n"+ BYE_DESCRIPTION);
+ }
+}
diff --git a/src/main/java/duke/command/AddDeadlineCommand.java b/src/main/java/duke/command/AddDeadlineCommand.java
new file mode 100644
index 0000000000..8058edc949
--- /dev/null
+++ b/src/main/java/duke/command/AddDeadlineCommand.java
@@ -0,0 +1,37 @@
+package duke.command;
+
+import duke.Parser;
+import duke.TaskList;
+import duke.Ui;
+import duke.exception.DukeException;
+
+/**
+ * a command class that executes the operation to add a deadline task to task list
+ */
+public class AddDeadlineCommand extends Command {
+
+ private String taskName;
+ private String deadline;
+
+ /**
+ * constructor of this class (need to split user command to find more information about the deadline task)
+ * @param taskName task name
+ * @param deadline deadline of the task
+ */
+ public AddDeadlineCommand(String taskName, String deadline){
+ this.taskName = taskName;
+ this.deadline = deadline;
+ }
+
+ @Override
+ public boolean isExit() {
+ return false;
+ }
+
+ @Override
+ public void execute(TaskList tasks, Ui ui) {
+ String description = tasks.addDeadline(taskName, deadline);
+ ui.printFormat(Ui.ADD_TASK+description);
+ }
+
+}
diff --git a/src/main/java/duke/command/AddEventCommand.java b/src/main/java/duke/command/AddEventCommand.java
new file mode 100644
index 0000000000..efdac909d5
--- /dev/null
+++ b/src/main/java/duke/command/AddEventCommand.java
@@ -0,0 +1,37 @@
+package duke.command;
+
+import duke.Parser;
+import duke.TaskList;
+import duke.Ui;
+import duke.exception.DukeException;
+
+/**
+ * a command class that executes the operation to add a event task to task list
+ */
+public class AddEventCommand extends Command {
+
+ private String taskName;
+ private String timeSlot;
+
+ /**
+ * constructor of this class (need to split user command to find more information about the event task)
+ * @param taskName task name
+ * @param timeSlot time slot of the task
+ */
+ public AddEventCommand(String taskName, String timeSlot){
+ this.taskName = taskName;
+ this.timeSlot = timeSlot;
+ }
+
+ @Override
+ public boolean isExit() {
+ return false;
+ }
+
+ @Override
+ public void execute(TaskList tasks, Ui ui) {
+ String description = tasks.addEvent(taskName,timeSlot);
+ ui.printFormat(Ui.ADD_TASK+description);
+ }
+
+}
diff --git a/src/main/java/duke/command/AddTodoCommand.java b/src/main/java/duke/command/AddTodoCommand.java
new file mode 100644
index 0000000000..8156303d40
--- /dev/null
+++ b/src/main/java/duke/command/AddTodoCommand.java
@@ -0,0 +1,29 @@
+package duke.command;
+
+import duke.Parser;
+import duke.TaskList;
+import duke.Ui;
+
+/**
+ * a command class that executes the operation to add a todo task to task list
+ */
+public class AddTodoCommand extends Command {
+
+ private String taskName;
+
+ public AddTodoCommand(String taskName) {
+ this.taskName = taskName;
+ }
+
+ @Override
+ public boolean isExit() {
+ return false;
+ }
+
+ @Override
+ public void execute(TaskList tasks, Ui ui) {
+ String description = tasks.addTodo(taskName);
+ ui.printFormat(Ui.ADD_TASK+description);
+ }
+
+}
diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java
new file mode 100644
index 0000000000..25d98c952b
--- /dev/null
+++ b/src/main/java/duke/command/Command.java
@@ -0,0 +1,14 @@
+package duke.command;
+
+import duke.TaskList;
+import duke.Ui;
+import duke.exception.DukeException;
+
+/**
+ * the abstract command class(superclass of other command-related class(ExitCommand, HelpCommand etc.))
+ * has some abstract methods
+ */
+public abstract class Command {
+ public abstract boolean isExit();
+ public abstract void execute(TaskList tasks, Ui ui) throws DukeException;
+}
diff --git a/src/main/java/duke/command/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java
new file mode 100644
index 0000000000..9de8fd4848
--- /dev/null
+++ b/src/main/java/duke/command/DeleteCommand.java
@@ -0,0 +1,39 @@
+package duke.command;
+
+import duke.Parser;
+import duke.TaskList;
+import duke.Ui;
+import duke.exception.DukeException;
+
+/**
+ * a command class that executes the operation of deleting a task in task list
+ */
+public class DeleteCommand extends Command {
+
+ private int taskNo;
+
+ public DeleteCommand(int taskNo) {
+ this.taskNo = taskNo;
+ }
+
+ @Override
+ public boolean isExit() {
+ return false;
+ }
+
+ @Override
+ /**
+ * execution method of delete command
+ * @param tasks the object stores task list and can do operations on the task list
+ * @param ui the object that interacts with users
+ * @throws DukeException if the task# entered by the user is out of bound
+ */
+ public void execute(TaskList tasks, Ui ui) throws DukeException{
+ try {
+ String description = tasks.deleteTask(taskNo);
+ ui.printFormat(Ui.DELETE_TASK + description);
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException("The taskNo is not within the range");
+ }
+ }
+}
diff --git a/src/main/java/duke/command/DoneCommand.java b/src/main/java/duke/command/DoneCommand.java
new file mode 100644
index 0000000000..79ab230dd7
--- /dev/null
+++ b/src/main/java/duke/command/DoneCommand.java
@@ -0,0 +1,39 @@
+package duke.command;
+
+import duke.Parser;
+import duke.TaskList;
+import duke.Ui;
+import duke.exception.DukeException;
+
+/**
+ * a command class that executes the operation of marking a task as done in task list
+ */
+public class DoneCommand extends Command {
+
+ private int taskNo;
+
+ public DoneCommand(int taskNo) {
+ this.taskNo = taskNo;
+ }
+
+ @Override
+ public boolean isExit() {
+ return false;
+ }
+
+ /**
+ * execution method of done command
+ * @param tasks the object stores task list and can do operations on the task list
+ * @param ui the object that interact with user
+ * @throws DukeException if the task# entered by the user is out of bound
+ */
+ public void execute(TaskList tasks, Ui ui) throws DukeException {
+ try {
+ String description = tasks.markTask(taskNo);
+ ui.printFormat(Ui.DONE_TASK + description);
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException("the taskNo is not within the range");
+ }
+ }
+
+}
diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java
new file mode 100644
index 0000000000..d8fbe86560
--- /dev/null
+++ b/src/main/java/duke/command/ExitCommand.java
@@ -0,0 +1,19 @@
+package duke.command;
+
+import duke.TaskList;
+import duke.Ui;
+
+/**
+ * a command class that executes the operation of quiting from Duke
+ */
+public class ExitCommand extends Command {
+ public boolean isExit() {
+ return true;
+ }
+
+ @Override
+ public void execute(TaskList tasks, Ui ui) {
+ ui.exit();
+ }
+
+}
diff --git a/src/main/java/duke/command/FindCommand.java b/src/main/java/duke/command/FindCommand.java
new file mode 100644
index 0000000000..a6dca658d0
--- /dev/null
+++ b/src/main/java/duke/command/FindCommand.java
@@ -0,0 +1,26 @@
+package duke.command;
+
+import duke.TaskList;
+import duke.Ui;
+import duke.exception.DukeException;
+
+/**
+ * a command class that execute operation of searching tasks in the task list in terms of a keyword entered by users
+ */
+public class FindCommand extends Command {
+ private String keyword;
+
+ public FindCommand(String keyword) {
+ this.keyword = keyword;
+ }
+
+ @Override
+ public boolean isExit() {
+ return false;
+ }
+
+ @Override
+ public void execute(TaskList tasks, Ui ui) throws DukeException {
+ ui.printFormat(tasks.findMatchingTasks(keyword));
+ }
+}
diff --git a/src/main/java/duke/command/HelpCommand.java b/src/main/java/duke/command/HelpCommand.java
new file mode 100644
index 0000000000..84c8865c6c
--- /dev/null
+++ b/src/main/java/duke/command/HelpCommand.java
@@ -0,0 +1,22 @@
+package duke.command;
+
+import duke.Storage;
+import duke.TaskList;
+import duke.Ui;
+import duke.exception.DukeException;
+
+/**
+ * a command class that executes the operation of printing out
+ * all commands of Duke and corresponding format(a simple User Guide)
+ */
+public class HelpCommand extends Command {
+ @Override
+ public boolean isExit() {
+ return false;
+ }
+
+ @Override
+ public void execute(TaskList tasks, Ui ui) {
+ ui.printUserGuide();
+ }
+}
diff --git a/src/main/java/duke/command/ListCommand.java b/src/main/java/duke/command/ListCommand.java
new file mode 100644
index 0000000000..6d7c76311c
--- /dev/null
+++ b/src/main/java/duke/command/ListCommand.java
@@ -0,0 +1,21 @@
+package duke.command;
+
+import duke.TaskList;
+import duke.Ui;
+
+/**
+ * a command class that executes the operation of listing all tasks in task list
+ */
+public class ListCommand extends Command {
+
+ @Override
+ public boolean isExit() {
+ return false;
+ }
+
+ @Override
+ public void execute(TaskList tasks, Ui ui) {
+ tasks.listTask(ui);
+ }
+
+}
diff --git a/src/main/java/duke/exception/DukeException.java b/src/main/java/duke/exception/DukeException.java
new file mode 100644
index 0000000000..148a0383ec
--- /dev/null
+++ b/src/main/java/duke/exception/DukeException.java
@@ -0,0 +1,7 @@
+package duke.exception;
+
+public class DukeException extends Exception{
+ public DukeException(String s) {
+ super(s);
+ }
+}
diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java
new file mode 100644
index 0000000000..d348ae05f0
--- /dev/null
+++ b/src/main/java/duke/task/Deadline.java
@@ -0,0 +1,39 @@
+package duke.task;
+
+/**
+ * a deadline class that can be instantiated to deadline object
+ */
+public class Deadline extends Task {
+ String deadline;
+
+ public Deadline(String command, boolean status, String deadline) {
+ super(command, status);
+ this.deadline = deadline;
+ }
+
+ /**
+ * generate description of a deadline task that need to be stored in the file*
+ * @return a string that will be stored in the local file
+ */
+ public String textToFile() {
+ String text = "D | 0 | ";
+ if(isDone) text = "D | 1| ";
+ text += name + " | " + deadline + System.lineSeparator();
+ return text;
+ }
+
+ /**
+ * generate a string that display all attributes of a deadline task
+ * @return a string that describes the task
+ */
+ public String print() {
+ String str = "[D]";
+ if(isDone) {
+ str += "[Y]";
+ } else {
+ str += "[N]";
+ }
+ return str = str + " " + name + " (by: " + deadline + ")";
+
+ }
+}
diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java
new file mode 100644
index 0000000000..94ee2dd57e
--- /dev/null
+++ b/src/main/java/duke/task/Event.java
@@ -0,0 +1,36 @@
+package duke.task;
+
+/* a event class that can be instantiated to event object */
+public class Event extends Task {
+ String timeSlot;
+
+ public Event(String command, boolean status, String timeSlot) {
+ super(command, status);
+ this.timeSlot = timeSlot;
+ }
+
+ /**
+ * generate description of a event task that need to be stored in the file
+ * @return a string that will be stored in the local file
+ */
+ public String textToFile() {
+ String text = "E | 0 | ";
+ if(isDone) text = "E | 1 | ";
+ text += name + " | " + timeSlot + System.lineSeparator();
+ return text;
+ }
+
+ /**
+ * generate a string that display all attributes of a event task
+ * @return a string that describes the task
+ */
+ public String print() {
+ String str = "[E]";
+ if(isDone) {
+ str += "[Y]";
+ } else {
+ str += "[N]";
+ }
+ return str = str + " " + name + " (at: " + timeSlot + ")";
+ }
+}
diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java
new file mode 100644
index 0000000000..ef97e9dbfe
--- /dev/null
+++ b/src/main/java/duke/task/Task.java
@@ -0,0 +1,26 @@
+package duke.task;
+
+/**
+ * the abstract task class(superclass of Deadline, Event, Todo Class)
+ */
+public abstract class Task {
+ String name;
+ boolean isDone;
+
+ public Task(String name, boolean status) {
+ this.name = name;
+ isDone = status;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void changeStatus(boolean newStatus) {
+ isDone = newStatus;
+ }
+
+ public abstract String textToFile();
+
+ public abstract String print();
+}
diff --git a/src/main/java/duke/task/Todo.java b/src/main/java/duke/task/Todo.java
new file mode 100644
index 0000000000..a131281847
--- /dev/null
+++ b/src/main/java/duke/task/Todo.java
@@ -0,0 +1,33 @@
+package duke.task;
+
+/* a todo class that can be instantiated to todo object */
+public class Todo extends Task {
+
+ public Todo(String command, boolean status) {super(command, status);};
+
+ /**
+ * generate description of a todo task that need to be stored in the file
+ * @return a string that will be stored in the local file
+ */
+ public String textToFile() {
+ String text = "T | 0 | ";
+ if(isDone) text = "T | 1 | ";
+ text += name + System.lineSeparator();
+ return text;
+ }
+
+ /**
+ * generate a string that display all attributes of a todo task
+ * @return a string that describes the task
+ */
+ public String print(){
+ String str = "[T]";
+ if(isDone) {
+ str += "[Y]";
+ } else {
+ str += "[N]";
+ }
+ return str = str + " " + name;
+ }
+
+}
diff --git a/tutorials/gradleTutorial.md b/tutorials/gradleTutorial.md
index 08292b118d..2d60727f2b 100644
--- a/tutorials/gradleTutorial.md
+++ b/tutorials/gradleTutorial.md
@@ -30,10 +30,10 @@ As a developer, you write a _build file_ that describes the project. A build fil
git checkout master
git merge gradle
```
-1. Open the `build.gradle` file in an editor. Update the following code block to point to the main class (i.e., the one containing the `main` method) of your application. The code below assumes your main class is `seedu.duke.Duke`
+1. Open the `build.gradle` file in an editor. Update the following code block to point to the main class (i.e., the one containing the `main` method) of your application. The code below assumes your main class is `seedu.duke.duke.Duke`
```groovy
application {
- mainClassName = "seedu.duke.Duke"
+ mainClassName = "seedu.duke.duke.Duke"
}
```
1. To check if Gradle has been added to the project correctly, open a terminal window, navigate to the root directory of your project and run the command `gradlew run`. This should result in Gradle running the main method of your project.
@@ -146,7 +146,7 @@ By convention, java tests belong in `src/test/java` folder. Create a new `test/j
src
├─main
│ └─java
-│ └─seedu/duke/Duke.java
+│ └─seedu/duke/duke.Duke.java
└─test
└─java
└─seedu/duke/DukeTest.java
diff --git a/tutorials/javaFxTutorialPart1.md b/tutorials/javaFxTutorialPart1.md
index 561daeca43..d9c611fbb7 100644
--- a/tutorials/javaFxTutorialPart1.md
+++ b/tutorials/javaFxTutorialPart1.md
@@ -27,24 +27,31 @@ A JavaFX application is like a play you are directing. Instead of creating props
Update your `build.gradle` to include the following lines:
```groovy
-plugins {
- id 'java'
- id 'org.openjfx.javafxplugin' version '0.0.7'
-}
-
repositories {
mavenCentral()
}
-javafx {
- version = "11.0.2"
- modules = [ 'javafx.controls', 'javafx.fxml' ]
+dependencies {
+ String javaFxVersion = '11'
+
+ implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux'
+ implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux'
+ implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux'
+ implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux'
}
```
## Writing your first program
-As customary, let’s start off with a simple “Hello World” program. Modify your `Duke` class to extend `javafx.application.Application`. This requires you to override the `Application#start()` method and provide a concrete implementation. Notice that the method signature for `Application#start()` has a parameter `Stage`. This is the _primary stage_ that JavaFX provides.
+As customary, let’s start off with a simple “Hello World” program. Modify your `duke.Duke` class to extend `javafx.application.Application`. This requires you to override the `Application#start()` method and provide a concrete implementation. Notice that the method signature for `Application#start()` has a parameter `Stage`. This is the _primary stage_ that JavaFX provides.
```java
import javafx.application.Application;
@@ -52,7 +59,7 @@ import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
-public class Duke extends Application {
+public class duke.Duke extends Application {
// ...
@@ -73,7 +80,7 @@ Next, we create another Java class, `Launcher`, as an entry point to our applica
The `Launcher` class is reproduced below in its entirety.
```java
-import javafx.application.Application;
+import duke.Duke;import javafx.application.Application;
/**
* A launcher class to workaround classpath issues.
diff --git a/tutorials/javaFxTutorialPart2.md b/tutorials/javaFxTutorialPart2.md
index f24a0cd6ad..ade0b458cd 100644
--- a/tutorials/javaFxTutorialPart2.md
+++ b/tutorials/javaFxTutorialPart2.md
@@ -1,8 +1,8 @@
-# JavaFX Tutorial Part 2 - Creating a GUI for Duke
+# JavaFX Tutorial Part 2 - Creating a GUI for duke.Duke
-In this tutorial, we will be creating a GUI for Duke from scratch based on the following mockup.
+In this tutorial, we will be creating a GUI for duke.Duke from scratch based on the following mockup.
-![Mockup for Duke](assets/DukeMockup.png)
+![Mockup for duke.Duke](assets/DukeMockup.png)
## JavaFX controls
@@ -34,7 +34,7 @@ But how do we get the exact layout we want in the UI? JavaFX provides that funct
One way to obtain the layout in the mockup is as follows.
-![Duke's layout](assets/DukeSceneGraph.png)
+![duke.Duke's layout](assets/DukeSceneGraph.png)
To get that layout, we create a new `AnchorPane` and add our controls to it. Similarly, we create a new `VBox` to hold the contents of the `ScrollPane`. The code should look something like this:
@@ -49,7 +49,7 @@ import javafx.scene.layout.VBox;
import javafx.stage.Stage;
-public class Duke extends Application {
+public class duke.Duke extends Application {
private ScrollPane scrollPane;
private VBox dialogContainer;
@@ -88,7 +88,7 @@ public class Duke extends Application {
Run the application and you should see something like this:
-![Duke's raw layout](assets/RawLayout.png)
+![duke.Duke's raw layout](assets/RawLayout.png)
That is not what we were expecting, what did we forget to do?
@@ -106,7 +106,7 @@ Add the following code to the bottom of the `start` method. You'll have to add `
//...
//Step 2. Formatting the window to look as expected
- stage.setTitle("Duke");
+ stage.setTitle("duke.Duke");
stage.setResizable(false);
stage.setMinHeight(600.0);
stage.setMinWidth(400.0);
@@ -141,7 +141,7 @@ Add the following code to the bottom of the `start` method. You'll have to add `
Run the application again. It should now look like this:
-![Duke's Final layout](assets/FinalLayout.png)
+![duke.Duke's Final layout](assets/FinalLayout.png)
## Exercises
diff --git a/tutorials/javaFxTutorialPart3.md b/tutorials/javaFxTutorialPart3.md
index a9e1bdddd3..813079f3fa 100644
--- a/tutorials/javaFxTutorialPart3.md
+++ b/tutorials/javaFxTutorialPart3.md
@@ -8,7 +8,7 @@ Rather than to do everything in one try, let’s iterate and build up towards ou
JavaFX has an _event-driven architecture style_. As such, we programmatically define _handler_ methods to execute as a response to certain _events_. When an event is detected, JavaFX will call the respective handlers.
-For Duke, there are two events that we want to respond to, namely the user pressing `Enter` in the `TextField` and left-clicking the `Button`. These are the `onAction` event for the `TextField` and the `onMouseClicked` event for the `Button`.
+For duke.Duke, there are two events that we want to respond to, namely the user pressing `Enter` in the `TextField` and left-clicking the `Button`. These are the `onAction` event for the `TextField` and the `onMouseClicked` event for the `Button`.
For now, let’s have the application add a new `Label` with the text from the `TextField`. Update the `Main` class as follows. You'll need to add an `import javafx.scene.control.Label;` too.
```java
@@ -103,7 +103,7 @@ import javafx.scene.image.ImageView;
```
Next, add two images to the `main/resources/images` folder.
-For this tutorial, we have two images `DaUser.png` and `DaDuke.png` to represent the user avatar and Duke's avatar respectively but you can use any image you want.
+For this tutorial, we have two images `DaUser.png` and `DaDuke.png` to represent the user avatar and duke.Duke's avatar respectively but you can use any image you want.
Image|Filename
---|---
@@ -112,7 +112,7 @@ Image|Filename
```java
-public class Duke extends Application {
+public class duke.Duke extends Application {
// ...
private Image user = new Image(this.getClass().getResourceAsStream("/images/DaUser.png"));
private Image duke = new Image(this.getClass().getResourceAsStream("/images/DaDuke.png"));
@@ -124,7 +124,7 @@ Add a new method to handle user input:
```java
/**
* Iteration 2:
- * Creates two dialog boxes, one echoing user input and the other containing Duke's reply and then appends them to
+ * Creates two dialog boxes, one echoing user input and the other containing duke.Duke's reply and then appends them to
* the dialog container. Clears the user input after processing.
*/
private void handleUserInput() {
@@ -142,7 +142,7 @@ private void handleUserInput() {
* Replace this stub with your completed method.
*/
private String getResponse(String input) {
- return "Duke heard: " + input;
+ return "duke.Duke heard: " + input;
}
```
@@ -170,7 +170,7 @@ Run the program and see how it works.
## Iteration 3 – Adding custom behavior to DialogBox
-One additional benefit of defining a custom control is that we can add behavior specific to our `DialogBox`. Let’s add a method to flip a dialog box such that the image on the left to differentiate between user input and Duke’s output.
+One additional benefit of defining a custom control is that we can add behavior specific to our `DialogBox`. Let’s add a method to flip a dialog box such that the image on the left to differentiate between user input and duke.Duke’s output.
```java
/**
@@ -224,7 +224,7 @@ Run the application and play around with it.
![DialogBoxes Iteration 3](assets/DialogBoxesIteration3.png)
Congratulations!
-You have successfully implemented a fully functional GUI for Duke!
+You have successfully implemented a fully functional GUI for duke.Duke!
## Exercises
diff --git a/tutorials/javaFxTutorialPart4.md b/tutorials/javaFxTutorialPart4.md
index 0e0ab280c4..638505a99b 100644
--- a/tutorials/javaFxTutorialPart4.md
+++ b/tutorials/javaFxTutorialPart4.md
@@ -29,7 +29,7 @@ FXML is a XML-based language that allows us to define our user interface. Proper
The FXML snippet define a TextField similar to the one that we programmatically defined previous in Tutorial 2. Notice how concise FXML is compared to the plain Java version.
-Let's return to Duke and convert it to use FXML instead.
+Let's return to duke.Duke and convert it to use FXML instead.
# Rebuilding the Scene using FXML
@@ -101,14 +101,14 @@ We will get to that later.
## Using Controllers
-As part of the effort to separate the code handling Duke's logic and UI, let's _refactor_ the UI-related code to its own class.
+As part of the effort to separate the code handling duke.Duke's logic and UI, let's _refactor_ the UI-related code to its own class.
We call these UI classes _controllers_.
Let's implement the `MainWindow` controller class that we specified in `MainWindow.fxml`.
**MainWindow.java**
```java
-import javafx.fxml.FXML;
+import duke.Duke;import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
@@ -143,7 +143,7 @@ public class MainWindow extends AnchorPane {
}
/**
- * Creates two dialog boxes, one echoing user input and the other containing Duke's reply and then appends them to
+ * Creates two dialog boxes, one echoing user input and the other containing duke.Duke's reply and then appends them to
* the dialog container. Clears the user input after processing.
*/
@FXML
@@ -168,7 +168,7 @@ Similarly, methods like private methods like `handleUserInput` can be used in FX
## Using FXML in our application
-Let's create a new `Main` class as the bridge between the existing logic in `Duke` and the UI in `MainWindow`.
+Let's create a new `Main` class as the bridge between the existing logic in `duke.Duke` and the UI in `MainWindow`.
**Main.java**
```java
@@ -182,7 +182,7 @@ import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/**
- * A GUI for Duke using FXML.
+ * A GUI for duke.Duke using FXML.
*/
public class Main extends Application {
diff --git a/tutorials/textUiTestingTutorial.md b/tutorials/textUiTestingTutorial.md
index f397d76aef..b421fa37da 100644
--- a/tutorials/textUiTestingTutorial.md
+++ b/tutorials/textUiTestingTutorial.md
@@ -13,7 +13,7 @@
del ACTUAL.TXT
REM compile the code into the bin folder
- javac -cp ..\src -Xlint:none -d ..\bin ..\src\main\java\Duke.java
+ javac -cp ..\src -Xlint:none -d ..\bin ..\src\main\java\duke.Duke.java
IF ERRORLEVEL 1 (
echo ********** BUILD FAILURE **********
exit /b 1
@@ -21,7 +21,7 @@
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.Duke < input.txt > ACTUAL.TXT
REM compare the output to the expected output
FC ACTUAL.TXT EXPECTED.TXT
@@ -44,14 +44,14 @@
fi
# compile the code into the bin folder, terminates if error occurred
- if ! javac -cp ../src -Xlint:none -d ../bin ../src/main/java/Duke.java
+ if ! javac -cp ../src -Xlint:none -d ../bin ../src/main/java/duke.Duke.java
then
echo "********** BUILD FAILURE **********"
exit 1
fi
# 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.Duke < input.txt > ACTUAL.TXT
# compare the output to the expected output
diff ACTUAL.TXT EXPECTED.TXT