diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..d2c8cb72be --- /dev/null +++ b/build.gradle @@ -0,0 +1,59 @@ +plugins { + id 'java' + id 'application' + id 'checkstyle' + id 'com.github.johnrengelman.shadow' version '5.1.0' +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' + String javaFxVersion = '11' + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux' +} + +test { + useJUnitPlatform() + + testLogging { + events "passed", "skipped", "failed" + + showExceptions true + exceptionFormat "full" + showCauses true + showStackTraces true + showStandardStreams = false + } +} + +application { + mainClassName = "seedu.duke.Duke" +} + +shadowJar { + archiveBaseName = "duke" + archiveClassifier = null +} + +checkstyle { + toolVersion = '8.29' +} + +run{ + standardInput = System.in +} diff --git a/data/duke.txt b/data/duke.txt new file mode 100644 index 0000000000..fe6a2a7b5e --- /dev/null +++ b/data/duke.txt @@ -0,0 +1,3 @@ +T | 0 | 0 | dance +D | 0 | 1 | jogging | 28/09/2021 1600 +E | 0 | 0 | gym | 26/10/2021 1300 diff --git a/docs/README.md b/docs/README.md index 8077118ebe..8c2ddd4e3b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,29 +1,147 @@ # User Guide +Hello this is Duke! + +It will help you keep track of your tasks, and save them on your device. ## Features -### Feature-ABC +### Feature-Managing Tasks + +Duke helps you manage three kind of tasks: -Description of the feature. +1. Deadline - A deadline task is one which needs to be completed within a stipulated period of time. For example, deadline to finish an assignment or group project submission. +2. Event - An event task is one which occurs on a particular time. For example attending an online conference, zoom call, family function or official meetings. +3. ToDo - A toDo task is one which does not have any particular date or time. This task serves the purpose of reminding the user that it needs to done. For example, visiting the dentist. -### Feature-XYZ +### Feature-Prioritizing Tasks -Description of the feature. +Duke helps you prioritize your tasks in the following way: + +1. High - The tasks with high priority need to be given utmost importance. +2. Low - The tasks with low priority need to be given the least importance. ## Usage -### `Keyword` - Describe action +### `todo` - Add a ToDo task + +This command adds a toDo task to the existing list of tasks. You do not have to enter the date for this type of task. + +Format: + +`todo breakfast` + +Output: + +``` +Got it. I've added this task: +[T][][Low] breakfast +Now you have 8 tasks in the list +``` +### `list` - Display all the tasks + +This command is used to display the list of all the tasks. + +Format: + +`list` + +Output: + +``` +Here are the tasks in your list +1.[T][][Low]dance +2.[D][X][High]jogging (by:Sep 28 2021, 16:00) +3.[E][][Low]gym (at:Sep 23 2021, 17:00) +``` +### `delete` - Delete a task + +This command is used to delete a task from the list of tasks. + +Format: + +`delete 7` + +Output: + +``` +Noted. I've removed this task: +[D][][Low]CS2103Tip (by:Sep 20 2021, 11;59) +Now you have 11 tasks in the list +``` +### `done` - Mark the task as Completed + +This command is used to mark the task as completed. This command is basically used to change the status of task from incomplete to complete. + +Format: + +`done 3` + +Output: + +``` +Nice! I've marked this task as done: +[E][X][Low]gym(at:Oct 26 2021,13:00) +``` +### `find` - Find tasks similar to the given keyword + +This command is used to find similar tasks from the list of tasks matching the keyword entered by the user. + +Format: + +`find book` + +Output: + +``` +Here are the matching tasks in your listbook +11.[T][][Low]read book +12.[T][][Low]revise book +``` +### `deadline` - Add a Deadline task + +This command is used to add a deadline task to the list of tasks. You need to specify the date and time as well for this type of task. The date and time should strictly follow this format: dd/mm/yyyy HHmm + +Format: + +`deadline assignment /by 24/09/2021 1800`` + +Output: + +``` +Got it. I've added this task: +[D][][Low] assignment (by: Sep 24 2021, 18:00) +Now you have 10 tasks in the list +``` +### `event` - Add an Event task + +This command is used to add an event task to the list of tasks. You need to specify the date and time as well for this type of task, The date and time should strictly follow this format: dd/mm/yyyy HHmm + +Format: + +`event Flutter /at 25/09/2021 1100` + +Output: + +``` +Got it. I've added this task: +[E][][Low] Flutter (at: Sep 25 2021, 11:00) +Now you have 9 tasks in the list +``` + +### `high` - Change the Priority of Task to High -Describe the action and its outcome. +This command is used to change the priority of the task to High. The default priority of the task is set to by Low. In this release Duke has only two levels of Priority for each type of tasks: -Example of usage: +1. High +2. Low -`keyword (optional arguments)` +Format: -Expected outcome: +`high 5` -Description of the outcome. +Output: ``` -expected output +I've given HIGH priority to this task +[T][x][High] dinner ``` diff --git a/docs/Ui.png b/docs/Ui.png new file mode 100644 index 0000000000..95c72cab77 Binary files /dev/null and b/docs/Ui.png differ diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000000..c4192631f2 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..f3d88b1c2f Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..b7c8c5dbf5 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000..2fe81a7d95 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..62bd9b9cce --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334cc..fae7b7dec4 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,56 @@ +import duke.Parser; +import duke.Storage; +import duke.Ui; +import duke.command.Command; +import duke.command.CommandResult; +import duke.tasks.TaskManager; +import duke.tasks.TaskManagerUi; +import javafx.application.Application; + +import java.util.Scanner; + public class Duke { + + // Path to file data/duke.txt + public static final String DUKE_TXT = "data/duke.txt"; + + private TaskManager taskList; + private Storage storage; + private Ui ui; + private Parser parser; + private Scanner in; + + public Duke() { + this(DUKE_TXT); + } + + public Duke(String filePath) { + storage = new Storage(filePath); + parser = new Parser(); + TaskManagerUi result = storage.initialiseTaskList(); + taskList = result.taskList; + } + + public CommandResult executeCommand(Command command) { + try { + return command.execute(); + } catch (Exception e) { + return new CommandResult(e.getMessage(), false, null); + } + } + + CommandResult getResponse(String data) { + Command command = parser.parseCommand(taskList, data); + CommandResult commandResult = executeCommand(command); + if (commandResult.isUpdated()) { + taskList = commandResult.getTaskList(); + String errorMessage = storage.writeToFile(taskList); + } + return commandResult; + } + + public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} + Application.launch(Main.class, args); + } +} \ No newline at end of file diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 0000000000..6a4914f6e0 --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,100 @@ +import duke.PrintType; +import duke.command.CommandResult; +import javafx.application.Application; +import javafx.application.Platform; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import javafx.stage.Stage; + +/** + * A GUI for Duke using FXML. + */ +public class Main extends Application { + + private Duke duke; + private ScrollPane scrollPane; + private VBox dialogContainer; + private TextField userInput; + private Button sendButton; + private Scene scene; + private Text textArea; + + @Override + public void start(Stage stage) { + duke = new Duke(); + + + scrollPane = new ScrollPane(); + dialogContainer = new VBox(); + scrollPane.setContent(dialogContainer); + + userInput = new TextField(); + textArea = new Text(); + sendButton = new Button("Send"); + + scrollPane.setContent(textArea); + + AnchorPane mainLayout = new AnchorPane(); + mainLayout.getChildren().addAll(scrollPane, userInput, sendButton); + + scene = new Scene(mainLayout); + + + stage.setScene(scene); + stage.show(); + + stage.setTitle("Duke"); + stage.setResizable(false); + stage.setMinHeight(600.0); + stage.setMinWidth(400.0); + + mainLayout.setPrefSize(400.0, 600.0); + + scrollPane.setPrefSize(385, 535); + scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); + scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS); + + scrollPane.setVvalue(1.0); + scrollPane.setFitToWidth(true); + + // You will need to import `javafx.scene.layout.Region` for this. + dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE); + + userInput.setPrefWidth(325.0); + + sendButton.setPrefWidth(55.0); + + AnchorPane.setTopAnchor(scrollPane, 1.0); + + AnchorPane.setBottomAnchor(sendButton, 1.0); + AnchorPane.setRightAnchor(sendButton, 1.0); + + AnchorPane.setLeftAnchor(userInput , 1.0); + AnchorPane.setBottomAnchor(userInput, 1.0); + + sendButton.setOnMouseClicked(e -> { + String input = userInput.getText(); + String response = ""; + + if (input.trim().equals("bye")) { + response = PrintType.BYE_LINE.getPrintType(); + Platform.exit(); + } else { + CommandResult commandResult = duke.getResponse(input); + response = commandResult.getFeedbackMessage(); + } + textArea.setText(response); + userInput.clear(); + }); + + + } + + +} \ No newline at end of file diff --git a/src/main/java/duke/InputType.java b/src/main/java/duke/InputType.java new file mode 100644 index 0000000000..e70d1fcce5 --- /dev/null +++ b/src/main/java/duke/InputType.java @@ -0,0 +1,26 @@ +package duke; + +public enum InputType { + + BYE("bye"), + LIST("list"), + TODO("todo"), + DEADLINE("deadline"), + EVENT("event"), + DELETE("delete"), + FIND("find"), + HIGH("high"), + DONE("done"); + + public final String str; + + InputType(String str) { + this.str = str; + } + + public String getInputType() { + return str; + } + + +} diff --git a/src/main/java/duke/Parser.java b/src/main/java/duke/Parser.java new file mode 100644 index 0000000000..312c534bd9 --- /dev/null +++ b/src/main/java/duke/Parser.java @@ -0,0 +1,52 @@ +package duke; + +import duke.tasks.TaskManager; +import duke.tasks.TaskType; +import duke.command.*; + +public class Parser { + + + public Parser(){ + } + + + // Reads the input of the line to determine the command and run it + public Command parseCommand(TaskManager taskList, String userInput){ + + // Get command from the userInput + final String[] splitLine = userInput.split(" ", 3); + final String command = splitLine[0]; + + // Remove command from userInput + final String arguments = userInput.replaceAll( RegexType.START_LINE_REGEX.getRegexType() + command + RegexType.SPACE_REGEX.getRegexType(), ""); + + // Check the command type then execute the commands + if(arguments.equals(InputType.LIST.getInputType())) { + return new ListCommand(taskList); + } + + if (command.equals(InputType.TODO.getInputType())){ + return new AddCommand(taskList, arguments, TaskType.TODO); + } + if (command.equals(InputType.DEADLINE.getInputType())){ + return new AddCommand(taskList, arguments, TaskType.DEADLINE); + } + if (command.equals(InputType.EVENT.getInputType())){ + return new AddCommand(taskList, arguments, TaskType.EVENT); + } + if (command.equals(InputType.DELETE.getInputType()) ){ + return new DeleteCommand(taskList, arguments); + } + if (command.equals(InputType.DONE.getInputType()) ) { + return new MarkAsDoneCommand(taskList, arguments); + } + if(command.equals(InputType.HIGH.getInputType())) { + return new PriorityCommand(taskList, arguments); + } + if (command.equals(InputType.FIND.getInputType())) { + return new FindCommand(taskList, arguments); + } + return new EmptyCommand(taskList); + } +} \ No newline at end of file diff --git a/src/main/java/duke/PrintType.java b/src/main/java/duke/PrintType.java new file mode 100644 index 0000000000..1ed36d0168 --- /dev/null +++ b/src/main/java/duke/PrintType.java @@ -0,0 +1,24 @@ +package duke; + +public enum PrintType { + GREETING_LINES("Hello! I'm Duke\nWhat can I do for you?"), + BYE_LINE("Bye. Hope to see you again soon!"), + TASK_ADDED_LINE("Got it. I've added this task:"), + TASK_DONE_LINE("Nice! I've marked this task as done: "), + TASK_SET_PRIORITY_HIGH("I've given HIGH priority to this task"), + TASK_DELETED_LINE("Noted. I've removed this task:"), + LIST_INTRO_LINE("Here are the tasks in your list"), + NOT_RECOGNISED_LINE(":( Oh no! Command not recognized"), + FIND_INTRO_LINE("Here are the matching tasks in your list:"); + + public final String str; + + PrintType(String str) { + this.str = str; + } + + public String getPrintType() { + return str; + } + +} diff --git a/src/main/java/duke/RegexType.java b/src/main/java/duke/RegexType.java new file mode 100644 index 0000000000..ee89a17364 --- /dev/null +++ b/src/main/java/duke/RegexType.java @@ -0,0 +1,28 @@ +package duke; + +public enum RegexType { + GET_DESCRIPTION_REGEX("/.+"), + GET_AT_REGEX(".+/at "), + GET_BY_REGEX(".+/by "), + SPACE_REGEX("\\s"), + START_LINE_REGEX("^"), + DIGITS_REGEX("\\d+"), + DEADLINE_REGEX(".+/by.+"), + TASK_ADDED_LINE("Got it. I've added this task:"), + SPLIT_REGEX("\\s\\|\\s"), + TODO_REGEX("T\\s\\|\\s[01]\\s\\|\\s[01]\\s\\|.+"), + EVENT_DEADLINE_REGEX("[ED]\\s\\|\\s[01]\\s\\|\\s[01]\\s\\|.+\\|.+"), + EVENT_REGEX(".+/at.+"); + + + public final String str; + + RegexType(String str) { + this.str = str; + } + + public String getRegexType() { + return str; + } + +} \ No newline at end of file diff --git a/src/main/java/duke/Storage.java b/src/main/java/duke/Storage.java new file mode 100644 index 0000000000..b54441e672 --- /dev/null +++ b/src/main/java/duke/Storage.java @@ -0,0 +1,147 @@ +package duke; + +import duke.tasks.*; +import duke.exceptions.FileFormatException; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Scanner; + + +/** + * Class to facilitate the storing of tasks + */ +public class Storage { + + private final String filePath; + private final File f; + + /** + * Constructor for the storage class + * @param filePath - refers to the path where the data has been stored + */ + public Storage(String filePath) { + this.filePath = filePath; + this.f = new File(filePath); + } + + + /** + * To load the existing data of tasks from the hard disk + * @param taskList - the list of tasks + * @throws FileNotFoundException - the file does not exist + * @throws FileFormatException - incorrect format + */ + public void loadData(TaskManager taskList) + throws FileNotFoundException, FileFormatException { + + assert taskList != null : "Tasklist is empty and has not been initialized"; + + Scanner s = new Scanner(f); + while (s.hasNext()){ + String entry = s.nextLine(); + + // Check if entry is in the correct format + if(!entry.matches(RegexType.TODO_REGEX.getRegexType()) + && !entry.matches(RegexType.EVENT_DEADLINE_REGEX.getRegexType())) { + throw new FileFormatException("File formatting error"); + } + + String[] entrySplit= entry.split(RegexType.SPLIT_REGEX.getRegexType()); + String taskType = entrySplit[0]; + boolean isDone = entrySplit[1].equals("1"); + boolean isHighOrLow = entrySplit[2].equals("1"); + String description = entrySplit[3]; + String atBy = entrySplit.length >= 5 ? entrySplit[4] : ""; + + + switch (taskType) { + case "T": + taskList.tasks.add(new Todo(description, isDone, isHighOrLow)); + + break; + case "D": + taskList.tasks.add(new Deadline(description, atBy, isDone, isHighOrLow)); + + break; + case "E": + taskList.tasks.add(new Event(description, atBy, isDone, isHighOrLow)); + + break; + } + } + } + + /** + * Creates a new File + * @throws IOException - Standard Input Output Exception + */ + public void createFile() throws IOException { + Path pathToFile = Paths.get(filePath); + Files.createDirectories(pathToFile.getParent()); + f.createNewFile(); + } + + /** + * Initialises the task list + * @return - Returns the taskList with a message + */ + public TaskManagerUi initialiseTaskList(){ + TaskManager taskList = new TaskManager(); + String message = ""; + + try { + loadData(taskList); + } catch (FileNotFoundException e){ + message = message + "File not found"; + try { + createFile(); + message = message + "\n" + "New file data/duke.txt created"; + + } catch (IOException e1){ + message = message + "\n" + "Error creating new file"; + } + + } catch (FileFormatException e){ + message = message + "\n" + "File formatting error"; + taskList.clearList(); + } + + return new TaskManagerUi(taskList, message); + } + + /** + * Writes data into the file that stores the list of tasks. + * the taskList argument must specify the list of tasks. + * @param taskList - the list of tasks + * @throws IOException - Standard Input Output Exception + */ + private void _writeToFile(TaskManager taskList) throws IOException{ + FileWriter fw = new FileWriter(f); + for (Task task : taskList.tasks){ + fw.write(task.saveTask() + "\n"); + } + fw.close(); + } + + /** + * Writes data into the file that stores the list of tasks. + * the taskList argument must specify the list of tasks. + * @param taskList - the list of tasks + * @return - empty String + */ + public String writeToFile(TaskManager taskList){ + try { + _writeToFile(taskList); + } catch (IOException e) { + return "Error writing to file"; + } + + return ""; + } +} \ No newline at end of file diff --git a/src/main/java/duke/Ui.java b/src/main/java/duke/Ui.java new file mode 100644 index 0000000000..2d200037f0 --- /dev/null +++ b/src/main/java/duke/Ui.java @@ -0,0 +1,37 @@ +package duke; + +public class Ui { + + // Prints a horizontal dash line + public void printDashLine(){ + System.out.println("--------------------------------" + + "---------------------------------------"); + } + + public void printOneLine(String line){ + if (line.isEmpty()){ + return; + } + printDashLine(); + System.out.println(line); + printDashLine(); + } + + public void printPrompt(){ + System.out.print(" ---> "); + } + + // Prints the greet statement + public void printGreeting(){ + printOneLine(PrintType.GREETING_LINES.getPrintType()); + } + + // Prints the exit statement + public void printExitLine() { + printOneLine(PrintType.BYE_LINE.getPrintType()); + } + + public void printMessage(String message) { + printOneLine(message); + } +} \ No newline at end of file diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java new file mode 100644 index 0000000000..06f8787a09 --- /dev/null +++ b/src/main/java/duke/command/AddCommand.java @@ -0,0 +1,32 @@ +package duke.command; + +import duke.tasks.TaskManager; +import duke.tasks.TaskType; + +public class AddCommand extends Command{ + public TaskType type; + + + public AddCommand(TaskManager taskList, String arguments, TaskType type){ + super(taskList, arguments); + this.type = type; + } + + @Override + public CommandResult execute() throws Exception { + + String message = ""; + + if (type == TaskType.TODO) { + message = taskList.addTodo(arguments); + + } else if (type == TaskType.DEADLINE) { + message = taskList.addDeadline(arguments); + + } else if (type == TaskType.EVENT) { + message = taskList.addEvent(arguments); + } + + return new CommandResult(message, true, taskList); + } +} diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java new file mode 100644 index 0000000000..77fb4f1f27 --- /dev/null +++ b/src/main/java/duke/command/Command.java @@ -0,0 +1,16 @@ +package duke.command; + +import duke.tasks.TaskManager; + +public abstract class Command { + protected TaskManager taskList; + protected String arguments; + + protected Command(TaskManager taskList, String arguments){ + this.taskList = taskList; + this.arguments = arguments; + } + + public abstract CommandResult execute() throws Exception; + +} \ No newline at end of file diff --git a/src/main/java/duke/command/CommandResult.java b/src/main/java/duke/command/CommandResult.java new file mode 100644 index 0000000000..97f1abd2d9 --- /dev/null +++ b/src/main/java/duke/command/CommandResult.java @@ -0,0 +1,33 @@ +package duke.command; + +import duke.tasks.TaskManager; + +public class CommandResult { + private String feedbackMessage; + private TaskManager taskList; + private boolean updated; + + public CommandResult(String feedbackMessage, boolean updated){ + this.updated = updated; + this.feedbackMessage = feedbackMessage; + taskList = null; + } + + public CommandResult(String feedbackMessage, boolean updated, TaskManager taskList){ + this.updated = updated; + this.feedbackMessage = feedbackMessage; + this.taskList = taskList; + } + + public String getFeedbackMessage(){ + return feedbackMessage; + } + + public boolean isUpdated(){ + return updated; + } + + public TaskManager getTaskList(){ + return taskList; + } +} \ No newline at end of file diff --git a/src/main/java/duke/command/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java new file mode 100644 index 0000000000..c00d30c970 --- /dev/null +++ b/src/main/java/duke/command/DeleteCommand.java @@ -0,0 +1,17 @@ +package duke.command; + +import duke.tasks.TaskManager; + +public class DeleteCommand extends Command{ + + public DeleteCommand(TaskManager taskList, String arguments){ + super(taskList, arguments); + } + + @Override + public CommandResult execute() throws Exception{ + String message = taskList.deleteTask(arguments); + + return new CommandResult(message,true, taskList); + } +} \ No newline at end of file diff --git a/src/main/java/duke/command/EmptyCommand.java b/src/main/java/duke/command/EmptyCommand.java new file mode 100644 index 0000000000..99cf487410 --- /dev/null +++ b/src/main/java/duke/command/EmptyCommand.java @@ -0,0 +1,16 @@ +package duke.command; + +import duke.PrintType; +import duke.tasks.TaskManager; + +public class EmptyCommand extends Command{ + + public EmptyCommand(TaskManager taskList) { + super(taskList, ""); + } + + @Override + public CommandResult execute() throws Exception { + return new CommandResult(PrintType.NOT_RECOGNISED_LINE.getPrintType(), false, taskList); + } +} diff --git a/src/main/java/duke/command/FindCommand.java b/src/main/java/duke/command/FindCommand.java new file mode 100644 index 0000000000..19144ecf1f --- /dev/null +++ b/src/main/java/duke/command/FindCommand.java @@ -0,0 +1,18 @@ +package duke.command; + +import duke.tasks.TaskManager; + +public class FindCommand extends Command{ + public FindCommand(TaskManager taskList, String arguments){ + super(taskList, arguments); + } + + @Override + public CommandResult execute() throws Exception{ + String message = taskList.findTask(arguments); + + return new CommandResult(message, false); + } + + +} diff --git a/src/main/java/duke/command/ListCommand.java b/src/main/java/duke/command/ListCommand.java new file mode 100644 index 0000000000..ad5ad6125e --- /dev/null +++ b/src/main/java/duke/command/ListCommand.java @@ -0,0 +1,16 @@ +package duke.command; + +import duke.tasks.TaskManager; + +public class ListCommand extends Command{ + + public ListCommand(TaskManager taskList){ + super(taskList, ""); + } + + public CommandResult execute() throws Exception{ + String message = taskList.getList(); + + return new CommandResult(message, false); + } +} \ No newline at end of file diff --git a/src/main/java/duke/command/MarkAsDoneCommand.java b/src/main/java/duke/command/MarkAsDoneCommand.java new file mode 100644 index 0000000000..6f38215a8b --- /dev/null +++ b/src/main/java/duke/command/MarkAsDoneCommand.java @@ -0,0 +1,17 @@ +package duke.command; + +import duke.tasks.TaskManager; + +public class MarkAsDoneCommand extends Command { + + public MarkAsDoneCommand(TaskManager taskList, String arguments){ + super(taskList, arguments); + } + + @Override + public CommandResult execute() throws Exception{ + String message = taskList.markAsDone(arguments); + + return new CommandResult(message, true, taskList); + } +} \ No newline at end of file diff --git a/src/main/java/duke/command/PriorityCommand.java b/src/main/java/duke/command/PriorityCommand.java new file mode 100644 index 0000000000..39aea7c0c8 --- /dev/null +++ b/src/main/java/duke/command/PriorityCommand.java @@ -0,0 +1,17 @@ +package duke.command; + +import duke.tasks.TaskManager; + +public class PriorityCommand extends Command { + + public PriorityCommand(TaskManager taskList, String arguments){ + super(taskList, arguments); + } + + @Override + public CommandResult execute() throws Exception{ + String message = taskList.markAsHigh(arguments); + + return new CommandResult(message, true, taskList); + } +} \ No newline at end of file diff --git a/src/main/java/duke/exceptions/DeadlineException.java b/src/main/java/duke/exceptions/DeadlineException.java new file mode 100644 index 0000000000..993fdb3dd6 --- /dev/null +++ b/src/main/java/duke/exceptions/DeadlineException.java @@ -0,0 +1,4 @@ +package duke.exceptions; + +public class DeadlineException extends Exception{ +} diff --git a/src/main/java/duke/exceptions/DeleteFormatException.java b/src/main/java/duke/exceptions/DeleteFormatException.java new file mode 100644 index 0000000000..037d0a44c2 --- /dev/null +++ b/src/main/java/duke/exceptions/DeleteFormatException.java @@ -0,0 +1,4 @@ +package duke.exceptions; + +public class DeleteFormatException extends Exception{ +} diff --git a/src/main/java/duke/exceptions/DeleteRangeException.java b/src/main/java/duke/exceptions/DeleteRangeException.java new file mode 100644 index 0000000000..54489b49d9 --- /dev/null +++ b/src/main/java/duke/exceptions/DeleteRangeException.java @@ -0,0 +1,5 @@ +package duke.exceptions; + +public class DeleteRangeException extends Exception{ + +} diff --git a/src/main/java/duke/exceptions/DoneAlreadyException.java b/src/main/java/duke/exceptions/DoneAlreadyException.java new file mode 100644 index 0000000000..76db8db0e2 --- /dev/null +++ b/src/main/java/duke/exceptions/DoneAlreadyException.java @@ -0,0 +1,4 @@ +package duke.exceptions; + +public class DoneAlreadyException extends Exception{ +} diff --git a/src/main/java/duke/exceptions/DoneFormatException.java b/src/main/java/duke/exceptions/DoneFormatException.java new file mode 100644 index 0000000000..0593734732 --- /dev/null +++ b/src/main/java/duke/exceptions/DoneFormatException.java @@ -0,0 +1,4 @@ +package duke.exceptions; + +public class DoneFormatException extends Exception{ +} diff --git a/src/main/java/duke/exceptions/DoneRangeException.java b/src/main/java/duke/exceptions/DoneRangeException.java new file mode 100644 index 0000000000..f71b25501c --- /dev/null +++ b/src/main/java/duke/exceptions/DoneRangeException.java @@ -0,0 +1,4 @@ +package duke.exceptions; + +public class DoneRangeException extends Exception{ +} diff --git a/src/main/java/duke/exceptions/DukeException.java b/src/main/java/duke/exceptions/DukeException.java new file mode 100644 index 0000000000..4b079b86bc --- /dev/null +++ b/src/main/java/duke/exceptions/DukeException.java @@ -0,0 +1,12 @@ +package duke.exceptions; + +public class DukeException extends Exception{ + public DukeException(String message) { + super(message); + } + + @Override + public String getMessage() { + return super.getMessage(); + } +} diff --git a/src/main/java/duke/exceptions/EmptyListException.java b/src/main/java/duke/exceptions/EmptyListException.java new file mode 100644 index 0000000000..e7acc22c24 --- /dev/null +++ b/src/main/java/duke/exceptions/EmptyListException.java @@ -0,0 +1,11 @@ +package duke.exceptions; + +public class EmptyListException extends Exception { + public final String EMPTY_LIST_LINE = + ":( Oh no! List is empty."; + + @Override + public String getMessage(){ + return EMPTY_LIST_LINE; + } +} diff --git a/src/main/java/duke/exceptions/EventException.java b/src/main/java/duke/exceptions/EventException.java new file mode 100644 index 0000000000..706aa06052 --- /dev/null +++ b/src/main/java/duke/exceptions/EventException.java @@ -0,0 +1,4 @@ +package duke.exceptions; + +public class EventException extends Exception{ +} diff --git a/src/main/java/duke/exceptions/FileFormatException.java b/src/main/java/duke/exceptions/FileFormatException.java new file mode 100644 index 0000000000..e71b6c8f13 --- /dev/null +++ b/src/main/java/duke/exceptions/FileFormatException.java @@ -0,0 +1,12 @@ +package duke.exceptions; + +public class FileFormatException extends Exception{ + public FileFormatException(String message) { + super(message); + } + + @Override + public String getMessage() { + return super.getMessage(); + } +} diff --git a/src/main/java/duke/exceptions/NoGoodByeException.java b/src/main/java/duke/exceptions/NoGoodByeException.java new file mode 100644 index 0000000000..9accfcb23c --- /dev/null +++ b/src/main/java/duke/exceptions/NoGoodByeException.java @@ -0,0 +1,4 @@ +package duke.exceptions; + +public class NoGoodByeException extends Exception{ +} diff --git a/src/main/java/duke/exceptions/NotFoundException.java b/src/main/java/duke/exceptions/NotFoundException.java new file mode 100644 index 0000000000..2ff45da47f --- /dev/null +++ b/src/main/java/duke/exceptions/NotFoundException.java @@ -0,0 +1,11 @@ +package duke.exceptions; + +public class NotFoundException extends Exception{ + public final String NOT_FOUND_LINE = + "No similar tasks can be found"; + + @Override + public String getMessage(){ + return NOT_FOUND_LINE; + } +} diff --git a/src/main/java/duke/exceptions/NothingException.java b/src/main/java/duke/exceptions/NothingException.java new file mode 100644 index 0000000000..a8b3a88dad --- /dev/null +++ b/src/main/java/duke/exceptions/NothingException.java @@ -0,0 +1,4 @@ +package duke.exceptions; + +public class NothingException extends Exception{ +} diff --git a/src/main/java/duke/exceptions/TodoException.java b/src/main/java/duke/exceptions/TodoException.java new file mode 100644 index 0000000000..22b1b7586f --- /dev/null +++ b/src/main/java/duke/exceptions/TodoException.java @@ -0,0 +1,4 @@ +package duke.exceptions; + +public class TodoException extends Exception{ +} diff --git a/src/main/java/duke/tasks/Deadline.java b/src/main/java/duke/tasks/Deadline.java new file mode 100644 index 0000000000..8e2c62f6fc --- /dev/null +++ b/src/main/java/duke/tasks/Deadline.java @@ -0,0 +1,45 @@ +package duke.tasks; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + + +/** + * Encapsulates a Deadline type task + */ +public class Deadline extends Task { + private TaskType type = TaskType.DEADLINE; + private LocalDateTime timeBy; + + /** + * Creates a new Deadline task with a description and deadline time. + * @param description - the description of the task + * @param timeBy - the deadline time for the task + */ + public Deadline (String description, String timeBy){ + super(description); + this.timeBy = LocalDateTime.parse(timeBy, DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm")); + } + + /** + * Creates a new Deadline task with a description, deadline time and isDone + * @param description - the description of the task + * @param timeBy - the deadline time for the task + * @param isDone - determines if the task has been completed or not + */ + public Deadline (String description, String timeBy, boolean isDone, boolean isHighOrLow) { + super(description, isDone, isHighOrLow); + this.timeBy = LocalDateTime.parse(timeBy, DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm")); + } + + @Override + public String showTask(){ + return "[D][" + (isDone ? "✗" : " ") + "] " + "["+ (isHighOrLow ? "High" : "Low") + " ] " + description + " (by: " + timeBy.format(DateTimeFormatter.ofPattern("MMM dd yyyy, HH:mm")) + ")"; + } + + @Override + public String saveTask() { + return "D | " + (isDone ? 1 : 0) + " | " + (isHighOrLow ? 1 : 0) + " | " + description + " | " + timeBy.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm")); + } + +} diff --git a/src/main/java/duke/tasks/Event.java b/src/main/java/duke/tasks/Event.java new file mode 100644 index 0000000000..1d7463826f --- /dev/null +++ b/src/main/java/duke/tasks/Event.java @@ -0,0 +1,43 @@ +package duke.tasks; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Encapsulates a Event type task + */ +public class Event extends Task { + private TaskType type = TaskType.EVENT; + private LocalDateTime timeAt; + + /** + * Creates a new Event task with description and time of the task + * @param description - the description of the task + * @param timeAt - the event time + */ + public Event (String description, String timeAt){ + super(description); + this.timeAt = LocalDateTime.parse(timeAt, DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm")); + } + + /** + * Creates a new Event task with description, time of the task and isDone + * @param description - the description of the task + * @param timeAt - the event time + * @param isDone - determines if the task has been completed or not + */ + public Event (String description, String timeAt, boolean isDone, boolean isHighOrLow) { + super(description, isDone, isHighOrLow); + this.timeAt = LocalDateTime.parse(timeAt, DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm")); + } + + @Override + public String showTask() { + return "[E][" + (isDone ? "✗" : " ") + "] " + "["+ (isHighOrLow ? "High" : "Low") + " ] " + description + " (at: " + timeAt.format(DateTimeFormatter.ofPattern("MMM dd yyyy, HH:mm")) + ")"; + } + + @Override + public String saveTask() { + return "E | " + (isDone ? 1 : 0) + " | " + (isHighOrLow ? 1 : 0) + " | " + description + " | " + timeAt.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm")); + } +} \ No newline at end of file diff --git a/src/main/java/duke/tasks/Task.java b/src/main/java/duke/tasks/Task.java new file mode 100644 index 0000000000..4d7726cd07 --- /dev/null +++ b/src/main/java/duke/tasks/Task.java @@ -0,0 +1,50 @@ +package duke.tasks; + +public abstract class Task { + protected final String description; + protected boolean isDone; + protected boolean isHighOrLow; + + public Task(String description) { + this.description = description; + this.isDone = false; + this.isHighOrLow = false; + } + + public Task(String description, boolean isDone) { + this.description = description; + this.isDone = isDone; + this.isHighOrLow = false; + } + + public Task(String description, boolean isDone, boolean isHighOrLow) { + this.description = description; + this.isDone = isDone; + this.isHighOrLow = isHighOrLow; + } + + + public String getDescription() { + return description; + } + + public boolean isDone() { + return isDone; + } + + public void markAsDone() { + isDone = true; + } + + public boolean isHighOrLow() { + return isHighOrLow; + } + + public void markAsHigh() { + isHighOrLow = true; + } + + public abstract String showTask(); + + public abstract String saveTask(); +} \ No newline at end of file diff --git a/src/main/java/duke/tasks/TaskManager.java b/src/main/java/duke/tasks/TaskManager.java new file mode 100644 index 0000000000..d45163d32b --- /dev/null +++ b/src/main/java/duke/tasks/TaskManager.java @@ -0,0 +1,243 @@ +package duke.tasks; + +import duke.PrintType; +import duke.RegexType; +import duke.exceptions.*; + +import java.util.ArrayList; + +/** + * Manages all the operations on list of tasks. Central class to manage tasks + */ +public class TaskManager { + public ArrayList tasks = new ArrayList<>(); + + /** + * Prints the current status of the task + * + * @param line - the message to be displayed + * @param index - the index of the task in the taskList + * @return - the message to be displayed in the String form along with the index of the task + */ + public String getAcknowledgement(String line, int index) { + assert ((index >=0) && (index < tasks.size())) : "Index out of limit (0 - Size)"; + return line + "\n " + tasks.get(index).showTask(); + } + + /** + * To get the number of the tasks in the taskList + * + * @return - it returns the number of tasks in String form + */ + public String getNumOfTask() { + return "Now you have " + tasks.size() + " tasks in the list"; + } + + /** + * Gives the list of tasks + * + * @return - list of tasks in the String form + * @throws EmptyListException - when the size of the taskList is zero + */ + public String getList() throws EmptyListException { + if (tasks.size() == 0) { + throw new EmptyListException(); + } + StringBuilder fullList = new StringBuilder(PrintType.LIST_INTRO_LINE.getPrintType()); + + // Add each item to listLines + for (int i = 1; i <= tasks.size(); ++i) { + fullList.append("\n").append(i).append(". ").append(tasks.get(i - 1).showTask()); + } + + return fullList.toString(); + } + + /** + * Adds the Todo task to the taskList + * + * @param userInput - the user input for the todo task + * @return - the message of acknowledgement in String form + * @throws TodoException - if the description is empty + */ + public String addTodo(String userInput) throws TodoException { + + if (userInput.equals("todo") || userInput.equals("")) { + throw new TodoException(); + } + // Create new duke.tasks.Todo instance an add it to end taskList + tasks.add(new Todo(userInput)); + + return getAcknowledgement(PrintType.TASK_ADDED_LINE.getPrintType(), tasks.size() - 1) + + "\n" + getNumOfTask(); + } + + /** + * Adds the Deadline task to the list of tasks + * + * @param userInput - the user input for the deadline task + * @return - the message of acknowledgement in String form + * @throws DeadlineException - if the format is incorrect + */ + public String addDeadline(String userInput) throws DeadlineException { + // Check if line follows the format " /by