diff --git a/README.md b/README.md
index 0dd8f7fb21..fcb2dbc508 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,8 @@
-# Duke project template
+# Duke project
-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.
+This is a project named after the Java mascot _Duke_. Given below are instructions on how to use the interactive Duke bot.
+# User Guide
## Setting up in Intellij
Prerequisites: JDK 11, update Intellij to the most recent version.
@@ -12,12 +13,168 @@ Prerequisites: JDK 11, update Intellij to the most recent version.
1. Select the project directory, and click `OK`.
1. If there are any further prompts, accept the defaults.
1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
-1. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()`. If the setup is correct, you should see something like the below:
- ```
- Hello from
- ____ _
- | _ \ _ _| | _____
- | | | | | | | |/ / _ \
- | |_| | |_| | < __/
- |____/ \__,_|_|\_\___|
- ```
+1. After that, locate the `src/main/java/Launcher.java` file, right-click it, and choose `Run Launcher.main()`.
+1. Refer to the Features below for details of each command.
+
+## Features
+
+***NOTE: Words in UPPER_CASE are the parameters to be supplied by the user.***
+
+### Adding a task:
+
+#### Adding a ToDo task: `todo`
+
+Adds a new ToDo task to the Duke's tasklist.
+
+Format: `todo CONTENT`
+
+- The content field must be provided.
+
+Examples:
+
+- `todo hello`
+- `todo read book`
+
+
+
+#### Adding a Deadline task: `deadline`
+
+Adds a new Deadline task to the Duke's tasklist.
+
+Format: `deadline CONTENT /by DATE_AND_TIME`
+
+- The date and time must be in the format DD/MM/YYYY HH:MM
+- Both fields must be provided.
+
+Examples:
+- `deadline read book /by 12/12/2020 18:30`
+- `deadline return book /by 10/10/2020 10:00`
+
+
+#### Adding an Event task: `event`
+
+Adds a new Event task to the Duke's tasklist.
+
+Format: `event CONTENT /at DATE_AND_TIME`
+
+- The date and time must be in the format DD/MM/YYYY HH:MM
+- Both fields must be provided.
+
+Examples:
+- `event go for meeting /at 12/10/2020 18:00`
+- `event meet groupmates /at 10/10/2020 10:30`
+
+
+
+### Listing all tasks: `list`
+
+Shows a list of all tasks in the Duke's tasklist.
+
+Format: `list`
+
+
+### Marking a task as done: `done`
+
+Marks an existing task in the Duke's tasklist as done.
+
+Format: `done INDEX`
+
+- Updates the task status to done for the task at the specified `INDEX`
+- The index refers to the index number shown in the displayed tasklist.
+- The index **must be a positive integer**.
+
+Examples:
+- `list` followed by `done 3` marks the 3rd task in the tasklist as done.
+
+
+### Deleting a task: `delete`
+
+Deletes an existing task from the Duke's tasklist.
+
+Format: `delete INDEX`
+
+- Deletes the task at the specified `INDEX`
+- The index refers to the index number shown in the displayed tasklist.
+- The index **must be a positive integer**.
+
+Examples:
+- `list` followed by `delete 1` deletes the 1st task in the tasklist.
+
+
+### Finding a task by content: `find`
+
+Finds tasks with contents that contain the given keyword/s.
+
+Format: `find KEYWORD OR KEYWORDS`
+
+- The search is **case-sensitive**.
+- Only the contents of the tasks are searched.
+- The following tasks will be returned:
+ 1. content matching the keyword/s
+ 2. the keyword/s form a part of the content
+
+Examples:
+- `find read` returns both task with content `read book` and task with content `read` from the tasklist.
+
+
+
+### Editing a task: `edit`
+
+
+
+#### Editing a task's content: `edit_content`
+
+Edits an existing task's content in the Duke's tasklist.
+
+Format: `edit INDEX content NEW_CONTENT`
+
+- Edits the content of the task at the specified `INDEX`
+- The index refers to the index number shown in the displayed tasklist.
+- The index **must be a positive integer**.
+- Existing content will be updated to `NEW_CONTENT`.
+- All fields must be provided.
+
+Examples:
+- `edit 1 content read new book` edits the content of the 1st task in the tasklist to `read new book`.
+
+
+
+#### Editing a task's date and time: `edit_datetime`
+
+Edits an existing task's date and time in the Duke's tasklist.
+
+Format: `edit INDEX datetime NEW_DATETIME`
+
+- Edit the date and time of the task at the specified `INDEX`
+- The index refers to the index number shown in the displayed tasklist.
+- The index **must be a positive integer**.
+- The date and time must be in the format DD/MM/YYYY HH:MM
+- Existing date and time will be updated to `NEW_DATETIME`.
+- All fields must be provided.
+
+Examples:
+- `edit 2 datetime 12/12/2020 18:30` edits the date and time of the 2nd task in the tasklist to `12/12/2020 18:30`.
+
+
+### Exiting the program: `bye`
+
+Saves the tasklist's changes to the file at relative filepath `/data/duke.txt`.
+
+Format: `bye`
+
+
+
+##Command Summary
+
+
+Action | Format, Examples
+------------ | -------------
+Add | ToDo Task `todo CONTENT` e.g. `todo hello` Deadline Task `deadline CONTENT /by DATE_AND_TIME` e.g. `deadline read book /by 12/12/2020 18:30` Event Task `event CONTENT /at DATE_AND_TIME` e.g. `event go for meeting /at 12/10/2020 18:00`
+List | `list`
+Done | `done INDEX` e.g. `done 3`
+Delete | `delete INDEX` e.g. `delete 1`
+Find | `find KEYWORD OR KEYWORDS` e.g. `find read`
+Edit | Edit content `edit INDEX content NEW_CONTENT` e.g. `edit 1 content read new book`
Edit date and time `edit INDEX datetime NEW_DATETIME` e.g. `edit 2 datetime 12/12/2020 18:30`
+Exit | `bye`
+
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000000..10b23a9eec
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,61 @@
+plugins {
+ id 'java'
+ id 'application'
+ id 'checkstyle'
+ id 'com.github.johnrengelman.shadow' version '5.1.0'
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0'
+ testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0'
+
+ 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'
+}
+
+test {
+ useJUnitPlatform()
+
+ testLogging {
+ events "passed", "skipped", "failed"
+
+ showExceptions true
+ exceptionFormat "full"
+ showCauses true
+ showStackTraces true
+ showStandardStreams = false
+ }
+}
+
+application {
+ mainClassName = "ip.src.main.java.Launcher"
+}
+
+shadowJar {
+ archiveBaseName = "duke"
+ archiveClassifier = null
+}
+
+checkstyle {
+ toolVersion = '8.29'
+}
+
+run{
+ standardInput = System.in
+}
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
new file mode 100644
index 0000000000..502fbd3a58
--- /dev/null
+++ b/config/checkstyle/checkstyle.xml
@@ -0,0 +1,398 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml
new file mode 100644
index 0000000000..dcaa1af3c3
--- /dev/null
+++ b/config/checkstyle/suppressions.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data/duke.txt b/data/duke.txt
new file mode 100644
index 0000000000..1b23f50bc0
--- /dev/null
+++ b/data/duke.txt
@@ -0,0 +1,3 @@
+E | 1 | bye | 12/02/2019 18:00
+E | 0 | read | 12/12/2020 18:40
+D | 0 | read book | 12/12/2020 18:20
diff --git a/docs/README.md b/docs/README.md
index fd44069597..83f3829b2d 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,20 +1,180 @@
+# Duke project
+
+This is a project named after the Java mascot Duke. Given below are instructions on how to use the interactive Duke bot.
+
# User Guide
+## Setting up in Intellij
+
+Prerequisites: JDK 11, update Intellij to the most recent version.
+
+1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first)
+1. Open the project into Intellij as follows:
+ 1. Click `Open`.
+ 1. Select the project directory, and click `OK`.
+ 1. If there are any further prompts, accept the defaults.
+1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
+1. After that, locate the `src/main/java/Launcher.java` file, right-click it, and choose `Run Launcher.main()`.
+1. Refer to the Features below for details of each command.
+
+## Features
+
+***NOTE: Words in UPPER_CASE are the parameters to be supplied by the user.***
+
+### Adding a task:
+
+#### Adding a ToDo task: `todo`
+
+Adds a new ToDo task to the Duke's tasklist.
+
+Format: `todo CONTENT`
+
+- The content field must be provided.
+
+Examples:
+
+- `todo hello`
+- `todo read book`
+
+
+
+#### Adding a Deadline task: `deadline`
+
+Adds a new Deadline task to the Duke's tasklist.
+
+Format: `deadline CONTENT /by DATE_AND_TIME`
+
+- The date and time must be in the format DD/MM/YYYY HH:MM
+- Both fields must be provided.
+
+Examples:
+- `deadline read book /by 12/12/2020 18:30`
+- `deadline return book /by 10/10/2020 10:00`
+
+
+#### Adding an Event task: `event`
+
+Adds a new Event task to the Duke's tasklist.
+
+Format: `event CONTENT /at DATE_AND_TIME`
+
+- The date and time must be in the format DD/MM/YYYY HH:MM
+- Both fields must be provided.
+
+Examples:
+- `event go for meeting /at 12/10/2020 18:00`
+- `event meet groupmates /at 10/10/2020 10:30`
+
+
+
+### Listing all tasks: `list`
+
+Shows a list of all tasks in the Duke's tasklist.
+
+Format: `list`
+
+
+### Marking a task as done: `done`
+
+Marks an existing task in the Duke's tasklist as done.
+
+Format: `done INDEX`
+
+- Updates the task status to done for the task at the specified `INDEX`
+- The index refers to the index number shown in the displayed tasklist.
+- The index **must be a positive integer**.
+
+Examples:
+- `list` followed by `done 3` marks the 3rd task in the tasklist as done.
+
+
+### Deleting a task: `delete`
+
+Deletes an existing task from the Duke's tasklist.
+
+Format: `delete INDEX`
+
+- Deletes the task at the specified `INDEX`
+- The index refers to the index number shown in the displayed tasklist.
+- The index **must be a positive integer**.
+
+Examples:
+- `list` followed by `delete 1` deletes the 1st task in the tasklist.
+
+
+### Finding a task by content: `find`
+
+Finds tasks with contents that contain the given keyword/s.
+
+Format: `find KEYWORD OR KEYWORDS`
+
+- The search is **case-sensitive**.
+- Only the contents of the tasks are searched.
+- The following tasks will be returned:
+ 1. content matching the keyword/s
+ 2. the keyword/s form a part of the content
+
+Examples:
+- `find read` returns both task with content `read book` and task with content `read` from the tasklist.
+
+
+
+### Editing a task: `edit`
+
+
+
+#### Editing a task's content: `edit_content`
+
+Edits an existing task's content in the Duke's tasklist.
+
+Format: `edit INDEX content NEW_CONTENT`
+
+- Edits the content of the task at the specified `INDEX`
+- The index refers to the index number shown in the displayed tasklist.
+- The index **must be a positive integer**.
+- Existing content will be updated to `NEW_CONTENT`.
+- All fields must be provided.
+
+Examples:
+- `edit 1 content read new book` edits the content of the 1st task in the tasklist to `read new book`.
+
+
+
+#### Editing a task's date and time: `edit_datetime`
+
+Edits an existing task's date and time in the Duke's tasklist.
+
+Format: `edit INDEX datetime NEW_DATETIME`
+
+- Edit the date and time of the task at the specified `INDEX`
+- The index refers to the index number shown in the displayed tasklist.
+- The index **must be a positive integer**.
+- The date and time must be in the format DD/MM/YYYY HH:MM
+- Existing date and time will be updated to `NEW_DATETIME`.
+- All fields must be provided.
+
+Examples:
+- `edit 2 datetime 12/12/2020 18:30` edits the date and time of the 2nd task in the tasklist to `12/12/2020 18:30`.
-## Features
+
+### Exiting the program: `bye`
-### Feature 1
-Description of feature.
+Saves the tasklist's changes to the file at relative filepath `/data/duke.txt`.
-## Usage
+Format: `bye`
-### `Keyword` - Describe action
-Describe action and its outcome.
+
+##Command Summary
-Example of usage:
-`keyword (optional arguments)`
+Action | Format, Examples
+------------ | -------------
+Add | ToDo Task `todo CONTENT` e.g. `todo hello` Deadline Task `deadline CONTENT /by DATE_AND_TIME` e.g. `deadline read book /by 12/12/2020 18:30` Event Task `event CONTENT /at DATE_AND_TIME` e.g. `event go for meeting /at 12/10/2020 18:00`
+List | `list`
+Done | `done INDEX` e.g. `done 3`
+Delete | `delete INDEX` e.g. `delete 1`
+Find | `find KEYWORD OR KEYWORDS` e.g. `find read`
+Edit | Edit content `edit INDEX content NEW_CONTENT` e.g. `edit 1 content read new book`
Edit date and time `edit INDEX datetime NEW_DATETIME` e.g. `edit 2 datetime 12/12/2020 18:30`
+Exit | `bye`
-Expected outcome:
-`outcome`
diff --git a/docs/Ui.png b/docs/Ui.png
new file mode 100644
index 0000000000..a0aa456a48
Binary files /dev/null and b/docs/Ui.png differ
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 0000000000..c4192631f2
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-cayman
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..f3d88b1c2f
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..b7c8c5dbf5
--- /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-6.2-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000000..2fe81a7d95
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## 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" "-Xms64m"'
+
+# 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 or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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=`expr $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"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000..62bd9b9cce
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@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 Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@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" "-Xms64m"
+
+@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/src/main/A_MoreOop.java b/src/main/A_MoreOop.java
new file mode 100644
index 0000000000..bcde1396cd
--- /dev/null
+++ b/src/main/A_MoreOop.java
@@ -0,0 +1,131 @@
+package ip.src.main;
+
+import ip.src.main.java.*;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+
+/** A-More OOP class that demonstrates OOP by having classes such as Task, Event etc.
+ *
+ */
+
+public class A_MoreOop {
+
+ /** Returns a Duke bot that has loaded the tasks from the file given.
+ *
+ * @param filePath Location of the file with the tasks information.
+ * @param bot The Duke bot to be updated with the tasks from the file.
+ * @throws FileNotFoundException
+ */
+
+ private static void createBot(String filePath, Duke bot) throws FileNotFoundException {
+ File f = new File(filePath); // create a File for the given file path
+ Scanner s = new Scanner(f); // create a Scanner using the File as the source
+ Storage storage = new Storage(filePath, bot);
+ Task newTask = new Task("");
+
+ while (s.hasNext()) {
+ storage.loadTask(s.nextLine());
+ }
+
+ }
+
+ /**
+ * Overwrites the file with the updated tasks everytime a user gives a command/input.
+ *
+ * @param filePath The location of the file to be updated.
+ * @param bot The bot with the new tasks to be written to the file.
+ * @throws IOException
+ */
+ private static void updateFile(String filePath, Duke bot) throws IOException {
+ Storage storage = new Storage(filePath, bot);
+ storage.updateFile();
+ }
+
+ /**
+ * Main method that greets users and interacts with users.
+ */
+ public static void main(String[] args) throws DukeException {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Duke bot = new Duke();
+
+ try {
+ File f = new File("data/duke.txt");
+ f.getParentFile().mkdirs();
+ if (f.createNewFile()) {
+ System.out.println("File created");
+ } else {
+ createBot("data/duke.txt", bot);
+ }
+ } catch (IOException e) {
+ System.out.println("Error in creating file");
+
+ }
+
+ Scanner sc = new Scanner(System.in);
+ String input = sc.nextLine();
+ Parser parser = new Parser();
+ Ui ui = new Ui(bot);
+
+ while (!(input.equals("bye"))) {
+ if (input.equals("list")) {
+ bot.printList();
+ } else {
+ String command = parser.getCommand(input);
+ try {
+ if (command.equals("done")) {
+ int id = parser.getId(input);
+ ui.doneCommand(id);
+
+ } else if (command.equals("todo")) {
+ try {
+ input = parser.toDoTask(input);
+ ui.toDoCommand(input);
+
+ } catch (Exception e) {
+ throw new DukeException(("OOPS!!! The description cannot be empty."));
+ }
+ } else if (command.equals("event")) {
+ String content = parser.eventTaskContent(input);
+ String at = parser.eventTaskAt(input);
+ ui.eventCommand(content, at);
+
+ } else if (command.equals("deadline")) {
+ String content = parser.deadlineTaskContent(input);
+ String by = parser.deadlineTaskBy(input);
+ ui.deadlineCommand(content, by);
+
+ } else if(command.equals("delete")) {
+ int id = parser.getId(input);
+ ui.deleteCommand(id);
+
+ } else {
+ throw new DukeException("OOPS!!! I'm sorry, but I don't know what that means :-{");
+ }
+ } catch (DukeException e1) {
+ System.out.println(e1);
+
+ }
+ }
+ try {
+ updateFile("data/duke.txt", bot);
+ } catch (IOException e) {
+ System.out.println("Unable to update file");
+ }
+ input = sc.nextLine();
+ }
+
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
+
+
+
+
+
+
+
diff --git a/src/main/Level1_9/Level_1.java b/src/main/Level1_9/Level_1.java
new file mode 100644
index 0000000000..e4c3b76b05
--- /dev/null
+++ b/src/main/Level1_9/Level_1.java
@@ -0,0 +1,21 @@
+package Level1_9;
+import ip.src.main.java.Duke;
+
+import java.util.Scanner;
+
+public class Level_1 {
+ public static void main(String[] args) {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Scanner sc = new Scanner(System.in);
+ String input = sc.next();
+ Duke bot = new Duke();
+
+ while(!(input.equals("bye"))){
+ bot.echo(input);
+ input = sc.next();
+ }
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
diff --git a/src/main/Level1_9/Level_2.java b/src/main/Level1_9/Level_2.java
new file mode 100644
index 0000000000..13783cbe85
--- /dev/null
+++ b/src/main/Level1_9/Level_2.java
@@ -0,0 +1,29 @@
+package Level1_9;
+import ip.src.main.java.Duke;
+import ip.src.main.java.Task;
+
+import java.util.Scanner;
+
+public class Level_2 {
+ public static void main(String[] args) {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Scanner sc = new Scanner(System.in);
+ String input = sc.nextLine();
+ Duke bot = new Duke();
+ //int counter = 1;
+
+ while(!(input.equals("bye"))) {
+ if (input.equals("list")) {
+ bot.printList();
+ }else{
+ Task newTask = new Task(input);
+ bot.addToList(newTask);
+ //counter++;
+ }
+ input = sc.nextLine();
+ }
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
diff --git a/src/main/Level1_9/Level_3.java b/src/main/Level1_9/Level_3.java
new file mode 100644
index 0000000000..b0d3f29c8a
--- /dev/null
+++ b/src/main/Level1_9/Level_3.java
@@ -0,0 +1,36 @@
+package Level1_9;
+import ip.src.main.java.Duke;
+import ip.src.main.java.Task;
+
+import java.util.Scanner;
+
+public class Level_3 {
+ public static void main(String[] args) {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Scanner sc = new Scanner(System.in);
+ String input = sc.nextLine();
+ Duke bot = new Duke();
+ //int counter = 1;
+
+ while(!(input.equals("bye"))) {
+ if (input.equals("list")) {
+ bot.printList();
+ }else{
+ String command = input.split(" ")[0];
+ if(command.equals("done")){
+ int id = Integer.valueOf(input.split(" ")[1]);
+ bot.markTaskAsDone(id);
+
+ }else {
+ Task newTask = new Task(input);
+ bot.addToList(newTask);
+ //counter++;
+ }
+ }
+ input = sc.nextLine();
+ }
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
diff --git a/src/main/Level1_9/Level_4.java b/src/main/Level1_9/Level_4.java
new file mode 100644
index 0000000000..6cd11a5b58
--- /dev/null
+++ b/src/main/Level1_9/Level_4.java
@@ -0,0 +1,52 @@
+package Level1_9;
+import ip.src.main.java.Deadline;
+import ip.src.main.java.Duke;
+import ip.src.main.java.Event;
+import ip.src.main.java.ToDo;
+
+import java.util.Scanner;
+
+public class Level_4 {
+ public static void main(String[] args) {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Scanner sc = new Scanner(System.in);
+ String input = sc.nextLine();
+ Duke bot = new Duke();
+ //int counter = 1;
+
+ while(!(input.equals("bye"))) {
+ if (input.equals("list")) {
+ bot.printList();
+ }else{
+ String command = input.split(" ")[0];
+ if(command.equals("done")){
+ int id = Integer.valueOf(input.split(" ")[1]);
+ bot.markTaskAsDone(id);
+
+ }else if(command.equals("todo")) {
+ input = input.split(" ",2)[1];
+ ToDo newTask = new ToDo(input);
+ bot.addToList(newTask);
+ //counter++;
+ }else if(command.equals("event")){
+ input = input.split(" ",2)[1];
+ String content = input.split("/at")[0];
+ String at = input.split("/at")[1];
+ Event newTask = new Event(content,at);
+ bot.addToList(newTask);
+ }else{
+ input = input.split(" ",2)[1];
+ String content = input.split("/by")[0];
+ String by= input.split("/by")[1];
+ Deadline newTask = new Deadline(content,by);
+ bot.addToList(newTask);
+ }
+
+ }
+ input = sc.nextLine();
+ }
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
diff --git a/src/main/Level1_9/Level_5.java b/src/main/Level1_9/Level_5.java
new file mode 100644
index 0000000000..26b08458dc
--- /dev/null
+++ b/src/main/Level1_9/Level_5.java
@@ -0,0 +1,62 @@
+package Level1_9;
+import ip.src.main.java.*;
+
+import java.util.Scanner;
+
+public class Level_5 {
+ public static void main(String[] args) throws DukeException {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Scanner sc = new Scanner(System.in);
+ String input = sc.nextLine();
+ Duke bot = new Duke();
+ //int counter = 1;
+
+ while (!(input.equals("bye"))) {
+ if (input.equals("list")) {
+ bot.printList();
+ } else {
+ String command = input.split(" ")[0];
+ try {
+ if (command.equals("done")) {
+ int id = Integer.valueOf(input.split(" ")[1]);
+ bot.markTaskAsDone(id);
+
+ } else if (command.equals("todo")) {
+ try {
+ input = input.split(" ", 2)[1];
+ ToDo newTask = new ToDo(input);
+ bot.addToList(newTask);
+ //counter++;
+ } catch (Exception e) {
+ throw new DukeException(("OOPS!!! The description cannot be empty."));
+ }
+ } else if (command.equals("event")) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/at")[0];
+ String at = input.split("/at")[1];
+ Event newTask = new Event(content, at);
+ bot.addToList(newTask);
+ } else if (command.equals("deadline")) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/by")[0];
+ String by = input.split("/by")[1];
+ Deadline newTask = new Deadline(content, by);
+ bot.addToList(newTask);
+ } else {
+ throw new DukeException("OOPS!!! I'm sorry, but I don't know what that means :-{");
+ }
+ } catch (DukeException e1) {
+ System.out.println(e1);
+
+ }
+ }
+
+ input = sc.nextLine();
+ }
+
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
+
diff --git a/src/main/Level1_9/Level_6.java b/src/main/Level1_9/Level_6.java
new file mode 100644
index 0000000000..326a361d75
--- /dev/null
+++ b/src/main/Level1_9/Level_6.java
@@ -0,0 +1,68 @@
+package Level1_9;
+import ip.src.main.java.*;
+
+import java.util.Scanner;
+
+public class Level_6 {
+ public static void main(String[] args) throws DukeException {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Scanner sc = new Scanner(System.in);
+ String input = sc.nextLine();
+ Duke bot = new Duke();
+ //int counter = 1;
+
+ while (!(input.equals("bye"))) {
+ if (input.equals("list")) {
+ bot.printList();
+ } else {
+ String command = input.split(" ")[0];
+ try {
+ if (command.equals("done")) {
+ int id = Integer.valueOf(input.split(" ")[1]);
+ bot.markTaskAsDone(id);
+
+ } else if (command.equals("todo")) {
+ try {
+ input = input.split(" ", 2)[1];
+ ToDo newTask = new ToDo(input);
+ bot.addToList(newTask);
+ //counter++;
+ } catch (Exception e) {
+ throw new DukeException(("OOPS!!! The description cannot be empty."));
+ }
+ } else if (command.equals("event")) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/at")[0];
+ String at = input.split("/at")[1];
+ Event newTask = new Event(content, at);
+ bot.addToList(newTask);
+ } else if (command.equals("deadline")) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/by")[0];
+ String by = input.split("/by")[1];
+ Deadline newTask = new Deadline(content, by);
+ bot.addToList(newTask);
+ }else if(command.equals("delete")){
+ int id = Integer.valueOf(input.split(" ")[1]);
+ bot.deleteTask(id);
+
+ } else {
+ throw new DukeException("OOPS!!! I'm sorry, but I don't know what that means :-{");
+ }
+ } catch (DukeException e1) {
+ System.out.println(e1);
+
+ }
+ }
+
+ input = sc.nextLine();
+ }
+
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
+
+
+
diff --git a/src/main/Level1_9/Level_7.java b/src/main/Level1_9/Level_7.java
new file mode 100644
index 0000000000..29ece14bc8
--- /dev/null
+++ b/src/main/Level1_9/Level_7.java
@@ -0,0 +1,135 @@
+package Level1_9;
+import ip.src.main.java.*;
+
+import java.io.IOException;
+import java.util.Scanner;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+
+public class Level_7 {
+
+ private static void createBot(String filePath, Duke bot) throws FileNotFoundException {
+ File f = new File(filePath); // create a File for the given file path
+ Scanner s = new Scanner(f); // create a Scanner using the File as the source
+ Task newTask = new Task("");
+ while (s.hasNext()) {
+ String[] taskData = s.nextLine().split(" \\| ");
+ String type = taskData[0];
+ String doneStatus = taskData[1];
+ if (type.equals("T")) {
+ String details = taskData[2];
+ newTask = new ToDo(details);
+ bot.addToBot(newTask);
+
+ } else if (type.equals("E")) {
+ String content = taskData[2];
+ String at = taskData[3];
+ newTask = new Event(content, at);
+ bot.addToBot(newTask);
+
+ } else {
+ String content = taskData[2];
+ String by = taskData[3];
+ newTask = new Deadline(content, by);
+ bot.addToBot(newTask);
+ }
+
+ if (doneStatus == " 1 ") {
+ newTask.markDone();
+ }
+
+ }
+ }
+
+
+ private static void updateFile(String filePath, Duke bot) throws IOException {
+ FileWriter fw = new FileWriter(filePath);
+ for(Task element:bot.list.list) {
+ fw.write(element.toString() + "\n");
+
+ }
+ fw.close();
+ }
+ public static void main(String[] args) throws DukeException {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Duke bot = new Duke();
+ try{
+ File f = new File("data/duke.txt");
+ f.getParentFile().mkdirs();
+ if(f.createNewFile()){
+ System.out.println("File created");
+ }else {
+ createBot("data/duke.txt", bot);
+ }
+ }catch (IOException e){
+ System.out.println("Error in creating file");
+
+
+ }
+ Scanner sc = new Scanner(System.in);
+ String input = sc.nextLine();
+
+ while (!(input.equals("bye"))) {
+ if (input.equals("list")) {
+ bot.printList();
+ } else {
+ String command = input.split(" ")[0];
+ try {
+ if (command.equals("done")) {
+ int id = Integer.valueOf(input.split(" ")[1]);
+ bot.markTaskAsDone(id);
+
+ } else if (command.equals("todo")) {
+ try {
+ input = input.split(" ", 2)[1];
+ ToDo newTask = new ToDo(input);
+ bot.addToList(newTask);
+ //counter++;
+ } catch (Exception e) {
+ throw new DukeException(("OOPS!!! The description cannot be empty."));
+ }
+ } else if (command.equals("event")) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/at")[0];
+ String at = input.split("/at")[1];
+ Event newTask = new Event(content, at);
+ bot.addToList(newTask);
+ } else if (command.equals("deadline")) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/by")[0];
+ String by = input.split("/by")[1];
+ Deadline newTask = new Deadline(content, by);
+ bot.addToList(newTask);
+ }else if(command.equals("delete")){
+ int id = Integer.valueOf(input.split(" ")[1]);
+ bot.deleteTask(id);
+
+ } else {
+ throw new DukeException("OOPS!!! I'm sorry, but I don't know what that means :-{");
+ }
+ } catch (DukeException e1) {
+ System.out.println(e1);
+
+ }
+ }
+ try {
+ updateFile("data/duke.txt", bot);
+ }catch (IOException e) {
+ System.out.println("Unable to update file");
+ }
+ input = sc.nextLine();
+ }
+
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
+
+
+
+
+
+
+
diff --git a/src/main/Level1_9/Level_8.java b/src/main/Level1_9/Level_8.java
new file mode 100644
index 0000000000..f9f23f89cc
--- /dev/null
+++ b/src/main/Level1_9/Level_8.java
@@ -0,0 +1,137 @@
+package Level1_9;
+import ip.src.main.java.*;
+
+import java.io.IOException;
+import java.util.Scanner;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.time.LocalDate;
+
+public class Level_8 {
+
+ private static void createBot(String filePath, Duke bot) throws FileNotFoundException {
+ File f = new File(filePath); // create a File for the given file path
+ Scanner s = new Scanner(f); // create a Scanner using the File as the source
+ Task newTask = new Task("");
+ while (s.hasNext()) {
+ String[] taskData = s.nextLine().split(" \\| ");
+ String type = taskData[0];
+ String doneStatus = taskData[1];
+ if (type.equals("T")) {
+ String details = taskData[2];
+ newTask = new ToDo(details);
+ bot.addToBot(newTask);
+
+ } else if (type.equals("E")) {
+ String content = taskData[2];
+ String at = taskData[3];
+ newTask = new Event(content, at);
+ bot.addToBot(newTask);
+
+ } else {
+ String content = taskData[2];
+ String by = taskData[3];
+ newTask = new Deadline(content, by);
+ bot.addToBot(newTask);
+ }
+
+ if (doneStatus == " 1 ") {
+ newTask.markDone();
+ }
+
+ }
+ }
+
+
+ private static void updateFile(String filePath, Duke bot) throws IOException {
+ FileWriter fw = new FileWriter(filePath);
+ for(Task element:bot.list.list) {
+ fw.write(element.toString() + "\n");
+
+ }
+ fw.close();
+ }
+ public static void main(String[] args) throws DukeException {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Duke bot = new Duke();
+ try{
+ File f = new File("data/duke.txt");
+ f.getParentFile().mkdirs();
+ if(f.createNewFile()){
+ System.out.println("File created");
+ }else {
+ createBot("data/duke.txt", bot);
+ }
+ }catch (IOException e){
+ System.out.println("Error in creating file");
+
+
+ }
+ Scanner sc = new Scanner(System.in);
+ String input = sc.nextLine();
+
+ while (!(input.equals("bye"))) {
+ if (input.equals("list")) {
+ bot.printList();
+ } else {
+ String command = input.split(" ")[0];
+ try {
+ if (command.equals("done")) {
+ int id = Integer.valueOf(input.split(" ")[1]);
+ bot.markTaskAsDone(id);
+
+ } else if (command.equals("todo")) {
+ try {
+ input = input.split(" ", 2)[1];
+ ToDo newTask = new ToDo(input);
+ bot.addToList(newTask);
+ //counter++;
+ } catch (Exception e) {
+ throw new DukeException(("OOPS!!! The description cannot be empty."));
+ }
+ } else if (command.equals("event")) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/at")[0];
+ String at = input.split(" /at ")[1];
+ Event newTask = new Event(content, at);
+ bot.addToList(newTask);
+ } else if (command.equals("deadline")) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/by")[0];
+ String by = input.split(" /by ")[1];
+ System.out.println(by);
+ Deadline newTask = new Deadline(content, by);
+ bot.addToList(newTask);
+ }else if(command.equals("delete")){
+ int id = Integer.valueOf(input.split(" ")[1]);
+ bot.deleteTask(id);
+
+ } else {
+ throw new DukeException("OOPS!!! I'm sorry, but I don't know what that means :-{");
+ }
+ } catch (DukeException e1) {
+ System.out.println(e1);
+
+ }
+ }
+ try {
+ updateFile("data/duke.txt", bot);
+ }catch (IOException e) {
+ System.out.println("Unable to update file");
+ }
+ input = sc.nextLine();
+ }
+
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
+
+
+
+
+
+
+
diff --git a/src/main/Level1_9/Level_9.java b/src/main/Level1_9/Level_9.java
new file mode 100644
index 0000000000..c827ab2114
--- /dev/null
+++ b/src/main/Level1_9/Level_9.java
@@ -0,0 +1,130 @@
+package Level1_9;
+
+import ip.src.main.java.*;
+
+import java.io.IOException;
+import java.util.Scanner;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+
+/** A-More OOP class that demonstrates OOP by having classes such as Task, Event etc.
+ *
+ */
+
+public class Level_9 {
+
+ /** Returns a Duke bot that has loaded the tasks from the file given.
+ *
+ * @param filePath Location of the file with the tasks information.
+ * @param bot The Duke bot to be updated with the tasks from the file.
+ * @throws FileNotFoundException
+ */
+
+ private static void createBot(String filePath, Duke bot) throws FileNotFoundException {
+ File f = new File(filePath); // create a File for the given file path
+ Scanner s = new Scanner(f); // create a Scanner using the File as the source
+ Storage storage = new Storage(filePath, bot);
+ Task newTask = new Task("");
+
+ while (s.hasNext()) {
+ storage.loadTask(s.nextLine());
+ }
+
+ }
+
+ /**
+ * Overwrites the file with the updated tasks everytime a user gives a command/input.
+ *
+ * @param filePath The location of the file to be updated.
+ * @param bot The bot with the new tasks to be written to the file.
+ * @throws IOException
+ */
+ private static void updateFile(String filePath, Duke bot) throws IOException {
+ Storage storage = new Storage(filePath, bot);
+ storage.updateFile();
+ }
+
+ public static void main(String[] args) throws DukeException {
+ System.out.println("Hello! I'm Duke");
+ System.out.println("What can I do for you?");
+ Duke bot = new Duke();
+
+ try{
+ File f = new File("data/duke.txt");
+ f.getParentFile().mkdirs();
+ if(f.createNewFile()){
+ System.out.println("File created");
+ }else {
+ createBot("data/duke.txt", bot);
+ }
+ }catch (IOException e){
+ System.out.println("Error in creating file");
+
+ }
+
+ Scanner sc = new Scanner(System.in);
+ String input = sc.nextLine();
+ Parser parser = new Parser();
+ Ui ui = new Ui(bot);
+
+ while (!(input.equals("bye"))) {
+ if (input.equals("list")) {
+ bot.printList();
+ } else {
+ String command = parser.getCommand(input);
+ try {
+ if (command.equals("done")) {
+ int id = parser.getId(input);
+ ui.doneCommand(id);
+
+ } else if (command.equals("find")) {
+ String keyword = parser.getKeyword(input);
+ bot.findMatchingTasks(keyword);
+
+ } else if (command.equals("todo")) {
+ try {
+ input = parser.toDoTask(input);
+ ui.toDoCommand(input);
+
+ } catch (Exception e) {
+ throw new DukeException(("OOPS!!! The description cannot be empty."));
+ }
+ } else if (command.equals("event")) {
+ String content = parser.eventTaskContent(input);
+ String at = parser.eventTaskAt(input);
+ ui.eventCommand(content, at);
+
+ } else if (command.equals("deadline")) {
+ String content = parser.deadlineTaskContent(input);
+ String by = parser.deadlineTaskBy(input);
+ ui.deadlineCommand(content, by);
+
+ }else if(command.equals("delete")){
+ int id = parser.getId(input);
+ ui.deleteCommand(id);
+
+ } else {
+ throw new DukeException("OOPS!!! I'm sorry, but I don't know what that means :-{");
+ }
+ } catch (DukeException e1) {
+ System.out.println(e1);
+
+ }
+ }
+ try {
+ updateFile("data/duke.txt", bot);
+ }catch (IOException e) {
+ System.out.println("Unable to update file");
+ }
+ input = sc.nextLine();
+ }
+
+
+ System.out.println("Bye. Hope to see you again soon!");
+ }
+}
+
+
+
+
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..ad933595bc
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: ip.src.main.java.A_MoreOOP
+
diff --git a/src/main/java/ip/src/main/java/Command.java b/src/main/java/ip/src/main/java/Command.java
new file mode 100644
index 0000000000..fb5889c37f
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Command.java
@@ -0,0 +1,16 @@
+package ip.src.main.java;
+
+/**
+ * Command enum class for the different types of commands available for the Duke bot.
+ */
+public enum Command {
+ BYE,
+ DEADLINE,
+ DELETE,
+ DONE,
+ EDIT,
+ EVENT,
+ FIND,
+ LIST,
+ TODO;
+}
diff --git a/src/main/java/ip/src/main/java/Deadline.java b/src/main/java/ip/src/main/java/Deadline.java
new file mode 100644
index 0000000000..45481d481e
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Deadline.java
@@ -0,0 +1,80 @@
+package ip.src.main.java;
+
+import java.text.ParseException;
+import java.util.Date;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+/**
+ * Deadline is a type of Task with attributes String content and a Date stored as a Date object.
+ *
+ */
+
+public class Deadline extends Task{
+ protected Date by;
+
+ /**
+ * Constructor for Deadline Class.
+ *
+ * @param content String content given by user.
+ * @param by_str Deadline date given by user, parsed into a Date object with the format dd/MM/yyyy HH:mm.
+ */
+
+ public Deadline(String content , String by_str) {
+ super(content);
+ DateFormat sourceFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
+ try {
+ Date by = sourceFormat.parse(by_str);
+ this.by = by;
+ } catch (ParseException e) {
+ System.out.println("Date and Time is not in correct format DD/MM/YYYY HH:MM");
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ *Edits the date and time of the Deadline task by cloning the old Deadline task.
+ *
+ * @param newDate New date given by user.
+ * @return A clone of the old Deadline task with the new date and time change.
+ */
+ protected Deadline editDate (String newDate) {
+ String content = this.content;
+ boolean doneStatus = this.done;
+ Deadline newDeadlineTask = new Deadline(content , newDate);
+ newDeadlineTask.done = doneStatus;
+ return newDeadlineTask;
+ }
+
+ /**
+ *Edits the content of the Deadline task by cloning the old Deadline task.
+ *
+ * @param newContent New content given by user.
+ * @return A clone of the old Deadline task with the new content change.
+ */
+ public Deadline editContent (String newContent) {
+ Deadline newTask = new Deadline(newContent , "0/0/0 00:00");
+ newTask.by = this.by;
+ newTask.done = this.done;
+ return newTask;
+ }
+
+ /**
+ * toString() of Deadline Class.
+ *
+ * @return toString() representation of a Deadline object with its done status, content and date.
+ */
+
+ @Override
+ public String toString() {
+ DateFormat sourceFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
+ String strDate = sourceFormat.format(this.by);
+ if (!this.done) {
+ return "D | 0 | " + super.toString() + " | " + strDate;
+ } else {
+ return "D | 1 | " + super.toString() + " | " + strDate;
+
+ }
+ }
+}
diff --git a/src/main/java/ip/src/main/java/DialogBox.java b/src/main/java/ip/src/main/java/DialogBox.java
new file mode 100644
index 0000000000..8be2edb316
--- /dev/null
+++ b/src/main/java/ip/src/main/java/DialogBox.java
@@ -0,0 +1,61 @@
+package ip.src.main.java;
+
+import java.io.IOException;
+import java.util.Collections;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.HBox;
+
+/**
+ * An example of a custom control using FXML.
+ * This control represents a dialog box consisting of an ImageView to represent the speaker's face and a label
+ * containing text from the speaker.
+ */
+public class DialogBox extends HBox {
+ @FXML
+ private Label dialog;
+ @FXML
+ private ImageView displayPicture;
+
+ private DialogBox(String text, Image img) {
+ try {
+ FXMLLoader fxmlLoader = new FXMLLoader(MainWindow.class.getResource("/view/DialogBox.fxml"));
+ fxmlLoader.setController(this);
+ fxmlLoader.setRoot(this);
+ fxmlLoader.load();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ dialog.setText(text);
+ displayPicture.setImage(img);
+ }
+
+ /**
+ * Flips the dialog box such that the ImageView is on the left and text on the right.
+ */
+ private void flip() {
+ ObservableList tmp = FXCollections.observableArrayList(this.getChildren());
+ Collections.reverse(tmp);
+ getChildren().setAll(tmp);
+ setAlignment(Pos.TOP_LEFT);
+ }
+
+ public static DialogBox getUserDialog(String text, Image img) {
+ return new DialogBox(text, img);
+ }
+
+ public static DialogBox getDukeDialog(String text, Image img) {
+ var db = new DialogBox(text, img);
+ db.flip();
+ return db;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ip/src/main/java/Duke.java b/src/main/java/ip/src/main/java/Duke.java
new file mode 100644
index 0000000000..55869fb2ea
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Duke.java
@@ -0,0 +1,170 @@
+package ip.src.main.java;
+
+import java.io.IOException;
+
+/**
+ * Returns a Duke bot that stores the tasks given by the user.
+ */
+public class Duke {
+ /** Tasks stored in this task list object */
+ TaskList list;
+
+ public Duke() {
+ this.list = new TaskList();
+ }
+
+ /**
+ *Sends a greeting to the user.
+ *
+ * @return A string representation of the greeting.
+ */
+ public String greet() {
+ String output = "";
+ output += "Hello! I'm Duke! :) " + "\n";
+ output += "What can I do for you?";
+ return output;
+ }
+
+ /**
+ * Exits the conversion with the bot.
+ * Initiates the saving of the new tasklist to the file at the relative filepath (attribute of storage).
+ *
+ * @param storage Storage object used to save final data to the data file.
+ * @return A string saying bye to the user.
+ * @throws DukeException
+ */
+ public String bye(Storage storage) throws DukeException {
+ try {
+ storage.updateFile();
+ return "Bye! See you again";
+ } catch (IOException e) {
+ throw new DukeException("Can't save to file!");
+ }
+ }
+
+ /**
+ * Echos the user input.
+ *
+ * @param input User input given.
+ */
+
+ public void echo(String input) {
+ System.out.println(input);
+
+ }
+
+ /**
+ * Adds the given task to the Duke bot list, informs the user and prints the number of tasks in the bot list.
+ *
+ * @param task Task object created from user input.
+ * @return A string representation that informs the user of the task added and the number of tasks in the tasklist.
+ */
+ public String addToList(Task task) {
+ this.list.addTask(task);
+ String output = "";
+ output += "Got it. I've added this task: " + "\n";
+ output += " " + task + "\n";
+ output += "Now you have " + String.valueOf(this.list.size()) + " tasks in the list.";
+ return output;
+ }
+
+ /**
+ * Adds the given task to the Duke bot list quietly.
+ *
+ * @param task Task object created from user input.
+ */
+ public void addToBot(Task task) {
+ this.list.addTask(task);
+ }
+
+ /**
+ *Prints the bot's tasklist.
+ *
+ * @return A string representation of the bot's current tasklist.
+ */
+ public String printList() {
+ String output = "";
+
+ if (this.list.isEmpty()) {
+ output += "There are no tasks!";
+ } else {
+ output += this.list.printTasks();
+ }
+ return output;
+ }
+
+ /**
+ * Marks a task specified in the bot list as done.
+ *
+ * @param id The position ,1-th based, of the task to be marked done in the bot list.
+ * @return A string representation to inform the user of the task marked done.
+ */
+ public String markTaskAsDone(int id) {
+ Task task = this.list.getTask(id-1);
+ task.markDone();
+ String output = "";
+ output += "Nice! I've marked this task as done: \n";
+ output += " [X] "+ task.content;
+ return output;
+ }
+
+ /**
+ * Deletes a task specified in the bot list.
+ *
+ * @param id The position ,1-th based, of the task to be marked done in the bot list.
+ * @return A string representation to inform the user of the deletion of the specified task.
+ */
+ public String deleteTask(int id) {
+ Task task = this.list.getTask(id-1);
+ this.list.remove(id-1);
+ String output = "";
+ output += "Noted. I've removed this task: \n";
+ output += " " + task + "\n";
+ output += "Now you have " + String.valueOf(this.list.size()) + " tasks in the list.";
+ return output;
+ }
+
+ /**
+ * Prints all the tasks with content that contain the keyword.
+ *
+ * @param keyword The keyword given by the user.
+ * @return A string representation of all the matching tasks.
+ */
+ public String findMatchingTasks(String keyword) {
+ TaskList matchingTasks = this.list.findTasks(keyword);
+ return matchingTasks.printMatchingTasks();
+ }
+
+ /**
+ * Retrieves a task from the bot's TaskList at the specified index.
+ *
+ * @param id The specified index of the task in the tasklist to be retrieved.
+ * @return The task at the specified index.
+ */
+ public Task getTask (int id) {
+ return this.list.getTask(id);
+ }
+
+ /**
+ *Updates the old task with the new task with the edited task details.
+ *
+ * @param newTask The new task with the new edited task details.
+ * @param id The index of the old task to be updated with the new task.
+ * @return A string representation of the new edited tasklist.
+ */
+ public String editTask(Task newTask , int id) {
+ this.list.editTask(newTask , id-1);
+ String output = "Task has been edited. \n";
+ output += this.list.printEditedTasks();
+ return output;
+ }
+
+ 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/ip/src/main/java/DukeException.java b/src/main/java/ip/src/main/java/DukeException.java
new file mode 100644
index 0000000000..4de69bffab
--- /dev/null
+++ b/src/main/java/ip/src/main/java/DukeException.java
@@ -0,0 +1,16 @@
+package ip.src.main.java;
+
+/**
+ * Customized Exception Class for Duke.
+ */
+
+public class DukeException extends Exception {
+ public DukeException(String message) {
+ super(message);
+ }
+
+ @Override
+ public String toString() {
+ return this.getMessage();
+ }
+}
diff --git a/src/main/java/ip/src/main/java/EditType.java b/src/main/java/ip/src/main/java/EditType.java
new file mode 100644
index 0000000000..79a80474e6
--- /dev/null
+++ b/src/main/java/ip/src/main/java/EditType.java
@@ -0,0 +1,9 @@
+package ip.src.main.java;
+
+/**
+ * Edit enum class shows the different types of edit commands available for the bot.
+ */
+public enum EditType {
+ EDIT_CONTENT,
+ EDIT_DATETIME
+}
diff --git a/src/main/java/ip/src/main/java/Event.java b/src/main/java/ip/src/main/java/Event.java
new file mode 100644
index 0000000000..e738426ac3
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Event.java
@@ -0,0 +1,75 @@
+package ip.src.main.java;
+import java.text.ParseException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Event is a type of Task with attributes String content and a Date stored as a Date object.
+ *
+ */
+public class Event extends Task {
+ protected Date at;
+
+ /**
+ * Constructor for Event Class.
+ *
+ * @param content String content given by user.
+ * @param atStr Event date given by user, parsed into a Date object with the format dd/MM/yyyy HH:mm.
+ */
+ public Event(String content , String atStr) {
+ super(content);
+ DateFormat sourceFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
+ try {
+ Date at = sourceFormat.parse(atStr);
+ this.at = at;
+ } catch (ParseException e) {
+ System.out.println("Date and Time is not in correct format DD/MM/YYYY HH:MM");
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ *Edits the date and time of the Event task by cloning the old Event task.
+ *
+ * @param newDate New date given by user.
+ * @return A clone of the old Event task with the new date and time change.
+ */
+ public Event editDate (String newDate) {
+ String content = this.content;
+ boolean doneStatus = this.done;
+ Event newEventTask = new Event (content , newDate);
+ newEventTask.done = doneStatus;
+ return newEventTask;
+ }
+
+ /**
+ *Edits the content of the Event task by cloning the old Event task.
+ *
+ * @param newContent New content given by user.
+ * @return A clone of the old Event task with the new content change.
+ */
+ public Event editContent (String newContent) {
+ Event newTask = new Event(newContent , "0/0/0 00:00");
+ newTask.at = this.at;
+ newTask.done = this.done;
+ return newTask;
+ }
+
+ /**
+ * toString() of Event Class.
+ *
+ * @return toString() representation of a Event object with its done status, content and date.
+ */
+ @Override
+ public String toString() {
+ DateFormat sourceFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
+ String strDate = sourceFormat.format(this.at);
+ if (!this.done) {
+ return "E | 0 | " + super.toString() + " | " + strDate;
+ } else {
+ return "E | 1 | " + super.toString() + " | " + strDate;
+ }
+ }
+}
diff --git a/src/main/java/ip/src/main/java/Launcher.java b/src/main/java/ip/src/main/java/Launcher.java
new file mode 100644
index 0000000000..8c03f37cb9
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Launcher.java
@@ -0,0 +1,12 @@
+package ip.src.main.java;
+
+import javafx.application.Application;
+
+/**
+ * A launcher class to workaround classpath issues.
+ */
+public class Launcher {
+ public static void main(String[] args) {
+ Application.launch(Main.class, args);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ip/src/main/java/Main.java b/src/main/java/ip/src/main/java/Main.java
new file mode 100644
index 0000000000..72f9276f3a
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Main.java
@@ -0,0 +1,50 @@
+package ip.src.main.java;
+
+import java.io.File;
+import java.io.IOException;
+
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.text.TextAlignment;
+import javafx.stage.Stage;
+
+/**
+ * A GUI for Duke using FXML.
+ */
+public class Main extends Application {
+
+ private Duke duke = new Duke();
+
+
+ @Override
+ public void start(Stage stage) {
+ Storage storage = new Storage("data/duke.txt" , duke);
+
+ try {
+ File f = new File("data/duke.txt");
+ f.getParentFile().mkdirs();
+ if (!f.createNewFile()) {
+ storage.createBot("data/duke.txt" , duke);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("/view/MainWindow.fxml"));
+ AnchorPane ap = fxmlLoader.load();
+ Scene scene = new Scene(ap);
+ stage.setScene(scene);
+ fxmlLoader.getController().setDuke(duke);
+ stage.show();
+ String greet = duke.greet();
+ Label label = new Label(greet);
+ stage.setTitle(greet);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ip/src/main/java/MainWindow.java b/src/main/java/ip/src/main/java/MainWindow.java
new file mode 100644
index 0000000000..9fbd418c10
--- /dev/null
+++ b/src/main/java/ip/src/main/java/MainWindow.java
@@ -0,0 +1,55 @@
+package ip.src.main.java;
+
+import ip.src.main.java.DialogBox;
+import ip.src.main.java.Duke;
+import ip.src.main.java.Ui;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.TextField;
+import javafx.scene.image.Image;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+/**
+ * Controller for MainWindow. Provides the layout for the other controls.
+ */
+public class MainWindow extends AnchorPane {
+ @FXML
+ private ScrollPane scrollPane;
+ @FXML
+ private VBox dialogContainer;
+ @FXML
+ private TextField userInput;
+ @FXML
+ private Button sendButton;
+
+ private Duke duke;
+
+ private Image userImage = new Image(this.getClass().getResourceAsStream("/images/MaskedPikachu.png"));
+ private Image dukeImage = new Image(this.getClass().getResourceAsStream("/images/MaskedSquirtle.png"));
+
+ @FXML
+ public void initialize() {
+ scrollPane.vvalueProperty().bind(dialogContainer.heightProperty());
+ }
+
+ public void setDuke(Duke d) {
+ duke = d;
+ }
+
+ /**
+ * Creates two dialog boxes, one echoing user input and the other containing Duke's reply and then appends them to
+ * the dialog container. Clears the user input after processing.
+ */
+ @FXML
+ private void handleUserInput() {
+ String input = userInput.getText();
+ Ui ui = new Ui(duke);
+ String response = ui.handleUserInput(input);
+ dialogContainer.getChildren().addAll(
+ DialogBox.getUserDialog(input, userImage),
+ DialogBox.getDukeDialog(response, dukeImage)
+ );
+ userInput.clear();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ip/src/main/java/Parser.java b/src/main/java/ip/src/main/java/Parser.java
new file mode 100644
index 0000000000..11cb508e24
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Parser.java
@@ -0,0 +1,168 @@
+package ip.src.main.java;
+
+import java.util.Locale;
+
+/**
+ * Parser is a class that parsers user input to retrieve user commands, information to create Task objects etc.
+ *
+ */
+
+public class Parser {
+
+ //static field to standardize the parsing for Edit commands.
+ private static final String EDIT_HEADER = "EDIT_";
+
+ Parser() {
+ }
+
+ /**
+ * Retrieves the command entered by the user.
+ *
+ * @param input Input entered by user.
+ * @return Returns the first word that represents the command given by the user.
+ */
+ public Command getCommand(String input) throws DukeException {
+ String commandType = "";
+ if (input.equals("bye")) {
+ commandType = "bye";
+ } else if (input.equals("list")) {
+ commandType = "list";
+ } else {
+ assert input.length() > 1;
+ commandType = input.split(" ")[0];
+ }
+ try {
+ Command command = Command.valueOf(commandType.toUpperCase(Locale.ENGLISH));
+ return command;
+ } catch (IllegalArgumentException e) {
+ throw new DukeException("OOPS! I don't know what this means! :(");
+ }
+ }
+
+ /**
+ * Gets the specific edit type from the edit command given.
+ *
+ * @param input The type of edit stated by the user.
+ * @return EditType command.
+ * @throws DukeException
+ */
+ protected EditType getEditType (String input) throws DukeException {
+ try {
+ String editType = input.split(" ")[2];
+ editType = EDIT_HEADER + editType;
+ EditType edit = EditType.valueOf(editType.toUpperCase(Locale.ENGLISH));
+ return edit;
+ } catch (Exception e) {
+ throw new DukeException("OOPS! Invalid edit type! :( \n Edit format should be: edit {index} {type of edit} {edit details}");
+ }
+ }
+
+ /**
+ * Gets the edit details from the edit command given.
+ *
+ * @param input The edit details provided by the users.
+ * @return Edit details, either new content or new date and time.
+ * @throws DukeException
+ */
+ protected String getEditDetails (String input) throws DukeException {
+ try {
+ input = input.split(" ", 4)[3];
+ return input;
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException(("OOPS!!! The edit details cannot be empty. \n Edit format should be: edit {index} {type of edit} {edit details}"));
+ }
+
+ }
+
+
+ /**
+ * Retrieves the information needed from the user input for a ToDo object.
+ *
+ * @param input User input.
+ * @return String content needed to create a ToDo Object.
+ */
+ public String toDoTask(String input) throws DukeException {
+ try {
+ input = input.split(" ", 2)[1];
+ return input;
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException(("OOPS!!! The description cannot be empty."));
+ }
+ }
+
+
+ /**
+ * Retrieves the information needed from the user input for a Event object.
+ *
+ * @param input User input.
+ * @return String content needed to create a Event Object.
+ */
+ public String eventTaskContent(String input) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/at")[0];
+ return content;
+ }
+
+ /**
+ * Retrieves the information needed from the user input for a Event object.
+ *
+ * @param input User input.
+ * @return String date needed to create a Event Object.
+ */
+ public String eventTaskAt(String input) {
+ input = input.split(" ", 2)[1];
+ String at = input.split("/at")[1];
+ return at;
+ }
+
+ /**
+ * Retrieves the information needed from the user input for a Deadline object.
+ *
+ * @param input User input.
+ * @return String content needed to create a Deadline Object.
+ */
+ public String deadlineTaskContent(String input) {
+ input = input.split(" ", 2)[1];
+ String content = input.split("/by")[0];
+ return content;
+ }
+
+ /**
+ * Retrieves the information needed from the user input for a Deadline object.
+ *
+ * @param input User input.
+ * @return String date needed to create a Deadline Object.
+ */
+ public String deadlineTaskBy(String input) {
+ input = input.split(" ", 2)[1];
+ String by = input.split("/by")[1];
+ return by;
+ }
+
+ /**
+ * Gives the ID (position) of the task to be manipulated in the TaskList.
+ *
+ * @param input User input.
+ * @return Integer ID that represents the position (1-th based) of the task in the TaskList.
+ */
+ public int getId(String input) throws DukeException {
+ try {
+ int id = Integer.valueOf(input.split(" ")[1]);
+ return id;
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException("Invalid input! Please enter in the correct format with the task index!");
+ }
+
+ }
+
+ /**
+ * Retrieves the keyword from the user input to for the find task method.
+ *
+ * @param input User input.
+ * @return The keyword used to find the matching tasks in the Task list.
+ */
+ public String getKeyword(String input) {
+ String keyword = input.split(" ", 2)[1];
+ return keyword;
+ }
+}
diff --git a/src/main/java/ip/src/main/java/Storage.java b/src/main/java/ip/src/main/java/Storage.java
new file mode 100644
index 0000000000..a8a4bbe180
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Storage.java
@@ -0,0 +1,107 @@
+package ip.src.main.java;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Scanner;
+
+/**
+ * Storage class that deals with loading and updating the tasks in the given file.
+ *
+ */
+public class Storage {
+ protected String filePath;
+ protected Duke bot;
+
+ Storage (String filePath, Duke bot) {
+ this.filePath = filePath;
+ this.bot = bot;
+ }
+
+ private Task loadToDoTask (String[] taskDataArr) {
+ String details = taskDataArr[2];
+ Task newTask = new ToDo(details);
+ bot.addToBot(newTask);
+ return newTask;
+ }
+
+ private Task loadEventTask (String[] taskDataArr) {
+ String content = taskDataArr[2];
+ String at = taskDataArr[3];
+ Task newTask = new Event(content, at);
+ bot.addToBot(newTask);
+ return newTask;
+ }
+
+ private Task loadDeadlineTask (String[] taskDataArr) {
+ String content = taskDataArr[2];
+ String by = taskDataArr[3];
+ Task newTask = new Deadline(content, by);
+ bot.addToBot(newTask);
+ return newTask;
+ }
+
+ /**
+ * Updates the Duke bot with the tasks by loading the tasks in the file.
+ * Task is in the format {type} | {doneStatus} | {details}.
+ *
+ * @param taskData The task from the file.
+ * @throws FileNotFoundException
+ */
+ public void loadTasks(String taskData) throws FileNotFoundException {
+ // create a File for the given file path
+ File f = new File(this.filePath);
+ // create a Scanner using the File as the source
+ Scanner s = new Scanner(f);
+
+ String[] taskDataArr = taskData.split(" \\| ");
+ String type = taskDataArr[0];
+ String doneStatus = taskDataArr[1];
+ Task newTask = new Task("");
+
+ if (newTask.isToDoTask(type)) {
+ newTask = loadToDoTask(taskDataArr);
+ } else if (newTask.isEventTask(type)) {
+ newTask = loadEventTask(taskDataArr);
+ } else {
+ assert type.equals("D");
+ newTask = loadDeadlineTask(taskDataArr);
+ }
+
+ if (newTask.isDone(doneStatus)) {
+ newTask.markDone();
+ }
+ }
+
+ /**
+ * Updates the Duke bot with the tasks stored in the file by calling the loadTask method.
+ *
+ * @param filePath The file with the tasks.
+ * @param bot The duke bot.
+ * @throws FileNotFoundException
+ */
+ public void createBot(String filePath, Duke bot) throws FileNotFoundException {
+ // create a File for the given file path
+ File f = new File(filePath);
+ // create a Scanner using the File as the source
+ Scanner s = new Scanner(f);
+ Storage storage = new Storage(filePath, bot);
+
+ while (s.hasNext()) {
+ storage.loadTasks(s.nextLine());
+ }
+ }
+
+ /**
+ * Updates the file at the specific relative filepath with the bot's final tasklist.
+ *
+ * @throws IOException
+ */
+ public void updateFile() throws IOException {
+ FileWriter fw = new FileWriter(this.filePath);
+ for (Task element:this.bot.list.list) {
+ fw.write(element.toString() + "\n");
+ }
+ fw.close();
+ }
+}
diff --git a/src/main/java/ip/src/main/java/Task.java b/src/main/java/ip/src/main/java/Task.java
new file mode 100644
index 0000000000..af0236b22d
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Task.java
@@ -0,0 +1,78 @@
+package ip.src.main.java;
+
+/**
+ * Task class that stores Task details and Task status.
+ *
+ */
+
+public class Task {
+ //int id;
+ protected String content;
+ protected boolean done = false;
+
+ public Task(String content) {
+ //this.id = id;
+ this.content = content;
+
+ }
+
+ /**
+ * Updates the Task Status to completed.
+ */
+ public void markDone() {
+ this.done = true;
+ }
+
+ public boolean isDone(String doneStatus) {
+ return doneStatus.equals(" 1 ");
+ }
+
+ /**
+ * Checks if Task content has matching keyword.
+ *
+ * @return Returns True if task content has keyword.
+ */
+ public boolean isMatch(String keyword) {
+ return this.content.contains(keyword);
+ }
+
+ protected boolean isToDoTask(String inputType) {
+ return inputType.equals("T");
+ }
+
+ protected boolean isEventTask(String inputType) {
+ return inputType.equals("E");
+ }
+
+ /**
+ *Dummy method for editing the content of the old task.
+ * Exact implementations in each child class, utilizing Polymorphism when editContent is called.
+ *
+ * @param newContent New content given by user.
+ * @return A clone of the old task with the new content change.
+ */
+ protected Task editContent (String newContent) {
+ Task newTask = new Task(newContent);
+ newTask.done = this.done;
+ return newTask;
+ }
+
+ /**
+ * Dummy method for editDate in Task.
+ * Exact implementations in each child class, utilizing Polymorphism when editDate is called.
+ *
+ * @param newDate New date given by user.
+ */
+ protected Task editDate (String newDate) {
+ return this;
+ }
+
+
+ public String toString() {
+ return this.content;
+ }
+
+
+}
+
+
diff --git a/src/main/java/ip/src/main/java/TaskList.java b/src/main/java/ip/src/main/java/TaskList.java
new file mode 100644
index 0000000000..f3e5552f73
--- /dev/null
+++ b/src/main/java/ip/src/main/java/TaskList.java
@@ -0,0 +1,129 @@
+package ip.src.main.java;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TaskList stores and manipulate the tasks in a List.
+ *
+ */
+public class TaskList {
+ protected List list;
+
+ TaskList() {
+ this.list = new ArrayList<>();
+ }
+
+ /**
+ * Adds a Task to the list.
+ *
+ * @param task New Task to be added to list.
+ */
+ public void addTask(Task task) {
+ this.list.add(task);
+ }
+
+ /**
+ * Checks if list is empty.
+ *
+ * @return Boolean to indicate if list is empty.
+ */
+ public boolean isEmpty() {
+ return this.list.isEmpty();
+ }
+
+ /**
+ * Prints the tasks in the bot's tasklist.
+ *
+ * @return A string representation of the list of the tasks in the tasklist.
+ */
+ public String printTasks() {
+ int counter = 1;
+ String output = "";
+ for (Task element : this.list) {
+ output += String.valueOf(counter) + ". " + element + "\n";
+ counter++;
+ }
+ output += "Now you have " + String.valueOf(this.list.size()) + " tasks in the list.";
+ return output;
+ }
+
+ /**
+ * Prints the tasks that contain the keyword/s from the bot's tasklist.
+ *
+ * @return A string representation of the list of matching tasks.
+ */
+ public String printMatchingTasks() {
+ int counter = 1;
+ String output = "";
+ for (Task element : this.list) {
+ output += String.valueOf(counter) + ". " + element + "\n";
+ counter++;
+ }
+ output += "You have " + String.valueOf(this.list.size()) + " matching tasks from the list!";
+ return output;
+ }
+
+ /**
+ * Prints the edited bot's tasklist.
+ *
+ * @return A string representation of the newly edited tasks in the tasklist.
+ */
+ public String printEditedTasks() {
+ int counter = 1;
+ String output = "";
+ for (Task element : this.list) {
+ output += String.valueOf(counter) + ". " + element + "\n";
+ counter++;
+ }
+ return output;
+ }
+
+ /**
+ * Gets the task at a specified position in the list.
+ *
+ * @param id The position of the task to be retrieved in the list.
+ * @return A task in the list.
+ */
+ public Task getTask(int id) {
+ return this.list.get(id);
+ }
+
+ /**
+ * Removes a task at a specified position in the list.
+ *
+ * @param id The position of the task to be removed from the list.
+ */
+ public void remove(int id) {
+ this.list.remove(id);
+ }
+
+ /**
+ * Returns size of the Task list.
+ *
+ * @return The number of tasks in the list.
+ */
+ public int size() {
+ return this.list.size();
+ }
+
+ /**
+ * Gets the matching tasks that contain the keyword/s.
+ *
+ * @param keyword Keyword/s given by user.
+ * @return A tasklist of tasks that contain the keyword/s.
+ */
+ public TaskList findTasks(String keyword) {
+ TaskList taskListWithMatches = new TaskList();
+
+ for (Task task: this.list) {
+ if (task.isMatch(keyword)) {
+ taskListWithMatches.addTask(task);
+ }
+ }
+ return taskListWithMatches;
+ }
+
+ protected void editTask(Task newTask , int id) {
+ this.list.set(id , newTask);
+ }
+}
diff --git a/src/main/java/ip/src/main/java/ToDo.java b/src/main/java/ip/src/main/java/ToDo.java
new file mode 100644
index 0000000000..bdf4f5892d
--- /dev/null
+++ b/src/main/java/ip/src/main/java/ToDo.java
@@ -0,0 +1,39 @@
+package ip.src.main.java;
+
+/**
+ * ToDo class is a type of Task that has attribute String content.
+ *
+ */
+
+public class ToDo extends Task {
+
+ public ToDo(String content) {
+ super(content);
+ }
+
+ /**
+ *Edits the content of the ToDo task by cloning the old ToDo task.
+ *
+ * @param newContent New content given by user.
+ * @return A clone of the old ToDo task with the new content change.
+ */
+ public ToDo editContent (String newContent) {
+ ToDo newTask = new ToDo(newContent);
+ newTask.done = this.done;
+ return newTask;
+ }
+
+ /**
+ * toString() of ToDo Class.
+ *
+ * @return toString() representation of a ToDo object with its done status and content.
+ */
+ @Override
+ public String toString() {
+ if (!this.done) {
+ return "T | 0 | " + super.toString();
+ } else {
+ return "T | 1 | " + super.toString();
+ }
+ }
+}
diff --git a/src/main/java/ip/src/main/java/Ui.java b/src/main/java/ip/src/main/java/Ui.java
new file mode 100644
index 0000000000..42c42f6033
--- /dev/null
+++ b/src/main/java/ip/src/main/java/Ui.java
@@ -0,0 +1,171 @@
+package ip.src.main.java;
+
+import java.io.IOException;
+
+/**
+ * Ui class deals with user interactions.
+ *
+ */
+
+public class Ui {
+ protected Duke bot;
+
+ public Ui(Duke bot) {
+ this.bot = bot;
+ }
+
+ /**
+ * Deals with the done command by the user by telling the bot to mark a specified task as done.
+ *
+ * @param id The specified position of the task which status is to be updated as done in the Task List.
+ */
+ public String doneCommand(int id) {
+ return this.bot.markTaskAsDone(id);
+ }
+
+ /**
+ * Deals with the ToDo command. Creates a ToDo task from the input
+ * and tells the bot to add the new task to its Task list.
+ *
+ * @param content Content of the ToDo object.
+ */
+ private String toDoCommand(String content) {
+ ToDo newTask = new ToDo(content);
+ return this.bot.addToList(newTask);
+ }
+
+ /**
+ * Deals with the Event command.
+ * Creates a Event task from the input and tells the bot to add the new task to its Task list.
+ *
+ * @param content Content of the Event object.
+ * @param at Date of the Event object.
+ */
+ private String eventCommand(String content, String at) {
+ Event newTask = new Event(content, at);
+ return this.bot.addToList(newTask);
+
+ }
+
+ /**
+ * Deals with the Deadline command.
+ * Creates a Deadline task from the input and tells the bot to add the new task to its Task list.
+ *
+ * @param content Content of the Event object.
+ * @param by Date of the Event object.
+ */
+ private String deadlineCommand(String content, String by) {
+ Deadline newTask = new Deadline(content, by);
+ return this.bot.addToList(newTask);
+ }
+
+ private String editCommand(String editDetails , int id , EditType editType) throws DukeException {
+ try {
+ Task oldTask = this.bot.getTask(id-1);
+ Task newTask = new Task("");
+
+ switch (editType) {
+ case EDIT_DATETIME:
+ newTask = oldTask.editDate(editDetails);
+ break;
+
+ case EDIT_CONTENT:
+ newTask = oldTask.editContent(editDetails);
+ break;
+
+ default:
+ assert false : editType;
+ }
+ return this.bot.editTask(newTask , id);
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException("Index is out of bounds! \n Please enter a valid task number!");
+ }
+ }
+
+ /**
+ * Deals with the Delete command. Tells the bot to remove a task from its Task list.
+ *
+ * @param id The specified position of the task to be removed from the bot Task List.
+ */
+ public String deleteCommand(int id) throws DukeException {
+ try {
+ return this.bot.deleteTask(id-1);
+ } catch (IndexOutOfBoundsException e) {
+ throw new DukeException("Index is out of bounds! \n Please enter a valid task number!");
+ }
+ }
+
+ /**
+ * Handles user input for the different commands given by the user.
+ * Gets the result string to respond to the user.
+ *
+ * @param input User input.
+ * @return Result string.
+ */
+ public String handleUserInput(String input) {
+ Parser parser = new Parser();
+ String output = "";
+ try {
+ Command command = parser.getCommand(input);
+ switch (command) {
+
+ case BYE:
+ Storage storage = new Storage("data/duke.txt" , this.bot);
+ output = this.bot.bye(storage);
+ break;
+
+ case LIST:
+ output = this.bot.printList();
+ break;
+
+ case DONE:
+ int id = parser.getId(input);
+ output = doneCommand(id);
+ break;
+
+ case FIND:
+ String keyword = parser.getKeyword(input);
+ output = this.bot.findMatchingTasks(keyword);
+ break;
+
+ case TODO:
+ input = parser.toDoTask(input);
+ output = toDoCommand(input);
+ break;
+
+ case EVENT:
+ String content = parser.eventTaskContent(input);
+ String at = parser.eventTaskAt(input);
+ output = eventCommand(content, at);
+ break;
+
+ case DEADLINE:
+ content = parser.deadlineTaskContent(input);
+ String by = parser.deadlineTaskBy(input);
+ output = deadlineCommand(content, by);
+ break;
+
+ case EDIT:
+ id = parser.getId(input);
+ EditType editType = parser.getEditType(input);
+ String editDetails = parser.getEditDetails(input);
+ output = editCommand(editDetails , id , editType);
+ break;
+
+ case DELETE:
+ id = parser.getId(input);
+ output = deleteCommand(id);
+ break;
+
+ default:
+ assert false : command;
+ }
+
+ } catch (DukeException e1) {
+ output = e1.getMessage();
+ }
+ return output;
+ }
+
+}
+
diff --git a/src/main/resources/images/MaskedPikachu.png b/src/main/resources/images/MaskedPikachu.png
new file mode 100644
index 0000000000..009c0e5b13
Binary files /dev/null and b/src/main/resources/images/MaskedPikachu.png differ
diff --git a/src/main/resources/images/MaskedSquirtle.png b/src/main/resources/images/MaskedSquirtle.png
new file mode 100644
index 0000000000..1ef91c0718
Binary files /dev/null and b/src/main/resources/images/MaskedSquirtle.png differ
diff --git a/src/main/resources/view/DialogBox.fxml b/src/main/resources/view/DialogBox.fxml
new file mode 100644
index 0000000000..c9521bd5af
--- /dev/null
+++ b/src/main/resources/view/DialogBox.fxml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml
new file mode 100644
index 0000000000..e35f459ae4
--- /dev/null
+++ b/src/main/resources/view/MainWindow.fxml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/DeadlineTest.java b/src/test/java/DeadlineTest.java
new file mode 100644
index 0000000000..b48bab76c8
--- /dev/null
+++ b/src/test/java/DeadlineTest.java
@@ -0,0 +1,19 @@
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+import ip.src.main.java.Deadline;
+
+public class DeadlineTest {
+ @Test
+
+ /*
+ Tests the toString() method of the Deadline class to see if deadline object is represented as expected.
+ */
+ public void deadlineToStringTest() {
+ Deadline deadline = new Deadline("Test" , "12/2/2019 18:00");
+ String deadlineToString = deadline.toString();
+ String expectedString = "D | 0 | " + "Test" + " | " + "12/02/2019 18:00";
+ assertEquals(expectedString , deadlineToString);
+ }
+}
diff --git a/src/test/java/EventTest.java b/src/test/java/EventTest.java
new file mode 100644
index 0000000000..4fe68e4ec0
--- /dev/null
+++ b/src/test/java/EventTest.java
@@ -0,0 +1,19 @@
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+import ip.src.main.java.Event;
+
+public class EventTest {
+ @Test
+
+ /*
+ Tests the toString() method of the Event class to see if deadline object is represented as expected.
+ */
+ public void eventToStringTest() {
+ Event event = new Event("Test" , "12/2/2019 18:00");
+ String eventToString = event.toString();
+ String expectedString = "E | 0 | " + "Test" + " | " + "12/02/2019 18:00";
+ assertEquals(expectedString , eventToString);
+ }
+}
diff --git a/src/test/java/TaskTest.java b/src/test/java/TaskTest.java
new file mode 100644
index 0000000000..526b749004
--- /dev/null
+++ b/src/test/java/TaskTest.java
@@ -0,0 +1,20 @@
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+import ip.src.main.java.Task;
+
+
+public class TaskTest {
+ @Test
+
+ /*
+ Tests if the markDone() method in the Task class behaves as expected.
+ */
+ public void taskDoneTest() {
+ Task task = new Task("Test");
+ task.markDone();
+ assertEquals(true , task.done);
+
+ }
+}
diff --git a/text-ui-test/ACTUAL.TXT b/text-ui-test/ACTUAL.TXT
new file mode 100644
index 0000000000..657e74f6e7
--- /dev/null
+++ b/text-ui-test/ACTUAL.TXT
@@ -0,0 +1,7 @@
+Hello from
+ ____ _
+| _ \ _ _| | _____
+| | | | | | | |/ / _ \
+| |_| | |_| | < __/
+|____/ \__,_|_|\_\___|
+
diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh
old mode 100644
new mode 100755