diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
index f69985ef1f..4ef9ef622d
--- a/.gitignore
+++ b/.gitignore
@@ -4,9 +4,7 @@
/*.iml
# Gradle build files
-/.gradle/
-/build/
-src/main/resources/docs/
+
# MacOS custom attributes files created by Finder
.DS_Store
@@ -15,3 +13,4 @@ bin/
/text-ui-test/ACTUAL.txt
text-ui-test/EXPECTED-UNIX.TXT
+/logs
diff --git a/.gradle/6.2/executionHistory/executionHistory.bin b/.gradle/6.2/executionHistory/executionHistory.bin
new file mode 100644
index 0000000000..8d349c6c2d
Binary files /dev/null and b/.gradle/6.2/executionHistory/executionHistory.bin differ
diff --git a/.gradle/6.2/executionHistory/executionHistory.lock b/.gradle/6.2/executionHistory/executionHistory.lock
new file mode 100644
index 0000000000..9773d7e8ff
Binary files /dev/null and b/.gradle/6.2/executionHistory/executionHistory.lock differ
diff --git a/.gradle/6.2/fileChanges/last-build.bin b/.gradle/6.2/fileChanges/last-build.bin
new file mode 100644
index 0000000000..f76dd238ad
Binary files /dev/null and b/.gradle/6.2/fileChanges/last-build.bin differ
diff --git a/.gradle/6.2/fileContent/fileContent.lock b/.gradle/6.2/fileContent/fileContent.lock
new file mode 100644
index 0000000000..d855fbdc78
Binary files /dev/null and b/.gradle/6.2/fileContent/fileContent.lock differ
diff --git a/.gradle/6.2/fileHashes/fileHashes.bin b/.gradle/6.2/fileHashes/fileHashes.bin
new file mode 100644
index 0000000000..87e15bd24a
Binary files /dev/null and b/.gradle/6.2/fileHashes/fileHashes.bin differ
diff --git a/.gradle/6.2/fileHashes/fileHashes.lock b/.gradle/6.2/fileHashes/fileHashes.lock
new file mode 100644
index 0000000000..f6ab44e99a
Binary files /dev/null and b/.gradle/6.2/fileHashes/fileHashes.lock differ
diff --git a/.gradle/6.2/fileHashes/resourceHashesCache.bin b/.gradle/6.2/fileHashes/resourceHashesCache.bin
new file mode 100644
index 0000000000..68ce423fbb
Binary files /dev/null and b/.gradle/6.2/fileHashes/resourceHashesCache.bin differ
diff --git a/.gradle/6.2/gc.properties b/.gradle/6.2/gc.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/.gradle/6.2/javaCompile/classAnalysis.bin b/.gradle/6.2/javaCompile/classAnalysis.bin
new file mode 100644
index 0000000000..ce962c1417
Binary files /dev/null and b/.gradle/6.2/javaCompile/classAnalysis.bin differ
diff --git a/.gradle/6.2/javaCompile/jarAnalysis.bin b/.gradle/6.2/javaCompile/jarAnalysis.bin
new file mode 100644
index 0000000000..b51dc2e1c9
Binary files /dev/null and b/.gradle/6.2/javaCompile/jarAnalysis.bin differ
diff --git a/.gradle/6.2/javaCompile/javaCompile.lock b/.gradle/6.2/javaCompile/javaCompile.lock
new file mode 100644
index 0000000000..714783f5f7
Binary files /dev/null and b/.gradle/6.2/javaCompile/javaCompile.lock differ
diff --git a/.gradle/6.2/javaCompile/taskHistory.bin b/.gradle/6.2/javaCompile/taskHistory.bin
new file mode 100644
index 0000000000..dc85424cc6
Binary files /dev/null and b/.gradle/6.2/javaCompile/taskHistory.bin differ
diff --git a/.gradle/6.8.2/executionHistory/executionHistory.bin b/.gradle/6.8.2/executionHistory/executionHistory.bin
new file mode 100644
index 0000000000..9ef931fdbd
Binary files /dev/null and b/.gradle/6.8.2/executionHistory/executionHistory.bin differ
diff --git a/.gradle/6.8.2/executionHistory/executionHistory.lock b/.gradle/6.8.2/executionHistory/executionHistory.lock
new file mode 100644
index 0000000000..5f350c8946
Binary files /dev/null and b/.gradle/6.8.2/executionHistory/executionHistory.lock differ
diff --git a/.gradle/6.8.2/fileChanges/last-build.bin b/.gradle/6.8.2/fileChanges/last-build.bin
new file mode 100644
index 0000000000..f76dd238ad
Binary files /dev/null and b/.gradle/6.8.2/fileChanges/last-build.bin differ
diff --git a/.gradle/6.8.2/fileHashes/fileHashes.bin b/.gradle/6.8.2/fileHashes/fileHashes.bin
new file mode 100644
index 0000000000..ace76e9f5d
Binary files /dev/null and b/.gradle/6.8.2/fileHashes/fileHashes.bin differ
diff --git a/.gradle/6.8.2/fileHashes/fileHashes.lock b/.gradle/6.8.2/fileHashes/fileHashes.lock
new file mode 100644
index 0000000000..09207460e7
Binary files /dev/null and b/.gradle/6.8.2/fileHashes/fileHashes.lock differ
diff --git a/.gradle/6.8.2/gc.properties b/.gradle/6.8.2/gc.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/.gradle/6.8.2/javaCompile/javaCompile.lock b/.gradle/6.8.2/javaCompile/javaCompile.lock
new file mode 100644
index 0000000000..0feba0bb86
Binary files /dev/null and b/.gradle/6.8.2/javaCompile/javaCompile.lock differ
diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock
new file mode 100644
index 0000000000..df98d7afc5
Binary files /dev/null and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties
new file mode 100644
index 0000000000..49219baaaf
--- /dev/null
+++ b/.gradle/buildOutputCleanup/cache.properties
@@ -0,0 +1,2 @@
+#Wed Mar 24 20:58:26 SGT 2021
+gradle.version=6.2
diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin
new file mode 100644
index 0000000000..40f88484c3
Binary files /dev/null and b/.gradle/buildOutputCleanup/outputFiles.bin differ
diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock
new file mode 100644
index 0000000000..9affac60d1
Binary files /dev/null and b/.gradle/checksums/checksums.lock differ
diff --git a/.gradle/checksums/md5-checksums.bin b/.gradle/checksums/md5-checksums.bin
new file mode 100644
index 0000000000..dc36a2e8d9
Binary files /dev/null and b/.gradle/checksums/md5-checksums.bin differ
diff --git a/.gradle/checksums/sha1-checksums.bin b/.gradle/checksums/sha1-checksums.bin
new file mode 100644
index 0000000000..00aac60210
Binary files /dev/null and b/.gradle/checksums/sha1-checksums.bin differ
diff --git a/.gradle/configuration-cache/gc.properties b/.gradle/configuration-cache/gc.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
old mode 100644
new mode 100755
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000000..3da7462dde
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,60 @@
+plugins {
+ id 'java'
+ id 'application'
+ 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 = "Launcher"
+}
+
+shadowJar {
+ archiveBaseName = "duke"
+ archiveClassifier = null
+}
+
+
+run{
+ standardInput = System.in
+}
+
+apply plugin: 'idea'
\ No newline at end of file
diff --git a/build/classes/java/main/Deadline.class b/build/classes/java/main/Deadline.class
new file mode 100644
index 0000000000..050d4897c3
Binary files /dev/null and b/build/classes/java/main/Deadline.class differ
diff --git a/build/classes/java/main/DescriptionException.class b/build/classes/java/main/DescriptionException.class
new file mode 100644
index 0000000000..2bd8b5eb84
Binary files /dev/null and b/build/classes/java/main/DescriptionException.class differ
diff --git a/build/classes/java/main/DialogBox.class b/build/classes/java/main/DialogBox.class
new file mode 100644
index 0000000000..8dc80941a2
Binary files /dev/null and b/build/classes/java/main/DialogBox.class differ
diff --git a/build/classes/java/main/Duke.class b/build/classes/java/main/Duke.class
new file mode 100644
index 0000000000..25acccc688
Binary files /dev/null and b/build/classes/java/main/Duke.class differ
diff --git a/build/classes/java/main/DukeException.class b/build/classes/java/main/DukeException.class
new file mode 100644
index 0000000000..5ff4ae76b8
Binary files /dev/null and b/build/classes/java/main/DukeException.class differ
diff --git a/build/classes/java/main/Event.class b/build/classes/java/main/Event.class
new file mode 100644
index 0000000000..95e8452f71
Binary files /dev/null and b/build/classes/java/main/Event.class differ
diff --git a/build/classes/java/main/Launcher.class b/build/classes/java/main/Launcher.class
new file mode 100644
index 0000000000..ff41d530a9
Binary files /dev/null and b/build/classes/java/main/Launcher.class differ
diff --git a/build/classes/java/main/NotFoundException.class b/build/classes/java/main/NotFoundException.class
new file mode 100644
index 0000000000..32f1cd1bc6
Binary files /dev/null and b/build/classes/java/main/NotFoundException.class differ
diff --git a/build/classes/java/main/Parser.class b/build/classes/java/main/Parser.class
new file mode 100644
index 0000000000..042f4f076f
Binary files /dev/null and b/build/classes/java/main/Parser.class differ
diff --git a/build/classes/java/main/ParserOutput.class b/build/classes/java/main/ParserOutput.class
new file mode 100644
index 0000000000..b9cee5c9f3
Binary files /dev/null and b/build/classes/java/main/ParserOutput.class differ
diff --git a/build/classes/java/main/Storage.class b/build/classes/java/main/Storage.class
new file mode 100644
index 0000000000..f99f7e9d4f
Binary files /dev/null and b/build/classes/java/main/Storage.class differ
diff --git a/build/classes/java/main/Task.class b/build/classes/java/main/Task.class
new file mode 100644
index 0000000000..61010c7882
Binary files /dev/null and b/build/classes/java/main/Task.class differ
diff --git a/build/classes/java/main/TaskList.class b/build/classes/java/main/TaskList.class
new file mode 100644
index 0000000000..6448ce9c5b
Binary files /dev/null and b/build/classes/java/main/TaskList.class differ
diff --git a/build/classes/java/main/TimeException.class b/build/classes/java/main/TimeException.class
new file mode 100644
index 0000000000..22becdc694
Binary files /dev/null and b/build/classes/java/main/TimeException.class differ
diff --git a/build/classes/java/main/Todo.class b/build/classes/java/main/Todo.class
new file mode 100644
index 0000000000..f603ac19c6
Binary files /dev/null and b/build/classes/java/main/Todo.class differ
diff --git a/build/classes/java/main/UI.class b/build/classes/java/main/UI.class
new file mode 100644
index 0000000000..5b215176da
Binary files /dev/null and b/build/classes/java/main/UI.class differ
diff --git a/build/libs/duke.jar b/build/libs/duke.jar
new file mode 100644
index 0000000000..ad3449d50d
Binary files /dev/null and b/build/libs/duke.jar differ
diff --git a/build/libs/logs b/build/libs/logs
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/build/tmp/shadowJar/MANIFEST.MF b/build/tmp/shadowJar/MANIFEST.MF
new file mode 100644
index 0000000000..8a51453653
--- /dev/null
+++ b/build/tmp/shadowJar/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: Launcher
+
diff --git a/docs/README.md b/docs/README.md
old mode 100644
new mode 100755
index fd44069597..aba46f691d
--- a/docs/README.md
+++ b/docs/README.md
@@ -2,14 +2,137 @@
## Features
-### Feature 1
-Description of feature.
+### `list` - List all the tasks in the current task list
+
+Example of usage:
+
+`list`
+
+Expected outcome:
+
+`_______________________________________________________`
+
+`1.[T][X]shopping`
+
+`2.[T][ ]write some code`
+
+`_______________________________________________________`
+
+### `todo` - Add a task without any date/time attached to it
+
+Example of usage:
+
+`todo cook dinner`
+
+Expected outcome:
+
+`_______________________________________________________`
+
+`Added cook dinner.`
+
+`You now have 3 items in the list.`
+
+`______________________________________________________`
+
+### `deadline` - Add a task with deadline (e.g. 2019-10-15) attached to it
+
+Example of usage:
+
+`deadline sign consent form /by 2019-10-15`
+
+Expected outcome:
+
+`_______________________________________________________`
+
+` Added deadline sign consent form.`
+
+`[D][ ] sign consent form (by: Oct 15 2019)`
+
+`You now have 4 items in the list`
+
+`_______________________________________________________`
+
+### `event` - Add a task with date (e.g. 2019-10-15) attached to it
+
+Example of usage:
+
+`event project meeting /at 2019-10-15`
+
+Expected outcome:
+
+`_______________________________________________________`
+
+`Added event project meeting.`
+
+`[E][ ] project meeting (by: Oct 15 2019)`
+
+`Now you have 5 tasks in the list`
+
+`_______________________________________________________`
+
+### `delete` - Delete a task from the list
+
+Example of usage:
+
+`list`
+
+`_______________________________________________________`
+
+` 1.[T][X] shopping`
+
+` 2.[T][X] write some code`
+
+` 3.[T][X] cook dinner`
+
+` 4.[D][ ] deadline sign consent form (by: Oct 15 2019)`
+
+` 5.[E][X] event project meeting (at: Oct 15 2019)`
+
+
+` _______________________________________________________`
+
+`delete 3`
+
+Expected outcome:
+
+`_______________________________________________________`
+
+`I have removed item 3`
+`_______________________________________________________`
+
+`list`
+
+
+` 1.[T][X] shopping`
+
+` 2.[T][X] write some code`
+
+` 3.[D][ ] deadline sign consent form (by: Oct 15 2019)`
+
+` 4.[E][X] event project meeting (at: Oct 15 2019)`
+
+
+` ______________________________________________________`
+
+### `find` - Find a task from the list
+
+Example of usage:
+
+`find code`
+
+Expected outcome:
+
+`_______________________________________________________`
+
+`[T][X] write some code`
+`_______________________________________________________`
+
## Usage
### `Keyword` - Describe action
-Describe action and its outcome.
+Enter keyward with command line arguments to prompt duke to do something
Example of usage:
diff --git a/docs/Ui.png b/docs/Ui.png
new file mode 100644
index 0000000000..28f724cc70
Binary files /dev/null and b/docs/Ui.png differ
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/ip.ipr b/ip.ipr
new file mode 100644
index 0000000000..0857022103
--- /dev/null
+++ b/ip.ipr
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.6
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ip.iws b/ip.iws
new file mode 100644
index 0000000000..d5bc7591fb
--- /dev/null
+++ b/ip.iws
@@ -0,0 +1,207 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ localhost
+ 5050
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java
new file mode 100755
index 0000000000..4ef008a180
--- /dev/null
+++ b/src/main/java/Deadline.java
@@ -0,0 +1,20 @@
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public class Deadline extends Task {
+
+ private LocalDate deadline;
+ private DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-M-dd");
+
+
+ Deadline(String name, String time) {
+ super(name);
+ this.deadline = LocalDate.parse(time, format);
+ }
+
+ @Override
+ public String toString(){
+ return "[D]" + super.toString() + " (by:" + this.deadline.format(DateTimeFormatter.ofPattern("MMM dd YYYY")) + ")";
+ }
+}
diff --git a/src/main/java/DescriptionException.java b/src/main/java/DescriptionException.java
new file mode 100644
index 0000000000..29e87bc73b
--- /dev/null
+++ b/src/main/java/DescriptionException.java
@@ -0,0 +1,5 @@
+public class DescriptionException extends DukeException {
+ public DescriptionException(String event){
+ super("The description of a " + event + " cannot be empty");
+ }
+}
diff --git a/src/main/java/DialogBox.java b/src/main/java/DialogBox.java
new file mode 100644
index 0000000000..fd983ba156
--- /dev/null
+++ b/src/main/java/DialogBox.java
@@ -0,0 +1,40 @@
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.layout.HBox;
+
+public class DialogBox extends HBox {
+
+ private Label text;
+
+ public DialogBox(Label l) {
+ text = l;
+
+ text.setWrapText(true);
+
+ this.setAlignment(Pos.TOP_RIGHT);
+ this.getChildren().addAll(text);
+ }
+
+ /**
+ * Flips the dialog box such that the ImageView is on the left and text on the right.
+ */
+ private void flip() {
+ this.setAlignment(Pos.TOP_LEFT);
+ ObservableList tmp = FXCollections.observableArrayList(this.getChildren());
+ FXCollections.reverse(tmp);
+ this.getChildren().setAll(tmp);
+ }
+
+ public static DialogBox getUserDialog(Label l) {
+ return new DialogBox(l);
+ }
+
+ public static DialogBox getDukeDialog(Label l) {
+ var dialog = new DialogBox(l);
+ dialog.flip();
+ return dialog;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java
old mode 100644
new mode 100755
index 5d313334cc..ae5f31bbd7
--- a/src/main/java/Duke.java
+++ b/src/main/java/Duke.java
@@ -1,10 +1,199 @@
-public class Duke {
- public static void main(String[] args) {
- String logo = " ____ _ \n"
- + "| _ \\ _ _| | _____ \n"
- + "| | | | | | | |/ / _ \\\n"
- + "| |_| | |_| | < __/\n"
- + "|____/ \\__,_|_|\\_\\___|\n";
- System.out.println("Hello from\n" + logo);
+
+import java.util.List;
+
+
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+
+
+public class Duke extends Application {
+
+ private UI ui;
+ private TaskList taskList;
+
+
+ private ScrollPane scrollPane;
+ private VBox dialogueContainer;
+ private TextField userInput;
+ private Button sendButton;
+ private Scene scene;
+
+ public Duke() {
+ Storage store = new Storage("./logs");
+ this.taskList = new TaskList(store);
+ this.ui = new UI();
+ }
+
+
+ private void readParse(ParserOutput parserOutput) throws DukeException {
+ switch (parserOutput.getAction()) {
+ case 1: //delete
+ this.taskList.remove(parserOutput.getIndex());
+ ui.printRemoved(parserOutput.getIndex());
+ break;
+ case 2: //done
+ Task doneTask = this.taskList.get(parserOutput.getIndex());
+ doneTask.setDone(true);
+ this.taskList.set(parserOutput.getIndex(), doneTask);
+ ui.printDone(doneTask);
+ break;
+ case 3: //add
+ this.taskList.add(parserOutput.getTask());
+ ui.printAdded(parserOutput.getTask(), this.taskList.getCount());
+ break;
+ case 4: //find
+ List results = this.taskList.find((parserOutput.getSearchString()));
+ ui.printFind(results);
+ break;
+ case 5: //list
+ ui.printList(this.taskList);
+ break;
+ default:
+ throw new DukeException("action not found");
+ }
+ }
+ public int run() throws DukeException {
+ ui.printHello();
+ while(true){
+ String userInput = ui.getInputFromUser();
+ ParserOutput parserOutput = null;
+ try {
+ parserOutput = Parser.parse(userInput);
+ } catch (DukeException e) {
+ System.out.println(e.getMessage());
+ continue;
+ }
+ UI.printline();
+ if (parserOutput.isBye()) {
+ break;
+ }
+ this.readParse(parserOutput);
+ ui.printline();
+ }
+ ui.printGoodbye();
+ return 0;
+ }
+
+ private String readParseGui(ParserOutput parserOutput) {
+ switch (parserOutput.getAction()) {
+ case 1: //remove
+ this.taskList.remove(parserOutput.getIndex());
+ return ui.printRemoved(parserOutput.getIndex());
+ case 2: //done
+ Task doneTask = this.taskList.get(parserOutput.getIndex());
+ doneTask.setDone(true);
+ this.taskList.set(parserOutput.getIndex(), doneTask);
+ return ui.printDone(doneTask);
+ case 3: //add
+ this.taskList.add(parserOutput.getTask());
+ return ui.printAdded(parserOutput.getTask(), this.taskList.getCount());
+ case 4: //find
+ List results = this.taskList.find(parserOutput.getSearchString());
+ return ui.printFind(results);
+ case 5: //list
+ return ui.printList(this.taskList);
+ default:
+ return("action not found");
+
+ }
+ }
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ Label helloWorld = new Label("Hello World!");
+ Scene scene = new Scene(helloWorld);
+
+ stage.setScene(scene); //set up stage to show screen
+ stage.show(); //render
+
+ //Container for contents of chat
+ scrollPane = new ScrollPane();
+ dialogueContainer = new VBox();
+ scrollPane.setContent(dialogueContainer);
+
+ userInput = new TextField();
+ sendButton = new Button("Send");
+
+ AnchorPane mainLayout = new AnchorPane();
+ mainLayout.getChildren().addAll(scrollPane, userInput, sendButton);
+
+ scene = new Scene(mainLayout);
+
+ stage.setScene(scene);
+ stage.setTitle("Duke");
+ stage.setResizable(false);
+ stage.setMinHeight(600.0);
+ stage.setMinWidth(400.0);
+
+ mainLayout.setPrefSize(400.0, 600.0);
+
+ scrollPane.setPrefSize(385, 535);
+ scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
+ scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
+
+ scrollPane.setVvalue(1.0);
+ scrollPane.setFitToWidth(true);
+
+ dialogueContainer.setPrefHeight(Region.USE_COMPUTED_SIZE);
+
+ userInput.setPrefWidth(325.0);
+ sendButton.setPrefWidth(55.0);
+
+ AnchorPane.setTopAnchor(scrollPane, 1.0);
+
+ AnchorPane.setBottomAnchor(sendButton, 1.0);
+ AnchorPane.setRightAnchor(sendButton, 1.0);
+
+ AnchorPane.setLeftAnchor(userInput , 1.0);
+ AnchorPane.setBottomAnchor(userInput, 1.0);
+
+ stage.show();
+
+ sendButton.setOnMouseClicked((event) -> {
+ handleUserInput();
+ });
+
+ userInput.setOnAction((event) -> {
+ handleUserInput();
+ });
+
+ //Scroll down to the end every time dialogContainer's height changes.
+ dialogueContainer.heightProperty().addListener((observable) -> scrollPane.setVvalue(1.0));
+ }
+
+
+ private void handleUserInput() {
+ Label userText = new Label(userInput.getText());
+ Label dukeText = new Label(getResponse(userInput.getText()));
+ dialogueContainer.getChildren().addAll(
+ DialogBox.getUserDialog(userText),
+ DialogBox.getDukeDialog(dukeText)
+ );
+ userInput.clear();
+ }
+
+ private String getResponse(String input) {
+ ParserOutput parserOutput = null;
+ try{
+ parserOutput = Parser.parse(input);
+ } catch (DukeException e) {
+ return e.getMessage();
+ }
+
+ if (parserOutput.isBye()) {
+ return ui.printGoodbye();
+ }
+
+ return readParseGui(parserOutput);
+ }
+
+ public static void main(String[] args) throws DukeException {
+ new Duke().run();
}
}
diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java
new file mode 100644
index 0000000000..1079d2754b
--- /dev/null
+++ b/src/main/java/DukeException.java
@@ -0,0 +1,6 @@
+
+public class DukeException extends Exception {
+ public DukeException(String error){
+ super("Uh Oh, there seems to be an error somewhere \n" + error);
+ }
+}
diff --git a/src/main/java/Event.java b/src/main/java/Event.java
new file mode 100755
index 0000000000..80120a0bb5
--- /dev/null
+++ b/src/main/java/Event.java
@@ -0,0 +1,20 @@
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+
+
+public class Event extends Task {
+
+ private LocalDate time;
+ private DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-M-dd");
+
+ Event(String name, String time) {
+ super(name);
+ this.time = LocalDate.parse(time, format);
+ }
+
+ @Override
+ public String toString(){
+ return "[E]" + super.toString() + " (at:" + this.time.format(DateTimeFormatter.ofPattern("MMM dd YYYY")) + ")";
+ }
+}
diff --git a/src/main/java/Launcher.java b/src/main/java/Launcher.java
new file mode 100644
index 0000000000..f6485dba64
--- /dev/null
+++ b/src/main/java/Launcher.java
@@ -0,0 +1,11 @@
+
+import javafx.application.Application;
+
+/**
+ * A launcher class to workaround classpath issues.
+ */
+public class Launcher {
+ public static void main(String[] args) {
+ Application.launch(Duke.class, "./logs");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/NotFoundException.java b/src/main/java/NotFoundException.java
new file mode 100644
index 0000000000..a33d127e4e
--- /dev/null
+++ b/src/main/java/NotFoundException.java
@@ -0,0 +1,5 @@
+public class NotFoundException extends DukeException {
+ public NotFoundException(){
+ super("OOPS!!! I'm sorry, but I don't know what that means :-(" );
+ }
+}
diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java
new file mode 100644
index 0000000000..f68592a009
--- /dev/null
+++ b/src/main/java/Parser.java
@@ -0,0 +1,75 @@
+
+public class Parser {
+
+ public static ParserOutput parse(String raw_in) throws DescriptionException, TimeException, NotFoundException {
+ String reconnected= "";
+ String timing = "";
+ String[] input = raw_in.split(" ");
+ if (raw_in.equals("bye")) {
+ return ParserOutput.byeOutput();
+ } else {
+ switch (input[0]) {
+ case "list":
+ return ParserOutput.listOutput();
+ case "done":
+ int itemToBeUpdatedIndex = Integer.parseInt(input[1]);
+ return ParserOutput.doneOutput(itemToBeUpdatedIndex);
+
+
+ case "todo":
+ for (String str: input) {
+ reconnected = reconnected + " " + str;
+ }
+
+ return ParserOutput.addOutput(new Todo(reconnected));
+
+ case "deadline":
+ int seq = 0;
+ while (!input[seq].equals("/by")) {
+ reconnected = reconnected + " " + input[seq];
+ seq++;
+ if (seq == input.length) {
+ throw new DescriptionException(input[0]);
+ }
+ }
+
+ if (seq + 1 == input.length) {
+ throw new TimeException(input[0]);
+ }
+
+ for (int i = seq + 1; i < input.length; i++) {
+ timing = timing + " " + input[i];
+ }
+ return ParserOutput.addOutput(new Deadline(reconnected, timing.trim()));
+
+ case "event":
+ int seq2 = 0;
+ while (!input[seq2].equals("/at")) {
+ reconnected = reconnected + " " + input[seq2];
+ seq2++;
+ if (seq2 == input.length) {
+ throw new DescriptionException(input[0]);
+ }
+ }
+
+ if (seq2 + 1 == input.length) {
+ throw new TimeException(input[0]);
+ }
+
+ for (int i = seq2 + 1; i < input.length; i++) {
+ timing = timing + " " + input[i];
+ }
+ return ParserOutput.addOutput(new Event(reconnected, timing.trim()));
+
+ case "delete":
+ return ParserOutput.removeOutput(Integer.parseInt(input[1]));
+
+ case "find":
+ return ParserOutput.findOutput(input[1]);
+ default:
+ throw new NotFoundException();
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/ParserOutput.java b/src/main/java/ParserOutput.java
new file mode 100644
index 0000000000..3c12c811e6
--- /dev/null
+++ b/src/main/java/ParserOutput.java
@@ -0,0 +1,67 @@
+
+public class ParserOutput {
+ private boolean bye;
+ private Task task;
+ private int index;
+ private int action;
+ private String searchString;
+
+ private ParserOutput(boolean bye, Task task, int action, int index) {
+ this.bye = bye;
+ this.task = task;
+ this.action = action;
+ this.index = index;
+ }
+ private ParserOutput(boolean bye, Task task, int action, int index, String searchString) {
+ this.bye = bye;
+ this.task = task;
+ this.action = action;
+ this.index = index;
+ this.searchString = searchString;
+ }
+
+
+ public static ParserOutput byeOutput() {
+ return new ParserOutput(true, null, 0, 0);
+ }
+
+ public static ParserOutput removeOutput(int index) {
+ return new ParserOutput(false, null, 1, index);
+ }
+
+ public static ParserOutput doneOutput(int index) {
+ return new ParserOutput(false, null, 2, index);
+ }
+
+ public static ParserOutput addOutput(Task task) {
+ return new ParserOutput(false, task, 3, 0);
+ }
+
+ public static ParserOutput findOutput(String str) {
+ return new ParserOutput(false, null, 4, 0, str);
+ }
+
+ public static ParserOutput listOutput() {
+ return new ParserOutput(false, null, 5, 0);
+ }
+
+ public boolean isBye() {
+ return bye;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public int getAction() {
+ return action;
+ }
+
+ public Task getTask() {
+ return task;
+ }
+
+ public String getSearchString(){
+ return searchString;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java
new file mode 100644
index 0000000000..7f344d7a6b
--- /dev/null
+++ b/src/main/java/Storage.java
@@ -0,0 +1,65 @@
+
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Scanner;
+import java.io.File;
+
+public class Storage {
+ private ArrayList itemList;
+ private String path;
+
+ public Storage (String path) {
+ File logFile = new File(path);
+ try {
+ if (logFile.isFile()) {
+ Scanner logs = new Scanner(logFile);
+ logs.close();
+ } else {
+ logFile.createNewFile();
+ }
+ } catch (IOException e) {
+ System.out.println("no file created " + e);
+ }
+
+ this.path = path;
+ try {
+ this.itemList = new ArrayList<>(Files.readAllLines(Paths.get(path)));
+ } catch (IOException e) {
+ System.out.println(e);
+ this.itemList = new ArrayList<>();
+ }
+ }
+ public void add(Task task) {
+ this.itemList.add(task.toString());
+ this.update();
+ }
+ public void set(int index, Task newTask) {
+ this.itemList.set(index -1, newTask.toString());
+ this.update();
+ }
+ public void remove(int index) {
+ this.itemList.remove(index -1);
+ this.update();
+ }
+
+ public ArrayList readStorage () {
+ return this.itemList;
+ }
+ public void update() {
+ try {
+ PrintWriter writer = new PrintWriter(path);
+ for (String line : this.itemList) {
+ writer.println(line);
+ }
+ writer.close();
+ } catch (FileNotFoundException e) {
+ System.out.println(e);
+ }
+ }
+}
+
diff --git a/src/main/java/Task.java b/src/main/java/Task.java
new file mode 100755
index 0000000000..5df31e0de5
--- /dev/null
+++ b/src/main/java/Task.java
@@ -0,0 +1,33 @@
+
+public class Task {
+ String name;
+ boolean done;
+
+ Task( String name){
+ this.name = name;
+ this.done = false;
+ }
+
+
+ public String getName() {
+ return name;
+ }
+
+ public void setDone(boolean bool){
+ this.done = bool;
+ }
+
+ public boolean isDone(){
+ return this.done;
+ }
+
+ @Override
+ public String toString() {
+ if (done) {
+ return "[X] " + name;
+ } else {
+ return "[ ] " + name;
+ }
+ }
+
+}
diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java
new file mode 100644
index 0000000000..d9f3b50f8f
--- /dev/null
+++ b/src/main/java/TaskList.java
@@ -0,0 +1,52 @@
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class TaskList {
+ private Storage storage;
+ private List tasks;
+ private int count;
+
+ public TaskList(Storage storage) {
+ this.storage = storage;
+ this.tasks = new ArrayList<>();
+
+ }
+
+
+ public Task get(int index) {
+ return this.tasks.get(index - 1);
+ }
+
+ public void remove(int index) {
+ this.storage.remove(index);
+ this.tasks.remove(index -1);
+ this.count--;
+ }
+
+ public void set(int index, Task task) {
+ this.storage.set(index, task);
+ this.tasks.set(index -1, task );
+ }
+
+ public void add(Task task) {
+ this.storage.add(task);
+ this.tasks.add(task);
+ this.count++;
+ }
+
+ public List find (String str){
+ Listresults = new ArrayList<>();
+ for (Task t : tasks){
+ if(t.getName().contains(str)){
+ results.add(t);
+ }
+ }
+ return results;
+ }
+
+ public int getCount() {
+ return this.count;
+ }
+
+}
diff --git a/src/main/java/TimeException.java b/src/main/java/TimeException.java
new file mode 100644
index 0000000000..1b79389b70
--- /dev/null
+++ b/src/main/java/TimeException.java
@@ -0,0 +1,6 @@
+
+public class TimeException extends DukeException {
+ public TimeException(String event){
+ super("The timing of " + event + "cannot be empty");
+ }
+}
diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java
new file mode 100755
index 0000000000..812e74ed24
--- /dev/null
+++ b/src/main/java/Todo.java
@@ -0,0 +1,12 @@
+public class Todo extends Task {
+
+
+ Todo(String name) {
+ super(name);
+ }
+
+ @Override
+ public String toString(){
+ return "[T]" + super.toString();
+ }
+}
diff --git a/src/main/java/UI.java b/src/main/java/UI.java
new file mode 100644
index 0000000000..238c2b29c6
--- /dev/null
+++ b/src/main/java/UI.java
@@ -0,0 +1,79 @@
+import java.util.Scanner;
+import java.util.TreeSet;
+import java.util.List;
+
+public class UI {
+ private static final String line = "────────────────────────────────────────────────────────────────────";
+ private Scanner sc;
+ private String raw_in;
+ private String[] input;
+
+ public UI() {
+ this.sc = new Scanner(System.in);
+ }
+
+ public String getInputFromUser() {
+ this.raw_in = this.sc.nextLine().trim();
+ return raw_in;
+ }
+
+ public static String printHello() {
+ String logo = " ____ _ \n"
+ + "| _ \\ _ _| | _____ \n"
+ + "| | | | | | | |/ / _ \\\n"
+ + "| |_| | |_| | < __/\n"
+ + "|____/ \\__,_|_|\\_\\___|\n";
+
+ String str = "Hello from\n" + logo +"Greetings! I am Duke! How may I assist you?\n" + line;
+ System.out.println(str);
+ return str;
+ }
+
+ public static String printGoodbye() {
+ System.out.println("\nGoodbye\n");
+ return "\n Goodbye \n";
+ }
+
+ public static String printList(TaskList tasks) {
+ String str ="";
+
+ for (int i = 1; i <= tasks.getCount(); i++) {
+ System.out.println(i + ". " + tasks.get(i).toString());
+ str = str + i + "." + tasks.get(i).toString() + "\n";
+ }
+ return str;
+ }
+
+ public static void printline() {
+ System.out.println(line);
+ }
+
+ public String printDone(Task task) {
+ String str = "Alright, I will mark this as done.\n" + task.toString();
+ System.out.println(str);
+ return str;
+
+ }
+
+ public String printAdded(Task task, int count) {
+ String str ="Added" + task.getName() + ". \nYou now have " + count + " items in your list.";
+ System.out.println(str);
+ return str;
+ }
+
+ public String printRemoved(int index) {
+ String str ="I have removed item " + index + ".";
+ System.out.println(str);
+ return str;
+ }
+
+ public String printFind(List tasks){
+ String str = "";
+ for (Task t : tasks){
+ System.out.println(t);
+ str = str + t.toString() + "\n";
+ }
+ return str;
+
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/ParserTest.java b/src/test/java/ParserTest.java
new file mode 100644
index 0000000000..19021a0c12
--- /dev/null
+++ b/src/test/java/ParserTest.java
@@ -0,0 +1,46 @@
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+//import static org.hamcrest.MatcherAssert.assertThat;
+//import static org.hamcrest.CoreMatchers.instanceOf;
+
+public class ParserTest {
+
+ @DisplayName("Test for list. ")
+ @Test
+ public void listTest() throws DukeException {
+ ParserOutput out = Parser.parse("list");
+ assertEquals(out.getAction(), 5);
+ }
+
+ @DisplayName("Test for add. ")
+ @Test
+ public void addTest() throws DukeException {
+ ParserOutput out = Parser.parse("todo do something");
+ assertEquals(out.getAction(), 3);
+ }
+
+
+
+ @DisplayName("Test for delete. ")
+ @Test
+ public void deleteTest() throws DukeException {
+ ParserOutput out = Parser.parse("delete 1");
+ assertEquals(out.getAction(), 1);
+ }
+
+ @DisplayName("Test for done. ")
+ @Test
+ public void doneTest() throws DukeException {
+ ParserOutput out = Parser.parse("done 1");
+ assertEquals(out.getAction(), 2);
+ }
+
+ @DisplayName("Test for bye. ")
+ @Test
+ public void byeTest() throws DukeException {
+ ParserOutput out = Parser.parse("bye");
+ assertEquals(out.isBye(), true);
+ }
+}
\ No newline at end of file
diff --git a/text-ui-test/ACTUAL.TXT b/text-ui-test/ACTUAL.TXT
new file mode 100644
index 0000000000..c0f9ecb764
--- /dev/null
+++ b/text-ui-test/ACTUAL.TXT
@@ -0,0 +1,25 @@
+Hello from
+ ____ _
+| _ \ _ _| | _____
+| | | | | | | |/ / _ \
+| |_| | |_| | < __/
+|____/ \__,_|_|\_\___|
+
+Got it. I've added this task:
+todo meet friends
+you now have 1 tasks in the list
+Got it. I've added this task:
+deadline do 2103 by 123
+you now have 2 tasks in the list
+Got it. I've added this task:
+event lecture at 456
+you now have 3 tasks in the list
+1[T][ ] todo meet friends
+2[D][ ] deadline do 2103 (by:123)
+3[E][ ] event lecture (at:456)
+Nice! I've marked this Task as done:
+1[T][X] todo meet friends
+1[T][X] todo meet friends
+2[D][ ] deadline do 2103 (by:123)
+3[E][ ] event lecture (at:456)
+Bye. Hope to see you again
diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT
old mode 100644
new mode 100755
index 657e74f6e7..c0f9ecb764
--- a/text-ui-test/EXPECTED.TXT
+++ b/text-ui-test/EXPECTED.TXT
@@ -5,3 +5,21 @@ Hello from
| |_| | |_| | < __/
|____/ \__,_|_|\_\___|
+Got it. I've added this task:
+todo meet friends
+you now have 1 tasks in the list
+Got it. I've added this task:
+deadline do 2103 by 123
+you now have 2 tasks in the list
+Got it. I've added this task:
+event lecture at 456
+you now have 3 tasks in the list
+1[T][ ] todo meet friends
+2[D][ ] deadline do 2103 (by:123)
+3[E][ ] event lecture (at:456)
+Nice! I've marked this Task as done:
+1[T][X] todo meet friends
+1[T][X] todo meet friends
+2[D][ ] deadline do 2103 (by:123)
+3[E][ ] event lecture (at:456)
+Bye. Hope to see you again
diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt
old mode 100644
new mode 100755
index e69de29bb2..94e3165f8f
--- a/text-ui-test/input.txt
+++ b/text-ui-test/input.txt
@@ -0,0 +1,7 @@
+todo meet friends
+deadline do 2103 /by 123
+event lecture /at 456
+list
+done 1
+list
+bye
diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat
old mode 100644
new mode 100755
diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh
old mode 100644
new mode 100755