diff --git a/.gitignore b/.gitignore
index f69985ef1f..110417a037 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@ bin/
/text-ui-test/ACTUAL.txt
text-ui-test/EXPECTED-UNIX.TXT
+*.class
\ No newline at end of file
diff --git a/README.md b/README.md
index 8715d4d915..7b44397355 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Duke project template
+# duke.Duke project template
This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it.
@@ -13,7 +13,7 @@ Prerequisites: JDK 11, update Intellij to the most recent version.
1. If there are any further prompts, accept the defaults.
1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
In the same dialog, set the **Project language level** field to the `SDK default` option.
-3. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output:
+3. After that, locate the file, right-click it, and choose (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output:
```
Hello from
____ _
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000000..d397ad2781
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,63 @@
+plugins {
+ id 'java'
+ id 'application'
+ id 'checkstyle'
+ id 'com.github.johnrengelman.shadow' version '5.1.0'
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0'
+ testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0'
+}
+
+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'
+}
+
+test {
+ useJUnitPlatform()
+
+ testLogging {
+ events "passed", "skipped", "failed"
+
+ showExceptions true
+ exceptionFormat "full"
+ showCauses true
+ showStackTraces true
+ showStandardStreams = false
+ }
+}
+
+application {
+ mainClassName = "duke.Launcher"
+}
+
+shadowJar {
+ archiveBaseName = "duke"
+ archiveClassifier = null
+}
+
+checkstyle {
+ toolVersion = '8.29'
+}
+
+run{
+ standardInput = System.in
+}
diff --git a/data/duke.txt b/data/duke.txt
new file mode 100644
index 0000000000..9a379f6276
--- /dev/null
+++ b/data/duke.txt
@@ -0,0 +1,2 @@
+[T][ ]/home
+[T][ ]/party
diff --git a/docs/README.md b/docs/README.md
index 8077118ebe..5fadfa813b 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,29 +1,132 @@
# User Guide
+Hi This is Halloumi ^_^.
+I can keep track of your tasks, deadlines and events for you, and am your own personal tasks manager.
+
## Features
-### Feature-ABC
+1. **ToDo** : A simple task with only a description that.
+2. **Deadline** : A task with a specific deadline that needs to be completed before that deadline.
+3. **Event** : A task that is going to happen occur on a specific date.
-Description of the feature.
+## Usage
-### Feature-XYZ
+### `todo` - add a todo task into the task list.
-Description of the feature.
+using this keyword with a description will add a todo task in the list.
-## Usage
+Example of usage:
+
+`todo read book`
+
+Expected outcome:
+
+this will add the task of reading a book to the list.
+
+```
+New task added:
+[T][ ] read book
+```
+
+### `deadline` - add a deadline task into the task list.
+
+using this keyword with a description and a date after "/by" will add a deadline task in the list.
+
+Example of usage:
+
+`deadline finish project /by 2022-06-10`
+
+Expected outcome:
+
+this will add the deadline task of finishing a project and set the deadline as June 10 2022.
+
+```
+New task added:
+[D][ ] finish project (by: Jun 10 2022)
+```
+
+### `event` - add an event task into the task list.
+
+using this keyword with a description and a date after "/at" will add a event task in the list.
+
+Example of usage:
+
+`event go party /at 2022-06-10`
+
+Expected outcome:
+
+this will add the event task of going to a party and set the event date as June 10 2022.
+
+```
+New task added:
+[E][ ] go party (at: June 10 2022)
+```
+
+### `mark` - marks a task as completed
+
+using this keyword with a task number from the list will mark that task as complete
+Example of usage:
+
+`mark 6`
+
+Expected outcome:
+
+this will mark the 6th task in the list as complete
+
+```
+Good Job! ^_^
+Task number 6 has been marked as done!
+[D][X] finish project (by: Jun 10 2022)
+```
+
+### `unmark` - marks a task as incompleted
+
+using this keyword with a task number from the list will mark that task as incomplete
+Example of usage:
+
+`unmark 6`
+
+Expected outcome:
+
+this will mark the 6th task in the list as incomplete
+
+```
+I've unmarked task number 6
+Complete it soon! ^_^
+[D][ ] finish project (by: Jun 10 2022))
+```
+### `delete` - delete a task
+
+using this keyword with a task number from the list will delete that task from the list
+
+Example of usage:
+
+`delete 6`
+
+Expected outcome:
+
+this will delete the 6th task in the list
+
+```
+Noted. I've removed this task:
+[D][ ] finish project (by: Jun 10 2022)
+```
-### `Keyword` - Describe action
+### `find` - find a task
-Describe the action and its outcome.
+using this keyword with a keyword will find the tasks where the description contain that keyword
Example of usage:
-`keyword (optional arguments)`
+`find run`
Expected outcome:
-Description of the outcome.
+this will find all the tasks where the description contains 'run'
```
-expected output
+Here are the matching tasks:
+1. [T][ ] run
+2. [D][ ] run (by: Jan 2 2007)
+3. [E][ ] run (at: Jan 2 2007)
```
diff --git a/docs/Ui.png b/docs/Ui.png
new file mode 100644
index 0000000000..12f840d06c
Binary files /dev/null and b/docs/Ui.png differ
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 0000000000..c4192631f2
--- /dev/null
+++ b/docs/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-cayman
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..f3d88b1c2f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..b7c8c5dbf5
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000000..2fe81a7d95
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000..62bd9b9cce
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,103 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/src/main/java/Duke.class b/src/main/java/Duke.class
new file mode 100644
index 0000000000..acbcbd380b
Binary files /dev/null and b/src/main/java/Duke.class differ
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..6e864153e8
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: duke.Duke
+
diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java
new file mode 100644
index 0000000000..805bf723f9
--- /dev/null
+++ b/src/main/java/duke/Duke.java
@@ -0,0 +1,134 @@
+package duke;
+
+import duke.*;
+import exceptions.DukeExceptions;
+import exceptions.DukeInvalidInput;
+import exceptions.DukeInvalidTodo;
+
+import java.io.*;
+import java.util.Collections;
+import java.util.Scanner;
+import java.util.ArrayList;
+
+/**
+ * Main method containing the Chat Bot.
+ */
+public class Duke {
+
+ static Storage storage = new Storage();
+ static TaskList taskList = new TaskList();
+ static ArrayList lists = new ArrayList();
+ public Duke() {
+ try {
+ storage.loadFromFile(lists);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Method containing the main execution of the Chat Bot.
+ * @param
+ * @throws DukeExceptions
+ * @throws IOException
+ */
+ public static String main(String input) throws DukeExceptions, IOException {
+ StringBuilder str = new StringBuilder();
+
+
+ boolean isOver = false;
+ int num = 0;
+
+ //Ui.enterHalloumi(str);
+
+
+ String[] textSplitOne = Parser.splitForwardSlash(input);
+ String[] textSplit = Parser.splitSpace(textSplitOne[0]);
+ String fullDesc = Parser.makeDesc(textSplit, textSplit.length);
+ try {
+ switch (textSplit[0]) {
+ case "bye":
+ num = Ui.exitHalloumi(str);
+ storage.writeToFile(lists);
+ break;
+ case "list":
+ Ui.printList(lists, lists.size(), str);
+ break;
+ case "mark":
+ for(int i = 1; i < textSplit.length; i++) {
+ taskList.mark(textSplit[i], lists, str);
+
+ }
+ break;
+ case "unmark":
+ for(int i = 1; i < textSplit.length; i++) {
+ taskList.unmark(textSplit[i], lists, str);
+
+ }
+ break;
+ case "delete" :
+ ArrayList array = new ArrayList<>();
+ for(int i = 1; i < textSplit.length; i++) {
+ Integer integer = Integer.parseInt(textSplit[i]);
+ array.add(integer);
+ }
+ Collections.sort(array, Collections.reverseOrder());
+// System.out.println(array);
+ for(int i = 0; i < array.size(); i++) {
+// System.out.println(textSplit[i]);
+ taskList.delete(String.valueOf(array.get(i)), lists, str);
+ }
+ break;
+ case "todo":
+ try {
+ if(fullDesc.equals(" ") || fullDesc.equals("")) {
+ throw new DukeInvalidTodo();
+ }
+ }
+ catch(DukeInvalidTodo e) {
+ str.append(e.getMessage());
+ }
+ taskList.todo(fullDesc, lists, str);
+ break;
+ case "event":
+ taskList.event(fullDesc, textSplitOne[1], lists, str);
+ break;
+ case "deadline":
+ taskList.deadline(fullDesc, textSplitOne[1], lists, str);
+ break;
+ case "find":
+ taskList.find(fullDesc, lists, str);
+ break;
+ default:
+ throw new DukeInvalidInput();
+ }
+ } catch (DukeInvalidInput e) {
+ str.append(e.getMessage());
+ }
+
+ isOver = true;
+
+ assert isOver;
+ return str.toString();
+ }
+
+ /**
+ *
+ * @param input the input from the user
+ * @return the response by the program
+ * @throws DukeExceptions
+ */
+
+ public String getResponse(String input) throws DukeExceptions, IOException {
+ try {
+
+ return main(input);
+ }
+ catch (DukeExceptions e) {
+ return e.getMessage();
+ }
+
+ }
+
+}
+
diff --git a/src/main/java/duke/Launcher.java b/src/main/java/duke/Launcher.java
new file mode 100644
index 0000000000..3b04bb6423
--- /dev/null
+++ b/src/main/java/duke/Launcher.java
@@ -0,0 +1,14 @@
+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);
+ }
+
+}
+
diff --git a/src/main/java/duke/Main.java b/src/main/java/duke/Main.java
new file mode 100644
index 0000000000..cf0d05fb07
--- /dev/null
+++ b/src/main/java/duke/Main.java
@@ -0,0 +1,34 @@
+package duke;
+import java.io.IOException;
+
+import duke.javafx.MainWindow;
+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.duke.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("/views/MainWindow.fxml"));
+ AnchorPane ap = fxmlLoader.load();
+ Scene scene = new Scene(ap);
+ stage.setScene(scene);
+ fxmlLoader.getController().setDuke(duke);
+ stage.show();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/Parser.java b/src/main/java/duke/Parser.java
new file mode 100644
index 0000000000..c9fd6b9b13
--- /dev/null
+++ b/src/main/java/duke/Parser.java
@@ -0,0 +1,57 @@
+package duke;
+
+/**
+ * Class for parsing through the input.
+ */
+public class Parser {
+
+ /**
+ * Method to split the string input with a forward slash.
+ * @param input user input.
+ * @return String[] array after splitting.
+ */
+ public static String[] splitForwardSlash(String input) {
+ return input.split("/");
+ }
+
+ /**
+ * Method to split the string input with a white space.
+ * @param input user input.
+ * @return String[] array after splitting.
+ */
+ public static String[] splitSpace(String input) {
+ return input.split(" ");
+ }
+
+ /**
+ * Method to split the string input with a bracket.
+ * @param input user input.
+ * @return String[] array after splitting
+ */
+ public static String[] splitBracket(String input) {
+ return input.split("]");
+ }
+
+ /**
+ * Method to change string to int type.
+ * @param input user input.
+ * @return int after parsing through string.
+ */
+ public static int stringToInt(String input) {
+ return Integer.parseInt(input);
+ }
+
+ /**
+ * Method to make the description of tasks.
+ * @param text user input.
+ * @param len length of user input.
+ * @return full description of the task.
+ */
+ public static String makeDesc(String[] text, int len) {
+ String newText = "";
+ for (int i = 1; i < len; i++) {
+ newText = newText + text[i] + " ";
+ }
+ return newText.trim();
+ }
+}
diff --git a/src/main/java/duke/Storage.java b/src/main/java/duke/Storage.java
new file mode 100644
index 0000000000..04a11b3a54
--- /dev/null
+++ b/src/main/java/duke/Storage.java
@@ -0,0 +1,86 @@
+package duke;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.Scanner;
+
+/**
+ * Class to save and load data.
+ */
+public class Storage {
+
+ /**
+ * Method to write the task list to file.
+ * @param list provides data to write tasks to the file.
+ * @throws IOException
+ */
+ public void writeToFile(ArrayList list) throws IOException {
+ try {
+ File f = new File("./data/duke.txt");
+ boolean hasCreatedDirectory = f.getParentFile().mkdirs();
+ boolean hasCreated = f.createNewFile();
+ FileWriter writer = new FileWriter(f, false);
+ for (Task task : list) {
+ String fileInput;
+ Task ele = task;
+ if (ele instanceof ToDo) {
+ fileInput = "[T][" + ele.getStatusIcon() + "]/" + ele.description;
+ } else if (ele instanceof Deadline) {
+ Deadline deadL = (Deadline) ele;
+ fileInput = "[D][" + deadL.getStatusIcon() + "]/" + deadL.description + "/" + deadL.when;
+ } else {
+ Event eve = (Event) ele;
+ fileInput = "[E][" + eve.getStatusIcon() + "]/" + eve.description + "/" + eve.when;
+ }
+ writer.write(fileInput + "\n");
+ writer.flush();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Method to read tasks from the file.
+ * @param list data is written to this variable.
+ * @throws IOException
+ */
+ public void loadFromFile(ArrayList list) throws IOException {
+ File f = new File("./data/duke.txt");
+ boolean hasCreatedDirectory = f.getParentFile().mkdirs();
+ boolean hasCreated = f.createNewFile();
+ String input, desc;
+ Task t;
+ Scanner in = new Scanner(f);
+ while(in.hasNextLine()) {
+ input = in.nextLine();
+ String[] tSplit = Parser.splitForwardSlash(input);
+ String[] splitT = Parser.splitBracket(tSplit[0]);
+ switch(splitT[0]) {
+ case "[T":
+ t = new ToDo(tSplit[1]);
+ break;
+ case "[E":
+ t = new Event(tSplit[1], LocalDate.parse(tSplit[2]));
+ break;
+ case "[D":
+ t = new Deadline(tSplit[1], LocalDate.parse(tSplit[2]));
+ break;
+ default:
+ t = new Task("eee");
+ break;
+ }
+ if(splitT[1].equals("[X")) {
+ t.done();
+ list.add(t);
+ }
+ else {
+ list.add(t);
+ }
+ }
+ in.close();
+ }
+}
diff --git a/src/main/java/duke/Task.java b/src/main/java/duke/Task.java
new file mode 100644
index 0000000000..9857a69d1f
--- /dev/null
+++ b/src/main/java/duke/Task.java
@@ -0,0 +1,79 @@
+package duke;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * Class that contains information for all tasks.
+ */
+public class Task {
+ String description;
+ boolean isDone;
+
+ public Task(String desc) {
+ description = desc;
+ isDone = false;
+ }
+ public String getStatusIcon() {
+ return (isDone ? "X" : " "); // mark done task with X
+ }
+
+ public String toString() {
+ return String.format("[%s] %s", getStatusIcon(), description);
+ }
+
+ public void done() {
+ isDone = true;
+ }
+
+ public void undo() {
+ isDone = false;
+ }
+}
+
+/**
+ * Todo class that inherits from the Task class.
+ */
+class ToDo extends Task {
+ public ToDo(String desc) {
+ super(desc);
+ }
+
+ public String toString() {
+ return "[T]" + super.toString();
+ }
+}
+
+/**
+ * Event class that inherits from the Task class.
+ */
+class Event extends Task {
+ LocalDate when;
+
+ public Event(String desc, LocalDate date) {
+ super(desc);
+ when = date;
+ }
+
+ public String toString() {
+ return "[E]" + super.toString() + " (at: " +
+ when.format(DateTimeFormatter.ofPattern("MMM d yyyy")) + ")";
+ }
+}
+
+ /**
+ * Deadline class that inherits from the Task class.
+ */
+ class Deadline extends Task {
+ LocalDate when;
+
+ public Deadline(String desc, LocalDate date) {
+ super(desc);
+ when = date;
+ }
+
+ public String toString() {
+ return "[D]" + super.toString() + " (by: " +
+ when.format(DateTimeFormatter.ofPattern("MMM d yyyy")) + ")";
+ }
+ }
diff --git a/src/main/java/duke/TaskList.java b/src/main/java/duke/TaskList.java
new file mode 100644
index 0000000000..1aa469143d
--- /dev/null
+++ b/src/main/java/duke/TaskList.java
@@ -0,0 +1,128 @@
+package duke;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+
+/**
+ * Class that contains all task related functions.
+ */
+public class TaskList {
+
+ /**
+ * Method to mark task as done.
+ * @param task the task number as a string.
+ * @param list list containing all the tasks.
+ */
+ public void mark(String task, ArrayList list, StringBuilder str) {
+ str.append(Ui.lineOne());
+ str.append("Good Job! ^_^\n");
+ str.append("Task number ").append(task).append(" has been marked as done!\n");
+ int tNum = Integer.parseInt(task);
+ list.get(tNum - 1).done();
+ str.append(list.get(tNum - 1)).append("\n");
+ str.append(Ui.lineOne());
+ }
+
+ /**
+ * Method to unmark task as done.
+ * @param task the task number as a string.
+ * @param list list containing all the tasks.
+ */
+ public void unmark(String task, ArrayList list, StringBuilder str) {
+ str.append(Ui.lineOne());
+ str.append("I've unmarked task number ").append(task).append("\n");
+ str.append("Complete it soon! ^_^\n");
+ int tNo = Parser.stringToInt(task);
+ list.get(tNo - 1).undo();
+ str.append(list.get(tNo - 1)).append("\n");
+ str.append(Ui.lineOne());
+ }
+
+ /**
+ * Method to delete a task from the list.
+ * @param task the task number as a string.
+ * @param list list containing all the tasks.
+ */
+ public void delete(String task, ArrayList list, StringBuilder str) {
+ str.append(Ui.lineOne());
+ str.append("Noted. I've removed this task:\n");
+ int t2No = Parser.stringToInt(task);
+ str.append(list.get(t2No - 1)).append("\n");
+ list.remove(t2No - 1);
+ str.append(Ui.lineOne());
+ }
+
+ /**
+ * Method to create an event task and add it to the list.
+ * @param desc description of the event.
+ * @param at additional information.
+ * @param list list containing all the tasks.
+ */
+ public void event(String desc, String at, ArrayList list, StringBuilder str) {
+ str.append(Ui.lineTwo());
+ str.append("New task added:\n");
+ String[] date = Parser.splitSpace(at);
+ Task t2 = new Event(desc, LocalDate.parse(date[1]));
+ list.add(t2);
+ str.append(t2).append("\n");
+ str.append("You have ").append(list.size()).append(" tasks left now! ^_^\n");
+ str.append(Ui.lineTwo());
+ }
+
+ /**
+ * Method to create a todo task and add it to the list.
+ * @param desc description of the event.
+ * @param list list containing all the tasks.
+ */
+ public void todo(String desc, ArrayList list, StringBuilder str) {
+ str.append(Ui.lineTwo());
+ str.append("New task added:\n");
+ Task t = new ToDo(desc);
+ list.add(t);
+ str.append(t).append("\n");
+ str.append("You have ").append(list.size()).append(" tasks left now! ^_^\n");
+ str.append(Ui.lineTwo());
+ }
+
+ /**
+ * Method to create a deadline task and add it to the list.
+ * @param desc description of the event.
+ * @param by additional information
+ * @param list list containing all the tasks.
+ */
+ public void deadline(String desc, String by, ArrayList list, StringBuilder str) {
+ str.append(Ui.lineTwo());
+ str.append("New task added:\n");
+ String[] date = Parser.splitSpace(by);
+ Task t2 = new Deadline(desc, LocalDate.parse(date[1]));
+ list.add(t2);
+ str.append(t2).append("\n");
+ str.append("You have ").append(list.size()).append(" tasks left now! ^_^\n");
+ str.append(Ui.lineTwo());
+ }
+
+ /**
+ * Method that returns a string.
+ * @return String
+ */
+ public String returnMatching() {
+ String string = "Here are the matching tasks:\n";
+ return string;
+ }
+
+ /**
+ * Method to find a task.
+ * @param desc description of the task to be found.
+ * @param list list containing all the tasks.
+ */
+ public void find(String desc, ArrayList list, StringBuilder str) {
+ str.append(Ui.lineTwo());
+ str.append(returnMatching());
+ for(int i = 0; i < list.size(); i++) {
+ if(list.get(i).description.contains(desc)) {
+ str.append(i+1).append(". ").append(list.get(i)).append("\n");
+ }
+ }
+ str.append(Ui.lineTwo());
+ }
+}
diff --git a/src/main/java/duke/Ui.java b/src/main/java/duke/Ui.java
new file mode 100644
index 0000000000..58e37ceda4
--- /dev/null
+++ b/src/main/java/duke/Ui.java
@@ -0,0 +1,67 @@
+package duke;
+
+import java.util.ArrayList;
+
+/**
+ * Class that contains UI related functions.
+ */
+public class Ui {
+
+ /**
+ * Method to print divider of type *.
+ */
+ public static String lineOne() {
+ return("***************************\n");
+ }
+
+ /**
+ * Method to print divider of type |-|.
+ */
+ public static String lineTwo() {
+ return("|-|-|-|-|-|-|-|-|-|-|-|-|-|\n");
+ }
+
+ /**
+ * Method to print all the tasks currently in the list.
+ * @param list contains all the current tasks.
+ * @param size list size.
+ */
+ public static void printList(ArrayList list, int size, StringBuilder str) {
+ str.append(lineOne());
+ str.append("List: \n");
+ if(list.isEmpty()) {
+ str.append("No tasks to complete! ^_^\n");
+ return;
+ }
+ for (int i = 0; i < size; i++) {
+ str.append(i+1).append(". ").append(list.get(i)).append("\n");
+ }
+ str.append(lineOne());
+ }
+
+ /**
+ * Method to print the start of program.
+ */
+ public static void enterHalloumi(StringBuilder str) {
+ str.append(lineOne());
+ str.append("Hi! I'm Halloumi ^_^\n");
+ str.append("What do you need help with today?\n");
+ str.append(lineOne());
+ }
+
+ public static String byeMessage() {
+ String string = "See you soon! Have a good day ^_^\n";
+ return string;
+ }
+
+ /**
+ * Method to exit the chatbot.
+ * @return an int to signify the end of the program.
+ */
+ public static int exitHalloumi(StringBuilder str) {
+ str.append(lineOne());
+ str.append(byeMessage());
+ str.append(lineOne());
+ return 1;
+ }
+}
diff --git a/src/main/java/duke/javafx/DialogBox.java b/src/main/java/duke/javafx/DialogBox.java
new file mode 100644
index 0000000000..d8ca7c9689
--- /dev/null
+++ b/src/main/java/duke/javafx/DialogBox.java
@@ -0,0 +1,66 @@
+package duke.javafx;
+
+import java.io.IOException;
+import java.util.Collections;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.HBox;
+import javafx.scene.text.Font;
+
+/**
+ * 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 {
+
+ private static final Font CHAT_FONT = Font.loadFont(
+ DialogBox.class.getResource("/fonts/tnr.ttf").toExternalForm(), 12);
+ @FXML
+ private Label dialog;
+ @FXML
+ private ImageView displayPicture;
+
+ private DialogBox(String text, Image img) {
+ try {
+ FXMLLoader fxmlLoader = new FXMLLoader(MainWindow.class.getResource("/views/DialogBox.fxml"));
+ fxmlLoader.setController(this);
+ fxmlLoader.setRoot(this);
+ fxmlLoader.load();
+ dialog.setFont(CHAT_FONT);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ dialog.setText(text);
+ displayPicture.setImage(img);
+ }
+
+ /**
+ * Flips the dialog box such that the ImageView is on the left and text on the right.
+ */
+ private void flip() {
+ ObservableList tmp = FXCollections.observableArrayList(this.getChildren());
+ Collections.reverse(tmp);
+ getChildren().setAll(tmp);
+ setAlignment(Pos.TOP_LEFT);
+ }
+
+ public static DialogBox getUserDialog(String text, Image img) {
+ return new DialogBox(text, img);
+ }
+
+ public static DialogBox getDukeDialog(String text, Image img) {
+ var db = new DialogBox(text, img);
+ db.flip();
+ return db;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/duke/javafx/MainWindow.java b/src/main/java/duke/javafx/MainWindow.java
new file mode 100644
index 0000000000..8be7dc05c9
--- /dev/null
+++ b/src/main/java/duke/javafx/MainWindow.java
@@ -0,0 +1,61 @@
+package duke.javafx;
+import duke.Duke;
+import exceptions.DukeExceptions;
+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 javafx.scene.text.Font;
+
+import java.io.IOException;
+
+/**
+ * Controller for MainWindow. Provides the layout for the other controls.
+ */
+public class MainWindow extends AnchorPane {
+
+ private static final Font CHAT_FONT = Font.loadFont(
+ DialogBox.class.getResource("/fonts/tnr.ttf").toExternalForm(), 12);
+ @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/DaUser.png"));
+ private Image dukeImage = new Image(this.getClass().getResourceAsStream("/images/DaDuke.png"));
+
+ @FXML
+ public void initialize() {
+ scrollPane.vvalueProperty().bind(dialogContainer.heightProperty());
+ userInput.setFont(CHAT_FONT);
+ sendButton.setFont(CHAT_FONT);
+ }
+
+ public void setDuke(Duke d) {
+ duke = d;
+ }
+
+ /**
+ * Creates two dialog boxes, one echoing user input and the other containing duke.duke.Duke's reply and then appends them to
+ * the dialog container. Clears the user input after processing.
+ */
+ @FXML
+ private void handleUserInput() throws DukeExceptions, IOException {
+ 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/exceptions/DukeExceptions.java b/src/main/java/exceptions/DukeExceptions.java
new file mode 100644
index 0000000000..e143662e7e
--- /dev/null
+++ b/src/main/java/exceptions/DukeExceptions.java
@@ -0,0 +1,7 @@
+package exceptions;
+
+public class DukeExceptions extends Exception {
+ public DukeExceptions(String output) {
+ super(output);
+ }
+}
diff --git a/src/main/java/exceptions/DukeInvalidInput.java b/src/main/java/exceptions/DukeInvalidInput.java
new file mode 100644
index 0000000000..9968966406
--- /dev/null
+++ b/src/main/java/exceptions/DukeInvalidInput.java
@@ -0,0 +1,7 @@
+package exceptions;
+
+public class DukeInvalidInput extends DukeExceptions {
+ public DukeInvalidInput() {
+ super("ENTER A VALID INPUT! ^_^");
+ }
+}
diff --git a/src/main/java/exceptions/DukeInvalidTodo.java b/src/main/java/exceptions/DukeInvalidTodo.java
new file mode 100644
index 0000000000..fb7c43afe5
--- /dev/null
+++ b/src/main/java/exceptions/DukeInvalidTodo.java
@@ -0,0 +1,7 @@
+package exceptions;
+
+public class DukeInvalidTodo extends DukeExceptions {
+ public DukeInvalidTodo() {
+ super("ENTER A DESCRIPTION! ^_^");
+ }
+}
diff --git a/src/main/resources/fonts/tnr.ttf b/src/main/resources/fonts/tnr.ttf
new file mode 100644
index 0000000000..5cdac9ca59
Binary files /dev/null and b/src/main/resources/fonts/tnr.ttf differ
diff --git a/src/main/resources/images/DaDuke.png b/src/main/resources/images/DaDuke.png
new file mode 100644
index 0000000000..730ac16b0b
Binary files /dev/null and b/src/main/resources/images/DaDuke.png differ
diff --git a/src/main/resources/images/DaUser.png b/src/main/resources/images/DaUser.png
new file mode 100644
index 0000000000..2513a80e93
Binary files /dev/null and b/src/main/resources/images/DaUser.png differ
diff --git a/src/main/resources/views/DialogBox.fxml b/src/main/resources/views/DialogBox.fxml
new file mode 100644
index 0000000000..ede775d4f9
--- /dev/null
+++ b/src/main/resources/views/DialogBox.fxml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/views/MainWindow.fxml b/src/main/resources/views/MainWindow.fxml
new file mode 100644
index 0000000000..84c540a154
--- /dev/null
+++ b/src/main/resources/views/MainWindow.fxml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/DukeTest.java b/src/test/java/DukeTest.java
new file mode 100644
index 0000000000..94f917bd8d
--- /dev/null
+++ b/src/test/java/DukeTest.java
@@ -0,0 +1,12 @@
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class DukeTest {
+
+ @Test
+ public void dummyTest() {
+ assertEquals(2, 2);
+ }
+
+
+}
diff --git a/src/test/java/duke/ParserTest.java b/src/test/java/duke/ParserTest.java
new file mode 100644
index 0000000000..2444388692
--- /dev/null
+++ b/src/test/java/duke/ParserTest.java
@@ -0,0 +1,21 @@
+package duke;
+
+import org.junit.jupiter.api.Test;
+
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ParserTest {
+
+ @Test
+ public void ParserTest() {
+ String testSpace = "hello world";
+ String[] output1 = Parser.splitSpace(testSpace);
+
+ String testForwardSlash = "hello/world";
+ String[] output2 = Parser.splitForwardSlash(testForwardSlash);
+
+ assertEquals("world", output1[1]);
+ assertEquals("hello", output2[0]);
+ }
+}
diff --git a/src/test/java/duke/TaskListTest.java b/src/test/java/duke/TaskListTest.java
new file mode 100644
index 0000000000..fa4c49794c
--- /dev/null
+++ b/src/test/java/duke/TaskListTest.java
@@ -0,0 +1,16 @@
+package duke;
+
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class TaskListTest {
+
+ @Test
+ public void TaskListTest() {
+ Task t1 = new ToDo("todo run");
+ Task t2 = new Event("event swim", "at 12pm");
+ assertEquals("[T][ ] todo run", t1.toString());
+ assertEquals("[E][ ] event swim (at 12pm)", t2.toString());
+ }
+}
diff --git a/src/test/java/duke/UiTest.java b/src/test/java/duke/UiTest.java
new file mode 100644
index 0000000000..af23d62950
--- /dev/null
+++ b/src/test/java/duke/UiTest.java
@@ -0,0 +1,13 @@
+package duke;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class UiTest {
+
+ @Test
+ public void UiTest() {
+ String output = "*************************************************************************";
+ assertEquals("*************************************************************************", output);
+ }
+}
diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT
index 657e74f6e7..326f908f81 100644
--- a/text-ui-test/EXPECTED.TXT
+++ b/text-ui-test/EXPECTED.TXT
@@ -1,7 +1,24 @@
-Hello from
- ____ _
-| _ \ _ _| | _____
-| | | | | | | |/ / _ \
-| |_| | |_| | < __/
-|____/ \__,_|_|\_\___|
-
+*************************************************************************
+Hi! I'm Halloumi ^_^
+What do you need help with today?
+*************************************************************************
+|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
+New task added:
+[T][ ] borrow book
+You have 1 tasks in the list now! ^_^
+|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
+|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
+New task added:
+[E][ ] wake up (: at 8am)
+You have 2 tasks in the list now! ^_^
+|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
+|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
+New task added:
+[D][ ] submit assignment (: by Sunday)
+You have 3 tasks in the list now! ^_^
+|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
+1. [T][ ] borrow book
+2. [E][ ] wake up (: at 8am)
+3. [D][ ] submit assignment (: by Sunday)
+See you soon! Have a good day ^_^
+*************************************************************************
diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt
index e69de29bb2..95cf5ee636 100644
--- a/text-ui-test/input.txt
+++ b/text-ui-test/input.txt
@@ -0,0 +1,5 @@
+todo borrow book
+event wake up /at 8am
+deadline submit assignment /by Sunday
+list
+bye
diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat
index 0873744649..62752b8814 100644
--- a/text-ui-test/runtest.bat
+++ b/text-ui-test/runtest.bat
@@ -15,7 +15,7 @@ IF ERRORLEVEL 1 (
REM no error here, errorlevel == 0
REM run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT
-java -classpath ..\bin Duke < input.txt > ACTUAL.TXT
+java -classpath ..\bin duke.Duke < input.txt > ACTUAL.TXT
REM compare the output to the expected output
FC ACTUAL.TXT EXPECTED.TXT
diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh
old mode 100644
new mode 100755