diff --git a/.classpath b/.classpath new file mode 100644 index 00000000..225833aa --- /dev/null +++ b/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore index f69985ef..2f776923 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ # Gradle build files /.gradle/ /build/ -src/main/resources/docs/ +src/resources/docs/ # MacOS custom attributes files created by Finder .DS_Store diff --git a/.project b/.project new file mode 100644 index 00000000..593d9d82 --- /dev/null +++ b/.project @@ -0,0 +1,34 @@ + + + Duke + Project Duke created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + + + 1635828326582 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 00000000..9233ccf5 --- /dev/null +++ b/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,13 @@ +arguments= +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) +connection.project.dir= +eclipse.preferences.version=1 +gradle.user.home= +java.home=C\:/Program Files/Java/jdk-11.0.2 +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/Duke-1.2.jar b/Duke-1.2.jar new file mode 100644 index 00000000..48e61023 Binary files /dev/null and b/Duke-1.2.jar differ diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..330c7f3d --- /dev/null +++ b/build.gradle @@ -0,0 +1,40 @@ +plugins { + id 'java' + id 'application' + id 'checkstyle' + id 'com.github.johnrengelman.shadow' version '5.1.0' +} + +group 'com.kangteng.duke' +version '1.0' + +repositories { + mavenCentral() +} + +mainClassName = 'duke.Duke' + +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' +} + +test { + useJUnitPlatform() +} + +shadowJar { + archiveBaseName = "duke" + archiveClassifier = null +} + +run{ + standardInput = System.in + enableAssertions = true +} + +checkstyle { + toolVersion = '8.29' +} + + diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 00000000..502fbd3a --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml new file mode 100644 index 00000000..dcaa1af3 --- /dev/null +++ b/config/checkstyle/suppressions.xml @@ -0,0 +1,10 @@ + + + + + + + + \ 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 00000000..f3d88b1c 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 00000000..be52383e --- /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.7-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..2fe81a7d --- /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 00000000..62bd9b9c --- /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/local.properties b/local.properties new file mode 100644 index 00000000..6a149695 --- /dev/null +++ b/local.properties @@ -0,0 +1,8 @@ +## This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +#Fri Nov 12 19:26:13 SGT 2021 +sdk.dir=C\:\\Users\\Endire\\AppData\\Local\\Android\\Sdk diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334..00000000 --- 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/duke/Duke.java b/src/main/java/duke/Duke.java new file mode 100644 index 00000000..74cafa95 --- /dev/null +++ b/src/main/java/duke/Duke.java @@ -0,0 +1,64 @@ +package duke; + +import duke.exception.UnableToLoadProcessException; +import duke.storage.FileAccess; +import duke.task.TaskList; +import duke.ui.Message; +import duke.ui.Ui; + +/** + * Begin the program here. + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ +public class Duke { + + private FileAccess fileAccess; + private TaskList myList; + private Ui ui; + + /** + * Constructor + *

+ * initialize the ui, fileAccess and taskList + * load the progress into taskList + */ + public Duke(String filepath) { + ui = new Ui(); + fileAccess = new FileAccess(filepath); + myList = new TaskList(); + + try { + String progress = fileAccess.loadProgressFromFile(); + new LoadDuke(myList, progress).run(); + } catch (UnableToLoadProcessException e) { + Message.msgUnableToLoadProgress(); + } + } + + /** + * Start the Duke program + */ + public void initialize() { + StartDuke.run(); + new RunDuke(myList, ui, fileAccess).run(); + } + + /** + * End the Duke program + */ + public void end() { + new EndDuke(fileAccess).run(); + } + + /** + * Starting point of the program + */ + public static void main(String[] args) { + Duke duke = new Duke("src\\resources\\progress.txt"); + duke.initialize(); + duke.end(); + } +} diff --git a/src/main/java/duke/EndDuke.java b/src/main/java/duke/EndDuke.java new file mode 100644 index 00000000..6e9db128 --- /dev/null +++ b/src/main/java/duke/EndDuke.java @@ -0,0 +1,47 @@ +package duke; + +import duke.exception.UnableToLoadBuddhaException; +import duke.storage.FileAccess; +import duke.ui.Message; + +/** + * Duke class that executes when Duke is ending + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class EndDuke { + + private static FileAccess fileAccess; + + /** + * Constructor + */ + public EndDuke(FileAccess fileAccess) { + this.fileAccess = fileAccess; + } + + /** + * Start the end sequence + */ + public static void run() { + showByeMessage(); + } + + /** + * Show the Bye Message + *

+ * called when Duke program ends + */ + public static void showByeMessage() { + try { + Message.msgBye(); + String buddhaText = fileAccess.readBuddhaText(); + Message.msgBuddha(buddhaText); + } catch (UnableToLoadBuddhaException e) { + Message.msgUnableToLoadBuddha(); + } + } +} diff --git a/src/main/java/duke/LoadDuke.java b/src/main/java/duke/LoadDuke.java new file mode 100644 index 00000000..926ef410 --- /dev/null +++ b/src/main/java/duke/LoadDuke.java @@ -0,0 +1,152 @@ +package duke; + +import java.time.LocalDate; +import java.time.LocalTime; + +import duke.action.ParseDateTime; +import duke.action.ParseProgress; +import duke.exception.UnableToLoadProcessException; +import duke.task.TaskList; +import duke.task.TaskPriority; +import duke.ui.Message; + +/** + * Duke class that executes when Duke is loading progress + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class LoadDuke { + + private TaskList myList; + private String progress; + private String[] sentences; + + /** + * Constructor + */ + public LoadDuke(TaskList myList, String progress) { + this.myList = myList; + this.progress = progress; + } + + /** + * Execute the load + */ + public void run() throws UnableToLoadProcessException { + try { + splitStringByTask(); + createTaskFromSentence(); + } catch (Exception e) { + Message.msgError(e); + throw new UnableToLoadProcessException(); + } + } + + /** + * Calls to parser to split progress.txt into sentences + * Each sentence represents a task in String + */ + private void splitStringByTask() throws Exception { + sentences = ParseProgress.splitProgressIntoSentence(progress); + } + + /** + * Loop through the sentences and read each sentence + * Generate task from each sentence + */ + private void createTaskFromSentence() throws Exception { + for (int i = 0; i < sentences.length - 1; i++) { + String[] phrases = ParseProgress.splitSentenceByBarSeparator(sentences[i]); + addTaskFromPhrases(phrases); + } + } + + /** + * Add task into taskList based on each sentence + */ + private void addTaskFromPhrases(String[] phrases) throws Exception { + + String taskIndexInString = phrases[0]; + int taskIndex = Integer.parseInt(taskIndexInString); + + String taskTypeInString = phrases[1]; + + String isDoneInString = phrases[2]; + + String taskDetail = phrases[3]; + + String taskPriorityInString = phrases[4]; + int taskPriorityInInt = Integer.parseInt(taskPriorityInString); + TaskPriority taskPriority = TaskPriority.convertIntToPriority(taskPriorityInInt); + + String taskDateInString = "null"; + LocalDate taskDate; + + String taskStartTimeInString = "null"; + LocalTime taskTimeStart; + + String taskEndTimeInString = "null"; + LocalTime taskTimeEnd; + + int i = 5; + while (true) { + if (phrases[i].equals(";\r")) { + break; + } + + switch (i) { + case 5: + taskDateInString = phrases[5]; + break; + case 6: + taskStartTimeInString = phrases[6]; + break; + case 7: + taskEndTimeInString = phrases[7]; + break; + default: + break; + } + i++; + } + + switch (taskTypeInString) { + case "T": + myList.addItemToDos(taskDetail); + break; + case "E": + taskDate = ParseDateTime.toDate(taskDateInString); + if (taskEndTimeInString.equals("null") && taskStartTimeInString.equals("null")) { + myList.addItemEvent(taskDetail, taskDate); + } else if (taskEndTimeInString.equals("null")) { + taskTimeStart = ParseDateTime.toTime(taskStartTimeInString); + myList.addItemEvent(taskDetail, taskDate, taskTimeStart); + } else { + taskTimeStart = ParseDateTime.toTime(taskStartTimeInString); + taskTimeEnd = ParseDateTime.toTime(taskEndTimeInString); + myList.addItemEvent(taskDetail, taskDate, taskTimeStart, taskTimeEnd); + } + break; + case "D": + taskDate = ParseDateTime.toDate(taskDateInString); + if (taskStartTimeInString.equals("null")) { + myList.addItemDeadline(taskDetail, taskDate); + } else { + taskTimeStart = ParseDateTime.toTime(taskStartTimeInString); + myList.addItemDeadline(taskDetail, taskDate, taskTimeStart); + } + break; + default: + break; + } + + if (isDoneInString.equals("1")) { + myList.setTaskDone(taskIndex); + } + + myList.setTaskPriority(taskIndex, taskPriority); + } +} diff --git a/src/main/java/duke/RunDuke.java b/src/main/java/duke/RunDuke.java new file mode 100644 index 00000000..c6e3c907 --- /dev/null +++ b/src/main/java/duke/RunDuke.java @@ -0,0 +1,118 @@ +package duke; + +import java.util.Scanner; + +import duke.action.Parser; +import duke.command.Command; +import duke.storage.FileAccess; +import duke.task.TaskList; +import duke.ui.Message; +import duke.ui.Ui; + +/** + * Duke class that run the main Duke program + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class RunDuke { + + private static TaskList myList; + private static Ui ui; + private static FileAccess fileAccess; + private static Parser parser; + private static Command cmd; + private static Scanner scanner; + + /** + * Constructor + */ + public RunDuke(TaskList myList, Ui ui, FileAccess fileAccess) { + this.myList = myList; + this.ui = ui; + this.fileAccess = fileAccess; + parser = new Parser(); + cmd = new Command(parser); + scanner = new Scanner(System.in); + } + + /** + * Execute the run + */ + public void run() { + + boolean isDukeRunning = true; + + while (isDukeRunning) { + String userInput = ui.requestUserInput(scanner); + if (userInput.isEmpty()) { + Message.msgInvalidInput(); + } else { + String userCommand = parser.processUserCommand(userInput); + isDukeRunning = canProcessCommand(userCommand, userInput); + } + } + } + + /** + * Read user command and execute respective methods accordingly + *

+ * Accepted user input: bye, list, set, done, todo, save + * Accepted user input: find, info, event, delete, deadline + *

+ * method returns true for all commands and non-accepted user input + * method return false for bye command. + * + * @param userCommand String that represents the command type by user + * @param userInput String that represents the full user input + * @return boolean false if the command is "bye"; true if otherwise + */ + private static boolean canProcessCommand(String userCommand, String userInput) { + + assert !userCommand.isEmpty() : "userCommand should not be empty"; + assert !userInput.isEmpty() : "userInput should not be empty"; + + switch (userCommand) { + case "bye": + return false; + case "list": + cmd.showFullList(myList); + return true; + case "set": + cmd.setPriorityTask(myList, scanner); + return true; + case "done": + cmd.markTaskDone(myList, userInput); + return true; + case "todo": + cmd.addTaskToDo(myList, userInput); + return true; + case "save": + cmd.saveTask(myList, fileAccess); + return true; + case "find": + cmd.findTask(myList, userInput); + return true; + case "info": + cmd.showInfo(); + return true; + case "event": + cmd.addTaskEvent(myList, userInput); + return true; + case "undone": + cmd.markTaskUnDone(myList, userInput); + return true; + case "delete": + cmd.deleteTask(myList, userInput); + return true; + case "deadline": + cmd.addTaskDeadline(myList, userInput); + return true; + default: + cmd.showInvalidCommand(); + return true; + } + } +} diff --git a/src/main/java/duke/StartDuke.java b/src/main/java/duke/StartDuke.java new file mode 100644 index 00000000..c59fdd63 --- /dev/null +++ b/src/main/java/duke/StartDuke.java @@ -0,0 +1,24 @@ +package duke; + +import duke.ui.Message; + +/** + * Duke class that executes when Duke is initialized + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ +public class StartDuke { + + public static void run() { + showGreetMessage(); + } + + /** + * Show the opening Greet Message in System.out.println + */ + public static void showGreetMessage() { + Message.msgGreet(); + } +} diff --git a/src/main/java/duke/action/ParseDateTime.java b/src/main/java/duke/action/ParseDateTime.java new file mode 100644 index 00000000..3bc69f9c --- /dev/null +++ b/src/main/java/duke/action/ParseDateTime.java @@ -0,0 +1,147 @@ +package duke.action; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.DateTimeParseException; +import java.util.Locale; + +/** + * Handle date and time related functions + *

+ * Conversion between String and LocalDate/LocalTime + * String manipulation + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class ParseDateTime { + + /** + * Convert date from String to LocalDate + * + * @param date TaskDate of the task + * @return LocalDate + * @throws DateTimeParseException If format of the date is not accepted + */ + public static LocalDate toDate(String date) { + + LocalDate formattedDate; + DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder() + .parseCaseInsensitive() + .parseLenient() + .appendPattern("[yyyy-MM-dd]") + .appendPattern("[M-d-yyyy]") + .appendPattern("[M-dd-yyyy]") + .appendPattern("[MM-d-yyyy]") + .appendPattern("[MM-dd-yyyy]") + .appendPattern("[M/d/yyyy]") + .appendPattern("[M/dd/yyyy]") + .appendPattern("[MM/d/yyyy]") + .appendPattern("[MM/dd/yyyy]") + .appendPattern("[d-M-yyyy]") + .appendPattern("[d-MM-yyyy]") + .appendPattern("[dd-M-yyyy]") + .appendPattern("[dd-MM-yyyy]") + .appendPattern("[d/M/yyyy]") + .appendPattern("[d/MM/yyyy]") + .appendPattern("[dd/M/yyyy]") + .appendPattern("[dd/MM/yyyy]") + .appendPattern("[MMM dd yyyy]"); + + DateTimeFormatter formatter = builder.toFormatter(Locale.ENGLISH); + + try { + formattedDate = LocalDate.parse(date, formatter); + return formattedDate; + } catch (DateTimeParseException e) { + throw e; + } + } + + /** + * Convert time from String to LocalTime + * + * @param time String that describes taskDate of the task + * @return LocalTime + * @throws DateTimeParseException If format of the date is not accepted + */ + public static LocalTime toTime(String time) { + LocalTime localTime = LocalTime.parse(time); + return localTime; + } + + /** + * Split Date and Time by empty space " " + * + * @param dateAndTime String that contains both date and time + * @return String[] + */ + public static String[] splitDateAndTime(String dateAndTime) { + return dateAndTime.split(" "); + } + + /** + * Check if the string contains date and time + *

+ * return 1 if the string contains only string representation of a Date + * return 2 if the string contains string representation of a Date and a Time + * return 3 if the string contains string representation of a Date and 2 Time + * + * @param dateAndTime String representation of date and time + * @return int 1 or 2 or 3 + */ + public static int isDateAndTime(String dateAndTime) { + String[] split = dateAndTime.split(" "); + if (split.length == 1) { + return 1; + } else if (split.length == 2) { + return 2; + } else { + return 3; + } + } + + /** + * Extract string representation of date from string array + * + * @param split String Array of date and time + * @return String Date + */ + public static String toExtractDateFromSplitDateAndTime(String[] split) { + return split[0]; + } + + /** + * Extract string representation of time from string array + * + * @param split String Array of date and time + * @return String Time + */ + public static String toExtractTimeFromSplitDateAndTime(String[] split) { + return split[1]; + } + + /** + * Extract string representation of start time from string array + * + * @param split String Array of date and time + * @return String TimeStart + */ + public static String toExtractTimeStartFromSplitDateAndTime(String[] split) { + return split[1]; + } + + /** + * Extract string representation of end time from string array + * + * @param split String Array of date and time + * @return String TimeEnd + */ + public static String toExtractTimeEndFromSplitDateAndTime(String[] split) { + return split[2]; + } +} diff --git a/src/main/java/duke/action/ParseProgress.java b/src/main/java/duke/action/ParseProgress.java new file mode 100644 index 00000000..0f5591c9 --- /dev/null +++ b/src/main/java/duke/action/ParseProgress.java @@ -0,0 +1,35 @@ +package duke.action; + +/** + * Handle progress related string + *

+ * Splitting of string (describes the progress) loaded from progress file into arrays + * String manipulation + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class ParseProgress { + + /** + * Convert date from String to LocalDate + * + * @param progress String that is loaded from progress.txt + * @return String[] String array that has been split based on \n + */ + public static String[] splitProgressIntoSentence(String progress) { + return progress.split("\\n", -1); + } + + /** + * Convert date from String to LocalDate + * + * @param sentence String that contains the task information + * @return String[] String array that has been split based on | + */ + public static String[] splitSentenceByBarSeparator(String sentence) { + return sentence.split("\\|", -1); + } +} diff --git a/src/main/java/duke/action/Parser.java b/src/main/java/duke/action/Parser.java new file mode 100644 index 00000000..4e8e21ea --- /dev/null +++ b/src/main/java/duke/action/Parser.java @@ -0,0 +1,80 @@ +package duke.action; + +/** + * Make sense of user input and return the user command + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class Parser { + + public Parser() { + + } + + /** + * Convert date from String to LocalDate + * + * @param userInput String + * @return String that describe the command specified by user + */ + public String processUserCommand(String userInput) { + + if (userInput.isEmpty()) { + return "invalid"; + } + + if (userInput.equals("bye")) { + return "bye"; + } else if (userInput.equals("list")) { + return "list"; + } else if (userInput.equals("set")) { + return "set"; + } else if (userInput.equals("info")) { + return "info"; + } else if (userInput.equals("save")) { + return "save"; + } + + String userInputStartWith = getFirstWord(userInput); + + switch (userInputStartWith) { + case "done": + return "done"; + case "todo": + return "todo"; + case "find": + return "find"; + case "event": + return "event"; + case "delete": + return "delete"; + case "undone": + return "undone"; + case "deadline": + return "deadline"; + default: + return "invalid"; + } + } + + /** + * Convert date from String to LocalDate + * + * @param firstWord String + * @return String that represents the first word of a line of string + */ + private String getFirstWord(String firstWord) { + + int index = firstWord.indexOf(' '); + + if (index > -1) { + return firstWord.substring(0, index).trim(); + } else { + return "invalid"; + } + } + +} diff --git a/src/main/java/duke/command/CmdAddTask.java b/src/main/java/duke/command/CmdAddTask.java new file mode 100644 index 00000000..e8f6bc96 --- /dev/null +++ b/src/main/java/duke/command/CmdAddTask.java @@ -0,0 +1,428 @@ +package duke.command; + +import java.time.LocalDate; +import java.time.LocalTime; + +import duke.action.ParseDateTime; +import duke.task.TaskList; +import duke.task.TaskType; +import duke.ui.Message; + +/** + * Command class that handle adding task + *

+ * add 3 types of class: TODO, DEADLINE and EVENT. + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class CmdAddTask { + + /** + * Add a task of todo type into TaskList + * + * @param myList TaskList that contains the list of task + * @param userInput String + */ + public static void addTaskToDo(TaskList myList, String userInput) { + + assert myList != null : "mylist should not be empty"; + assert userInput != null : "userInput should not be empty"; + + if (userInput.length() <= 5) { + Message.msgInvalidInputMissingDescription(); + return; + } + + myList.addItemToDos(userInput.substring(5)); + + int lastTaskIndex = myList.getNumOfItem() - 1; + String taskTypeInString = getTaskTypeInString(myList, lastTaskIndex); + String isDoneInString = getIsDoneInString(myList, lastTaskIndex); + String taskDetail = getTaskDetail(myList, lastTaskIndex); + int numOfItem = lastTaskIndex + 1; + + Message.msgAssignTaskToDo(taskTypeInString, isDoneInString, taskDetail, numOfItem); + } + + /** + * Add a task of event type into TaskList + * + * @param myList TaskList that contains the list of task + * @param userInput String + */ + public static void addTaskEvent(TaskList myList, String userInput) { + + assert myList != null : "mylist should not be empty"; + assert userInput != null : "userInput should not be empty"; + + if (userInput.length() <= 6) { + Message.msgInvalidInputMissingDescription(); + return; + } + + if (!userInput.contains("/at")) { + Message.msgInvalidInputMissingDate(); + return; + } + + try { + String taskDetail = userInput.substring(6, userInput.indexOf("/")); + String dateAndTime = userInput.substring(userInput.indexOf("/") + 4); + String date; + String timeStart; + String timeEnd; + + String[] split = ParseDateTime.splitDateAndTime(dateAndTime); + date = ParseDateTime.toExtractDateFromSplitDateAndTime(split); + + if (ParseDateTime.isDateAndTime(dateAndTime) == 1) { + toAddTaskEvent_localDate(myList, taskDetail, date); + } else if (ParseDateTime.isDateAndTime(dateAndTime) == 2) { + timeStart = ParseDateTime.toExtractTimeStartFromSplitDateAndTime(split); + toAddTaskEvent_localDate_localTime(myList, taskDetail, date, timeStart); + } else { + timeStart = ParseDateTime.toExtractTimeStartFromSplitDateAndTime(split); + timeEnd = ParseDateTime.toExtractTimeEndFromSplitDateAndTime(split); + toAddTaskEvent_localDate_localTime(myList, taskDetail, date, timeStart, timeEnd); + } + + } catch (Exception e) { + Message.msgInvalidInputWrongDateTimeStartEndFormat(); + } + } + + /** + * Add a task of deadline type into TaskList + * + * @param myList TaskList that contains the list of task + * @param userInput String + */ + public static void addTaskDeadline(TaskList myList, String userInput) { + + assert myList != null : "mylist should not be empty"; + assert userInput != null : "userInput should not be empty"; + + if (userInput.length() <= 9) { + Message.msgInvalidInputMissingDescription(); + return; + } + + if (!userInput.contains("/by")) { + Message.msgInvalidInputMissingDate(); + return; + } + + try { + String taskDetail = userInput.substring(9, userInput.indexOf("/")); + String dateAndTime = userInput.substring(userInput.indexOf("/") + 4); + String date; + String time; + + String[] split = ParseDateTime.splitDateAndTime(dateAndTime); + date = ParseDateTime.toExtractDateFromSplitDateAndTime(split); + + if (ParseDateTime.isDateAndTime(dateAndTime) == 1) { + toAddTaskDeadline_localDate(myList, taskDetail, date); + } else if (ParseDateTime.isDateAndTime(dateAndTime) == 2) { + time = ParseDateTime.toExtractTimeFromSplitDateAndTime(split); + toAddTaskDeadline_localDate_localTime(myList, taskDetail, date, time); + } else { + Message.msgInvalidInputWrongDateTimeFormat(); + } + + } catch (Exception e) { + Message.msgInvalidInputWrongDateTimeFormat(); + } + } + + /** + * Add a task of Event type into TaskList + * + * @param myList TaskList that contains the list of task + * @param taskDetail String that represents the task detail + * @param date String that represents the date of the event + */ + private static void toAddTaskEvent_localDate(TaskList myList, String taskDetail, String date) { + + assert myList != null : "mylist should not be empty"; + assert taskDetail != null : "taskDetail should not be empty"; + assert date != null : "date should not be empty"; + + LocalDate taskDate = ParseDateTime.toDate(date); + + if (taskDate == null) { + Message.msgInvalidInputWrongDateTimeFormat(); + return; + } + + myList.addItemEvent(taskDetail, taskDate); + + int lastTaskIndex = myList.getNumOfItem() - 1; + String taskTypeInString = getTaskTypeInString(myList, lastTaskIndex); + String isDoneInString = getIsDoneInString(myList, lastTaskIndex); + String dateInString = getTaskEventDateInString(myList, lastTaskIndex); + int numOfItem = lastTaskIndex + 1; + + Message.msgAssignTaskEventTaskDate(taskTypeInString, isDoneInString, + taskDetail, dateInString, numOfItem); + } + + /** + * Add a task of Event type into TaskList + * + * @param myList TaskList that contains the list of task + * @param taskDetail String that represents the task detail + * @param date String that represents the date of the event + * @param timeStart String that represents the start time of the event + */ + private static void toAddTaskEvent_localDate_localTime(TaskList myList, String taskDetail, + String date, String timeStart) { + + assert myList != null : "mylist should not be empty"; + assert taskDetail != null : "taskDetail should not be empty"; + assert date != null : "date should not be empty"; + assert timeStart != null : "timeStart should not be empty"; + + LocalDate taskDate = ParseDateTime.toDate(date); + LocalTime taskTimeStart = ParseDateTime.toTime(timeStart); + + if (taskDate == null) { + Message.msgInvalidInputMissingDate(); + return; + } + + if (taskTimeStart == null) { + Message.msgInvalidInputWrongDateTimeFormat(); + return; + } + + myList.addItemEvent(taskDetail, taskDate, taskTimeStart); + + int lastTaskIndex = myList.getNumOfItem() - 1; + String taskTypeInString = getTaskTypeInString(myList, lastTaskIndex); + String isDoneInString = getIsDoneInString(myList, lastTaskIndex); + String dateInString = getTaskEventDateInString(myList, lastTaskIndex); + int numOfItem = lastTaskIndex + 1; + String getTimeStartInString = getTaskEventTimeStartInString(myList, lastTaskIndex); + + Message.msgAssignTaskEventTaskDateTaskTimeStart(taskTypeInString, isDoneInString, + taskDetail, dateInString, getTimeStartInString, numOfItem); + } + + /** + * Add a task of Event type into TaskList + * + * @param myList TaskList that contains the list of task + * @param taskDetail String that represents the task detail + * @param date String that represents the date of the event + * @param timeStart String that represents the start time of the event + * @param timeEnd String that represents the end time of the event + */ + private static void toAddTaskEvent_localDate_localTime(TaskList myList, String taskDetail, + String date, String timeStart, String timeEnd) { + + assert myList != null : "mylist should not be empty"; + assert taskDetail != null : "taskDetail should not be empty"; + assert date != null : "date should not be empty"; + assert timeStart != null : "timeStart should not be empty"; + assert timeEnd != null : "timeEnd should not be empty"; + + LocalDate taskDate = ParseDateTime.toDate(date); + LocalTime taskTimeStart = ParseDateTime.toTime(timeStart); + LocalTime taskTimeEnd = ParseDateTime.toTime(timeEnd); + + if (taskDate == null) { + Message.msgInvalidInputMissingDate(); + return; + } + + if (taskTimeStart == null || taskTimeEnd == null) { + Message.msgInvalidInputWrongDateTimeFormat(); + return; + } + + if (taskTimeStart.isAfter(taskTimeEnd)) { + Message.msgInvalidInputTimeStartLaterThanTimeEnd(); + return; + } + + myList.addItemEvent(taskDetail, taskDate, taskTimeStart, taskTimeEnd); + + int lastTaskIndex = myList.getNumOfItem() - 1; + String taskTypeInString = getTaskTypeInString(myList, lastTaskIndex); + String isDoneInString = getIsDoneInString(myList, lastTaskIndex); + String dateInString = getTaskEventDateInString(myList, lastTaskIndex); + String getTimeStartInString = getTaskEventTimeStartInString(myList, lastTaskIndex); + String getTimeEndInString = getTaskEventTimeEndInString(myList, lastTaskIndex); + int numOfItem = lastTaskIndex + 1; + + Message.msgAssignEventTaskDateTimeStartEnd(taskTypeInString, isDoneInString, + taskDetail, dateInString, getTimeStartInString, getTimeEndInString, numOfItem); + } + + /** + * Add a task of Deadline type into TaskList + * + * @param myList TaskList that contains the list of task + * @param taskDetail String that represents the task detail + * @param date String that represents the date of the deadline + */ + private static void toAddTaskDeadline_localDate(TaskList myList, String taskDetail, String date) { + + assert myList != null : "mylist should not be empty"; + assert taskDetail != null : "taskDetail should not be empty"; + assert date != null : "date should not be empty"; + + LocalDate taskDate = ParseDateTime.toDate(date); + + if (taskDate == null) { + Message.msgInvalidInputWrongDateTimeFormat(); + return; + } + + myList.addItemDeadline(taskDetail, taskDate); + + int lastTaskIndex = myList.getNumOfItem() - 1; + String taskTypeInString = getTaskTypeInString(myList, lastTaskIndex); + String isDoneInString = getIsDoneInString(myList, lastTaskIndex); + String dateInString = getTaskDeadlineDateInString(myList, lastTaskIndex); + int numOfItem = lastTaskIndex + 1; + + Message.msgAssignTaskDeadlineTaskDate(taskTypeInString, isDoneInString, taskDetail, dateInString, numOfItem); + } + + /** + * Add a task of Event type into TaskList + * + * @param myList TaskList that contains the list of task + * @param taskDetail String that represents the task detail + * @param date String that represents the date of the deadline + * @param time String that represents the time of the deadline + */ + private static void toAddTaskDeadline_localDate_localTime(TaskList myList, String taskDetail, + String date, String time) { + + assert myList != null : "mylist should not be empty"; + assert taskDetail != null : "taskDetail should not be empty"; + assert date != null : "date should not be empty"; + assert time != null : "time should not be empty"; + + LocalDate taskDate = ParseDateTime.toDate(date); + LocalTime taskTime = ParseDateTime.toTime(time); + + if (taskDate == null) { + Message.msgInvalidInputMissingDate(); + return; + } + + if (taskTime == null) { + Message.msgInvalidInputWrongDateTimeFormat(); + return; + } + + myList.addItemDeadline(taskDetail, taskDate, taskTime); + + int lastTaskIndex = myList.getNumOfItem() - 1; + String taskTypeInString = getTaskTypeInString(myList, lastTaskIndex); + String isDoneInString = getIsDoneInString(myList, lastTaskIndex); + String dateInString = getTaskDeadlineDateInString(myList, lastTaskIndex); + String timeInString = getTaskDeadlineTimeInString(myList, lastTaskIndex); + int numOfItem = lastTaskIndex + 1; + + Message.msgAssignTaskDeadlineTaskDateTaskTime(taskTypeInString, + isDoneInString, taskDetail, dateInString, timeInString, numOfItem); + } + + /** + * Get TaskType of a task using myList and its task index. + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String representation of TaskType of a task in tasklist + */ + private static String getTaskTypeInString(TaskList myList, int taskIndex) { + TaskType taskType = myList.getTaskType(taskIndex); + return TaskType.taskTypeToString(taskType); + } + + /** + * Get isDone status of a task in String + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String representation of isDone of a task in tasklist + */ + private static String getIsDoneInString(TaskList myList, int taskIndex) { + boolean isDone = myList.getTaskDoneStatus(taskIndex); + return (isDone ? "X" : " "); + } + + /** + * Get taskDetail of a task + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String representation of taskDetail of a task in tasklist + */ + private static String getTaskDetail(TaskList myList, int taskIndex) { + return myList.getTaskDetail(taskIndex); + } + + /** + * Get date of an EVENT task in String + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String representation of date of a task in tasklist + */ + private static String getTaskEventDateInString(TaskList myList, int taskIndex) { + return myList.getTaskEventTaskDateInString(taskIndex); + } + + /** + * Get start time of an EVENT task in String + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String representation of start time of a task in tasklist + */ + private static String getTaskEventTimeStartInString(TaskList myList, int taskIndex) { + return myList.getTaskEventTaskTimeStartInString(taskIndex); + } + + /** + * Get end time of an EVENT task in String + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String representation of end time of a task in tasklist + */ + private static String getTaskEventTimeEndInString(TaskList myList, int taskIndex) { + return myList.getTaskEventTaskTimeEndInString(taskIndex); + } + + /** + * Get date of an DEADLINE task in String + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String representation of date of a task in tasklist + */ + private static String getTaskDeadlineDateInString(TaskList myList, int taskIndex) { + return myList.getTaskDeadLineTaskDateInString(taskIndex); + } + + /** + * Get start time of an DEADLINE task in String + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String representation of start time of a task in tasklist + */ + private static String getTaskDeadlineTimeInString(TaskList myList, int taskIndex) { + return myList.getTaskDeadLineTaskTimeInString(taskIndex); + } +} diff --git a/src/main/java/duke/command/CmdDelete.java b/src/main/java/duke/command/CmdDelete.java new file mode 100644 index 00000000..4d458dc0 --- /dev/null +++ b/src/main/java/duke/command/CmdDelete.java @@ -0,0 +1,48 @@ +package duke.command; + +import duke.task.TaskList; +import duke.ui.Message; + +/** + * Command class that delete a task from a tasklist + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class CmdDelete { + + /** + * Execute the delete task command + * Remove a task from a tasklist + * + * @param myList TaskList that contains the list of task + * @param userInput String + */ + public static void run(TaskList myList, String userInput) { + + assert myList != null : "mylist should not be empty"; + assert userInput != null : "userInput should not be empty"; + + if (myList.getNumOfItem() == 0) { + Message.msgTaskListIsEmpty(); + return; + } + + try { + int taskIndex = Integer.parseInt(userInput.substring(7)) - 1; + int numOfTaskAfterDelete = myList.getNumOfItem() - 1; + + if (taskIndex >= myList.getNumOfItem() || taskIndex < 0) { + Message.msgInvalidTaskNumber(); + return; + } + + Message.msgRemoveItem(myList, taskIndex, numOfTaskAfterDelete); + myList.removeItem(taskIndex); + } catch (Exception e) { + Message.msgInvalidTaskNumber(); + } + } +} diff --git a/src/main/java/duke/command/CmdFind.java b/src/main/java/duke/command/CmdFind.java new file mode 100644 index 00000000..73ae34b0 --- /dev/null +++ b/src/main/java/duke/command/CmdFind.java @@ -0,0 +1,93 @@ +package duke.command; + +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import duke.task.TaskList; +import duke.ui.Message; +import duke.ui.MsgTaskDetail; + +/** + * Command class that find a task from a tasklist + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class CmdFind { + + /** + * Execute the find task command + * Find a task based on the keyword input by the user + * + * @param myList TaskList that contains the list of task + * @param userInput String + */ + public static void run(TaskList myList, String userInput) { + + assert myList != null : "mylist should not be empty"; + assert userInput != null : "userInput should not be empty"; + + if (myList.getNumOfItem() == 0) { + Message.msgTaskListIsEmpty(); + return; + } + + if (userInput.length() <= 5) { + Message.msgInvalidFindTerm(); + return; + } + + String searchTerm = userInput.substring(5); + ArrayList taskNumberContainingSearchTerm = new ArrayList<>(); + for (int i = 0; i < myList.getNumOfItem(); i++) { + String taskDetail = myList.getTaskDetail(i); + if (hasStringContain(taskDetail, searchTerm)) { + taskNumberContainingSearchTerm.add(i); + } + } + + if (taskNumberContainingSearchTerm.isEmpty()) { + Message.msgInvalidFindTerm(); + return; + } + + Message.msgTaskFoundOpeningMsg(); + showTaskFound(myList, taskNumberContainingSearchTerm); + } + + /** + * Check if the searchString can be found inside the sourceString + * + * @param sourceString String that represents the source + * @param searchString String that represents the term used to search in the sourceString + * @return boolean True if the term is found; false otherwise + */ + private static boolean hasStringContain(String sourceString, String searchString) { + String pattern = "\\b" + searchString + "\\b"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(sourceString); + return m.find(); + } + + /** + * Display message to show a list of task found based on the term + */ + private static void showTaskFound(TaskList myList, ArrayList taskNumberContainingSearchTerm) { + + assert myList != null : "mylist should not be empty"; + assert taskNumberContainingSearchTerm != null : "taskNumberContainingSearchTerm should not be empty"; + + int index = 1; + for (int i = 0; i < taskNumberContainingSearchTerm.size(); i++) { + int taskNumber = taskNumberContainingSearchTerm.get(i); + Message.msgBlankBeforeTaskDetail(); + Message.msgShowBracketWithIndex(index); + new MsgTaskDetail(myList, taskNumber).showTaskDetail(); + index++; + } + Message.msgDashLines(); + } +} diff --git a/src/main/java/duke/command/CmdList.java b/src/main/java/duke/command/CmdList.java new file mode 100644 index 00000000..b515dfe9 --- /dev/null +++ b/src/main/java/duke/command/CmdList.java @@ -0,0 +1,35 @@ +package duke.command; + +import duke.task.TaskList; +import duke.ui.Message; +import duke.ui.MsgTaskDetail; + +/** + * Command class that list all the task in the tasklist + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class CmdList { + + /** + * Show full list of tasks + * + * @param myList TaskList that contains the list of task + */ + public static void run(TaskList myList) { + + if (myList.getNumOfItem() == 0) { + Message.msgTaskListIsEmpty(); + return; + } + + for (int i = 0; i < myList.getNumOfItem(); i++) { + Message.msgShowBracketWithIndex(i + 1); + new MsgTaskDetail(myList, i).showTaskDetail(); + } + Message.msgDashLines(); + } +} diff --git a/src/main/java/duke/command/CmdMarkTaskDone.java b/src/main/java/duke/command/CmdMarkTaskDone.java new file mode 100644 index 00000000..e342eaa6 --- /dev/null +++ b/src/main/java/duke/command/CmdMarkTaskDone.java @@ -0,0 +1,41 @@ +package duke.command; + +import duke.task.TaskList; +import duke.ui.Message; + +/** + * Command class that mark a task as done + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class CmdMarkTaskDone { + + /** + * Execute the marking command to mark a task as done + * + * @param myList TaskList that contains the list of task + * @param userInput String + */ + public static void run(TaskList myList, String userInput) { + + assert myList != null : "mylist should not be empty"; + assert userInput != null : "userInput should not be empty"; + + if (myList.getNumOfItem() == 0) { + Message.msgTaskListIsEmpty(); + return; + } + + try { + int taskNumber = Integer.parseInt(userInput.substring(5)); + myList.setTaskDone(taskNumber - 1); + Message.msgMarkDone(myList, taskNumber - 1); + } catch (Exception e) { + Message.msgInvalidTaskNumber(); + } + + } +} diff --git a/src/main/java/duke/command/CmdMarkTaskUnDone.java b/src/main/java/duke/command/CmdMarkTaskUnDone.java new file mode 100644 index 00000000..a89f9611 --- /dev/null +++ b/src/main/java/duke/command/CmdMarkTaskUnDone.java @@ -0,0 +1,40 @@ +package duke.command; + +import duke.task.TaskList; +import duke.ui.Message; + +/** + * Command class that mark a task as undone + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class CmdMarkTaskUnDone { + /** + * Execute the marking command to mark a task as done + * + * @param myList TaskList that contains the list of task + * @param userInput String + */ + public static void run(TaskList myList, String userInput) { + + assert myList != null : "mylist should not be empty"; + assert userInput != null : "userInput should not be empty"; + + if (myList.getNumOfItem() == 0) { + Message.msgTaskListIsEmpty(); + return; + } + + try { + int taskNumber = Integer.parseInt(userInput.substring(7)); + myList.setTaskUnDone(taskNumber - 1); + Message.msgMarkUnDone(myList, taskNumber - 1); + } catch (Exception e) { + Message.msgInvalidTaskNumber(); + } + + } +} diff --git a/src/main/java/duke/command/CmdPriority.java b/src/main/java/duke/command/CmdPriority.java new file mode 100644 index 00000000..2b3ff1a2 --- /dev/null +++ b/src/main/java/duke/command/CmdPriority.java @@ -0,0 +1,157 @@ +package duke.command; + +import java.util.Scanner; + +import duke.task.TaskList; +import duke.task.TaskPriority; +import duke.ui.Message; + +/** + * Command class that find a task from a tasklist + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class CmdPriority { + + /** + * Ask user which task to set priority and change the priority accordingly + * -- Ask user which task to be changed + * -- Ask user what is the new priority + * -- Update the task with new priority + * + * @param myList TaskList that contains the list of task + * @param scanner Scanner that contains read the user input + */ + public static void run(TaskList myList, Scanner scanner) { + + assert myList != null : "mylist should not be empty"; + assert scanner != null : "scanner should not be empty"; + + if (myList.getNumOfItem() < 1) { + Message.msgTaskListIsEmpty(); + return; + } + + boolean isTaskNumberValid = false; + String userInputTaskNumber = ""; + + boolean isPriorityNumberValid = false; + String userInputNewPriorityNumber = ""; + + while (isTaskNumberValid == false) { + Message.msgAskUserSetTaskPriority(); + Message.msgArrowHead(); + userInputTaskNumber = scanner.nextLine(); + isTaskNumberValid = hasValidTaskNumber(myList, userInputTaskNumber); + } + + int taskNumber = Integer.parseInt(userInputTaskNumber); + Message.msgDashLines(); + + while (isPriorityNumberValid == false) { + Message.msgAskUserWhatPriority(); + Message.msgArrowHead(); + userInputNewPriorityNumber = scanner.nextLine(); + isPriorityNumberValid = hasValidPriorityNumber(userInputNewPriorityNumber); + } + Message.msgDashLines(); + + int newPriorityInteger = Integer.parseInt(userInputNewPriorityNumber); + + TaskPriority taskPriority = TaskPriority.convertIntToPriority(newPriorityInteger); + toUpdatePriority(myList, taskNumber - 1, taskPriority); + } + + /** + * Check the validity of task number in String + * + * @param myList TaskList that contains the list of task + * @param userInputString String + * @return boolean True if userInput is a valid task number; False otherwise + */ + private static boolean hasValidTaskNumber(TaskList myList, String userInputString) { + + assert myList != null : "mylist should not be empty"; + assert userInputString != null : "userInputString should not be empty"; + + try { + int userInputInt = Integer.parseInt(userInputString); + int numOfItem = myList.getNumOfItem(); + + if (userInputInt <= numOfItem && userInputInt > 0) { + return true; + } + } catch (Exception e) { + Message.msgInvalidTaskNumber(); + return false; + } + Message.msgInvalidTaskNumber(); + return false; + } + + /** + * Check the validity of user input for priority number + *

+ * Expected input should be 1 to 3 + * + * @param userInputPriorityS + * @return boolean True if userInput is "1" to "3"; False otherwise + */ + private static boolean hasValidPriorityNumber(String userInputPriorityS) { + + assert userInputPriorityS != null : "userInputPriorityS should not be empty"; + + try { + TaskPriority taskPriority = TaskPriority.convertStringToPriority(userInputPriorityS); + if (taskPriority == TaskPriority.HIGH) { + return true; + } else if (taskPriority == TaskPriority.MEDIUM) { + return true; + } else if (taskPriority == TaskPriority.LOW) { + return true; + } + } catch (Exception e) { + Message.msgInvalidPriority(); + return false; + } + Message.msgInvalidPriority(); + return false; + } + + /** + * Update the priority of the task based on the taskPriority + * + * @param myList TaskList that contains the list of task + * @param taskIndex int that indicates the task number + * @param taskPriority TaskPriority(new one) that want to be set + */ + private static void toUpdatePriority(TaskList myList, int taskIndex, TaskPriority taskPriority) { + + assert myList != null : "mylist should not be empty"; + assert taskIndex >= 0 : "taskIndex should be equal or more than 0"; + assert taskPriority != null : "taskPriority should not be empty"; + + myList.setTaskPriority(taskIndex, taskPriority); + String taskPriorityInString = getTaskPriorityInString(myList, taskIndex); + Message.msgSetPriority(taskIndex + 1, taskPriorityInString); + } + + /** + * Get priority of the task in String + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task in tasklist + * @return String that represents the priority of the task + */ + private static String getTaskPriorityInString(TaskList myList, int taskIndex) { + + assert myList != null : "mylist should not be empty"; + assert taskIndex >= 0 : "taskIndex should be equal or more than 0"; + + TaskPriority taskPriority = myList.getTaskPriority(taskIndex); + return TaskPriority.convertPriorityToString(taskPriority); + } +} diff --git a/src/main/java/duke/command/CmdSave.java b/src/main/java/duke/command/CmdSave.java new file mode 100644 index 00000000..3d6a8d00 --- /dev/null +++ b/src/main/java/duke/command/CmdSave.java @@ -0,0 +1,200 @@ +package duke.command; + +import duke.storage.FileAccess; +import duke.task.TaskList; +import duke.task.TaskPriority; +import duke.task.TaskType; + +/** + * Command class that save all the task from the current taskList to progress.txt + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class CmdSave { + + private static FileAccess fileAccess; + private static TaskList myList; + private static StringBuilder sb; + + private static String taskTypeInString; + private static String isDoneInString; + private static String taskDetail; + private static String taskPriorityInString; + private static String taskDate; + private static String timeStart; + private static String timeEnd; + + /** + * Constructor + */ + public CmdSave(TaskList myList, FileAccess fileAccess) { + this.myList = myList; + this.fileAccess = fileAccess; + sb = new StringBuilder(); + } + + /** + * Execute the save + */ + public static void run() { + String listOfTaskString = generateListOfTaskInString(); + fileAccess.saveProgressIntoFile(listOfTaskString); + } + + /** + * Read a list of task and convert it into string + *

+ * calls the following methods to generate the string + * setStringToNull(); + * appendBasic(taskIndex); + * appendAdvance(taskIndex); + * appendEnd(); + * + * @return String that represents the string to be saved in text + */ + private static String generateListOfTaskInString() { + + for (int taskIndex = 0; taskIndex < myList.getNumOfItem(); taskIndex++) { + setStringToNull(); + appendBasic(taskIndex); + appendAdvance(taskIndex); + appendEnd(); + } + return sb.toString(); + } + + /** + * set the private variables to "null" + *

+ * taskTypeInString = "null"; + * isDoneInString = "null"; + * taskDetail = "null"; + * taskPriorityInString = "null"; + * taskDate = "null"; + * timeStart = "null"; + * timeEnd = "null"; + * + * @return StringBuilder + */ + private static void setStringToNull() { + taskTypeInString = "null"; + isDoneInString = "null"; + taskDetail = "null"; + taskPriorityInString = "null"; + taskDate = "null"; + timeStart = "null"; + timeEnd = "null"; + } + + /** + * append basic variables to the string builder + *

+ * taskIndex + * taskType + * isDone + * taskDetail + * taskPriority + * + * @return StringBuilder + */ + private static StringBuilder appendBasic(int taskIndex) { + + taskTypeInString = TaskType.taskTypeToString(myList.getTaskType(taskIndex)); + + boolean isDone = myList.getTaskDoneStatus(taskIndex); + isDoneInString = (isDone ? "1" : "0"); + + taskDetail = myList.getTaskDetail(taskIndex); + + TaskPriority taskPriority = myList.getTaskPriority(taskIndex); + taskPriorityInString = taskPriority.toStringInNumber(); + + assert taskTypeInString != null : "taskTypeInString should not be empty"; + assert taskDetail != null : "taskDetail should not be empty"; + assert taskPriority != null : "taskPriority should not be empty"; + + sb.append(taskIndex).append("|"); + sb.append(taskTypeInString).append("|"); + sb.append(isDoneInString).append("|"); + sb.append(taskDetail).append("|"); + sb.append(taskPriorityInString).append("|"); + + return sb; + } + + /** + * append advance variables to the string builder based on the variable types + *

+ * date` + * start time + * end time + *

+ * depending on the taskType, different String is appended + * + * @return StringBuilder + */ + private static StringBuilder appendAdvance(int taskIndex) { + + switch (taskTypeInString) { + case "D": + appendDeadline(taskIndex); + break; + case "E": + appendEvent(taskIndex); + break; + default: + break; + } + + return sb; + } + + /** + * append date and start time to DEADLINE type task + * + * @return StringBuilder + */ + private static StringBuilder appendDeadline(int taskIndex) { + + taskDate = myList.getTaskDeadLineTaskDateInString(taskIndex); + + timeStart = myList.getTaskDeadLineTaskTimeInString(taskIndex); + + sb.append(taskDate).append("|"); + sb.append(timeStart).append("|"); + + return sb; + } + + /** + * append date, start time, and end time to EVENT type task + * + * @return StringBuilder + */ + private static StringBuilder appendEvent(int taskIndex) { + + taskDate = myList.getTaskEventTaskDateInString(taskIndex); + + timeStart = myList.getTaskEventTaskTimeStartInString(taskIndex); + timeEnd = myList.getTaskEventTaskTimeEndInString(taskIndex); + + sb.append(taskDate).append("|"); + sb.append(timeStart).append("|"); + sb.append(timeEnd).append("|"); + + return sb; + } + + /** + * append ;\n to the StringBuilder + * + * @return StringBuilder + */ + private static StringBuilder appendEnd() { + sb.append(";\n"); + return sb; + } +} diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java new file mode 100644 index 00000000..eba13984 --- /dev/null +++ b/src/main/java/duke/command/Command.java @@ -0,0 +1,150 @@ +package duke.command; + +import java.util.Scanner; + +import duke.action.Parser; +import duke.storage.FileAccess; +import duke.task.TaskList; +import duke.ui.Message; + +/** + * Core Command class + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class Command { + + private static Parser parser; + + /** + * Constructor + */ + public Command(Parser parser) { + this.parser = parser; + } + + // Basic processCommand Method <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Show info of all the command Duke can accept + */ + public void showInfo() { + Message.msgShowDukeCommandList(); + } + + /** + * Show full list of tasks + * + * @param myList TaskList that contains the list of task + */ + public void showFullList(TaskList myList) { + CmdList.run(myList); + } + + /** + * Ask user which task to set priority and change the priority accordingly + * -- Ask user which task to be changed + * -- Ask user what is the new priority + * -- Update the task with new priority + * + * @param myList TaskList that contains the list of task + * @param scanner Scanner for user input + */ + public void setPriorityTask(TaskList myList, Scanner scanner) { + CmdPriority.run(myList, scanner); + } + + /** + * Mark a task as done + * + * @param myList TaskList that contains the list of task + * @param userInput String that the user type + */ + public void markTaskDone(TaskList myList, String userInput) { + CmdMarkTaskDone.run(myList, userInput); + } + + /** + * Mark a task as undone + * + * @param myList TaskList that contains the list of task + * @param userInput String that the user type + */ + public void markTaskUnDone(TaskList myList, String userInput) { + CmdMarkTaskUnDone.run(myList, userInput); + } + + /** + * Add a task of ToDo type into the list of task + * + * @param myList TaskList that contains the list of task + * @param userInput String that the user type + */ + public void addTaskToDo(TaskList myList, String userInput) { + CmdAddTask.addTaskToDo(myList, userInput); + } + + /** + * Save the current task list and output a text file + * + * @param myList TaskList that contains the list of task + */ + public void saveTask(TaskList myList, FileAccess fileAccess) { + new CmdSave(myList, fileAccess).run(); + } + + /** + * Find the Task requested + * + * @param myList TaskList that contains the list of task + */ + public void findTask(TaskList myList, String userInput) { + CmdFind.run(myList, userInput); + } + + /** + * Add a task of Event type into TaskList + *

+ * Identify the task date and time that the user input + * Calls for respective AddTaskEvent_XXX to create a task object in TaskList afterwards + * + * @param myList TaskList that contains the list of task + * @param userInput String that the user type + */ + public void addTaskEvent(TaskList myList, String userInput) { + CmdAddTask.addTaskEvent(myList, userInput); + } + + /** + * Delete a task from the user task + * + * @param myList TaskList that contains the list of task + * @param userInput String that represents the user input + */ + public void deleteTask(TaskList myList, String userInput) { + CmdDelete.run(myList, userInput); + } + + /** + * Add a task of Deadline type into TaskList + *

+ * Identify the task date and time that the user input + * Calls for respective AddTaskEvent_XXX to create a task object in TaskList afterwards + * + * @param myList TaskList that contains the list of task + * @param userInput String that represents the user input + */ + public void addTaskDeadline(TaskList myList, String userInput) { + CmdAddTask.addTaskDeadline(myList, userInput); + } + + /** + * Show invalid command + */ + public void showInvalidCommand() { + Message.msgInvalidInput(); + } +} diff --git a/src/main/java/duke/exception/UnableToLoadBuddhaException.java b/src/main/java/duke/exception/UnableToLoadBuddhaException.java new file mode 100644 index 00000000..9d396772 --- /dev/null +++ b/src/main/java/duke/exception/UnableToLoadBuddhaException.java @@ -0,0 +1,11 @@ +package duke.exception; + +/** + * Exception class that is called when buddha.txt fails to load + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ +public class UnableToLoadBuddhaException extends Exception { +} diff --git a/src/main/java/duke/exception/UnableToLoadProcessException.java b/src/main/java/duke/exception/UnableToLoadProcessException.java new file mode 100644 index 00000000..30fa4a42 --- /dev/null +++ b/src/main/java/duke/exception/UnableToLoadProcessException.java @@ -0,0 +1,12 @@ +package duke.exception; + +/** + * Exception class that is called when progress.txt fails to load + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ +public class UnableToLoadProcessException extends Exception { + +} diff --git a/src/main/java/duke/storage/FileAccess.java b/src/main/java/duke/storage/FileAccess.java new file mode 100644 index 00000000..0672a892 --- /dev/null +++ b/src/main/java/duke/storage/FileAccess.java @@ -0,0 +1,125 @@ +package duke.storage; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; + +import duke.exception.UnableToLoadBuddhaException; +import duke.exception.UnableToLoadProcessException; +import duke.ui.Message; +import duke.ui.Ui; + +/** + * Handles file handling related functions + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class FileAccess { + private String filepath; + private File progressFile; + private Ui ui; + + /** + * Constructor + * + * @param filepath + */ + public FileAccess(String filepath) { + this.filepath = filepath; + progressFile = new File(this.filepath); + } + + /** + * Save progress of the current task + * + * @param stringToBeWritten String that needs to be outputed + */ + public void saveProgressIntoFile(String stringToBeWritten) { + + assert !stringToBeWritten.isEmpty() : "stringToBeWritten should not be empty"; + + try { + FileWriter fw = new FileWriter(filepath); + fw.write(stringToBeWritten); + fw.close(); + Message.msgSave(); + } catch (Exception e) { + Message.msgError(e); + } + } + + /** + * Load existing progress of the task + * + * @return String that represents a list of task details + */ + public static String loadProgressFromFile() throws UnableToLoadProcessException { + String progress = ""; + String pathRoot = System.getProperty("user.dir"); + // e.g. pathRoot = D:\My Files\School Documents\Repository\Duke + + String pathRssFolder = "src" + File.separator + "resources"; + // pathRssFolder = src\resources + + String pathFileName = "progress.txt"; + // pathFileName = progress.txt + + String filePath = pathRoot + File.separator + pathRssFolder + File.separator + pathFileName; + // e.g. + // filePath = D:\My Files\School + // Documents\Repository\Duke\src\main\resources\progress.txt + + try { + FileReader fr = new FileReader(filePath); + BufferedReader br = new BufferedReader(fr); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + progress = sb.toString(); + br.close(); + } catch (Exception e) { + throw new UnableToLoadProcessException(); + } + return progress; + } + + /** + * Read Buddah.txt + * + * @return String that contains the content in Buddha.txt + */ + public String readBuddhaText() throws UnableToLoadBuddhaException { + String buddhaText = ""; + String pathRoot = System.getProperty("user.dir"); + String pathRssFolder = "src" + File.separator + "resources"; + String pathFileName = "buddha.txt"; + String filePath = pathRoot + File.separator + pathRssFolder + File.separator + pathFileName; + + try { + FileReader fr = new FileReader(filePath); + BufferedReader br = new BufferedReader(fr); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + buddhaText = sb.toString(); + br.close(); + } catch (Exception e) { + throw new UnableToLoadBuddhaException(); + } + return buddhaText; + } +} diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java new file mode 100644 index 00000000..7670ed13 --- /dev/null +++ b/src/main/java/duke/task/Task.java @@ -0,0 +1,111 @@ +package duke.task; + +/** + * Abstract class for Task + *

+ * A task object correspond to a single task object. + * The class object can be of the type todo, event, or deadline. + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public abstract class Task { + protected String taskDetail; + protected boolean isDone; + protected TaskType taskType; + protected TaskPriority taskPriority; + + /** + * Create an abstract Task object + */ + public Task(String taskDetail) { + this.taskDetail = taskDetail; + this.taskPriority = TaskPriority.LOW; + } + + // Getter <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Return the task detail + * + * @return String that represents the task detail + */ + public String getTaskDetail() { + return taskDetail; + } + + /** + * Return the boolean done status that represents if a task is done + * + * @return boolean that represents the done status of a task + */ + public boolean getDoneStatus() { + return isDone; + } + + /** + * Return the TaskType + * + * @return TaskType that represents the type of task + */ + public TaskType getTaskType() { + return taskType; + } + + + /** + * Return the TaskPriority + * + * @return TaskPriority that represents the priority of task + */ + public TaskPriority getTaskPriority() { + return taskPriority; + } + + // Setter <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Modified the task detail + * + * @param modifiedTaskDetail String that represent the new task detail + */ + public void setTask(String modifiedTaskDetail) { + taskDetail = modifiedTaskDetail; + } + + /** + * Set the task as completed + * Change the done status to completed + */ + public void setTaskCompleted() { + isDone = true; + } + + /** + * Set the task as completed + * Change the done status to completed + */ + public void setTaskInCompleted() { + isDone = false; + } + + /** + * Modified the type of the task + * + * @param taskType String that represent the new task type + */ + public void setTypeOfTask(TaskType taskType) { + this.taskType = taskType; + } + + /** + * Set thr priority of a task + * + * @param taskPriority TaskPriority that represent the new priority + */ + public void setPriority(TaskPriority taskPriority) { + this.taskPriority = taskPriority; + } +} diff --git a/src/main/java/duke/task/TaskDeadline.java b/src/main/java/duke/task/TaskDeadline.java new file mode 100644 index 00000000..b31c105c --- /dev/null +++ b/src/main/java/duke/task/TaskDeadline.java @@ -0,0 +1,100 @@ +package duke.task; + +import java.time.LocalDate; +import java.time.LocalTime; + +/** + * Create an instance of deadline class + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ +public class TaskDeadline extends Task { + private LocalDate taskDate; + private LocalTime taskTime; + + /** + * Constructor + */ + public TaskDeadline(String taskDetail, LocalDate taskDate) { + super(taskDetail); + this.isDone = false; + this.taskType = TaskType.DEADLINE; + this.taskDate = taskDate; + } + + /** + * Constructor + */ + public TaskDeadline(String taskDetail, LocalDate taskDate, LocalTime localTime) { + super(taskDetail); + this.isDone = false; + this.taskType = TaskType.DEADLINE; + this.taskDate = taskDate; + this.taskTime = localTime; + } + + /** + * Return LocalDate of a task + * + * @return LocalDate that represents the taskDate + */ + public LocalDate getLocalDate() { + return taskDate; + } + + /** + * Return LocalDate of a task in String + * + * @return String that represents the taskDate + */ + public String getLocalDateToString() { + return String.valueOf(taskDate); + } + + /** + * Return day from LocalDate of a task in String + * + * @return String that represents the day of taskDate + */ + public String getLocalDateDayToString() { + return String.valueOf(taskDate.getDayOfMonth()); + } + + /** + * Return month from LocalDate of a task in String + * + * @return String that represents the month of taskDate + */ + public String getLocalDateMonthToString() { + return String.valueOf(taskDate.getMonth()); + } + + /** + * Return year from LocalDate of a task in String + * + * @return String that represents the year of taskDate + */ + public String getLocalDateYearToString() { + return String.valueOf(taskDate.getYear()); + } + + /** + * Return LocalTime of a task + * + * @return LocalTime that represents the taskTime + */ + public LocalTime getLocalTime() { + return taskTime; + } + + /** + * Return LocalTime of a task in String + * + * @return String that represents the taskTime + */ + public String getLocalTime_toString() { + return String.valueOf(taskTime); + } +} diff --git a/src/main/java/duke/task/TaskEvent.java b/src/main/java/duke/task/TaskEvent.java new file mode 100644 index 00000000..8cc42c77 --- /dev/null +++ b/src/main/java/duke/task/TaskEvent.java @@ -0,0 +1,136 @@ +package duke.task; + +import java.time.LocalDate; +import java.time.LocalTime; + +/** + * Create an instance of event class + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class TaskEvent extends Task { + + private LocalDate taskDate; + private LocalTime taskTimeStart; + private LocalTime taskTimeEnd; + + /** + * Constructor + */ + public TaskEvent(String taskDetail, LocalDate taskDate) { + super(taskDetail); + this.isDone = false; + this.taskType = TaskType.EVENT; + this.taskDate = taskDate; + } + + /** + * Constructor + */ + public TaskEvent(String taskDetail, LocalDate taskDate, LocalTime taskTimeStart) { + super(taskDetail); + this.isDone = false; + this.taskType = TaskType.EVENT; + this.taskDate = taskDate; + this.taskTimeStart = taskTimeStart; + } + + /** + * Constructor + */ + public TaskEvent(String taskDetail, LocalDate taskDate, LocalTime taskTimeStart, LocalTime taskTimeEnd) { + super(taskDetail); + this.isDone = false; + this.taskType = TaskType.EVENT; + this.taskDate = taskDate; + this.taskTimeStart = taskTimeStart; + this.taskTimeEnd = taskTimeEnd; + } + + /** + * Return LocalDate of a task + * + * @return LocalDate that represents the taskDate + */ + public LocalDate getLocalDate() { + return taskDate; + } + + /** + * Return LocalDate of a task in String + * + * @return String that represents the taskDate + */ + public String getLocalDate_toString() { + return String.valueOf(taskDate); + } + + /** + * Return day from LocalDate of a task in String + * + * @return String that represents the day of taskDate + */ + public String getLocalDateDayToString() { + return String.valueOf(taskDate.getDayOfMonth()); + } + + /** + * Return month from LocalDate of a task in String + * + * @return String that represents the month of taskDate + */ + public String getLocalDateMonthToString() { + return String.valueOf(taskDate.getMonth()); + } + + /** + * Return year from LocalDate of a task in String + * + * @return String that represents the year of taskDate + */ + public String getLocalDateYearToString() { + return String.valueOf(taskDate.getYear()); + } + + /** + * Return start time of LocalTime of a task + * + * @return LocalTime that represents the start time of taskTime + */ + public LocalTime getLocalTimeStart() { + return taskTimeStart; + } + + /** + * Return end time of LocalTime of a task + * + * @return LocalTime that represents the end time of taskTime + */ + public LocalTime getLocalTimeEnd() { + return taskTimeEnd; + } + + /** + * Return start time of LocalTime of a task in String + * + * @return String that represents the start time of taskTime + */ + public String getLocalTimeStart_toString() { + return String.valueOf(taskTimeStart); + } + + /** + * Return end time of LocalTime of a task in String + * + * @return String that represents the start time of taskTime + */ + public String getLocalTimeEnd_toString() { + return String.valueOf(taskTimeEnd); + } +} + + + diff --git a/src/main/java/duke/task/TaskList.java b/src/main/java/duke/task/TaskList.java new file mode 100644 index 00000000..3e479eda --- /dev/null +++ b/src/main/java/duke/task/TaskList.java @@ -0,0 +1,318 @@ +package duke.task; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; + +/** + * Create an instance of list of task + *

+ * Create task object + * Manipulate task object creation, modification and deletion + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class TaskList { + private List list; + + // Initialize & Add Item & Remove Item <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + public TaskList() { + list = new ArrayList(); + } + + /** + * Add a task of type ToDo + * + * @param taskDetail String that represents the task detail + */ + public void addItemToDos(String taskDetail) { + list.add(new TaskToDos(taskDetail)); + } + + /** + * Add a task of type Deadline + * + * @param taskDetail String that represents the task detail + * @param taskDate LocalDate that represents the task date + */ + public void addItemDeadline(String taskDetail, LocalDate taskDate) { + list.add(new TaskDeadline(taskDetail, taskDate)); + } + + /** + * Add a task of type Deadline + * + * @param taskDetail String that represents the task detail + * @param taskDate LocalDate that represents the task date + * @param taskTime LocalTime that represents the task time + */ + public void addItemDeadline(String taskDetail, LocalDate taskDate, LocalTime taskTime) { + list.add(new TaskDeadline(taskDetail, taskDate, taskTime)); + } + + /** + * Add a task of type Event + * + * @param taskDetail String that represents the task detail + * @param taskDate LocalDate that represents the task date + */ + public void addItemEvent(String taskDetail, LocalDate taskDate) { + list.add(new TaskEvent(taskDetail, taskDate)); + } + + /** + * Add a task of type Event + * + * @param taskDetail String that represents the task detail + * @param taskDate LocalDate that represents the task date + * @param taskTimeStart LocalTime that represents the task start time + */ + public void addItemEvent(String taskDetail, LocalDate taskDate, LocalTime taskTimeStart) { + list.add(new TaskEvent(taskDetail, taskDate, taskTimeStart)); + } + + /** + * Add a task of type Event + * + * @param taskDetail String that represents the task detail + * @param taskDate LocalDate that represents the task date + * @param taskTimeStart LocalTime that represents the task start time + * @param taskTimeEnd LocalTime that represents the task end time + */ + public void addItemEvent(String taskDetail, LocalDate taskDate, LocalTime taskTimeStart, LocalTime taskTimeEnd) { + list.add(new TaskEvent(taskDetail, taskDate, taskTimeStart, taskTimeEnd)); + } + + /** + * Delete a task from tasklist + * + * @param index Int that represents the index in a task list + */ + public void removeItem(int index) { + list.remove(index); + } + + // Getter <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Return a task from tasklist + * + * @param index Int that represents the index in a task list + * @return Task at the index + */ + public Task getTask(int index) { + return list.get(index); + } + + /** + * Return a task detail from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the task detail + */ + public String getTaskDetail(int index) { + Task task = list.get(index); + return task.getTaskDetail(); + } + + /** + * Return a task priority from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return TaskPriority that represents the task priority + */ + public TaskPriority getTaskPriority(int index) { + Task task = list.get(index); + return task.getTaskPriority(); + } + + /** + * Return a boolean done status from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return boolean that represents the task done status + */ + public boolean getTaskDoneStatus(int index) { + Task task = list.get(index); + return task.getDoneStatus(); + } + + /** + * Return a taskDate in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the task date + */ + public String getTaskEventTaskDateInString(int index) { + TaskEvent task = (TaskEvent) list.get(index); + return task.getLocalDate_toString(); + } + + /** + * Return year from a taskDate in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the year from taskDate + */ + public String getTaskEventTaskDateYearInString(int index) { + TaskEvent task = (TaskEvent) list.get(index); + return task.getLocalDateYearToString(); + } + + /** + * Return month from a taskDate in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the month from taskDate + */ + public String getTaskEventTaskDateMonthInString(int index) { + TaskEvent task = (TaskEvent) list.get(index); + return task.getLocalDateMonthToString(); + } + + /** + * Return day from a taskDate in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the day from taskDate + */ + public String getTaskEventTaskDateDayInString(int index) { + TaskEvent task = (TaskEvent) list.get(index); + return task.getLocalDateDayToString(); + } + + /** + * Return start time in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the start time from TaskTime + */ + public String getTaskEventTaskTimeStartInString(int index) { + TaskEvent task = (TaskEvent) list.get(index); + return task.getLocalTimeStart_toString(); + } + + /** + * Return end time in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the end time from TaskTime + */ + public String getTaskEventTaskTimeEndInString(int index) { + TaskEvent task = (TaskEvent) list.get(index); + return task.getLocalTimeEnd_toString(); + } + + /** + * Return a taskDate in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the task date + */ + public String getTaskDeadLineTaskDateInString(int index) { + TaskDeadline task = (TaskDeadline) list.get(index); + return task.getLocalDateToString(); + } + + /** + * Return year from a taskDate in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the year from TaskDate + */ + public String getTaskDeadLineTaskDateYearInString(int index) { + TaskDeadline task = (TaskDeadline) list.get(index); + return task.getLocalDateYearToString(); + } + + /** + * Return month from a taskDate in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the month from TaskDate + */ + public String getTaskDeadLineTaskDateMonthInString(int index) { + TaskDeadline task = (TaskDeadline) list.get(index); + return task.getLocalDateMonthToString(); + } + + /** + * Return day from a taskDate in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the day from TaskDate + */ + public String getTaskDeadLineTaskDateDayInString(int index) { + TaskDeadline task = (TaskDeadline) list.get(index); + return task.getLocalDateDayToString(); + } + + /** + * Return TaskTime in String from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return String that represents the TaskTime + */ + public String getTaskDeadLineTaskTimeInString(int index) { + TaskDeadline task = (TaskDeadline) list.get(index); + return task.getLocalTime_toString(); + } + + /** + * Return the number of item in a tasklist + * + * @return Int that represents the number of item in a tasklist + */ + public int getNumOfItem() { + return list.size(); + } + + /** + * Return TaskType from a task of tasklist + * + * @param index Int that represents the index in a task list + * @return TaskType that represents the type of task + */ + public TaskType getTaskType(int index) { + Task task = list.get(index); + return task.getTaskType(); + } + + // Setter <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Return TaskType from a task of tasklist + * + * @param index Int that represents the index in a task list + */ + public void setTaskDone(int index) { + Task task = list.get(index); + task.setTaskCompleted(); + } + + /** + * Return TaskType from a task of tasklist + * + * @param index Int that represents the index in a task list + */ + public void setTaskUnDone(int index) { + Task task = list.get(index); + task.setTaskInCompleted(); + } + + /** + * Update the priority of a task in tasklist + * + * @param index Int that represents the index in a task list + * @param taskPriority TaskPriority(new) that will replace the TaskPriority(current) + */ + public void setTaskPriority(int index, TaskPriority taskPriority) { + Task task = list.get(index); + task.setPriority(taskPriority); + } +} diff --git a/src/main/java/duke/task/TaskPriority.java b/src/main/java/duke/task/TaskPriority.java new file mode 100644 index 00000000..6cd53c94 --- /dev/null +++ b/src/main/java/duke/task/TaskPriority.java @@ -0,0 +1,129 @@ +package duke.task; + +public enum TaskPriority { + HIGH, MEDIUM, LOW, INVALID; + + /** + * Compare two tasks and return true if taskA has higher priority than taskB + * + * @param taskA First Task to compare + * @param taskB Second Task to compare + * @return boolean true if taskA > taskB; false if otherwise + */ + public static boolean isHigherPriority(TaskPriority taskA, TaskPriority taskB) { + int taskAPriority = convertPriorityToInt(taskA); + int taskBPriority = convertPriorityToInt(taskB); + + if (taskAPriority < taskBPriority) { + return true; + } + return false; + } + + /** + * Convert Int value to Priority + *

+ * 1 -> HIGH + * 2 -> MEDIUM + * 3 -> LOW + * any other number -> INVALID + * + * @param priority Int that indicates the priority + * @return TaskPriority + */ + public static TaskPriority convertIntToPriority(int priority) { + switch (priority) { + case 1: + return HIGH; + case 2: + return MEDIUM; + case 3: + return LOW; + default: + return INVALID; + } + } + + /** + * Convert String value to Priority + *

+ * "1" -> HIGH + * "2" -> MEDIUM + * "3" -> LOW + * any other number -> INVALID + * + * @param priority String that indicates the priority + * @return TaskPriority + */ + public static TaskPriority convertStringToPriority(String priority) { + switch (priority) { + case "1": + return HIGH; + case "2": + return MEDIUM; + case "3": + return LOW; + default: + return INVALID; + } + } + + /** + * Convert TaskPriority to Int + *

+ * 1 <- HIGH + * 2 <- MEDIUM + * 3 <- LOW + * 0 <- INVALID + * + * @param task TaskPriority that indicates the TaskPriority + * @return int + */ + public static int convertPriorityToInt(TaskPriority task) { + switch (task) { + case LOW: + return 3; + case MEDIUM: + return 2; + case HIGH: + return 1; + default: + return 0; + } + } + + /** + * Convert TaskPriority to String + * + * @param task TaskPriority that indicates the TaskPriority + * @return String value of TaskPriority + */ + public static String convertPriorityToString(TaskPriority task) { + switch (task) { + case LOW: + return "LOW"; + case MEDIUM: + return "MEDIUM"; + case HIGH: + return "HIGH"; + default: + return "INVALID"; + } + } + + /** + * Convert TaskPriority to String + */ + public String toStringInNumber() { + switch (this) { + case LOW: + return "3"; + case MEDIUM: + return "2"; + case HIGH: + return "1"; + default: + return "0"; + } + } +} diff --git a/src/main/java/duke/task/TaskToDos.java b/src/main/java/duke/task/TaskToDos.java new file mode 100644 index 00000000..a05ba941 --- /dev/null +++ b/src/main/java/duke/task/TaskToDos.java @@ -0,0 +1,21 @@ +package duke.task; + +/** + * Create an instance of todo class + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class TaskToDos extends Task { + + /** + * Constructor + */ + public TaskToDos(String taskDetail) { + super(taskDetail); + this.isDone = false; + this.taskType = TaskType.TODOS; + } +} diff --git a/src/main/java/duke/task/TaskType.java b/src/main/java/duke/task/TaskType.java new file mode 100644 index 00000000..1b177045 --- /dev/null +++ b/src/main/java/duke/task/TaskType.java @@ -0,0 +1,34 @@ +package duke.task; + +/** + * Define task type + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public enum TaskType { + TODOS, DEADLINE, EVENT; + + /** + * Constructor + */ + public static String taskTypeToString(TaskType taskType) { + String s = ""; + switch (taskType) { + case TODOS: + s = "T"; + break; + case DEADLINE: + s = "D"; + break; + case EVENT: + s = "E"; + break; + default: + throw new IllegalStateException("Unexpected value: " + taskType); + } + return s; + } +} diff --git a/src/main/java/duke/ui/Message.java b/src/main/java/duke/ui/Message.java new file mode 100644 index 00000000..f418948f --- /dev/null +++ b/src/main/java/duke/ui/Message.java @@ -0,0 +1,545 @@ +package duke.ui; + +import duke.task.TaskList; + +/** + * Handle all the message methods + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class Message { + + // Starting Messages <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Display greet message at the start + */ + public static void msgGreet() { + String logo = " ____ _ \n" + "| _ \\ _ _| | _____ \n" + "| | | | | | | |/ / _ \\\n" + + "| |_| | |_| | < __/\n" + "|____/ \\__,_|_|\\_\\___|\n"; + System.out.println("Hello from\n" + logo); + System.out.println(">>> Copyright (c) Teng Kang Teng (A0211547L NUS) <<<"); + System.out.println(">>> Version 0.2 <<<\n"); + System.out.println("Hello! I'm Duke" + System.lineSeparator() + "What can I do for you?"); + System.out.println("Enter \"Info\" to show all Duke commands. "); + System.out.println("_________________________________"); + } + + // Assignment Messages <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Display message when a task is assigned + * + * @param taskTypeInString String that describes the task type + * @param isDoneInString String that describes the isDone status + * @param taskDetail String that describes the task detail + * @param numOfItem Int that describes the number of items in taskList + */ + public static void msgAssignTaskToDo(String taskTypeInString, String isDoneInString, + String taskDetail, int numOfItem) { + + System.out.println(" Got it. I've added this task: "); + System.out.println(" [" + taskTypeInString + "][" + isDoneInString + "] " + taskDetail); + System.out.println(" Now you have " + numOfItem + " tasks in the list."); + System.out.println("_________________________________"); + } + + /** + * Display message when a deadline task is assigned + * + * @param taskTypeInString String that describes the task type + * @param isDoneInString String that describes the isDone status + * @param taskDetail String that describes the task detail + * @param dateInString String that describes the task date + * @param numOfItem Int that describes the number of items in taskList + */ + public static void msgAssignTaskDeadlineTaskDate(String taskTypeInString, String isDoneInString, + String taskDetail, String dateInString, int numOfItem) { + + System.out.println(" Got it. I've added this task: "); + System.out.println( + " [" + taskTypeInString + "][" + isDoneInString + "] " + + taskDetail + "(by: " + dateInString + ")"); + System.out.println(" Now you have " + numOfItem + " tasks in the list."); + System.out.println("_________________________________"); + } + + /** + * Display message when a deadline task is assigned + * + * @param taskTypeInString String that describes the task type + * @param isDoneInString String that describes the isDone status + * @param taskDetail String that describes the task detail + * @param dateInString String that describes the task date + * @param timeInString String that describes the task time + * @param numOfItem Int that describes the number of items in taskList + */ + public static void msgAssignTaskDeadlineTaskDateTaskTime(String taskTypeInString, String isDoneInString, + String taskDetail, String dateInString, + String timeInString, int numOfItem) { + + System.out.println(" Got it. I've added this task: "); + System.out.println( + " [" + taskTypeInString + "][" + isDoneInString + "] " + + taskDetail + "(by: " + dateInString + " " + timeInString + ")"); + System.out.println(" Now you have " + numOfItem + " tasks in the list."); + System.out.println("_________________________________"); + } + + /** + * Display message when an event task is assigned + * + * @param taskTypeInString String that describes task type + * @param isDoneInString String that describes is done status + * @param taskDetail String that describes task detail + * @param dateInString String that describes task date + * @param numOfItem Int that describes the number of tasks + */ + public static void msgAssignTaskEventTaskDate(String taskTypeInString, String isDoneInString, + String taskDetail, String dateInString, int numOfItem) { + + System.out.println(" Got it. I've added this task: "); + System.out.println(" [" + taskTypeInString + "][" + + isDoneInString + "] " + + taskDetail + "(at: " + dateInString + ")"); + System.out.println(" Now you have " + numOfItem + " tasks in the list."); + System.out.println("_________________________________"); + } + + /** + * Display message when an event task is assigned + * + * @param taskTypeInString String that describes task type + * @param isDoneInString String that describes is done status + * @param taskDetail String that describes task detail + * @param dateInString String that describes task date + * @param timeStartInString String that describes the start time + * @param numOfItem Int that describes the number of tasks + */ + public static void msgAssignTaskEventTaskDateTaskTimeStart(String taskTypeInString, + String isDoneInString, + String taskDetail, + String dateInString, + String timeStartInString, + int numOfItem) { + + System.out.println(" Got it. I've added this task: "); + System.out.println(" [" + taskTypeInString + "][" + isDoneInString + "] " + taskDetail); + System.out.println(" (at: " + dateInString + ", from: " + timeStartInString + ")"); + System.out.println(" Now you have " + numOfItem + " tasks in the list."); + System.out.println("_________________________________"); + } + + /** + * Display message when an event task is assigned + * + * @param taskTypeInString String that describes task type + * @param isDoneInString String that describes is done status + * @param taskDetail String that describes task detail + * @param dateInString String that describes task date + * @param timeStartInString String that describes the start time + * @param timeEndInString String that describes the end time + * @param numOfItem Int that describes the number of tasks + */ + public static void msgAssignEventTaskDateTimeStartEnd(String taskTypeInString, + String isDoneInString, + String taskDetail, + String dateInString, + String timeStartInString, + String timeEndInString, + int numOfItem) { + + System.out.println(" Got it. I've added this task: "); + System.out.println(" [" + taskTypeInString + "][" + isDoneInString + "] " + taskDetail); + System.out.println(" (at: " + dateInString + ", from: " + timeStartInString + + " to " + timeEndInString + ")"); + System.out.println(" Now you have " + numOfItem + " tasks in the list."); + System.out.println("_________________________________"); + } + + // FileAccess Messages <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Display message when task is saved + */ + public static void msgSave() { + System.out.println(" Progress Saved!"); + System.out.println("_________________________________"); + } + + /** + * Display message when task is loaded + */ + public static void msgSLoad() { + System.out.println(" Progress loaded!"); + System.out.println("_________________________________"); + } + + // Set Messages <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Display message to ask user which task they want to set priority + */ + public static void msgAskUserSetTaskPriority() { + System.out.println(" Which task do you want to set priority?"); + } + + /** + * Display message to ask user what is the new priority + */ + public static void msgAskUserWhatPriority() { + System.out.println(" What is it's priority? choose 1 to 3"); + System.out.println(" 1: Very urgent >>> 3: Chin Cai not that urgent"); + } + + /** + * Display message to tell user that the new priority for a task is set successfully + * + * @param taskNumber Int that describes the task number in the TaskList + * @param taskPriorityInString String that describes the priority of the task + */ + public static void msgSetPriority(int taskNumber, String taskPriorityInString) { + System.out.println(" Done! The new task priority is set"); + System.out.println(" Priority of Task #" + taskNumber + " has been set to " + taskPriorityInString); + System.out.println("_________________________________"); + } + + // Find Messages <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Display message to tell user that the term that the user try to find is not found + */ + public static void msgInvalidFindTerm() { + System.out.println(" Sorry :( Cannot find what you are looking for ~ "); + System.out.println("_________________________________"); + } + + /** + * Display message to show the opening message of "find" + */ + public static void msgTaskFoundOpeningMsg() { + System.out.println(" Here are the matching tasks in your list:"); + } + + // Other Messages <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Display message when a task is marked as done + * + * @param myList TaskList that contains the list of task + * @param taskNumber Int that represents the task number + */ + public static void msgMarkDone(TaskList myList, int taskNumber) { + System.out.println(" Naisuuuu! This task is marked as done: "); + msgBlankBeforeTaskDetail(); + new MsgTaskDetail(myList, taskNumber).showTaskDetail(); + System.out.println("_________________________________"); + } + + /** + * Display message when a task is marked as not done + * + * @param myList TaskList that contains the list of task + * @param taskNumber Int that represents the task number + */ + public static void msgMarkUnDone(TaskList myList, int taskNumber) { + System.out.println(" Okie! This task is marked as not done: "); + msgBlankBeforeTaskDetail(); + new MsgTaskDetail(myList, taskNumber).showTaskDetail(); + System.out.println("_________________________________"); + } + + /** + * Display [x] where x is the int parameter + *

+ * Used in CmdList function to show the following: + * 1. + * 2. + * 3. + * etc. + * + * @param index Int that will be put inside the bracket + */ + public static void msgShowBracketWithIndex(int index) { + System.out.print(" " + index + "."); + } + + /** + * Display blanks + */ + public static void msgBlankBeforeTaskDetail() { + System.out.print(" "); + } + + /** + * Display dash lines separator + */ + public static void msgDashLines() { + System.out.println("_________________________________"); + } + + /** + * Display TODO task description + */ + public static void msgTaskTodo(String taskTypeInString, String isDoneInString, + String taskDetail, String taskPriorityInString) { + System.out.println("[" + taskTypeInString + "][" + + isDoneInString + "] " + taskDetail + " [" + taskPriorityInString + "]"); + } + + /** + * Display EVENT task description + */ + public static void msgTaskEvent(String taskTypeInString, String isDoneInString, String taskDetail, + String year, String month, String day, String taskPriorityInString) { + System.out.println("[" + taskTypeInString + "][" + isDoneInString + "] " + + taskDetail + " [" + taskPriorityInString + "]"); + System.out.println(" (at " + year + " " + month + " " + day + ")"); + } + + /** + * Display EVENT task description + */ + public static void msgTaskEvent(String taskTypeInString, + String isDoneInString, + String taskDetail, + String year, + String month, + String day, + String timeStart, + String taskPriorityInString) { + System.out.println("[" + taskTypeInString + "][" + + isDoneInString + "] " + taskDetail + " [" + taskPriorityInString + "]"); + System.out.print(" (at " + year + " " + month + " " + day); + System.out.println(" ; from: " + timeStart + ")"); + } + + /** + * Display EVENT task description + */ + public static void msgTaskEvent(String taskTypeInString, String isDoneInString, String taskDetail, + String year, String month, String day, String timeStart, + String timeEnd, String taskPriorityInString) { + System.out.println("[" + taskTypeInString + "][" + isDoneInString + "] " + + taskDetail + " [" + taskPriorityInString + "]"); + System.out.print(" (at " + year + " " + month + " " + day); + System.out.println(" ; from: " + timeStart + " to " + timeEnd + ")"); + } + + /** + * Display DEADLINE task description + */ + public static void msgTaskDeadline(String taskTypeInString, String isDoneInString, String taskDetail, + String year, String month, String day, String taskPriorityInString) { + System.out.println("[" + taskTypeInString + "][" + isDoneInString + "] " + + taskDetail + " [" + taskPriorityInString + "]"); + System.out.println(" by: " + year + " " + month + " " + day + ")"); + } + + /** + * Display DEADLINE task description + */ + public static void msgTaskDeadline(String taskTypeInString, String isDoneInString, String taskDetail, + String year, String month, String day, + String timeStart, String taskPriorityInString) { + System.out.println("[" + taskTypeInString + "][" + isDoneInString + "] " + + taskDetail + " [" + taskPriorityInString + "]"); + System.out.println(" by: " + year + " " + month + " " + day + " " + timeStart + ")"); + } + + + /** + * Display message when a task is removed + */ + public static void msgRemoveItem(TaskList myList, int taskNumber, int numOfTaskAfterDelete) { + + System.out.println(" Noted. I've removed this task:"); + msgBlankBeforeTaskDetail(); + new MsgTaskDetail(myList, taskNumber).showTaskDetail(); + System.out.println(" Now you have " + numOfTaskAfterDelete + " tasks in the list."); + System.out.println("_________________________________"); + } + + /** + * Display arrow head + */ + public static void msgArrowHead() { + System.out.print(">> "); + } + + /** + * Display full list of Duke command + */ + public static void msgShowDukeCommandList() { + System.out.println(">> Full List of Duke Command Available:"); + System.out.println(" 1. todo (task description)"); + System.out.println(" >> add a TODO task"); + System.out.println(" 2. event (task description)"); + System.out.println(" >> add a EVENT task"); + System.out.println(" 3. event (task description)/at (date)"); + System.out.println(" >> add a EVENT task"); + System.out.println(" 4. event (task description)/at (date) (time)"); + System.out.println(" >> add a EVENT task"); + System.out.println(" 5. deadline (task description)"); + System.out.println(" >> add a DEADLINE task"); + System.out.println(" 6. deadline (task description)/by (date)"); + System.out.println(" >> add a DEADLINE task"); + System.out.println(" 7. deadline (task description)/by (date) (time start) (time end)"); + System.out.println(" >> add a DEADLINE task"); + System.out.println(" 8. list"); + System.out.println(" >> show full list of task"); + System.out.println(" 9. set"); + System.out.println(" >> change priority of a task"); + System.out.println(" 10. done (task number)"); + System.out.println(" >> mark a task as completed"); + System.out.println(" 11. find (keyword)"); + System.out.println(" >> find a task based on keyword"); + System.out.println(" 12. info"); + System.out.println(" >> display full list of Duke Command"); + System.out.println(" 13. delete (task number)"); + System.out.println(" >> delete a task"); + System.out.println(" 14. save"); + System.out.println(" >> save all the tasks"); + System.out.println(" 15. bye"); + System.out.println(" >> end your friendly Duke chat box"); + System.out.println("_________________________________"); + } + // Error Messages <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Display message when a progress file fail to load + */ + public static void msgUnableToLoadProgress() { + System.out.println(" >> Fail to load progress. New Task List is created <<"); + System.out.println("_________________________________"); + } + + + /** + * Display message when a task is marked as done + * + * @param e Exception error + */ + public static void msgError(Exception e) { + System.out.println("Error Occurs: " + e); + System.out.println("_________________________________"); + } + + /** + * Display message that remind user about invalid input + */ + public static void msgInvalidInput() { + System.out.println(" Sorry :( Invalid Input. Try Again ~ "); + System.out.println("_________________________________"); + } + + /** + * Display message that remind user about invalid input + * Description of the task is missing + */ + public static void msgInvalidInputMissingDescription() { + System.out.println(" OOPS!!! The description cannot be empty."); + System.out.println("_________________________________"); + } + + /** + * Display message that remind user about invalid input + * Date of the task is missing + */ + public static void msgInvalidInputMissingDate() { + System.out.println(" OOPS!!! The date cannot be empty."); + System.out.println("_________________________________"); + } + + /** + * Display message that remind user about invalid input + * Time of the task is missing + */ + public static void msgInvalidInputMissingTime() { + System.out.println(" OOPS!!! The time cannot be empty."); + System.out.println("_________________________________"); + } + + /** + * Display message that remind user about invalid input + * The task number is not found + */ + public static void msgInvalidTaskNumber() { + System.out.println(" OOPS!!! The task number is invalid."); + System.out.println("_________________________________"); + } + + /** + * Display message that remind user about invalid input + * The priority is invalid + */ + public static void msgInvalidPriority() { + System.out.println(" OOPS!!! The priority is invalid. Choose 1, 2 or 3"); + System.out.println("_________________________________"); + } + + /** + * Display message that remind user about invalid input + * Format of the date is unaccepted + */ + public static void msgInvalidInputWrongDateTimeFormat() { + System.out.println(" OOPS!!! Please follow this format:"); + System.out.println(" /by yyyy-mm-dd hh:mm"); + System.out.println("_________________________________"); + } + + /** + * Display message that remind user about invalid input + * Format of the date and time is unaccepted + */ + public static void msgInvalidInputWrongDateTimeStartEndFormat() { + System.out.println(" OOPS!!! Please follow this format:"); + System.out.println(" /at yyyy-mm-dd hh:mm hh:mm:"); + System.out.println("_________________________________"); + } + + /** + * Display message that remind user about invalid input + * Start time should be before End time + */ + public static void msgInvalidInputTimeStartLaterThanTimeEnd() { + System.out.println(" OOPS!!! Event start time cannot be later than end time!"); + System.out.println("_________________________________"); + } + + /** + * Display message about task list being empty + */ + public static void msgTaskListIsEmpty() { + System.out.println(" OOPS!!! The task list is empty."); + System.out.println("_________________________________"); + } + + /** + * Display message when buddha.txt fails to load + */ + public static void msgUnableToLoadBuddha() { + System.out.println(" >> Buddha Protection is under maintenance <<"); + System.out.println("_________________________________"); + } + + // Ending Messages <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + /** + * Display message before the end of program + */ + public static void msgBye() { + System.out.println("Bye. Hope to see you again soon!"); + System.out.println("_________________________________"); + } + + /** + * Display buddha.txt before the end of program + */ + public static void msgBuddha(String buddhaText) { + System.out.println(buddhaText); + } +} diff --git a/src/main/java/duke/ui/MsgTaskDetail.java b/src/main/java/duke/ui/MsgTaskDetail.java new file mode 100644 index 00000000..0e32401f --- /dev/null +++ b/src/main/java/duke/ui/MsgTaskDetail.java @@ -0,0 +1,155 @@ +package duke.ui; + +import duke.task.TaskList; +import duke.task.TaskPriority; +import duke.task.TaskType; + +/** + * Ui class that display message about a task + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class MsgTaskDetail { + + private static TaskList myList; + private static int taskIndex; + private static String taskTypeInString; + private static String isDoneInString; + private static String taskDetail; + private static String taskPriorityInString; + private static String year; + private static String month; + private static String day; + private static String timeStart; + private static String timeEnd; + + /** + * Constructor + */ + public MsgTaskDetail(TaskList myList, int taskIndex) { + this.myList = myList; + this.taskIndex = taskIndex; + taskTypeInString = getTaskTypeInString(myList, taskIndex); + isDoneInString = getIsDoneInString(myList, taskIndex); + taskDetail = getTaskDetail(myList, taskIndex); + taskPriorityInString = getTaskPriority(myList, taskIndex); + } + + /** + * Show task detail based on the task type + */ + public static void showTaskDetail() { + TaskType taskType = myList.getTaskType(taskIndex); + + switch (taskType) { + case TODOS: + showTaskTodo(); + break; + case EVENT: + showTaskEvent(myList, taskIndex); + break; + case DEADLINE: + showTaskDeadline(myList, taskIndex); + break; + default: + break; + } + } + + /** + * Show task detail of TODO type + */ + private static void showTaskTodo() { + Message.msgTaskTodo(taskTypeInString, isDoneInString, taskDetail, taskPriorityInString); + } + + /** + * Show task detail of EVENT type + */ + private static void showTaskEvent(TaskList myList, int taskIndex) { + year = myList.getTaskEventTaskDateYearInString(taskIndex); + month = myList.getTaskEventTaskDateMonthInString(taskIndex); + day = myList.getTaskEventTaskDateDayInString(taskIndex); + timeStart = myList.getTaskEventTaskTimeStartInString(taskIndex); + timeEnd = myList.getTaskEventTaskTimeEndInString(taskIndex); + + if (timeStart.equals("null") && timeEnd.equals("null")) { + Message.msgTaskEvent(taskTypeInString, isDoneInString, taskDetail, + year, month, day, taskPriorityInString); + } else if (timeEnd.equals("null")) { + Message.msgTaskEvent(taskTypeInString, isDoneInString, taskDetail, + year, month, day, timeStart, taskPriorityInString); + } else { + Message.msgTaskEvent(taskTypeInString, isDoneInString, taskDetail, + year, month, day, timeStart, timeEnd, taskPriorityInString); + } + } + + /** + * Show task detail of DEADLINE type + */ + private static void showTaskDeadline(TaskList myList, int taskIndex) { + year = myList.getTaskDeadLineTaskDateYearInString(taskIndex); + month = myList.getTaskDeadLineTaskDateMonthInString(taskIndex); + day = myList.getTaskDeadLineTaskDateDayInString(taskIndex); + timeStart = myList.getTaskDeadLineTaskTimeInString(taskIndex); + + if (timeStart.equals("null")) { + Message.msgTaskDeadline(taskTypeInString, isDoneInString, taskDetail, + year, month, day, taskPriorityInString); + } else { + Message.msgTaskDeadline(taskTypeInString, isDoneInString, taskDetail, + year, month, day, timeStart, taskPriorityInString); + } + } + + /** + * Get task type in string + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String that describes the task type + */ + private static String getTaskTypeInString(TaskList myList, int taskIndex) { + TaskType taskType = myList.getTaskType(taskIndex); + return TaskType.taskTypeToString(taskType); + } + + /** + * Get isDone status in string + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String that describes the is done status + */ + private static String getIsDoneInString(TaskList myList, int taskIndex) { + boolean isDone = myList.getTaskDoneStatus(taskIndex); + return (isDone ? "X" : " "); + } + + /** + * Get task detail in string + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String that describes the task detail + */ + private static String getTaskDetail(TaskList myList, int taskIndex) { + return myList.getTaskDetail(taskIndex); + } + + /** + * Get task priority in string + * + * @param myList TaskList that contains the list of task + * @param taskIndex Int that represents the index of the task + * @return String that describes the priority of a task + */ + private static String getTaskPriority(TaskList myList, int taskIndex) { + TaskPriority taskPriority = myList.getTaskPriority(taskIndex); + return TaskPriority.convertPriorityToString(taskPriority); + } +} diff --git a/src/main/java/duke/ui/Ui.java b/src/main/java/duke/ui/Ui.java new file mode 100644 index 00000000..5f861b0e --- /dev/null +++ b/src/main/java/duke/ui/Ui.java @@ -0,0 +1,37 @@ +package duke.ui; + + +import java.util.Scanner; + +/** + * Interface class for User Interface + * + * @author Kang Teng + * @version 8.0 + * @since 2021-09-01 + */ + +public class Ui { + + public Ui() { + + } + + /** + * request user input and read the input string + * + * @param scanner Scanner that read user input + */ + public String requestUserInput(Scanner scanner) { + + String userInput = ""; + + try { + Message.msgArrowHead(); + userInput = scanner.nextLine(); + } catch (Exception e) { + Message.msgError(e); + } + return userInput; + } +} diff --git a/src/resources/FutureImporvement.txt b/src/resources/FutureImporvement.txt new file mode 100644 index 00000000..a92d8f62 --- /dev/null +++ b/src/resources/FutureImporvement.txt @@ -0,0 +1,6 @@ +Level 8: +1. date time should accept other format. for now cannot. +2. Stretch goal: Use dates and times in more meaningful ways. e.g., add a command to print deadlines/events occurring on a specific date. +3. save the time and date +4. JUnit Test buggy +5. Read JUnit Basic \ No newline at end of file diff --git a/src/resources/buddha.txt b/src/resources/buddha.txt new file mode 100644 index 00000000..d792d29f --- /dev/null +++ b/src/resources/buddha.txt @@ -0,0 +1,24 @@ +// +// _oo0oo_ +// o8888888o +// 88" . "88 +// (| -_- |) +// 0\ = /0 +// ___/`---'\___ +// .' \\| |// '. +// / \\||| : |||// \ +// / _||||| -:- |||||- \ +// | | \\\ - /// | | +// | \_| ''\---/'' |_/ | +// \ .-\__ '-' ___/-. / +// ___'. .' /--.--\ `. .'___ +// ."" '< `.___\_<|>_/___.' >' "". +// | | : `- \`.;`\ _ /`;.`/ - ` : | | +// \ \ `_. \_ __\ /__ _/ .-` / / +// =====`-.____`.___ \_____/___.-`___.-'===== +// `=---=' +// +// +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Buddha Protect Me Say Bye to All Bug +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \ No newline at end of file diff --git a/src/resources/progress.txt b/src/resources/progress.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/resources/progress_backup.txt b/src/resources/progress_backup.txt new file mode 100644 index 00000000..cf18a6ab --- /dev/null +++ b/src/resources/progress_backup.txt @@ -0,0 +1,5 @@ +0|E|0|project meeting|1|2001-01-25|null|null|; +1|E|0|project meeting|3|2002-06-25|18:00|null|; +2|E|0|project meeting|3|2002-06-25|18:00|19:00|; +3|D|0|return book|3|2010-01-25|null|; +4|D|0|return book|3|2011-02-25|06:00|; diff --git a/src/test/java/duke/SampleTest.java b/src/test/java/duke/SampleTest.java new file mode 100644 index 00000000..51694fe4 --- /dev/null +++ b/src/test/java/duke/SampleTest.java @@ -0,0 +1,64 @@ +package duke; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class SampleTest { + @Test + @DisplayName("Sample JUnit Test") + @Disabled("Sample Test") + public void dummyTest() { + assertEquals(2, 2); + } + + @Test + @Disabled("Sample Test") + public void dummyFailTest() { + assertEquals(2, 1); + } + + @Test + @Disabled("Sample Test") + public void shouldShowSimpleAssertion() { + assertEquals(1, 1); + assertEquals(1, 2); + } + + @Test + @DisplayName("Should check all items in the list") + @Disabled("Sample Test") + public void shouldCheckAllItemsInTheList() { + List numbers = List.of(2, 3, 5, 7); + + Assertions.assertAll(() -> + assertEquals(2, numbers.get(0)), () -> + assertEquals(300, numbers.get(1)), () -> + assertEquals(5, numbers.get(2)), () -> + assertEquals(700, numbers.get(3))); + } + + @Test + @DisplayName("Should only run the test if some criteria are met 1") + @Disabled("Sample Test") + void shouldOnlyRunTheTestIfSomeCriteriaAreMet1() { + Assumptions.assumeTrue(13 > 10); + assertEquals(2, 1); + } + + @Test + @DisplayName("Should only run the test if some criteria are met 2") + @Disabled("Sample Test") + void shouldOnlyRunTheTestIfSomeCriteriaAreMet2() { + Assumptions.assumeTrue(13 < 10); + assertEquals(2, 1); + } + + +} diff --git a/src/test/java/duke/action/ParseProgressTest.java b/src/test/java/duke/action/ParseProgressTest.java new file mode 100644 index 00000000..a8a78424 --- /dev/null +++ b/src/test/java/duke/action/ParseProgressTest.java @@ -0,0 +1,25 @@ +package duke.action; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +class ParseProgressTest { + + @Test + @Disabled("Unknown JUnit behaviour") + void testSplitStringIntoSentence() { + String input = "HelloWorld"; + String[] expected = {"HelloWorld"}; + assertEquals(expected, input); + } + + @Test + @Disabled("Unknown JUnit behaviour") + void splitSentenceByBarSeparator() { + String input = "HelloWorld"; + String[] expected = {"HelloWorld"}; + assertEquals(expected, input); + } +} diff --git a/src/test/java/duke/task/TaskPriorityTest.java b/src/test/java/duke/task/TaskPriorityTest.java new file mode 100644 index 00000000..04c242d7 --- /dev/null +++ b/src/test/java/duke/task/TaskPriorityTest.java @@ -0,0 +1,79 @@ +package duke.task; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class TaskPriorityTest { + + @Test + void testIsHigherPriority() { + TaskPriority taskPriorityHigh = TaskPriority.HIGH; + TaskPriority taskPriorityLow = TaskPriority.LOW; + + assertEquals(true, TaskPriority.isHigherPriority(taskPriorityHigh, taskPriorityLow)); + } + + @Test + void testConvertIntToPriority() { + List priorities = List.of(1, 2, 3, 4, 100, 0); + + Assertions.assertAll(() -> + assertEquals(TaskPriority.HIGH, TaskPriority.convertIntToPriority(priorities.get(0))), () -> + assertEquals(TaskPriority.MEDIUM, TaskPriority.convertIntToPriority(priorities.get(1))), () -> + assertEquals(TaskPriority.LOW, TaskPriority.convertIntToPriority(priorities.get(2))), () -> + assertEquals(TaskPriority.INVALID, TaskPriority.convertIntToPriority(priorities.get(3))), () -> + assertEquals(TaskPriority.INVALID, TaskPriority.convertIntToPriority(priorities.get(4))), () -> + assertEquals(TaskPriority.INVALID, TaskPriority.convertIntToPriority(priorities.get(5)))); + } + + @Test + void testConvertStringToPriority() { + List priorities = List.of("1", "2", "3", "4", "100", "0"); + + Assertions.assertAll(() -> + assertEquals(TaskPriority.HIGH, TaskPriority.convertStringToPriority(priorities.get(0))), () -> + assertEquals(TaskPriority.MEDIUM, TaskPriority.convertStringToPriority(priorities.get(1))), () -> + assertEquals(TaskPriority.LOW, TaskPriority.convertStringToPriority(priorities.get(2))), () -> + assertEquals(TaskPriority.INVALID, TaskPriority.convertStringToPriority(priorities.get(3))), () -> + assertEquals(TaskPriority.INVALID, TaskPriority.convertStringToPriority(priorities.get(4))), () -> + assertEquals(TaskPriority.INVALID, TaskPriority.convertStringToPriority(priorities.get(5)))); + } + + @Test + void testConvertPriorityToInt() { + List priorities = List.of(TaskPriority.LOW, + TaskPriority.MEDIUM, TaskPriority.HIGH, TaskPriority.INVALID); + + Assertions.assertAll(() -> + assertEquals(3, TaskPriority.convertPriorityToInt(priorities.get(0))), () -> + assertEquals(2, TaskPriority.convertPriorityToInt(priorities.get(1))), () -> + assertEquals(1, TaskPriority.convertPriorityToInt(priorities.get(2))), () -> + assertEquals(0, TaskPriority.convertPriorityToInt(priorities.get(3)))); + } + + @Test + void testConvertPriorityToString() { + List priorities = List.of(TaskPriority.LOW, + TaskPriority.MEDIUM, TaskPriority.HIGH, TaskPriority.INVALID); + + Assertions.assertAll(() -> + assertEquals("LOW", TaskPriority.convertPriorityToString(priorities.get(0))), () -> + assertEquals("MEDIUM", TaskPriority.convertPriorityToString(priorities.get(1))), () -> + assertEquals("HIGH", TaskPriority.convertPriorityToString(priorities.get(2))), () -> + assertEquals("INVALID", TaskPriority.convertPriorityToString(priorities.get(3)))); + } + + @Test + void testToStringInNumber() { + + Assertions.assertAll(() -> + assertEquals("3", TaskPriority.LOW.toStringInNumber()), () -> + assertEquals("2", TaskPriority.MEDIUM.toStringInNumber()), () -> + assertEquals("1", TaskPriority.HIGH.toStringInNumber()), () -> + assertEquals("0", TaskPriority.INVALID.toStringInNumber())); + } +} diff --git a/src/test/java/duke/task/TaskTypeTest.java b/src/test/java/duke/task/TaskTypeTest.java new file mode 100644 index 00000000..9838eb11 --- /dev/null +++ b/src/test/java/duke/task/TaskTypeTest.java @@ -0,0 +1,20 @@ +package duke.task; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class TaskTypeTest { + + @Test + void testTaskTypeToStringtaskTypeString() { + List types = List.of(TaskType.TODOS, TaskType.DEADLINE, TaskType.EVENT); + Assertions.assertAll(() -> + assertEquals("T", TaskType.taskTypeToString(types.get(0))), () -> + assertEquals("D", TaskType.taskTypeToString(types.get(1))), () -> + assertEquals("E", TaskType.taskTypeToString(types.get(2)))); + } +} diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6..67378fae 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,245 @@ Hello from - ____ _ -| _ \ _ _| | _____ + ____ _ +| _ \ _ _| | _____ | | | | | | | |/ / _ \ | |_| | |_| | < __/ |____/ \__,_|_|\_\___| +Hello! I'm Duke +What can I do for you? +_________________________________ +>> todo borrow book + Got it. I've added this task: + [T][ ] borrow book + Now you have 1 tasks in the list. +_________________________________ +>> event project meeting/at 2001-01-25 + Got it. I've added this task: + [E][ ] project meeting(at: 2001-01-25) + Now you have 2 tasks in the list. +_________________________________ +>> event project meeting/at 2002-06-25 18:00 + Got it. I've added this task: + [E][ ] project meeting + (at: 2002-06-25, from: 18:00) + Now you have 3 tasks in the list. +_________________________________ +>> event project meeting/at 2002-06-25 18:00 19:00 + Got it. I've added this task: + [E][ ] project meeting + (at: 2002-06-25, from: 18:00 to 19:00) + Now you have 4 tasks in the list. +_________________________________ +>> event project meeting/at 2003-12-25 19:00 19:00 + Got it. I've added this task: + [E][ ] project meeting + (at: 2003-12-25, from: 19:00 to 19:00) + Now you have 5 tasks in the list. +_________________________________ +>> deadline return book/by 2010-01-25 + Got it. I've added this task: + [D][ ] return book(by: 2010-01-25) + Now you have 6 tasks in the list. +_________________________________ +>> deadline return book/by 2011-02-25 06:00 + Got it. I've added this task: + [D][ ] return book(by: 2011-02-25 06:00) + Now you have 7 tasks in the list. +_________________________________ +>> list + 1.[T][ ] borrow book [LOW] + 2.[E][ ] project meeting [LOW] + (at 2001 JANUARY 25) + 3.[E][ ] project meeting [LOW] + (at 2002 JUNE 25 ; from: 18:00) + 4.[E][ ] project meeting [LOW] + (at 2002 JUNE 25 ; from: 18:00 to 19:00) + 5.[E][ ] project meeting [LOW] + (at 2003 DECEMBER 25 ; from: 19:00 to 19:00) + 6.[D][ ] return book [LOW] + by: 2010 JANUARY 25) + 7.[D][ ] return book [LOW] + by: 2011 FEBRUARY 25 06:00) +_________________________________ +>> done 2 + Naisuuuu! This task is marked as done: + [E][X] project meeting [LOW] + (at 2001 JANUARY 25) +_________________________________ +>> done 5 + Naisuuuu! This task is marked as done: + [E][X] project meeting [LOW] + (at 2003 DECEMBER 25 ; from: 19:00 to 19:00) +_________________________________ +>> done 6 + Naisuuuu! This task is marked as done: + [D][X] return book [LOW] + by: 2010 JANUARY 25) +_________________________________ +>> list + 1.[T][ ] borrow book [LOW] + 2.[E][X] project meeting [LOW] + (at 2001 JANUARY 25) + 3.[E][ ] project meeting [LOW] + (at 2002 JUNE 25 ; from: 18:00) + 4.[E][ ] project meeting [LOW] + (at 2002 JUNE 25 ; from: 18:00 to 19:00) + 5.[E][X] project meeting [LOW] + (at 2003 DECEMBER 25 ; from: 19:00 to 19:00) + 6.[D][X] return book [LOW] + by: 2010 JANUARY 25) + 7.[D][ ] return book [LOW] + by: 2011 FEBRUARY 25 06:00) +_________________________________ +>> delete 1 + Noted. I've removed this task: + [T][ ] borrow book [LOW] + Now you have 6 tasks in the list. +_________________________________ +>> delete 5 + Noted. I've removed this task: + [D][X] return book [LOW] + by: 2010 JANUARY 25) + Now you have 5 tasks in the list. +_________________________________ +>> list + 1.[E][X] project meeting [LOW] + (at 2001 JANUARY 25) + 2.[E][ ] project meeting [LOW] + (at 2002 JUNE 25 ; from: 18:00) + 3.[E][ ] project meeting [LOW] + (at 2002 JUNE 25 ; from: 18:00 to 19:00) + 4.[E][X] project meeting [LOW] + (at 2003 DECEMBER 25 ; from: 19:00 to 19:00) + 5.[D][ ] return book [LOW] + by: 2011 FEBRUARY 25 06:00) +_________________________________ +>> set + Which task do you want to set priority? +>> 2 +_________________________________ + What is it's priority? choose 1 to 3 + 1: Very urgent >>> 3: Chin Cai not that urgent +1 + Done! The new task priority is set + Priority of Task #2 has been set to HIGH +_________________________________ +>> list + 1.[E][X] project meeting [LOW] + (at 2001 JANUARY 25) + 2.[E][ ] project meeting [HIGH] + (at 2002 JUNE 25 ; from: 18:00) + 3.[E][ ] project meeting [LOW] + (at 2002 JUNE 25 ; from: 18:00 to 19:00) + 4.[E][X] project meeting [LOW] + (at 2003 DECEMBER 25 ; from: 19:00 to 19:00) + 5.[D][ ] return book [LOW] + by: 2011 FEBRUARY 25 06:00) +_________________________________ +>> save + Progress Saved! +_________________________________ +>> event project meeting/at 2003-12-25 19:00 19:00 + Got it. I've added this task: + [E][ ] project meeting + (at: 2003-12-25, from: 19:00 to 19:00) + Now you have 6 tasks in the list. +_________________________________ +>> deadline return book/by 2010-01-25 + Got it. I've added this task: + [D][ ] return book(by: 2010-01-25) + Now you have 7 tasks in the list. +_________________________________ +>> save + Progress Saved! +_________________________________ +>> deadline return book + ☹ OOPS!!! The day cannot be empty. +_________________________________ +>> event project meeting /at 2016-12-25 19:00 18:00 + ☹ OOPS!!! Event start time cannot be later than end time! +_________________________________ +>> event project AAmeeting /at 2016-12-25 18:00 19:00 + Got it. I've added this task: + [E][ ] project AAmeeting + (at: 2016-12-25, from: 18:00 to 19:00) + Now you have 8 tasks in the list. +_________________________________ +>> event project meeting /at 2016-12-25 18:00 19:00 + Got it. I've added this task: + [E][ ] project meeting + (at: 2016-12-25, from: 18:00 to 19:00) + Now you have 9 tasks in the list. +_________________________________ +>> event project meet /at 2016-12-25 18:00 19:00 + Got it. I've added this task: + [E][ ] project meet + (at: 2016-12-25, from: 18:00 to 19:00) + Now you have 10 tasks in the list. +_________________________________ +>> find meeting + Here are the matching tasks in your list: + 1.[E][X] project meeting [LOW] + (at 2001 JANUARY 25) + 2.[E][ ] project meeting [HIGH] + (at 2002 JUNE 25 ; from: 18:00) + 3.[E][ ] project meeting [LOW] + (at 2002 JUNE 25 ; from: 18:00 to 19:00) + 4.[E][X] project meeting [LOW] + (at 2003 DECEMBER 25 ; from: 19:00 to 19:00) + 5.[E][ ] project meeting [LOW] + (at 2003 DECEMBER 25 ; from: 19:00 to 19:00) + 6.[E][ ] project meeting [LOW] + (at 2016 DECEMBER 25 ; from: 18:00 to 19:00) +>> list + 1.[E][X] project meeting [LOW] + (at 2001 JANUARY 25) + 2.[E][ ] project meeting [HIGH] + (at 2002 JUNE 25 ; from: 18:00) + 3.[E][ ] project meeting [LOW] + (at 2002 JUNE 25 ; from: 18:00 to 19:00) + 4.[E][X] project meeting [LOW] + (at 2003 DECEMBER 25 ; from: 19:00 to 19:00) + 5.[D][ ] return book [LOW] + by: 2011 FEBRUARY 25 06:00) + 6.[E][ ] project meeting [LOW] + (at 2003 DECEMBER 25 ; from: 19:00 to 19:00) + 7.[D][ ] return book [LOW] + by: 2010 JANUARY 25) + 8.[E][ ] project AAmeeting [LOW] + (at 2016 DECEMBER 25 ; from: 18:00 to 19:00) + 9.[E][ ] project meeting [LOW] + (at 2016 DECEMBER 25 ; from: 18:00 to 19:00) + 10.[E][ ] project meet [LOW] + (at 2016 DECEMBER 25 ; from: 18:00 to 19:00) +_________________________________ +>> save + Progress Saved! +_________________________________ +>> bye +Bye. Hope to see you again soon! +_________________________________ +// +// _oo0oo_ +// o8888888o +// 88" . "88 +// (| -_- |) +// 0\ = /0 +// ___/`---'\___ +// .' \\| |// '. +// / \\||| : |||// \ +// / _||||| -:- |||||- \ +// | | \\\ - /// | | +// | \_| ''\---/'' |_/ | +// \ .-\__ '-' ___/-. / +// ___'. .' /--.--\ `. .'___ +// ."" '< `.___\_<|>_/___.' >' "". +// | | : `- \`.;`\ _ /`;.`/ - ` : | | +// \ \ `_. \_ __\ /__ _/ .-` / / +// =====`-.____`.___ \_____/___.-`___.-'===== +// `=---=' +// +// +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Buddha Protect Me Say Bye to All Bug +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \ No newline at end of file diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29b..880bf1d2 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,55 @@ +todo borrow book +event project meeting/at 2001-01-25 +event project meeting/at 2002-06-25 18:00 +event project meeting/at 2002-06-25 18:00 19:00 +deadline return book/by 2010-01-25 +deadline return book/by 2011-02-25 06:00 +list +set +2 +1 +done 2 +list +undone 2 +list +find meeting +info +delete 1 +save +list +save +bye + + +dfd gsfdg +XXXX +to do something +todo +event +deadline +event project meeting sometime later +deadline project meeting sometime later +event project meeting/at 2001 jan 15 +deadline project meeting/by 2001 jan 15 +event project meeting/at 2002-06-25 1800 +deadline return book/by 2011-02-25 0600 +event project meeting/at 2002-06-25 19:00 18:00 +list abc +set abc +set +100 +-1 +-1 +abc +100 +1 +done 100 +undone 100 +done aaa +undone aaa +find +find Meeting +find meeeeeeting +delete +delete 0 +delete -1 diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index 08737446..cde27337 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -4,10 +4,10 @@ REM create bin directory if it doesn't exist if not exist ..\bin mkdir ..\bin REM delete output from previous run -if exist ACTUAL.TXT del ACTUAL.TXT +del ACTUAL.TXT REM compile the code into the bin folder -javac -cp ..\src\main\java -Xlint:none -d ..\bin ..\src\main\java\*.java +javac -cp ..\src\main\java -Xlint:none -d ..\bin ..\src\main\java\duke\*.java IF ERRORLEVEL 1 ( echo ********** BUILD FAILURE ********** exit /b 1 @@ -18,4 +18,4 @@ REM run the program, feed commands from input.txt file and redirect the output t java -classpath ..\bin Duke < input.txt > ACTUAL.TXT REM compare the output to the expected output -FC ACTUAL.TXT EXPECTED.TXT +FC ACTUAL.TXT EXPECTED.TXT \ No newline at end of file diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh old mode 100644 new mode 100755