diff --git a/.todo.txt b/.todo.txt
new file mode 100644
index 0000000000..2845acb71b
--- /dev/null
+++ b/.todo.txt
@@ -0,0 +1,2 @@
+[T][N] hi
+[T][N] kasjdna
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..f5c99a7f66
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1 @@
+language: java
\ No newline at end of file
diff --git a/.txt b/.txt
new file mode 100644
index 0000000000..b6ea63bf1c
--- /dev/null
+++ b/.txt
@@ -0,0 +1,3 @@
+hello
+ yellow
+ mellow
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000000..b213c49c59
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,67 @@
+plugins {
+ id 'java'
+ id 'application'
+ id 'checkstyle'
+ id 'org.openjfx.javafxplugin' version '0.0.7'
+ id 'com.github.johnrengelman.shadow' version '5.1.0'
+}
+
+javafx {
+ version = "11.0.2"
+ modules = [ 'javafx.controls', 'javafx.fxml' ]
+}
+
+dependencies {
+ String javaFxVersion = '11'
+ implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux'
+ implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux'
+ implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux'
+ implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux'
+ implementation group: 'org.openjfx', name: 'javafx-media', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-media', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-media', version: javaFxVersion, classifier: 'linux'
+ implementation group: 'org.openjfx', name: 'javafx-web', version: javaFxVersion, classifier: 'win'
+ implementation group: 'org.openjfx', name: 'javafx-web', version: javaFxVersion, classifier: 'mac'
+ implementation group: 'org.openjfx', name: 'javafx-web', version: javaFxVersion, classifier: 'linux'
+
+ testCompile('org.junit.jupiter:junit-jupiter:5.5.1')
+ testImplementation('org.junit.jupiter:junit-jupiter:5.5.1')
+}
+
+test {
+ useJUnitPlatform()
+}
+
+checkstyle {
+ toolVersion = '8.23'
+}
+
+repositories {
+ mavenCentral()
+}
+
+application {
+ // Change this to your main class.
+ mainClassName = "duke.Launcher"
+}
+
+run {
+ standardInput = System.in
+}
+
+shadowJar {
+ archiveBaseName = "duke"
+ archiveVersion = "0.1.3"
+ archiveClassifier = null
+ archiveAppendix = null
+}
+group 'seedu.duke'
+version '0.1.0'
\ No newline at end of file
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
new file mode 100644
index 0000000000..b1a57ba6c0
--- /dev/null
+++ b/config/checkstyle/checkstyle.xml
@@ -0,0 +1,257 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/README.md b/docs/README.md
index fd44069597..4f3cefaac6 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,20 +1,105 @@
-# User Guide
+# Currents - User Guide
-## Features
+
-### Feature 1
-Description of feature.
+### Plan your personal timetable!
-## Usage
+## Features of Currents
-### `Keyword` - Describe action
+#### Todo: `todo`
+Allows you to track tasks that needs to be done and adds it to a list.
-Describe action and its outcome.
+#### Deadline: `deadline`
+Reminds you of your upcoming deadlines and adds it to a list.
-Example of usage:
+#### Event: `event`
+Remind you of your upcoming events and adds it to a list.
-`keyword (optional arguments)`
+#### Done: `done`
+Allows you to tick off todo/event/deadline tasks that have been completed.
-Expected outcome:
+#### Delete: `delete`
+Allows you to delete finished tasks or wrong tasks that was inputted.
-`outcome`
+#### Find: `find`
+Prints out matching words that you have inputted from the list.
+
+#### Expenses: `expenses`
+Allows you to record your expenses.
+
+#### List: `list`
+Prints out the entire list.
+
+#### Help: `help`
+Prints out all the commands that is available in the application.
+
+#### Bye: `bye`
+Closes the application.
+
+## Usage of Currents
+
+
+Command | Example | Description
+---------------|---------------|---------------
+`todo ` | todo go gym | Add a new to do task.
+`event /at
` | event party /at 20/06/2021 1700 | Add a new event task.
+`deadline /by
` | deadline essay /by 30/05/2023 2359 | Add a new deadline task.
+`done ` | done 1 | Ticks off a todo/event/deadline task.
+`delete ` | delete 1 | Deletes a tasks from the list
+`find ` | find essay | Find the words that match with your input and prints out corresponding tasks.
+`expenses $ /on ` | expenses $45.20 /on steak | Adds an expense to the list.
+`list` | list | Prints out everything that you have added to your list.
+`help` | help | Prints out all the command that you can use in the application.
+
+#### Todo: `todo`
+Expected Outcome:
+
+
+
+
+#### Event: `event`
+Expected Outcome:
+
+
+
+
+#### Deadline: `deadline`
+Expected Outcome:
+
+
+
+
+#### Done: `done`
+Expected Outcome:
+
+
+
+
+#### Delete: `delete`
+Expected Outcome:
+
+
+
+
+#### Find: `find`
+Expected Outcome:
+
+
+
+
+#### Expenses: `expenses`
+Expected Outcome:
+
+
+
+
+#### List: `list`
+Expected Outcome:
+
+
+
+
+#### Help: `help`
+Expected Outcome:
+
+
diff --git a/docs/Ui.png b/docs/Ui.png
new file mode 100644
index 0000000000..46791edda5
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..ddeb671b60
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-time-machine
\ No newline at end of file
diff --git a/docs/images/currents.jpg b/docs/images/currents.jpg
new file mode 100644
index 0000000000..1bc98621c9
Binary files /dev/null and b/docs/images/currents.jpg differ
diff --git a/docs/images/deadline.jpg b/docs/images/deadline.jpg
new file mode 100644
index 0000000000..7db8ef5cc9
Binary files /dev/null and b/docs/images/deadline.jpg differ
diff --git a/docs/images/delete.jpg b/docs/images/delete.jpg
new file mode 100644
index 0000000000..7993c6073e
Binary files /dev/null and b/docs/images/delete.jpg differ
diff --git a/docs/images/done.jpg b/docs/images/done.jpg
new file mode 100644
index 0000000000..8cbfdea290
Binary files /dev/null and b/docs/images/done.jpg differ
diff --git a/docs/images/event.jpg b/docs/images/event.jpg
new file mode 100644
index 0000000000..aee20d0214
Binary files /dev/null and b/docs/images/event.jpg differ
diff --git a/docs/images/expenses.jpg b/docs/images/expenses.jpg
new file mode 100644
index 0000000000..166e76fc69
Binary files /dev/null and b/docs/images/expenses.jpg differ
diff --git a/docs/images/find.jpg b/docs/images/find.jpg
new file mode 100644
index 0000000000..9fcbac5439
Binary files /dev/null and b/docs/images/find.jpg differ
diff --git a/docs/images/help.jpg b/docs/images/help.jpg
new file mode 100644
index 0000000000..863d925da3
Binary files /dev/null and b/docs/images/help.jpg differ
diff --git a/docs/images/list.jpg b/docs/images/list.jpg
new file mode 100644
index 0000000000..5f39e87386
Binary files /dev/null and b/docs/images/list.jpg differ
diff --git a/docs/images/todo.jpg b/docs/images/todo.jpg
new file mode 100644
index 0000000000..a95094fc84
Binary files /dev/null and b/docs/images/todo.jpg differ
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..87b738cbd0
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..4d12c764e2
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Sep 10 20:33:34 SGT 2019
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000000..af6708ff22
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000..6d57edc706
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000000..d1e92fe5db
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'duke'
diff --git a/src/.idea/$PRODUCT_WORKSPACE_FILE$ b/src/.idea/$PRODUCT_WORKSPACE_FILE$
new file mode 100644
index 0000000000..67bd976742
--- /dev/null
+++ b/src/.idea/$PRODUCT_WORKSPACE_FILE$
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/.idea/.gitignore b/src/.idea/.gitignore
new file mode 100644
index 0000000000..5c98b42884
--- /dev/null
+++ b/src/.idea/.gitignore
@@ -0,0 +1,2 @@
+# Default ignored files
+/workspace.xml
\ No newline at end of file
diff --git a/src/.idea/artifacts/src_jar.xml b/src/.idea/artifacts/src_jar.xml
new file mode 100644
index 0000000000..0f80aa6c05
--- /dev/null
+++ b/src/.idea/artifacts/src_jar.xml
@@ -0,0 +1,9 @@
+
+
+ $PROJECT_DIR$/out/artifacts/src_jar
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/.idea/misc.xml b/src/.idea/misc.xml
new file mode 100644
index 0000000000..1763e153b6
--- /dev/null
+++ b/src/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/.idea/modules.xml b/src/.idea/modules.xml
new file mode 100644
index 0000000000..47664256fc
--- /dev/null
+++ b/src/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/.idea/vcs.xml b/src/.idea/vcs.xml
new file mode 100644
index 0000000000..6c0b863585
--- /dev/null
+++ b/src/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java
deleted file mode 100644
index 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..9f37e4e0aa
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: Duke
+
diff --git a/src/main/java/data/todo.txt b/src/main/java/data/todo.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/main/java/duke/DialogBox.java b/src/main/java/duke/DialogBox.java
new file mode 100644
index 0000000000..cf63432648
--- /dev/null
+++ b/src/main/java/duke/DialogBox.java
@@ -0,0 +1,87 @@
+package duke;
+
+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.Background;
+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);
+ this.dialog.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
+ 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);
+ }
+
+ /**
+ * Sets the color of the dialog from the user.
+ *
+ * @param text User input.
+ * @param img Image that is linked to the user.
+ * @return Returns a DialogBox so that the user can use it to
+ * interact with the bot.
+ */
+ public static DialogBox getUserDialog(String text, Image img) {
+ DialogBox box = new DialogBox(text, img);
+ box.setBackground(Background.EMPTY);
+ String style = "-fx-background-color: rgb(255, 218, 26);"
+ + "-fx-text-fill: black";
+ box.dialog.setStyle(style);
+ return box;
+ }
+
+ /**
+ * Flips the dialog for the bot and colors the bot.
+ *
+ * @param text Output from the bot.
+ * @param img Duke image link to the bot.
+ * @return Returns a DialogBox so that the user can interact with it
+ * and see the dialog pop up.
+ */
+ public static DialogBox getDukeDialog(String text, Image img) {
+ var db = new DialogBox(text, img);
+ db.flip();
+ String style = "-fx-background-color: rgb(255, 218, 26);"
+ + "-fx-text-fill: black";
+ db.dialog.setStyle(style);
+ return db;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java
new file mode 100644
index 0000000000..fa0d8600dc
--- /dev/null
+++ b/src/main/java/duke/Duke.java
@@ -0,0 +1,127 @@
+package duke;
+
+import duke.exceptions.DukeException;
+
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import duke.execution.command.ByeCommand;
+import duke.execution.command.Command;
+import duke.execution.Parser;
+import duke.execution.Storage;
+import duke.execution.CompleteList;
+import duke.execution.Ui;
+import javafx.application.Platform;
+
+public class Duke {
+
+ private Storage storage;
+ private CompleteList errands;
+ private Ui ui;
+ private boolean byeBye = false;
+
+ /**
+ * Constructor for Duke.
+ *
+ * @throws IOException If the named file exists but is a directory rather than a regular file,
+ * does not exist but cannot be created, or cannot be opened for any other reason.
+ */
+ public Duke() throws IOException {
+ ui = new Ui();
+ storage = new Storage("./todo.txt");
+ try {
+ errands = new CompleteList(storage.load());
+ } catch (DukeException | FileNotFoundException e) {
+ ui.showLoadingError();
+ errands = new CompleteList();
+ }
+ }
+
+ /**
+ * Constructor for Duke that takes in a file to add text into.
+ *
+ * @param filepath File that the task is added to.
+ * @throws IOException If the named file exists but is a directory rather than a regular file,
+ * does not exist but cannot be created, or cannot be opened for any other reason.
+ */
+ public Duke(String filepath) throws IOException {
+ ui = new Ui();
+ storage = new Storage(filepath);
+ try {
+ errands = new CompleteList(storage.load());
+ } catch (DukeException | FileNotFoundException e) {
+ ui.showLoadingError();
+ errands = new CompleteList();
+ }
+ }
+
+ /**
+ * Contains the methods to start the bot and
+ * start to take in inputs for the bot.
+ */
+ public void run() {
+ System.out.println("test");
+ ui.greeting();
+ boolean isThereANextCommand = false;
+ while (!isThereANextCommand) {
+ try {
+ String fullCommand = ui.readCommand();
+ ui.printLine(); // show the divider line ("_______")
+ Command c = Parser.parse(fullCommand);
+ System.out.println(c.execute(errands, ui, storage));
+ isThereANextCommand = c.shouldExit();
+ } catch (DukeException | IOException e) {
+ ui.showError(e.getMessage());
+ } finally {
+ ui.printLine();
+ }
+ }
+ }
+
+ /**
+ * Main method.
+ */
+ public static void main(String[] args) throws IOException {
+ new Duke("todo.txt").run();
+ }
+
+ /**
+ * You should have your own function to generate a response to user input.
+ * Replace this stub with your completed method.
+ */
+ String getResponse(String input) throws DukeException, IOException {
+ try {
+ String fullCommand = input;
+ Command c = Parser.parse(fullCommand);
+ if (c instanceof ByeCommand) {
+ byeBye = true;
+ }
+ return (c.execute(errands, ui, storage));
+ } catch (DukeException | IOException e) {
+ ui.showError(e.getMessage());
+ return e.getMessage();
+ } finally {
+ if (byeBye) {
+ closeApplication();
+ }
+ }
+ }
+
+ /**
+ * Closes the application.
+ */
+ private void closeApplication() {
+ Timer countdown = new Timer();
+ TimerTask onExit = new TimerTask() {
+ @Override
+ public void run() {
+ Platform.exit();
+ System.exit(0);
+ }
+ };
+
+ countdown.schedule(onExit, 2000);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/Launcher.java b/src/main/java/duke/Launcher.java
new file mode 100644
index 0000000000..5483e63637
--- /dev/null
+++ b/src/main/java/duke/Launcher.java
@@ -0,0 +1,12 @@
+package duke;
+
+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/duke/Main.java b/src/main/java/duke/Main.java
new file mode 100644
index 0000000000..33b3ba325d
--- /dev/null
+++ b/src/main/java/duke/Main.java
@@ -0,0 +1,35 @@
+package duke;
+
+import java.io.IOException;
+
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Stage;
+
+/**
+ * A GUI for Duke using FXML.
+ */
+public class Main extends Application {
+
+ private Duke duke = new Duke();
+
+ public Main() throws IOException {
+ }
+
+ @Override
+ public void start(Stage stage) {
+ 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.setTitle("Currents - Plan your personal timetable!");
+ stage.show();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/MainWindow.java b/src/main/java/duke/MainWindow.java
new file mode 100644
index 0000000000..1765f14dd1
--- /dev/null
+++ b/src/main/java/duke/MainWindow.java
@@ -0,0 +1,70 @@
+package duke;
+
+import duke.exceptions.DukeException;
+
+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;
+
+import duke.execution.Ui;
+
+import java.io.IOException;
+
+/**
+ * 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/ester.jpg"));
+ private Image dukeImage = new Image(this.getClass().getResourceAsStream("/images/JoshuaSeet.jpg"));
+
+ /**
+ * Initializes the console that pops up when the application runs.
+ */
+ @FXML
+ public void initialize() {
+ Ui ui = new Ui();
+
+ scrollPane.vvalueProperty().bind(dialogContainer.heightProperty());
+ String style = "-fx-background-color: rgb(0, 81, 186);";
+ this.dialogContainer.setStyle(style);
+
+ //duke welcome message upon opening GUI
+ dialogContainer.getChildren().addAll(
+ DialogBox.getDukeDialog(ui.greeting(), dukeImage)
+ );
+ }
+
+ 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() throws IOException, DukeException, InterruptedException {
+ String input = userInput.getText();
+ String response = duke.getResponse(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/duke/exceptions/DukeException.java b/src/main/java/duke/exceptions/DukeException.java
new file mode 100644
index 0000000000..6233d24b4f
--- /dev/null
+++ b/src/main/java/duke/exceptions/DukeException.java
@@ -0,0 +1,14 @@
+package duke.exceptions;
+
+public class DukeException extends Exception {
+
+ /**
+ * Constructor for Duke Exceptions.
+ *
+ * @param message takes in the error and
+ * prints it out to the user.
+ */
+ public DukeException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/execution/CompleteList.java b/src/main/java/duke/execution/CompleteList.java
new file mode 100644
index 0000000000..708f44e058
--- /dev/null
+++ b/src/main/java/duke/execution/CompleteList.java
@@ -0,0 +1,33 @@
+package duke.execution;
+
+import duke.models.Planner;
+
+import java.util.ArrayList;
+
+public class CompleteList {
+
+ public static ArrayList listOfPlans = new ArrayList();
+
+ /**
+ * Constructor for CompleteList.
+ */
+ public CompleteList() {
+
+ }
+
+ /**
+ * Overloaded Constructor for Task list in
+ * the event that a array list is available
+ * from the file.
+ *
+ * @param list Arraylist that contains all the tasks.
+ */
+ public CompleteList(ArrayList list) {
+ listOfPlans = list;
+ }
+
+ public void addToCompleteList(Planner assignment) {
+ assert assignment != null;
+ listOfPlans.add(assignment);
+ }
+}
diff --git a/src/main/java/duke/execution/ExpenseList.java b/src/main/java/duke/execution/ExpenseList.java
new file mode 100644
index 0000000000..6045413dd6
--- /dev/null
+++ b/src/main/java/duke/execution/ExpenseList.java
@@ -0,0 +1,23 @@
+package duke.execution;
+
+import duke.models.Expenses;
+
+import java.util.ArrayList;
+
+public class ExpenseList extends CompleteList {
+
+ protected static ArrayList listOfExpenses = new ArrayList();
+
+ public ExpenseList() {
+
+ }
+
+ public ExpenseList(ArrayList list) {
+ listOfExpenses = list;
+ }
+
+ public void addToExpensesList(Expenses assignment) {
+ assert assignment != null;
+ listOfExpenses.add(assignment);
+ }
+}
diff --git a/src/main/java/duke/execution/Parser.java b/src/main/java/duke/execution/Parser.java
new file mode 100644
index 0000000000..80de53367f
--- /dev/null
+++ b/src/main/java/duke/execution/Parser.java
@@ -0,0 +1,571 @@
+package duke.execution;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import duke.Duke;
+import duke.execution.command.Command;
+import duke.execution.command.ByeCommand;
+import duke.execution.command.DeadlineCommand;
+import duke.execution.command.EventCommand;
+import duke.execution.command.DoneCommand;
+import duke.execution.command.DeleteCommand;
+import duke.execution.command.FindCommand;
+import duke.execution.command.HelpCommand;
+import duke.execution.command.ListCommand;
+import duke.execution.command.ToDoCommand;
+import duke.execution.command.ExpensesCommand;
+import duke.exceptions.DukeException;
+
+public class Parser {
+
+ /**
+ * Makes sense of the user input and finds out what command
+ * the user typed in.
+ *
+ * @param line Input by user.
+ * @return Returns the command that comes from the user.
+ * @throws DukeException Prints out the message to tell the user
+ * what was wrong with the input by the user.
+ */
+ public static Command parse(String line) throws DukeException {
+ assert line != null;
+ String properInput = line.trim().toLowerCase();
+ String[] inputArray = properInput.split(" ");
+ String taskType = inputArray[0];
+ assert taskType != null;
+ if (!isValidTaskType(taskType)) {
+ Ui.printIndent();
+ throw new DukeException("☹ OOPS!!! I'm sorry, but I don't \n"
+ + "know what that means :-(\n"
+ + " I can only do these functions for now: \n \n"
+ + " Todo \n" + " Eg. todo __(task)__\n"
+ + " Event \n" + " Eg. event __(task)__\n"
+ + " /at _(dd/MM/yyyy)_(hhmm)__\n"
+ + " Deadline \n" + " Eg. deadline __(task)__\n"
+ + " /by _(dd/MM/yyyy)_(hhmm)__\n"
+ + " Delete \n" + " Eg. delete __(number)__ or delete all\n"
+ + " Done \n" + " Eg. done __(number)__\n"
+ + " Find \n" + " Eg. find __(keyword)__\n"
+ + " Expenses \n" + " Eg. expenses __$(amount)__\n"
+ + " /on __(category)__\n"
+ + " List \n" + " Help\n" + " Bye\n");
+ }
+
+ //variable refers to either date or what the expenditure is spent on.
+ int variableIndex = 0;
+ String variable = inputArray[0];
+ String description = getDescriptionOfTask(properInput);
+ if (taskType.equals("deadline") || taskType.equals("event") || taskType.equals("expenses")) {
+ assert description != null;
+ int slashIndex = properInput.indexOf("/");
+ variableIndex = slashIndex + 4;
+ if (properInput.length() > variableIndex) {
+ variable = properInput.substring(variableIndex);
+ } else {
+ throw new DukeException("Sorry! Please follow the correct format! :)))");
+ }
+ }
+ switch (taskType) {
+ case "todo":
+ if (isValidToDoCommand(properInput)) {
+ return new ToDoCommand(description);
+ } else {
+ Ui.printIndent();
+ throw new DukeException("☹ OOPSY DAISY!!! Please follow \n"
+ + "the correct todo format! :<\n"
+ + " Todo \n"
+ + " Eg. todo __(task)__\n");
+ }
+ case "deadline":
+ if (isValidDeadlineCommand(properInput) && isValidDateFormat(properInput)) {
+ return new DeadlineCommand(description, formatDate(variable));
+ } else {
+ throw new DukeException("☹ OOPSY DAISY!!! Please follow \n"
+ + "the correct deadline format! :<\n"
+ + " Deadline \n"
+ + " Eg. deadline __(task)__ /by \n"
+ + " _(dd/MM/yyyy)_(hhmm)__\n");
+ }
+ case "event":
+ if (isValidEventCommand(properInput) && isValidDateFormat(properInput)) {
+ return new EventCommand(description, formatDate(variable));
+ } else {
+ Ui.printIndent();
+ throw new DukeException("☹ OOPSY DAISY!!! Please follow \n"
+ + "the correct event format! :<\n"
+ + " Event \n"
+ + " Eg. event __(task)__ /at \n"
+ + " _(dd/MM/yyyy)_(hhmm)__\n");
+ }
+ case "delete":
+ if (isValidDeleteCommand(properInput)) {
+ return new DeleteCommand(taskType, description);
+ } else {
+ Ui.printIndent();
+ throw new DukeException("☹ OOPSY DAISY!!! Please follow \n"
+ + "the correct delete format! :<\n"
+ + " Delete \n"
+ + " Eg. delete __(number)__ or delete all\n");
+ }
+ case "find":
+ if (isValidFindCommand(properInput)) {
+ return new FindCommand(taskType, description);
+ } else {
+ Ui.printIndent();
+ throw new DukeException("☹ OOPSY DAISY!!! Please follow\n"
+ + "the correct find format! :<\n"
+ + " Find \n" + " Eg. find __(keyword)__\n");
+ }
+ case "done":
+ if (isValidDoneCommand(properInput)) {
+ return new DoneCommand(taskType, description);
+ } else {
+ Ui.printIndent();
+ throw new DukeException("☹ OOPSY DAISY!!! Please follow \n"
+ + "the correct done format! :<\n"
+ + " Done \n"
+ + " Eg. done __(number[not expenses task])__\n");
+ }
+ case "expenses":
+ if (isValidExpensesCommand(properInput)) {
+ System.out.println("asda");
+ return new ExpensesCommand(description, variable);
+ } else {
+ Ui.printIndent();
+ throw new DukeException("☹ OOPSY DAISY!!! Please follow \n"
+ + "the correct done format! :<\n"
+ + " Expenses \n"
+ + " Eg. expenses __$(amount)__ /on __(category)__\n");
+ }
+ case "list":
+ return new ListCommand(description);
+ case "bye":
+ Command byeCommand = new ByeCommand(description);
+ byeCommand.exitSwitch();
+ return byeCommand;
+ case "help":
+ return new HelpCommand(description);
+ default:
+ throw new DukeException("☹ OOPS!!! I'm sorry, but I don't \n"
+ + "know what that means :-(\n"
+ + " I can only do these functions for now: \n \n"
+ + " Todo \n" + " Eg. todo __(task)__\n"
+ + " Event \n" + " Eg. event __(task)__\n"
+ + " /at _(dd/MM/yyyy)_(hhmm)__\n"
+ + " Deadline \n" + " Eg. deadline __(task)__\n"
+ + " /by _(dd/MM/yyyy)_(hhmm)__\n"
+ + " Delete \n" + " Eg. delete __(number)__ or delete all\n"
+ + " Done \n" + " Eg. done __(number)__\n"
+ + " Find \n" + " Eg. find __(keyword)__\n"
+ + " Expenses \n" + " Eg. expenses __$(amount)__\n"
+ + " /on __(category)__\n"
+ + " List \n" + " Help\n" + " Bye\n");
+ }
+ }
+
+ /**
+ * Gets the slash index from the input, if available.
+ * This is so that we can determine the dates easily.
+ *
+ * @param text Input by the user.
+ * @return Returns the index of the slash.
+ */
+ public static int getSlashIndex(String text) {
+ return text.indexOf("/");
+ }
+
+ /**
+ * Gets the day numbers from the input.
+ *
+ * @param text Date and Time.
+ * @return Returns the day numbers.
+ * @throws DukeException If the numbers are not valid, then a DukeException will
+ * be thrown to inform the user.
+ */
+ public static int getDayDateNumbers(String text) throws DukeException {
+ assert text != null;
+ if ((text.length() > (getSlashIndex(text) + 4)) && (text.length() > (getSlashIndex(text) + 6))) {
+ return Integer.parseInt(text.substring(getSlashIndex(text) + 4, getSlashIndex(text) + 6));
+ } else {
+ throw new DukeException("Wrong Format! Please enter a date\n"
+ + " format as follows: dd/mm/yyyy hhmm.");
+ }
+ }
+
+ /**
+ * Gets the month numbers from the input.
+ *
+ * @param text Date and Time.
+ * @return Returns the month numbers.
+ * @throws DukeException If the numbers are not valid, then a DukeException will
+ * be thrown to inform the user.
+ */
+ public static int getMonthDateNumbers(String text) throws DukeException {
+ assert text != null;
+ if ((text.length() > (getSlashIndex(text) + 7)) && (text.length() > (getSlashIndex(text) + 9))) {
+ return Integer.parseInt(text.substring(getSlashIndex(text) + 7, getSlashIndex(text) + 9));
+ } else {
+ throw new DukeException("Wrong Format! Please enter a date\n"
+ + " format as follows: dd/mm/yyyy hhmm.");
+ }
+ }
+
+ /**
+ * Gets the year numbers from the input.
+ *
+ * @param text Date and Time.
+ * @return Returns the year numbers.
+ * @throws DukeException If the numbers are not valid, then a DukeException will
+ * be thrown to inform the user.
+ */
+ public static int getYearDateNumbers(String text) throws DukeException {
+ assert text != null;
+ if ((text.length() > (getSlashIndex(text) + 10)) && (text.length() > (getSlashIndex(text) + 14))) {
+ return Integer.parseInt(text.substring(getSlashIndex(text) + 10, getSlashIndex(text) + 14));
+ } else {
+ throw new DukeException("Wrong Format! Please enter a date\n"
+ + " format as follows: dd/mm/yyyy hhmm.");
+ }
+ }
+
+ /**
+ * Gets the hour numbers from the input.
+ *
+ * @param text Date and Time.
+ * @return Returns the hour numbers.
+ * @throws DukeException If the numbers are not valid, then a DukeException will
+ * be thrown to inform the user.
+ */
+ public static int getHourDateNumbers(String text) throws DukeException {
+ assert text != null;
+ if ((text.length() > (getSlashIndex(text) + 15)) && (text.length() > (getSlashIndex(text) + 17))) {
+ return Integer.parseInt(text.substring(getSlashIndex(text) + 15, getSlashIndex(text) + 17));
+ } else {
+ Ui.printIndent();
+ throw new DukeException("Wrong Format! Please enter a date\n"
+ + " format as follows: dd/mm/yyyy hhmm.");
+ }
+ }
+
+
+ /**
+ * Gets the minute numbers from the input.
+ *
+ * @param text Date and Time.
+ * @return Returns the minute numbers.
+ * @throws DukeException If the numbers are not valid, then a DukeException will
+ * be thrown to inform the user.
+ */
+ public static int getMinuteDateNumbers(String text) throws DukeException {
+ assert text != null;
+ if (text.length() >= (getSlashIndex(text) + 17)) {
+ return Integer.parseInt(text.substring(getSlashIndex(text) + 17));
+ } else {
+ throw new DukeException("Wrong Format! Please enter a date\n"
+ + " format as follows: dd/mm/yyyy hhmm.");
+ }
+ }
+
+
+ /**
+ * Checks whether the numbers are within the limit of days,
+ * months, years, hours and minutes.
+ *
+ * @param text Date and Time.
+ * @return Returns a boolean that checks whether the numbers are valid or not.
+ * @throws DukeException If the numbers are not valid, then a DukeException will
+ * be thrown to inform the user.
+ */
+ public static boolean isValidDateNumbers(String text) throws DukeException {
+ assert text != null;
+ int dayDate = getDayDateNumbers(text);
+ int monthDate = getMonthDateNumbers(text);
+ int yearDate = getYearDateNumbers(text);
+ int timeHour = getHourDateNumbers(text);
+ int timeMin = getMinuteDateNumbers(text);
+ return dayDate > 0 && dayDate <= 31 && monthDate > 0 && monthDate <= 12
+ && timeHour > 0 && timeHour <= 24 && timeMin >= 0 && timeMin <= 59
+ && yearDate >= 2019;
+ }
+
+ /**
+ * Checks whether the dates and numbers given are valid or not.
+ *
+ * @param text Dates and Time.
+ * @return Returns a boolean that checks whether the numbers are valid or not.
+ * @throws DukeException If the numbers are not valid, then a DukeException will
+ * be thrown to inform the user.
+ */
+ public static boolean isValidDateFormat(String text) throws DukeException {
+ assert text != null;
+ if (isValidDateNumbers(text)) {
+ return true;
+ } else {
+ Ui.printIndent();
+ throw new DukeException("Invalid Date Format!\n"
+ + " There are at most 31 days, 12 months,\n"
+ + " 23 hours and 59 minutes! \n"
+ + "And remember that the year is 2019!\n"
+ + " Please try again! Thank you! :)");
+ }
+ }
+
+ /**
+ * Method to format the date into the appropriate format.
+ * For example, 10/02/2012 1800 to 10th of February 2012, 6:00 pm.
+ *
+ * @param date Takes in a valid date to format it.
+ * @return Returns the correctly formatted date with the
+ * appropriate strings.
+ */
+ public static String formatDate(String date) throws DukeException {
+ assert date != null;
+ String formatted = date;
+ if (!date.contains(")")) {
+ try {
+ Date d = new SimpleDateFormat("dd/MM/yyyy hhmm").parse(date);
+ String day = new SimpleDateFormat("dd").format(d);
+ String month = new SimpleDateFormat("MMMMMMMMMMMMMMM").format(d);
+ String year = new SimpleDateFormat("yyyy").format(d);
+ String time = new SimpleDateFormat("h:mm a").format(d).toLowerCase();
+ String endOfDate;
+ int dayInteger = Integer.parseInt(day);
+
+ if (dayInteger % 10 == 1 && dayInteger != 11) {
+ endOfDate = "st";
+ } else if (dayInteger % 10 == 2 && dayInteger != 12) {
+ endOfDate = "nd";
+ } else if (dayInteger % 10 == 3 && dayInteger != 13) {
+ endOfDate = "rd";
+ } else {
+ endOfDate = "th";
+ }
+ formatted = dayInteger + endOfDate + " of " + month + " " + year + ", " + time;
+ } catch (ParseException e) {
+ Ui.printIndent();
+ System.out.println(e.getMessage());
+ Ui.printIndent();
+ System.out.println("That is the wrong date format! >:-(");
+ }
+ } else {
+ throw new DukeException("Sorry, wrong format!");
+ }
+ return formatted;
+ }
+
+ /**
+ * Checks whether the task type is at least one of the functions available.
+ *
+ * @param taskType User input.
+ * @return Returns a boolean that checks whether the task type is valid or not.
+ */
+ public static boolean isValidTaskType(String taskType) {
+ assert taskType != null;
+ if (taskType.equals("todo") || taskType.equals("event") || taskType.equals("deadline")
+ || taskType.equals("delete") || taskType.equals("done") || taskType.equals("find")
+ || taskType.equals("list") || taskType.equals("bye") || taskType.equals("expenses")
+ || taskType.equals("help")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Sieves out the description of the task and returns it.
+ *
+ * @param text User input.
+ * @return Returns the description of the task without task type and dates/variables.
+ * @throws DukeException Throws out a DukeException if the text doesnt follow any of the
+ * task formats.
+ */
+ public static String getDescriptionOfTask(String text) throws DukeException {
+ assert text != null;
+ String description = text;
+ int spaceIndex = text.indexOf(" ");
+ if ((text.contains("deadline") && isValidDeadlineCommand(text))
+ || (text.contains("event") && isValidEventCommand(text))
+ || (text.contains("expenses") && isValidExpensesCommand(text))) {
+ int slashIndex = text.indexOf("/");
+ description = text.substring(spaceIndex + 1, slashIndex - 1);
+ return description;
+ } else if (text.contains("todo") || text.contains("done")
+ || text.contains("delete") || text.contains("find")) {
+ description = text.substring(spaceIndex + 1);
+ return description;
+ } else {
+ return description;
+ }
+ }
+
+ /**
+ * Checks whether the to do command input given is valid
+ * and follows the format that is provided.
+ *
+ * @param text User input.
+ * @return Returns a boolean that tells us whether the to do command is valid.
+ */
+ public static boolean isValidToDoCommand(String text) {
+ assert text != null;
+ return text.contains(" ") && text.length() > 5;
+ }
+
+ /**
+ * Checks whether the deadline command input given is valid
+ * and follows the format that is provided.
+ *
+ * @param text User input.
+ * @return Returns a boolean that tells us whether the deadline command is valid.
+ */
+ public static boolean isValidDeadlineCommand(String text) {
+ assert text != null;
+ return text.contains(" ") && text.contains("/") && text.contains("by");
+ }
+
+ /**
+ * Checks whether the event command input given is valid
+ * and follows the format that is provided.
+ *
+ * @param text User input.
+ * @return Returns a boolean that tells us whether the event command is valid.
+ */
+ public static boolean isValidEventCommand(String text) {
+ assert text != null;
+ return text.contains(" ") && text.contains("/") && text.contains("at");
+ }
+
+ /**
+ * Checks whether the delete command input given is valid
+ * and follows the format that is provided.
+ *
+ * @param text User input.
+ * @return Returns a boolean that tells us whether the delete command is valid.
+ * @throws DukeException If the format is wrong, a DukeException will be thrown
+ * to inform the user and to retype it properly again.
+ * @throws NumberFormatException If the user types in a character that is not a number,
+ * an exception will be thrown to inform the user.
+ */
+ public static boolean isValidDeleteCommand(String text) throws DukeException, NumberFormatException {
+ assert text != null;
+ if (text.length() < 7) {
+ Ui.printIndent();
+ throw new DukeException("Wrong Format! Please add an 'all' or\n"
+ + " a valid number after the delete word! :)");
+ } else {
+ char[] valueArray = text.substring(7).toCharArray();
+ boolean isNumber = false;
+ for (int i = 0; i < valueArray.length; i++) {
+ isNumber = false;
+ if (Character.isDigit(valueArray[i])) {
+ isNumber = true;
+ }
+ }
+ if (text.contains("all")) {
+ return text.contains(" ");
+ } else if (isNumber && Integer.parseInt(text.substring(7)) > 0) {
+ return text.contains(" ") && Integer.parseInt(text.substring(7)) <= CompleteList.listOfPlans.size();
+ } else {
+ Ui.printIndent();
+ throw new DukeException("Wrong Format! Please add an 'all' or\n"
+ + "a valid number after the delete word! Thank You :)");
+ }
+ }
+ }
+
+ /**
+ * Checks whether the find command input given is valid
+ * and follows the format that is provided.
+ *
+ * @param text User input.
+ * @return Returns a boolean that tells us whether the find command is valid.
+ */
+ public static boolean isValidFindCommand(String text) {
+ assert text != null;
+ return text.contains(" ") && text.length() > 5;
+ }
+
+ /**
+ * Checks whether the done command input given is valid
+ * and follows the format that is provided.
+ *
+ * @param text User input.
+ * @return Returns a boolean that tells us whether the done commmand is valid.
+ * @throws DukeException If the format is wrong, a DukeException will be thrown
+ * to inform the user and to retype it properly again.
+ */
+ public static boolean isValidDoneCommand(String text) throws DukeException {
+ assert text != null;
+ if (text.length() < 5) {
+ Ui.printIndent();
+ throw new DukeException("Wrong Format! Please add a \n"
+ + "valid number after the done word! :)");
+ } else {
+ char[] valueArray = text.substring(5).toCharArray();
+ boolean isNumber = false;
+ for (int i = 0; i < valueArray.length; i++) {
+ isNumber = false;
+ if (Character.isDigit(valueArray[i])) {
+ isNumber = true;
+ }
+ }
+ if (isNumber && Integer.parseInt(text.substring(5)) > 0) {
+ return text.contains(" ") && Integer.parseInt(text.substring(5)) <= CompleteList.listOfPlans.size()
+ && isValidDoneNumberGiven(text.substring(5));
+ } else {
+ Ui.printIndent();
+ throw new DukeException("Wrong Format! Please add a valid \n"
+ + "number that is a task (and not an expenses!!)\n"
+ + " after the done word! Thank You :)");
+ }
+ }
+ }
+
+ /**
+ * Checks whether the expenses command given is valid
+ * and follows the format provided.
+ *
+ * @param text User input
+ * @return Returns a boolean that tells us if the input is valid.
+ */
+ public static boolean isValidExpensesCommand(String text) {
+ assert text != null;
+ return text.contains(" ") && text.contains("/") && text.contains("on") && text.length() > 20;
+ }
+
+ /**
+ * Checks whether the done number given is valid. In other
+ * words, checks if done number is given to either todo, event
+ * or deadline.
+ *
+ * @param num Number given by the user.
+ * @return Returns a boolean that tells the user whether the number given
+ * satisfies the conditions.
+ */
+ public static boolean isValidDoneNumberGiven(String num) {
+ int taskNumber = Integer.parseInt(num);
+ try {
+ BufferedReader br = new BufferedReader(new FileReader(Storage.file));
+ String text;
+ int counter = 0;
+ int lineCounter = 0;
+ while ((text = br.readLine()) != null) {
+ lineCounter++;
+ if (lineCounter == taskNumber) {
+ if (text.contains("[Expenses]")) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+ } catch (IOException e) {
+ System.out.println(e);
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/duke/execution/Storage.java b/src/main/java/duke/execution/Storage.java
new file mode 100644
index 0000000000..83ac073fe9
--- /dev/null
+++ b/src/main/java/duke/execution/Storage.java
@@ -0,0 +1,176 @@
+package duke.execution;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Scanner;
+
+import duke.models.Planner;
+import duke.models.Deadline;
+import duke.models.Event;
+import duke.models.Expenses;
+import duke.models.Task;
+import duke.models.Todo;
+
+import duke.exceptions.DukeException;
+
+public class Storage {
+
+ protected static ArrayList taskList = new ArrayList();
+ public static String file = ".todo.txt";
+
+ /**
+ * Constructor for Storage.
+ *
+ * @param file File that the list of tasks to be.
+ */
+ public Storage(String file) {
+
+ }
+
+ /**
+ * Adds tasks to the file.
+ *
+ * @param filepath File that the task is added to.
+ * @param textToAdd Tasks that needs to be added.
+ * @throws IOException If the named file exists but
+ * is a directory rather than a regular file,
+ * does not exist but cannot be created, or
+ * cannot be opened for any other reason.
+ */
+ public void addToFile(String filepath, String textToAdd) throws IOException {
+ assert filepath != null;
+ assert textToAdd != null;
+ FileWriter typer = new FileWriter(filepath, true);
+ typer.write(textToAdd + System.lineSeparator());
+ typer.close();
+ }
+
+ /**
+ * Writes task to a file.
+ * Can be used as a way to overwrite tasks in the file as well.
+ *
+ * @param filepath File that the task is added to.
+ * @param textToAdd Tasks that needs to be added.
+ * @throws IOException If the named file exists but
+ * is a directory rather than a regular file,
+ * does not exist but cannot be created, or
+ * cannot be opened for any other reason.
+ */
+ public void writeToFile(String filepath, String textToAdd) throws IOException {
+ assert filepath != null;
+ assert textToAdd != null;
+ FileWriter typer = new FileWriter(filepath);
+ typer.write(textToAdd);
+ typer.close();
+ }
+
+ /**
+ * Counts the number of tasks in the list.
+ *
+ * @param filename File that the tasks are in.
+ * @return Returns the number of tasks.
+ * @throws IOException If the named file exists but
+ * is a directory rather than a regular file,
+ * does not exist but cannot be created, or
+ * cannot be opened for any other reason.
+ */
+ public static int countLines(String filename) throws IOException {
+ assert filename != null;
+ try (InputStream inputs = new BufferedInputStream(new FileInputStream(filename))) {
+ byte[] characters = new byte[1024];
+ int readCharacters = inputs.read(characters);
+ if (readCharacters == -1) {
+ // no lines to read
+ return 0;
+ }
+ int count = 0;
+ while (readCharacters == 1024) {
+ for (int i = 0; i < 1024; ) {
+ if (characters[i++] == '\n') {
+ ++count;
+ }
+ }
+ readCharacters = inputs.read(characters);
+ }
+ // count remaining characters
+ while (readCharacters != -1) {
+ for (int i = 0; i < readCharacters; ++i) {
+ if (characters[i] == '\n') {
+ ++count;
+ }
+ }
+ readCharacters = inputs.read(characters);
+ }
+
+ return count == 0 ? 1 : count;
+ }
+ }
+
+ /**
+ * Loads the task into the task list
+ * in TaskList from the file.
+ *
+ * @return ArrayList that has been copied from the file.
+ * @throws IOException If the named file exists but is a directory rather than a regular file,
+ * does not exist but cannot be created, or cannot be opened for any other reason.
+ * @throws DukeException If there is nothing in the file to be loaded,
+ * this exception will be thrown.
+ */
+ public ArrayList load() throws IOException, DukeException {
+ File f = new File(file);
+ assert f != null;
+ Scanner sc = new Scanner(f);
+ ArrayList tempList;
+ if (countLines(file) == 0) {
+ throw new DukeException("Woahsies wavy! There is nothing in this file!");
+ } else {
+ while (sc.hasNext()) {
+ String plans = sc.nextLine();
+ int startBracketIndex = plans.indexOf("[");
+ int closeBracketIndex = plans.indexOf("]");
+ String taskType = plans.substring(startBracketIndex + 1, closeBracketIndex);
+ int spaceIndex = plans.indexOf(" ");
+ switch (taskType) {
+ case "T":
+ Task toDo = new Todo(plans.substring(spaceIndex));
+ taskList.add(toDo);
+ TaskList.listOfTasks.add(toDo);
+ break;
+ case "D":
+ int byIndex = plans.indexOf("(");
+ Task deadline = new Deadline(plans.substring(spaceIndex, byIndex - 1),
+ plans.substring(byIndex + 4));
+ taskList.add(deadline);
+ TaskList.listOfTasks.add(deadline);
+ break;
+ case "E":
+ int atIndex = plans.indexOf("(");
+ Task event = new Event(plans.substring(spaceIndex, atIndex - 1),
+ plans.substring(atIndex + 4));
+ taskList.add(event);
+ TaskList.listOfTasks.add(event);
+ break;
+ case "Expenses":
+ int onIndex = plans.indexOf("(");
+ Expenses expense = new Expenses(plans.substring(spaceIndex, onIndex - 1),
+ plans.substring(onIndex + 4));
+ taskList.add(expense);
+ ExpenseList.listOfExpenses.add(expense);
+ break;
+ default:
+ break;
+ }
+ }
+ Ui.printLine();
+ Ui.printIndent();
+ System.out.println("Your file has been loaded! :)");
+ tempList = new ArrayList(taskList);
+ return tempList;
+ }
+ }
+}
diff --git a/src/main/java/duke/execution/TaskList.java b/src/main/java/duke/execution/TaskList.java
new file mode 100644
index 0000000000..29db5c3584
--- /dev/null
+++ b/src/main/java/duke/execution/TaskList.java
@@ -0,0 +1,33 @@
+package duke.execution;
+
+import java.util.ArrayList;
+
+import duke.models.Task;
+
+public class TaskList extends CompleteList {
+
+ public static ArrayList listOfTasks = new ArrayList();
+
+ /**
+ * Constructor for TaskList.
+ */
+ public TaskList() {
+
+ }
+
+ /**
+ * Overloaded Constructor for Task list in
+ * the event that a array list is available
+ * from the file.
+ *
+ * @param list Arraylist that contains all the tasks.
+ */
+ public TaskList(ArrayList list) {
+ listOfTasks = list;
+ }
+
+ public void addToTaskList(Task assignment) {
+ assert assignment != null;
+ listOfTasks.add(assignment);
+ }
+}
diff --git a/src/main/java/duke/execution/Ui.java b/src/main/java/duke/execution/Ui.java
new file mode 100644
index 0000000000..79d7b9ed31
--- /dev/null
+++ b/src/main/java/duke/execution/Ui.java
@@ -0,0 +1,173 @@
+package duke.execution;
+
+import java.io.IOException;
+import java.util.Scanner;
+
+public class Ui {
+
+ protected Scanner scan = new Scanner(System.in);
+
+ /**
+ * Constructor for Ui.
+ */
+ public Ui() {
+
+ }
+
+ /**
+ * Prints the greeting at the initiation of the chat bot.
+ */
+ public String greeting() {
+ String dukeLogo = " ____ _ \n"
+ + " | _ \\ _ _| | _____ \n"
+ + " | | | | | | | |/ / _ \\\n"
+ + " | |_| | |_| | < __/\n"
+ + " |____/ \\__,_|_|\\_\\___|\n";
+
+ // Prints out greeting of the chat bot.
+ String logo = " Hello! My name is \n" + dukeLogo + "\n"
+ + " What can I do for you? \n";
+ printIndent();
+ logo += " I can only do these functions for now: \n \n"
+ + " Todo \n" + " Eg. todo __(task)__\n"
+ + " Event \n" + " Eg. event __(task)__\n"
+ + " /at _(dd/MM/yyyy)_(hhmm)__\n"
+ + " Deadline \n" + " Eg. deadline __(task)__\n"
+ + " /by _(dd/MM/yyyy)_(hhmm)__\n"
+ + " Delete \n" + " Eg. delete __(number)__ or delete all\n"
+ + " Done \n" + " Eg. done __(number)__\n"
+ + " Find \n" + " Eg. find __(keyword)__\n"
+ + " Expenses \n" + " Eg. expenses __$(amount)__\n"
+ + " /on __(category)__\n"
+ + " List \n" + " Help\n" + " Bye\n";
+ //printIndent();
+ //System.out.println("Ill be adding in more features soon! Please be patient! :)");
+ return logo;
+ }
+
+ /**
+ * Prints indentation.
+ * Helps to order the output, making it much neater.
+ */
+ public static void printIndent() {
+ System.out.print(" ");
+ }
+
+ /**
+ * Prints line.
+ * Helps to order the output and makes it
+ * much neater.
+ */
+ public static void printLine() {
+ printIndent();
+ System.out.println("_____________________________"
+ + "______________________________________");
+ }
+
+ /**
+ * Prints a statement informing the user that the bot
+ * has added the task into the list.
+ */
+ public String printGI() {
+ return "Got it. I've added this task:";
+ }
+
+ /**
+ * Ends the chat bot.
+ */
+ public String printBye() {
+ return "Bye. Hope to see you again soon!";
+ }
+
+ /**
+ * Reads what the user writes.
+ *
+ * @return Returns what the scanner reads.
+ */
+ public String readCommand() {
+ return scan.nextLine();
+ }
+
+ /**
+ * To remove a task if it is not needed anymore.
+ *
+ * @param i Indicates the task number that is done.
+ */
+ public static String printDelete(int i) {
+ return CompleteList.listOfPlans.get(i - 1).toString();
+ }
+
+ /**
+ * Prints a statement to tell the user that the task has been removed.
+ */
+ public String printRemove() {
+ return "Noted. I've removed this task.";
+ }
+
+ /**
+ * Prints the number of tasks in the list.
+ *
+ * @throws IOException If the named file exists but is a directory rather than a regular file,
+ * does not exist but cannot be created, or cannot be opened for any other reason.
+ */
+ public static String printNumOfTasks() throws IOException {
+ return "Now you have " + Ui.getNumOfTasks() + " tasks in the list.";
+ }
+
+ /**
+ * Gets the number of task inside the file.
+ *
+ * @return Number of tasks.
+ * @throws IOException If the named file exists
+ * but is a directory rather than a regular file,
+ * does not exist but cannot be created, or
+ * cannot be opened for any other reason.
+ */
+ public static int getNumOfTasks() throws IOException {
+ return Storage.countLines(Storage.file);
+ }
+
+ /**
+ * When there is nothing in the file, this method
+ * will print out to the user, telling them that there
+ * is no previous tasks saved in the file.
+ */
+ public void showLoadingError() {
+ printLine();
+ printIndent();
+ System.out.println("Nothing in file!");
+ }
+
+ /**
+ * Prints out the error message.
+ *
+ * @param error Error message.
+ */
+ public void showError(String error) {
+ assert error != null;
+ System.out.println(error);
+ }
+
+ /**
+ * Prints out a String that informs the user what functions
+ * are available on this application.
+ *
+ * @return Returns a String that lists out all the functions.
+ */
+ public String printHelp() {
+ printLine();
+ printIndent();
+ return " I can only do these functions for now: \n \n"
+ + " Todo \n" + " Eg. todo __(task)__\n"
+ + " Event \n" + " Eg. event __(task)__\n"
+ + " /at _(dd/MM/yyyy)_(hhmm)__\n"
+ + " Deadline \n" + " Eg. deadline __(task)__\n"
+ + " /by _(dd/MM/yyyy)_(hhmm)__\n"
+ + " Delete \n" + " Eg. delete __(number)__ or delete all\n"
+ + " Done \n" + " Eg. done __(number)__\n"
+ + " Find \n" + " Eg. find __(keyword)__\n"
+ + " Expenses \n" + " Eg. expenses __$(amount)__\n"
+ + " /on __(category)__\n"
+ + " List \n" + " Help\n" + " Bye\n";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/execution/command/ByeCommand.java b/src/main/java/duke/execution/command/ByeCommand.java
new file mode 100644
index 0000000000..e8d7c8738b
--- /dev/null
+++ b/src/main/java/duke/execution/command/ByeCommand.java
@@ -0,0 +1,34 @@
+package duke.execution.command;
+
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.Ui;
+
+public class ByeCommand extends Command {
+
+ /**
+ * Constructor for Bye Command.
+ *
+ * @param action Bye action to shut down duke bot.
+ */
+ public ByeCommand(String action) {
+ super(action);
+ }
+
+ /**
+ * Prints out bye statement to signal to user
+ * that the bot is shutting down.
+ *
+ * @param errands Saves tasks into tasklist if task
+ * is present
+ * @param ui Prints out messages to show to user.
+ * @param storage Stores tasks into file.
+ */
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ return ui.printBye();
+ }
+}
diff --git a/src/main/java/duke/execution/command/Command.java b/src/main/java/duke/execution/command/Command.java
new file mode 100644
index 0000000000..1fddf763cd
--- /dev/null
+++ b/src/main/java/duke/execution/command/Command.java
@@ -0,0 +1,71 @@
+package duke.execution.command;
+
+import java.io.IOException;
+
+import duke.exceptions.DukeException;
+
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.Ui;
+
+public class Command {
+
+ protected String action;
+ protected String variable;
+ private static boolean canExit = false;
+
+ /**
+ * Constructor for Command classes.
+ *
+ * @param action Description of tasks.
+ */
+ public Command(String action) {
+ this.action = action;
+ }
+
+ /**
+ * Constructor for Command classes.
+ *
+ * @param action Description of tasks.
+ * @param variable Variable that changes depending on the command.
+ */
+ public Command(String action, String variable) {
+ this.action = action;
+ this.variable = variable;
+ }
+
+ /**
+ * Tells the loop whether it should exit it.
+ *
+ * @return Returns the boolean canExit.
+ */
+ public boolean shouldExit() {
+ return canExit;
+ }
+
+ /**
+ * Changes the boolean canExit to the opposite value.
+ *
+ * @return Returns the newly changed boolean.
+ */
+ public boolean exitSwitch() {
+ return canExit = !canExit;
+ }
+
+ /**
+ * Dummy return value as it is always overrided by child classes.
+ *
+ * @param list Not needed in this case.
+ * @param ui Not needed in this case.
+ * @param storage Not needed in this case.
+ * @return Returns a dummy string.
+ * @throws IOException If the named file exists but is a directory rather
+ * than a regular file, does not exist but cannot be
+ * created, or cannot be opened for any other reason.
+ * @throws DukeException If there is a different input that is not accepted,
+ * a error message will show up.
+ */
+ public String execute(CompleteList list, Ui ui, Storage storage) throws IOException, DukeException {
+ return "";
+ }
+}
diff --git a/src/main/java/duke/execution/command/DeadlineCommand.java b/src/main/java/duke/execution/command/DeadlineCommand.java
new file mode 100644
index 0000000000..072afdf986
--- /dev/null
+++ b/src/main/java/duke/execution/command/DeadlineCommand.java
@@ -0,0 +1,55 @@
+package duke.execution.command;
+
+import java.io.IOException;
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.TaskList;
+import duke.execution.Ui;
+
+import duke.models.Deadline;
+import duke.models.Task;
+
+public class DeadlineCommand extends Command {
+
+ /**
+ * Constructor for Deadline Command.
+ *
+ * @param action Description of the task.
+ * @param variable Date to finish the tasks.
+ */
+ public DeadlineCommand(String action, String variable) {
+ super(action, variable);
+ }
+
+ /**
+ * Executes the deadline command and prints out statements to
+ * tell the user that the deadline tasks has been added to
+ * the list of tasks.
+ *
+ * @param errands Adds the deadline to the list of tasks.
+ * @param ui Prints out statements to indicate to user what
+ * has happened.
+ * @param storage Stores the tasks inside another file so that
+ * the task will be available the next time the
+ * bot starts up.
+ * @return Returns String to print out to the user.
+ * @throws IOException If the named file exists but is a directory rather
+ * than a regular file, does not exist but cannot be
+ * created, or cannot be opened for any other reason.
+ */
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) throws IOException {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ Task assignmentToDo = new Deadline(action, variable);
+ TaskList tasks = new TaskList();
+ tasks.addToTaskList(assignmentToDo);
+ errands.addToCompleteList(assignmentToDo);
+ storage.addToFile(Storage.file, assignmentToDo.toString());
+ String deadlineOutput = ui.printGI() + "\n";
+ deadlineOutput += " " + assignmentToDo.toString() + "\n";
+ deadlineOutput += Ui.printNumOfTasks();
+ return deadlineOutput;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/execution/command/DeleteCommand.java b/src/main/java/duke/execution/command/DeleteCommand.java
new file mode 100644
index 0000000000..023fb59e76
--- /dev/null
+++ b/src/main/java/duke/execution/command/DeleteCommand.java
@@ -0,0 +1,62 @@
+package duke.execution.command;
+
+import java.io.IOException;
+
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.Ui;
+
+import duke.models.Planner;
+
+public class DeleteCommand extends Command {
+
+ /**
+ * Constructor for Delete command.
+ *
+ * @param action Delete command word.
+ * @param variable Number of task to be deleted.
+ */
+ public DeleteCommand(String action, String variable) {
+ super(action, variable);
+ }
+
+ /**
+ * Executes the delete command and prints out statements to
+ * tell the user that the delete tasks has been deleted to
+ * the list of tasks.
+ *
+ * @param errands Not needed in this case.
+ * @param ui Prints out statements to indicate to user what
+ * has happened.
+ * @param storage Stores the tasks inside another file so that
+ * the task will be available the next time the
+ * bot starts up.
+ * @return Returns String to print out to the user.
+ * @throws IOException If the named file exists but is a directory rather
+ * than a regular file, does not exist but cannot be
+ * created, or cannot be opened for any other reason.
+ */
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) throws IOException {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ if (variable.equals("all")) {
+ storage.writeToFile(Storage.file, "");
+ CompleteList.listOfPlans.clear();
+ Ui.printIndent();
+ return "Everything in your list has been removed!\n"
+ + "Add more tasks to get started again!!!";
+ } else {
+ int taskNumber = Integer.parseInt(variable);
+ CompleteList.listOfPlans.remove(taskNumber - 1);
+ storage.writeToFile(Storage.file, "");
+ for (Planner errand : CompleteList.listOfPlans) {
+ storage.addToFile(Storage.file, errand.toString());
+ }
+ String deleteOutput = ui.printRemove() + "\n" + Ui.printDelete(taskNumber) + "\n";
+ deleteOutput += Ui.printNumOfTasks();
+ return deleteOutput;
+ }
+ }
+}
diff --git a/src/main/java/duke/execution/command/DoneCommand.java b/src/main/java/duke/execution/command/DoneCommand.java
new file mode 100644
index 0000000000..c07e2ab5c9
--- /dev/null
+++ b/src/main/java/duke/execution/command/DoneCommand.java
@@ -0,0 +1,75 @@
+package duke.execution.command;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.Ui;
+import duke.execution.TaskList;
+
+public class DoneCommand extends Command {
+
+ /**
+ * Constructor for Done command.
+ *
+ * @param action Description of the task.
+ * @param variable Number of tasks that is completed.
+ */
+ public DoneCommand(String action, String variable) {
+ super(action, variable);
+ }
+
+ /**
+ * Executes the done command and prints out statements to
+ * tell the user that the deadline tasks has been added to
+ * the list of tasks.
+ *
+ * @param errands Not needed in this case.
+ * @param ui Not needed in this case.
+ * @param storage Not needed in this case.
+ * @return Returns String to print out to the user.
+ */
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ int taskNum = Integer.parseInt(variable);
+ System.out.println(taskNum - getNumOfExpensesBeforeDoneTask(taskNum) - 1);
+ TaskList.listOfTasks.get(taskNum - getNumOfExpensesBeforeDoneTask(taskNum) - 1).markAsDone();
+ String doneOutput = "Nice! I've marked this task as done:\n";
+ doneOutput += TaskList.listOfTasks.get(taskNum - getNumOfExpensesBeforeDoneTask(taskNum) - 1).toString();
+ return doneOutput;
+ }
+
+ /**
+ * Checks how many expenses task there are before
+ * the tasks that is to be ticked off.
+ *
+ * @param taskNum Task Number from User input.
+ * @return returns the number of expenses in front of the done task.
+ */
+ public static int getNumOfExpensesBeforeDoneTask(int taskNum) {
+ try {
+ BufferedReader br = new BufferedReader(new FileReader(Storage.file));
+ String text;
+ int counter = 0;
+ int lineCounter = 0;
+ while ((text = br.readLine()) != null) {
+ lineCounter++;
+ if (text.contains("Expenses")) {
+ counter++;
+ }
+ if (lineCounter == taskNum) {
+ break;
+ }
+ }
+ return counter;
+ } catch (IOException e) {
+ System.out.println(e);
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/duke/execution/command/EventCommand.java b/src/main/java/duke/execution/command/EventCommand.java
new file mode 100644
index 0000000000..d7f10d4b20
--- /dev/null
+++ b/src/main/java/duke/execution/command/EventCommand.java
@@ -0,0 +1,56 @@
+package duke.execution.command;
+
+import java.io.IOException;
+
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.TaskList;
+import duke.execution.Ui;
+
+import duke.models.Event;
+import duke.models.Task;
+
+public class EventCommand extends Command {
+
+ /**
+ * Constructor for Event Command.
+ *
+ * @param action Description of the task.
+ * @param variable Date to finish the tasks.
+ */
+ public EventCommand(String action, String variable) {
+ super(action, variable);
+ }
+
+ /**
+ * Executes the deadline command and prints out statements to
+ * tell the user that the deadline tasks has been added to
+ * the list of tasks.
+ *
+ * @param errands Adds the deadline to the list of tasks.
+ * @param ui Prints out statements to indicate to user what
+ * has happened.
+ * @param storage Stores the tasks inside another file so that
+ * the task will be available the next time the
+ * bot starts up.
+ * @return Returns String to print out to the user.
+ * @throws IOException If the named file exists but is a directory rather
+ * than a regular file, does not exist but cannot be
+ * created, or cannot be opened for any other reason.
+ */
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) throws IOException {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ TaskList tasks = new TaskList();
+ Task assignmentToDo = new Event(action, variable);
+ tasks.addToTaskList(assignmentToDo);
+ errands.addToCompleteList(assignmentToDo);
+ storage.addToFile(Storage.file, assignmentToDo.toString());
+ String eventOutput = ui.printGI() + "\n";
+ eventOutput += " " + assignmentToDo.toString() + "\n";
+ eventOutput += Ui.printNumOfTasks();
+ return eventOutput;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/execution/command/ExpensesCommand.java b/src/main/java/duke/execution/command/ExpensesCommand.java
new file mode 100644
index 0000000000..4e8967af67
--- /dev/null
+++ b/src/main/java/duke/execution/command/ExpensesCommand.java
@@ -0,0 +1,33 @@
+package duke.execution.command;
+
+import java.io.IOException;
+
+import duke.execution.CompleteList;
+import duke.execution.ExpenseList;
+import duke.execution.Storage;
+import duke.execution.Ui;
+
+import duke.models.Expenses;
+
+public class ExpensesCommand extends Command {
+
+ public ExpensesCommand(String action, String variable) {
+ super(action, variable);
+ }
+
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) throws IOException {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ Expenses expense = new Expenses(action, variable);
+ ExpenseList expenses = new ExpenseList();
+ expenses.addToExpensesList(expense);
+ expenses.addToCompleteList(expense);
+ storage.addToFile(Storage.file, expense.toString());
+ String expenseOutput = ui.printGI() + "\n";
+ expenseOutput += " " + expense.toString() + "\n";
+ expenseOutput += Ui.printNumOfTasks();
+ return expenseOutput;
+ }
+}
diff --git a/src/main/java/duke/execution/command/FindCommand.java b/src/main/java/duke/execution/command/FindCommand.java
new file mode 100644
index 0000000000..67d1e1bca4
--- /dev/null
+++ b/src/main/java/duke/execution/command/FindCommand.java
@@ -0,0 +1,81 @@
+package duke.execution.command;
+
+import duke.exceptions.DukeException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Scanner;
+
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.Ui;
+
+public class FindCommand extends Command {
+
+ /**
+ * Constructor for FindCommand.
+ *
+ * @param action Find command word.s
+ * @param variable Number of task to be deleted.
+ */
+ public FindCommand(String action, String variable) {
+ super(action, variable);
+
+ }
+
+ /**
+ * Executes the deadline command and prints out statements to
+ * tell the user that the deadline tasks has been added to
+ * the list of tasks.
+ *
+ * @param errands Not needed in this case.
+ * @param ui Prints out statements to indicate to user what
+ * has happened.
+ * @param storage Not needed in this case.
+ * @return Returns String to print out to the user.
+ * @throws IOException If the named file exists but is a directory rather
+ * than a regular file, does not exist but cannot be
+ * created, or cannot be opened for any other reason.
+ * @throws DukeException If there is no matching word, an error message
+ * will be sent to the user.
+ */
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) throws DukeException, IOException {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ File f = new File(Storage.file);
+ Scanner sc = new Scanner(f);
+ ArrayList tempList = new ArrayList<>();
+ int num = 1;
+ while (sc.hasNext()) {
+ String text = sc.nextLine();
+ int spaceIndex = text.indexOf(" ");
+ int bracketIndex = text.length();
+ if (text.contains("(")) {
+ bracketIndex = text.indexOf("(");
+ }
+ String description = text.substring(spaceIndex + 1, bracketIndex);
+ if (description.contains(variable)) {
+ String task = num + "." + text;
+ tempList.add(task);
+ num++;
+ }
+ }
+ if (tempList.isEmpty()) {
+ Ui.printIndent();
+ throw new DukeException("No such word is found in\n"
+ + "any of the tasks.");
+ } else {
+ Ui.printIndent();
+ String matchingTask = "Here are the matching tasks\n"
+ + " in your list!\n";
+ for (String str : tempList) {
+ Ui.printIndent();
+ matchingTask += str + "\n";
+ }
+ return matchingTask;
+ }
+ }
+}
diff --git a/src/main/java/duke/execution/command/HelpCommand.java b/src/main/java/duke/execution/command/HelpCommand.java
new file mode 100644
index 0000000000..a966d4ac11
--- /dev/null
+++ b/src/main/java/duke/execution/command/HelpCommand.java
@@ -0,0 +1,23 @@
+package duke.execution.command;
+
+import java.io.IOException;
+
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.Ui;
+
+public class HelpCommand extends Command {
+
+ public HelpCommand(String action) {
+ super(action);
+ }
+
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) throws IOException {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ return ui.printHelp();
+ }
+}
+
diff --git a/src/main/java/duke/execution/command/ListCommand.java b/src/main/java/duke/execution/command/ListCommand.java
new file mode 100644
index 0000000000..aec719b04f
--- /dev/null
+++ b/src/main/java/duke/execution/command/ListCommand.java
@@ -0,0 +1,53 @@
+package duke.execution.command;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.Ui;
+
+public class ListCommand extends Command {
+
+ /**
+ * Constructor for ListCommand.
+ *
+ * @param action List Command word.
+ */
+ public ListCommand(String action) {
+ super(action);
+ }
+
+ /**
+ * Executes the list command and prints out all the
+ * tasks in the list.
+ *
+ * @param errands Not needed in this case.
+ * @param ui Not needed in this case.
+ * @param storage Not needed in this case.
+ * @return Returns those tasks that match the keyword.
+ * @throws FileNotFoundException If there is no prior list of task
+ * available, there is nothing to print,
+ * thus, an error message will be shown.
+ */
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) throws FileNotFoundException {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ if (CompleteList.listOfPlans.isEmpty()) {
+ return "There is no tasks currently!!!";
+ } else {
+ String list = "Here are the tasks in your list:\n";
+ File temp = new File(Storage.file);
+ Scanner s = new Scanner(temp);
+ int numbering = 1;
+ while (s.hasNext()) {
+ list += numbering + ". " + s.nextLine() + "\n";
+ numbering++;
+ }
+ return list;
+ }
+ }
+}
diff --git a/src/main/java/duke/execution/command/ToDoCommand.java b/src/main/java/duke/execution/command/ToDoCommand.java
new file mode 100644
index 0000000000..6be19c8ac3
--- /dev/null
+++ b/src/main/java/duke/execution/command/ToDoCommand.java
@@ -0,0 +1,55 @@
+package duke.execution.command;
+
+import java.io.IOException;
+
+import duke.execution.CompleteList;
+import duke.execution.Storage;
+import duke.execution.TaskList;
+import duke.execution.Ui;
+
+import duke.models.Task;
+import duke.models.Todo;
+
+public class ToDoCommand extends Command {
+
+ /**
+ * Constructor for To Do Command.
+ *
+ * @param action Description of To Do task.
+ */
+ public ToDoCommand(String action) {
+ super(action);
+ }
+
+ /**
+ * Executes the To do command. Adds the to do task to
+ * a list and prints out the task again to confirm that
+ * task has been added to the list.
+ *
+ * @param errands Adds the deadline to the list of tasks.
+ * @param ui Prints out statements to indicate to user what
+ * has happened.
+ * @param storage Stores the tasks inside another file so that
+ * the task will be available the next time the
+ * bot starts up.
+ * @return Returns String to print out to the user.
+ * @throws IOException If the named file exists but is a directory rather
+ * than a regular file, does not exist but cannot be
+ * created, or cannot be opened for any other reason.
+ */
+ @Override
+ public String execute(CompleteList errands, Ui ui, Storage storage) throws IOException {
+ assert errands != null;
+ assert ui != null;
+ assert storage != null;
+ Task assignmentToDo = new Todo(action);
+ TaskList tasks = new TaskList();
+ tasks.addToTaskList(assignmentToDo);
+ errands.addToCompleteList(assignmentToDo);
+ storage.addToFile(Storage.file, assignmentToDo.toString());
+ String todoOutput = ui.printGI() + "\n";
+ todoOutput += " " + assignmentToDo.toString() + "\n";
+ todoOutput += Ui.printNumOfTasks();
+ return todoOutput;
+ }
+}
diff --git a/src/main/java/duke/models/Deadline.java b/src/main/java/duke/models/Deadline.java
new file mode 100644
index 0000000000..444d8963d2
--- /dev/null
+++ b/src/main/java/duke/models/Deadline.java
@@ -0,0 +1,30 @@
+package duke.models;
+
+public class Deadline extends Task {
+
+ protected String by;
+
+ /**
+ * Constructor for Deadline task.
+ *
+ * @param description Deadline task to be added.
+ * @param by Date of the deadline task.
+ */
+ public Deadline(String description, String by) {
+ super(description);
+ this.by = by;
+ }
+
+ /**
+ * Method to give the string that is to be
+ * added to the list of tasks.
+ *
+ * @return Returns the string to be loaded into
+ * the file and printed out.
+ */
+ @Override
+ public String toString() {
+ assert by != null;
+ return "[D]" + super.toString() + " " + description + " (by: " + by + ")";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/models/Event.java b/src/main/java/duke/models/Event.java
new file mode 100644
index 0000000000..783122e737
--- /dev/null
+++ b/src/main/java/duke/models/Event.java
@@ -0,0 +1,30 @@
+package duke.models;
+
+public class Event extends Task {
+
+ protected String when;
+ protected boolean isValid;
+
+ /**
+ * Constructor for Event task.
+ *
+ * @param description Event task to be attended.
+ * @param when Date of the event.
+ */
+ public Event(String description, String when) {
+ super(description);
+ this.when = when;
+ }
+
+ /**
+ * Method to give the string that is to be
+ * added to the list of tasks.
+ *
+ * @return Returns the string to be loaded into
+ * the file and printed out.
+ */
+ @Override
+ public String toString() {
+ return "[E]" + super.toString() + " " + description + " (at: " + when + ")";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/models/Expenses.java b/src/main/java/duke/models/Expenses.java
new file mode 100644
index 0000000000..6563653d4c
--- /dev/null
+++ b/src/main/java/duke/models/Expenses.java
@@ -0,0 +1,22 @@
+package duke.models;
+
+public class Expenses extends Planner {
+
+ protected String on;
+
+ public Expenses(String description, String on) {
+ super(description);
+ this.on = on;
+ }
+
+ /**
+ * Method to mark the task to done.
+ */
+ public void markAsDone() {
+ isDone = true;
+ }
+
+ public String toString() {
+ return "[Expenses] " + description + " (on: " + on + ")";
+ }
+}
diff --git a/src/main/java/duke/models/Find.java b/src/main/java/duke/models/Find.java
new file mode 100644
index 0000000000..e083525591
--- /dev/null
+++ b/src/main/java/duke/models/Find.java
@@ -0,0 +1,14 @@
+package duke.models;
+
+public class Find extends Task {
+
+ /**
+ * Constructor for Find tasks.
+ *
+ * @param description Description of tasks to find.
+ */
+ public Find(String description) {
+ super(description);
+ }
+
+}
diff --git a/src/main/java/duke/models/Planner.java b/src/main/java/duke/models/Planner.java
new file mode 100644
index 0000000000..1815cc2e46
--- /dev/null
+++ b/src/main/java/duke/models/Planner.java
@@ -0,0 +1,19 @@
+package duke.models;
+
+public class Planner {
+
+ protected String description;
+ protected boolean isDone;
+
+ public Planner(String description) {
+ this.description = description;
+ this.isDone = false;
+ }
+
+ /**
+ * Method to mark the task to done.
+ */
+ public void markAsDone() {
+ isDone = true;
+ }
+}
diff --git a/src/main/java/duke/models/Task.java b/src/main/java/duke/models/Task.java
new file mode 100644
index 0000000000..51ddfe51f9
--- /dev/null
+++ b/src/main/java/duke/models/Task.java
@@ -0,0 +1,48 @@
+package duke.models;
+
+public class Task extends Planner {
+
+ protected boolean isDone;
+ protected boolean isCorrectFormat;
+
+ /**
+ * Constructor for Task.
+ *
+ * @param description Takes in a string that is
+ * either Todo, Event or Deadline.
+ */
+ public Task(String description) {
+ super(description);
+ this.isDone = false;
+ this.isCorrectFormat = false;
+ }
+
+
+ /**
+ * Returns tick or cross symbol.
+ *
+ * @return A tick or cross to symbolize whether the task has been done.
+ */
+ public String getStatusIcon() {
+ return (isDone ? "done" : "not done");
+ }
+
+ /**
+ * Method to mark the task to done.
+ */
+ public void markAsDone() {
+ isDone = true;
+ }
+
+ /**
+ * Method to get the String for whether
+ * the task is done or not.
+ *
+ * @return Returns the tick or cross in brackets.
+ */
+ public String toString() {
+ return "[" + getStatusIcon() + "]";
+ }
+
+
+}
diff --git a/src/main/java/duke/models/Todo.java b/src/main/java/duke/models/Todo.java
new file mode 100644
index 0000000000..c9f82efc2a
--- /dev/null
+++ b/src/main/java/duke/models/Todo.java
@@ -0,0 +1,24 @@
+package duke.models;
+
+public class Todo extends Task {
+
+ /**
+ * Constructor for Todo task.
+ *
+ * @param description Takes in todo task.
+ */
+ public Todo(String description) {
+ super(description);
+ }
+
+ /**
+ * Method to get the string for Todo tasks.
+ *
+ * @return Returns the formatted string to
+ * be added into tasklist and file.
+ */
+ @Override
+ public String toString() {
+ return "[T]" + super.toString() + " " + description;
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/images/JoshuaSeet.jpg b/src/main/resources/images/JoshuaSeet.jpg
new file mode 100644
index 0000000000..708ec88763
Binary files /dev/null and b/src/main/resources/images/JoshuaSeet.jpg differ
diff --git a/src/main/resources/images/ester.jpg b/src/main/resources/images/ester.jpg
new file mode 100644
index 0000000000..6052bbdd9b
Binary files /dev/null and b/src/main/resources/images/ester.jpg differ
diff --git a/src/main/resources/view/DialogBox.fxml b/src/main/resources/view/DialogBox.fxml
new file mode 100644
index 0000000000..e433809947
--- /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..d1a786be62
--- /dev/null
+++ b/src/main/resources/view/MainWindow.fxml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/out/artifacts/src_jar/src.jar b/src/out/artifacts/src_jar/src.jar
new file mode 100644
index 0000000000..edc0d09d26
Binary files /dev/null and b/src/out/artifacts/src_jar/src.jar differ
diff --git a/src/out/production/main/Deadline.class b/src/out/production/main/Deadline.class
new file mode 100644
index 0000000000..0cceec5e53
Binary files /dev/null and b/src/out/production/main/Deadline.class differ
diff --git a/src/out/production/main/Duke.class b/src/out/production/main/Duke.class
new file mode 100644
index 0000000000..993d93ae6b
Binary files /dev/null and b/src/out/production/main/Duke.class differ
diff --git a/src/out/production/main/DukeException.class b/src/out/production/main/DukeException.class
new file mode 100644
index 0000000000..31be4c5b55
Binary files /dev/null and b/src/out/production/main/DukeException.class differ
diff --git a/src/out/production/main/Event.class b/src/out/production/main/Event.class
new file mode 100644
index 0000000000..f27ca2cca1
Binary files /dev/null and b/src/out/production/main/Event.class differ
diff --git a/src/out/production/main/META-INF/MANIFEST.MF b/src/out/production/main/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..9f37e4e0aa
--- /dev/null
+++ b/src/out/production/main/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: Duke
+
diff --git a/src/out/production/main/Parser.class b/src/out/production/main/Parser.class
new file mode 100644
index 0000000000..9503fc75f0
Binary files /dev/null and b/src/out/production/main/Parser.class differ
diff --git a/src/out/production/main/Storage.class b/src/out/production/main/Storage.class
new file mode 100644
index 0000000000..3c1fe4f6ad
Binary files /dev/null and b/src/out/production/main/Storage.class differ
diff --git a/src/out/production/main/Task.class b/src/out/production/main/Task.class
new file mode 100644
index 0000000000..50a24da18b
Binary files /dev/null and b/src/out/production/main/Task.class differ
diff --git a/src/out/production/main/TaskList.class b/src/out/production/main/TaskList.class
new file mode 100644
index 0000000000..a91a63e494
Binary files /dev/null and b/src/out/production/main/TaskList.class differ
diff --git a/src/out/production/main/TaskTest.class b/src/out/production/main/TaskTest.class
new file mode 100644
index 0000000000..123cf56369
Binary files /dev/null and b/src/out/production/main/TaskTest.class differ
diff --git a/src/out/production/main/Todo.class b/src/out/production/main/Todo.class
new file mode 100644
index 0000000000..3b0224f3fe
Binary files /dev/null and b/src/out/production/main/Todo.class differ
diff --git a/src/out/production/main/Ui.class b/src/out/production/main/Ui.class
new file mode 100644
index 0000000000..afe201ffc0
Binary files /dev/null and b/src/out/production/main/Ui.class differ
diff --git a/src/out/production/main/todo.txt b/src/out/production/main/todo.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/out/production/main1/META-INF/MANIFEST.MF b/src/out/production/main1/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..9f37e4e0aa
--- /dev/null
+++ b/src/out/production/main1/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: Duke
+
diff --git a/src/out/production/main1/todo.txt b/src/out/production/main1/todo.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/out/test/test/META-INF/test.kotlin_module b/src/out/test/test/META-INF/test.kotlin_module
new file mode 100644
index 0000000000..2983af7066
Binary files /dev/null and b/src/out/test/test/META-INF/test.kotlin_module differ
diff --git a/src/out/test/test/StorageTest.class b/src/out/test/test/StorageTest.class
new file mode 100644
index 0000000000..cd42250786
Binary files /dev/null and b/src/out/test/test/StorageTest.class differ
diff --git a/src/out/test/test/TaskTest.class b/src/out/test/test/TaskTest.class
new file mode 100644
index 0000000000..011aca40a7
Binary files /dev/null and b/src/out/test/test/TaskTest.class differ
diff --git a/src/test/java/ParserTest.java b/src/test/java/ParserTest.java
new file mode 100644
index 0000000000..de600fbe94
--- /dev/null
+++ b/src/test/java/ParserTest.java
@@ -0,0 +1,14 @@
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import duke.execution.Parser;
+
+public class ParserTest {
+
+ @Test
+ public void formatDateTest() {
+ assertEquals("23rd of September 1997, 6:27 am",
+ Parser.formatDate("23/09/1997 0627"));
+ }
+}
diff --git a/src/test/java/StorageTest.java b/src/test/java/StorageTest.java
new file mode 100644
index 0000000000..ce575c7603
--- /dev/null
+++ b/src/test/java/StorageTest.java
@@ -0,0 +1,16 @@
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import duke.execution.Storage;
+
+public class StorageTest {
+
+ @Test
+ public void countLinesTest() throws IOException {
+ String file = "./src/test/test.txt";;
+ assertEquals(2, Storage.countLines(file));
+ }
+}
\ No newline at end of file
diff --git a/src/test/test.txt b/src/test/test.txt
new file mode 100644
index 0000000000..0274852362
--- /dev/null
+++ b/src/test/test.txt
@@ -0,0 +1,2 @@
+testing
+watermelon