diff --git a/README.md b/README.md index 8715d4d91..014a6b49a 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Prerequisites: JDK 11, update Intellij to the most recent version. 1. If there are any further prompts, accept the defaults. 1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
In the same dialog, set the **Project language level** field to the `SDK default` option. -3. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: +3. After that, locate the `src/buddy.main/java/Duke.java` file, right-click it, and choose `Run Duke.buddy.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: ``` Hello from ____ _ diff --git a/docs/README.md b/docs/README.md index 8077118eb..01aa113bd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,29 +1,104 @@ # User Guide +Buddy is a very helpful tool in helping you manage your daily tasks +and helping you be more organised. It also helps you improve your day to day productivity! +Get immersed in this cli-optimised application! + ## Features -### Feature-ABC +### Add tasks to your task list +Add various types of tasks - todo, deadline and event. -Description of the feature. +### Delete tasks from your task list +Delete tasks from the list. -### Feature-XYZ +### Keep track of the progress of your tasks +Mark/Unmark tasks from the list to keep track of what you have completed. -Description of the feature. +### Find tasks in your task list +Find tasks that match a keyword ## Usage -### `Keyword` - Describe action +### `todo` - Adds a Todo task + +Format: `todo ` + +- Adds a todo with `` +- `` should not be empty + +Examples of usage: +- `todo cs2113 project` +- `todo cs2102 assignment` + +### `deadline` - Adds a Deadline task +Format: `deadline /by ` + +- Adds a task with a `` to be completed by `` +- Deadline date should be in `` format +- Deadline date cannot be before today's date +- Deadline date should not be empty + +Examples of usage: +- `deadline cs2113 ip /by 2023-03-03` +- `deadline cs1010 assignment /by 2024-04-04` + +### `event` - Adds a Event task +Format: `event /from /to ` + +- Adds a task with a `` with a start `` to end `` +- `` should not be empty +- `` and `` should not be empty + +Examples of usage: +- `event cs2113 exam /from 4pm /to 6pm` +- `event NUS Open House /from 24 Dec 2023 6am /to 6pm` + +### `mark` - Marks a task as done +Format: `mark ` + +- Marks a task as done +- `` should be within the task list + +Examples of usage: +- `mark 2` +- `mark 1` + +### `unmark` - Marks a task as not done +Format: `unmark ` + +- Marks a task as not done +- `` should be within the task list + +Examples of usage: +- `unmark 2` +- `unmark 4` + +### `delete` - Deletes a task from the task list +Format: `delete ` + +- Deletes a task +- `` should be within the task list + +Examples of usage: +- `delete 2` +- `delete 1` + +### `find` - Finds a task by keyword +Format: `find ` -Describe the action and its outcome. +- Finds matching tasks +- `` should be one word -Example of usage: +Examples of usage: +- `find cs2113` +- `find todo` -`keyword (optional arguments)` +### `bye` - Exits the program +Format: `bye` -Expected outcome: +- Exits the program. -Description of the outcome. +### HOW DO I SAVE MY TASK LIST? -``` -expected output -``` +- The program auto saves your task list and loads it when you run the program! \ No newline at end of file diff --git a/src/main/.idea/.gitignore b/src/main/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/src/main/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/src/main/.idea/misc.xml b/src/main/.idea/misc.xml new file mode 100644 index 000000000..639900d13 --- /dev/null +++ b/src/main/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/.idea/modules.xml b/src/main/.idea/modules.xml new file mode 100644 index 000000000..122a9054e --- /dev/null +++ b/src/main/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/.idea/vcs.xml b/src/main/.idea/vcs.xml new file mode 100644 index 000000000..b2bdec2d7 --- /dev/null +++ b/src/main/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334c..000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..c6d2c7caa --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: buddy.Buddy + diff --git a/src/main/java/buddy/Buddy.java b/src/main/java/buddy/Buddy.java new file mode 100644 index 000000000..cab52f7fd --- /dev/null +++ b/src/main/java/buddy/Buddy.java @@ -0,0 +1,52 @@ +package buddy; + +import java.util.Scanner; + +import buddy.parser.Parser; +import buddy.storage.Storage; +import buddy.tasks.TaskList; +import buddy.ui.Ui; + +/** + * The part which executes the entire program + */ +public class Buddy { + private final Storage storage; + private static TaskList taskList; + private final Ui ui; + public static int taskCount = 0; + + /** + * Constructor for Buddy class + * + * @param filePath The filepath of the file + */ + public Buddy(String filePath) { + taskList = new TaskList(); + storage = new Storage(filePath); + ui = new Ui(); + } + + /** + * This function runs the program till completion (till a "bye" is inputted) + */ + public void run() { + ui.loadFileOrCreateFile(taskList, storage); + ui.greetUser(); + String input; + Scanner in = new Scanner(System.in); + input = in.nextLine(); + Parser processAllCommands = new Parser(); + + while (!processAllCommands.isExit(input)) { + processAllCommands.executeInput(taskList, input, storage); + input = in.nextLine(); + } + ui.sayByeToUser(); + } + + + public static void main(String[] args) { + new Buddy("./Data").run(); + } +} diff --git a/src/main/java/buddy/commands/Command.java b/src/main/java/buddy/commands/Command.java new file mode 100644 index 000000000..7419249e4 --- /dev/null +++ b/src/main/java/buddy/commands/Command.java @@ -0,0 +1,17 @@ +package buddy.commands; + +import buddy.exceptions.InvalidCommandException; +import buddy.tasks.TaskList; + +/** + * Constructor for Command class + */ +public abstract class Command { + /** + * Executes the commands by the user for all the different types of commands - actionCommands and addTaskCommands + * + * @param taskList List of tasks + * @param input Command inputted by the user + */ + public abstract void executeCommand(TaskList taskList, String input) throws InvalidCommandException; +} diff --git a/src/main/java/buddy/commands/actionCommands/DeleteTaskCommand.java b/src/main/java/buddy/commands/actionCommands/DeleteTaskCommand.java new file mode 100644 index 000000000..9bf74d04b --- /dev/null +++ b/src/main/java/buddy/commands/actionCommands/DeleteTaskCommand.java @@ -0,0 +1,29 @@ +package buddy.commands.actionCommands; + +import buddy.commands.Command; +import buddy.messages.Messages; +import buddy.tasks.TaskList; + + +public class DeleteTaskCommand extends Command { + + /** + * Process DeleteTaskCommand by user and deletes task from task list + * + * @param taskList List of tasks + * @param input Command inputted by user + */ + @Override + public void executeCommand(TaskList taskList, String input) { + try { + String[] deleteSplit = input.split(" ", 2); + int taskNumberToBeDeleted = Integer.parseInt(deleteSplit[1]); + int indexOfTaskInTaskList = taskNumberToBeDeleted - 1; + taskList.deleteTask(indexOfTaskInTaskList); + + } catch (IndexOutOfBoundsException e) { + System.out.println("That is not a valid task to delete! Please check your list again and input a valid task"); + System.out.println(Messages.DIVIDER); + } + } +} diff --git a/src/main/java/buddy/commands/actionCommands/FindTaskCommand.java b/src/main/java/buddy/commands/actionCommands/FindTaskCommand.java new file mode 100644 index 000000000..f33201056 --- /dev/null +++ b/src/main/java/buddy/commands/actionCommands/FindTaskCommand.java @@ -0,0 +1,43 @@ +package buddy.commands.actionCommands; + +import buddy.exceptions.InvalidCommandException; +import buddy.messages.Messages; +import buddy.commands.Command; +import buddy.tasks.TaskList; +import buddy.tasks.Task; + +import java.util.ArrayList; + +import static java.util.stream.Collectors.toList; + +public class FindTaskCommand extends Command { + + /** + * Process FindTaskCommand by user and finds and outputs the matching task to keyword + * If there are no matching tasks, tells user that there are none + * + * @param taskList List of tasks + * @param input Command inputted by user + */ + @Override + public void executeCommand(TaskList taskList, String input) throws InvalidCommandException { + if (input.equals("find")){ + throw new InvalidCommandException(); + } + String keyword = input.split(" ")[1].trim().toLowerCase(); + ArrayList matchedTasks; + matchedTasks = (ArrayList) taskList.stream() // casts list to ArrayList + .filter(t -> t.getTaskName().trim().toLowerCase().contains(keyword)).collect(toList()); + System.out.println(Messages.DIVIDER); + if (!matchedTasks.isEmpty()) { + System.out.println("Well, here is the list of tasks matching your keyword!"); + } + for (Task task : matchedTasks) { + System.out.println(task); + } + if (matchedTasks.isEmpty()) { + System.out.println("Oops, there are no tasks matching the keyword! Try again with another keyword"); + } + System.out.println(Messages.DIVIDER); + } +} diff --git a/src/main/java/buddy/commands/actionCommands/HelpCommand.java b/src/main/java/buddy/commands/actionCommands/HelpCommand.java new file mode 100644 index 000000000..475b89c5b --- /dev/null +++ b/src/main/java/buddy/commands/actionCommands/HelpCommand.java @@ -0,0 +1,21 @@ +package buddy.commands.actionCommands; + +import buddy.messages.Messages; +import buddy.ui.Ui; +import buddy.commands.Command; +import buddy.tasks.TaskList; + +public class HelpCommand extends Command { + /** + * Process HelpCommand by user and prints help message + * + * @param taskList List of tasks + * @param input Command inputted by user + */ + @Override + public void executeCommand(TaskList taskList, String input) { + System.out.println(Messages.DIVIDER); + Ui.displayHelpMessage(); + System.out.println(Messages.DIVIDER); + } +} diff --git a/src/main/java/buddy/commands/actionCommands/ListCommand.java b/src/main/java/buddy/commands/actionCommands/ListCommand.java new file mode 100644 index 000000000..3727f8fbb --- /dev/null +++ b/src/main/java/buddy/commands/actionCommands/ListCommand.java @@ -0,0 +1,32 @@ +package buddy.commands.actionCommands; + +import buddy.Buddy; +import buddy.messages.Messages; +import buddy.commands.Command; +import buddy.tasks.TaskList; + +public class ListCommand extends Command { + + /** + * Process ListCommand by user and prints out the list of tasks + * + * @param taskList List of tasks + * @param input Command inputted by user + */ + @Override + public void executeCommand(TaskList taskList, String input) { + System.out.println(Messages.DIVIDER); + if (!taskList.isEmpty()) { + System.out.println("Here is the list of tasks you have remaining! Come on Buddy!"); + } + int index = 1; // index which shows numbers the task + for (int i = 0; i < Buddy.taskCount; i++) { + System.out.println(index + "." + taskList.get(i)); + index++; // increment the number on the task + } + if (taskList.isEmpty()) { + System.out.println("There is nothing in the list! Please enter a new command"); + } + System.out.println(Messages.DIVIDER); + } +} diff --git a/src/main/java/buddy/commands/actionCommands/MarkTaskCommand.java b/src/main/java/buddy/commands/actionCommands/MarkTaskCommand.java new file mode 100644 index 000000000..fb961c824 --- /dev/null +++ b/src/main/java/buddy/commands/actionCommands/MarkTaskCommand.java @@ -0,0 +1,31 @@ +package buddy.commands.actionCommands; + +import buddy.commands.Command; +import buddy.messages.Messages; +import buddy.tasks.TaskList; +import buddy.tasks.Task; + +public class MarkTaskCommand extends Command { + + /** + * Process MarkTaskCommand by user and marks task as done + * + * @param taskList List of tasks + * @param input Command inputted by user + */ + @Override + public void executeCommand(TaskList taskList, String input) { + try { + String[] markSplit = input.split(" ", 2); + int taskNumberToBeMarked = Integer.parseInt(markSplit[1]); + int indexOfTaskToBeMarked = taskNumberToBeMarked - 1; + Task taskToBeMarked = taskList.get(indexOfTaskToBeMarked); + taskToBeMarked.markAsDone(); + + } catch (IndexOutOfBoundsException e) { + System.out.println(Messages.DIVIDER); + System.out.println("That is not a valid task to mark! Please check your list again and input a valid task"); + System.out.println(Messages.DIVIDER); + } + } +} diff --git a/src/main/java/buddy/commands/actionCommands/UnmarkTaskCommand.java b/src/main/java/buddy/commands/actionCommands/UnmarkTaskCommand.java new file mode 100644 index 000000000..e186978f7 --- /dev/null +++ b/src/main/java/buddy/commands/actionCommands/UnmarkTaskCommand.java @@ -0,0 +1,32 @@ +package buddy.commands.actionCommands; + +import buddy.commands.Command; +import buddy.messages.Messages; +import buddy.tasks.TaskList; +import buddy.tasks.Task; + +public class UnmarkTaskCommand extends Command { + + /** + * Processes UnmarkTaskCommand by marking the task as not done + * + * @param taskList List of tasks + * @param input Command inputted by user + */ + @Override + public void executeCommand(TaskList taskList, String input) { + try { + String[] unmarkSplit = input.split(" ", 2); + int taskNumberToBeUnmarked = Integer.parseInt(unmarkSplit[1]); + int indexOfTaskToBeUnmarked = taskNumberToBeUnmarked - 1; + Task taskToBeUnmarked = taskList.get(indexOfTaskToBeUnmarked); + taskToBeUnmarked.markAsUndone(); + + } catch (IndexOutOfBoundsException e) { + System.out.println(Messages.DIVIDER); + System.out.println("That is not a valid task to unmark! Please check your list again and input a valid task"); + System.out.println(Messages.DIVIDER); + } + + } +} \ No newline at end of file diff --git a/src/main/java/buddy/commands/addTaskCommands/AddDeadlineCommand.java b/src/main/java/buddy/commands/addTaskCommands/AddDeadlineCommand.java new file mode 100644 index 000000000..f4c9208f7 --- /dev/null +++ b/src/main/java/buddy/commands/addTaskCommands/AddDeadlineCommand.java @@ -0,0 +1,53 @@ +package buddy.commands.addTaskCommands; + +import buddy.exceptions.InvalidCommandException; +import buddy.commands.Command; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +import buddy.messages.Messages; +import buddy.tasks.TaskList; +import buddy.tasks.Deadline; + + +public class AddDeadlineCommand extends Command { + + /** + * Process Deadline command by user and adds deadline + * Throws exception if command is in wrong format + * + * @param taskList List of tasks + * @param input Command inputted by user + */ + @Override + public void executeCommand(TaskList taskList, String input) { + try { + if (!input.contains("/")){ + throw new InvalidCommandException(); + } + String[] deadlineSplit = input.split("/by", 2); + String deadlineBy = deadlineSplit[1].trim(); + LocalDate toFormat = LocalDate.parse(deadlineBy); + if (toFormat.isBefore(LocalDate.now())) { // if deadline date is before today's date, invalid task + throw new InvalidCommandException(); + } + String deadlineByFormatted = toFormat.format(DateTimeFormatter.ofPattern("MMM d yyyy")); // Deadline must be in this format + String[] deadlineAndName = deadlineSplit[0].split(" ", 2); + String deadlineName = deadlineAndName[1].trim(); + if (deadlineName.equals("") || deadlineName.equals(" ")) { + throw new InvalidCommandException(); // if no deadline description inputted, invalid task + } + Deadline deadlineBeingAdded = new Deadline(deadlineName, deadlineByFormatted); + taskList.addTask(deadlineBeingAdded); + + } catch (InvalidCommandException e) { + InvalidCommandException.printMessage(); + } catch (DateTimeParseException e) { + System.out.println(Messages.DIVIDER); + System.out.println("This is the wrong format of deadline date! Please input deadline where is in YYYY-MM-DD!"); + System.out.println(Messages.DIVIDER); + } + } +} \ No newline at end of file diff --git a/src/main/java/buddy/commands/addTaskCommands/AddEventCommand.java b/src/main/java/buddy/commands/addTaskCommands/AddEventCommand.java new file mode 100644 index 000000000..04a4d7be4 --- /dev/null +++ b/src/main/java/buddy/commands/addTaskCommands/AddEventCommand.java @@ -0,0 +1,42 @@ +package buddy.commands.addTaskCommands; + +import buddy.exceptions.InvalidCommandException; +import buddy.commands.Command; +import buddy.tasks.TaskList; +import buddy.tasks.Event; + + +public class AddEventCommand extends Command { + + /** + * Process Event command by user and adds event + * Throws exception if command is in wrong format + * + * @param taskList List of tasks + * @param input Command inputted by user + */ + @Override + public void executeCommand(TaskList taskList, String input) { + try { + if ( !(input.contains("/from") && input.contains("/to")) ){ + throw new InvalidCommandException(); + } + String[] eventSplit = input.split("/", 3); + String[] eventAndName = eventSplit[0].split(" ", '2'); + String eventName = eventAndName[1]; + String[] fromAndStart = eventSplit[1].split(" ", '2'); + String start = fromAndStart[1].trim(); + String[] toAndEnd = eventSplit[2].split(" ", '2'); + String end = toAndEnd[1].trim(); + if (eventName.equals("") || start.equals("") || end.equals("")) { + throw new InvalidCommandException(); + } + Event eventBeingAdded = new Event(eventName, start, end); + taskList.addTask(eventBeingAdded); + + } catch (InvalidCommandException e) { + InvalidCommandException.printMessage(); + } + + } +} diff --git a/src/main/java/buddy/commands/addTaskCommands/AddTodoCommand.java b/src/main/java/buddy/commands/addTaskCommands/AddTodoCommand.java new file mode 100644 index 000000000..a904e09ea --- /dev/null +++ b/src/main/java/buddy/commands/addTaskCommands/AddTodoCommand.java @@ -0,0 +1,34 @@ +package buddy.commands.addTaskCommands; + +import buddy.exceptions.InvalidCommandException; +import buddy.commands.Command; +import buddy.tasks.TaskList; +import buddy.tasks.Todo; + +public class AddTodoCommand extends Command { + + /** + * Process Todo command by user and adds todo + * Throws exception if command is in wrong format + * + * @param taskList List of tasks + * @param input Command inputted by user + */ + @Override + public void executeCommand(TaskList taskList, String input) { + try { + if (!input.contains(" ")){ + throw new InvalidCommandException(); + } + String[] todoSplit = input.split(" ", 2); + if (todoSplit[1].equals("")) { + throw new InvalidCommandException(); + } + Todo todoBeingAdded = new Todo(todoSplit[1]); + taskList.addTask(todoBeingAdded); + + } catch (InvalidCommandException e) { + InvalidCommandException.printMessage(); + } + } +} diff --git a/src/main/java/buddy/exceptions/InvalidCommandException.java b/src/main/java/buddy/exceptions/InvalidCommandException.java new file mode 100644 index 000000000..19651a826 --- /dev/null +++ b/src/main/java/buddy/exceptions/InvalidCommandException.java @@ -0,0 +1,15 @@ +package buddy.exceptions; + +import buddy.messages.Messages; + +/** + * Prints the error message when there is an invalid command inputted by the user + */ +public class InvalidCommandException extends Exception { + public static void printMessage() { + System.out.println(Messages.DIVIDER); + System.out.println("This is an invalid command! Please check and type in again"); + System.out.println(Messages.DIVIDER); + } + +} \ No newline at end of file diff --git a/src/main/java/buddy/messages/Messages.java b/src/main/java/buddy/messages/Messages.java new file mode 100644 index 000000000..fe72a2c5a --- /dev/null +++ b/src/main/java/buddy/messages/Messages.java @@ -0,0 +1,30 @@ +package buddy.messages; + +public class Messages { + public static final String DIVIDER = "___________________________________________________________________________________________________________________________________"; + public static final String GREETING = "Hello there! I'm Buddy\n" + + "How may I assist you?"; + public static final String INTRODUCTION = "Here are the possible commands: todo, deadline, event, list, mark, unmark, find, bye\n" + "Type if you are unsure of what these commands do!"; + public static final String EXITMESSAGE = "Hope I was of help to you! Have a great day and see you again, Buddy :)"; + public static final String HELPMESSAGE = + "These are the various commands and their functions. Please type in the FORMAT that is stated below\n" + + "There are 3 add task commands which add 3 kinds of tasks: todo, deadline and event\n" + + "todo: Adds a todo to your task list\n" + + "FORMAT: todo \n" + + "deadline: Adds a deadline to your task list\n" + + "FORMAT: deadline /by (where YYYY is year, MM is month and DD is day)\n" + + "event: Adds an event to your task list\n" + + "FORMAT: event /from /to \n" + + "There are 5 other action commands: list, mark, unmark, find and bye\n" + + "list: lists all the tasks that you have remaining\n" + + "FORMAT: list\n" + + "mark: marks a task as done with an X\n" + + "FORMAT: mark \n" + + "unmark: marks a task as not done\n" + + "FORMAT: unmark \n" + + "find: finds a task which contains the keyword that you typed\n" + + "FORMAT: find \n" + + "bye: exits the application\n" + + "FORMAT: bye\n" + + "Hope that this was useful!"; +} diff --git a/src/main/java/buddy/parser/Parser.java b/src/main/java/buddy/parser/Parser.java new file mode 100644 index 000000000..1aa599635 --- /dev/null +++ b/src/main/java/buddy/parser/Parser.java @@ -0,0 +1,101 @@ +package buddy.parser; + +import java.io.IOException; + +import buddy.commands.Command; +import buddy.commands.actionCommands.DeleteTaskCommand; +import buddy.commands.actionCommands.HelpCommand; +import buddy.commands.actionCommands.ListCommand; +import buddy.commands.actionCommands.MarkTaskCommand; +import buddy.commands.actionCommands.UnmarkTaskCommand; +import buddy.commands.actionCommands.FindTaskCommand; +import buddy.commands.addTaskCommands.AddTodoCommand; +import buddy.commands.addTaskCommands.AddDeadlineCommand; +import buddy.commands.addTaskCommands.AddEventCommand; +import buddy.exceptions.InvalidCommandException; +import buddy.storage.Storage; +import buddy.tasks.TaskList; + +public class Parser { + /** + * Tells if the program needs to exit + * + * @param input Command typed by the user + * @return true if the command is equals to "bye" else false + */ + public boolean isExit(String input) { + return input.equals("bye"); + } + + /** + * Executes the commands inputted by the user based on what the commands are + * + * @param taskList List of tasks + * @param input Command inputted by the user + * @param storage Storage object to save the task list + */ + public void executeInput(TaskList taskList, String input, Storage storage) { + String[] inputSplit = input.split(" ", 2); + String commandName = inputSplit[0].trim(); + try { + switch (commandName) { + case "todo": + Command addTodo = new AddTodoCommand(); + addTodo.executeCommand(taskList, input); + break; + + case "deadline": + Command addDeadline = new AddDeadlineCommand(); + addDeadline.executeCommand(taskList, input); + break; + + case "event": + Command addEvent = new AddEventCommand(); + addEvent.executeCommand(taskList, input); + break; + + case "list": + Command list = new ListCommand(); + list.executeCommand(taskList, input); + break; + + case "mark": + Command mark = new MarkTaskCommand(); + mark.executeCommand(taskList, input); + break; + + case "unmark": + Command unmark = new UnmarkTaskCommand(); + unmark.executeCommand(taskList, input); + break; + + case "delete": + Command delete = new DeleteTaskCommand(); + delete.executeCommand(taskList, input); + + break; + + case "find": + Command find = new FindTaskCommand(); + find.executeCommand(taskList, input); + break; + + case "help": + Command help = new HelpCommand(); + help.executeCommand(taskList, input); + break; + + default: + throw new InvalidCommandException(); + } + } catch (InvalidCommandException e) { + InvalidCommandException.printMessage(); + } + + try { + storage.updateFile(taskList); + } catch (IOException e) { + System.out.println("IO Error"); + } + } +} diff --git a/src/main/java/buddy/storage/Storage.java b/src/main/java/buddy/storage/Storage.java new file mode 100644 index 000000000..e0dde3655 --- /dev/null +++ b/src/main/java/buddy/storage/Storage.java @@ -0,0 +1,136 @@ +package buddy.storage; + +import buddy.Buddy; +import buddy.tasks.TaskList; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Scanner; + +import buddy.tasks.Task; +import buddy.tasks.Todo; +import buddy.tasks.Deadline; +import buddy.tasks.Event; + +public class Storage { + + private final String filePath; + + /** + * Constructor for Storage class + * + * @param filePath Path to the file where it is stored + */ + public Storage(String filePath) { + this.filePath = filePath; + } + + /** + * Creates a new directory and a new file if they don't exist + */ + public void createFile() { + File directory = new File(filePath); + File newFile = new File(filePath + "/BuddyTaskList.txt"); + + try { + if (directory.mkdirs()) { + System.out.println("Directory has been created :)"); + } + + if (newFile.createNewFile()) { + System.out.println("File has been created :)"); + } else { + System.out.println("File already exists"); + } + } catch (IOException e) { + System.out.println("An error occurred when creating the file :("); + e.printStackTrace(); + } + } + + /** + * Updates the file by overwriting it with the updated task list + * + * @param taskList List of tasks + * @throws IOException If there is an error with the hard disk + */ + public void updateFile(TaskList taskList) throws IOException { + FileWriter overwriteFile = new FileWriter(filePath + "/BuddyTaskList.txt"); + for (Task task : taskList) { + String taskType = task.getType(); + String taskName = task.getTaskName(); + String taskStatus = task.getStatusIcon(); + + switch (taskType) { + case "T": + overwriteFile.write(taskType + "$" + taskStatus + "$" + taskName + "\n"); + break; + case "D": + Deadline deadlineTask = (Deadline) task; + overwriteFile.write(taskType + "$" + taskStatus + "$" + taskName + "$" + deadlineTask.getDeadline() + "\n"); + break; + case "E": + Event eventTask = (Event) task; + overwriteFile.write(taskType + "$" + taskStatus + "$" + taskName + "$" + eventTask.getStart() + "$" + eventTask.getEnd() + "\n"); + break; + default: + } + } + overwriteFile.close(); + } + + /** + * Loads the existing file with the task list + * + * @param taskList List of tasks + * @throws FileNotFoundException If there is no file found + */ + public void loadFile(TaskList taskList) throws FileNotFoundException { + File file = new File(filePath + "/BuddyTaskList.txt"); + Scanner s = new Scanner(file); + while (s.hasNext()) { + String line = s.nextLine(); + String[] taskElements = line.split("\\$"); + String taskType = taskElements[0].trim(); + String taskStatus = taskElements[1].trim(); + String taskName = taskElements[2].trim(); + + switch (taskType) { + case "T": + Todo newTodo = new Todo(taskName); + if (taskStatus.equals("X")) { + newTodo.setDone(true); + } + taskList.add(newTodo); + Buddy.taskCount++; + break; + + case "D": + String deadline = taskElements[3].trim(); + Deadline newDeadline = new Deadline(taskName, deadline); + if (taskStatus.equals("X")) { + newDeadline.setDone(true); + } + taskList.add(newDeadline); + Buddy.taskCount++; + break; + + case "E": + String start = taskElements[3].trim(); + String end = taskElements[4].trim(); + Event newEvent = new Event(taskName, start, end); + + if (taskStatus.equals("X")) { + newEvent.setDone(true); + } + taskList.add(newEvent); + Buddy.taskCount++; + break; + default: + + } + } + } +} diff --git a/src/main/java/buddy/tasks/Deadline.java b/src/main/java/buddy/tasks/Deadline.java new file mode 100644 index 000000000..0b125ccc9 --- /dev/null +++ b/src/main/java/buddy/tasks/Deadline.java @@ -0,0 +1,31 @@ +package buddy.tasks; + +public class Deadline extends Task { + + protected String by; + + /** + * Constructor for Deadline class which is a type of Task + * + * @param description Description of deadline + * @param by Deadline date in YYYY-MM-DD format + */ + public Deadline(String description, String by) { + super(description); + this.by = by; + } + + public String getDeadline() { + return by; + } + + @Override + public String getType() { + return "D"; + } + + @Override + public String toString() { + return "[D]" + super.toString() + " (Please do by: " + by + "!)"; + } +} \ No newline at end of file diff --git a/src/main/java/buddy/tasks/Event.java b/src/main/java/buddy/tasks/Event.java new file mode 100644 index 000000000..fba22cff4 --- /dev/null +++ b/src/main/java/buddy/tasks/Event.java @@ -0,0 +1,38 @@ +package buddy.tasks; + +public class Event extends Task { + + protected String from; + protected String to; + + /** + * Constructor for Event class which is a type of Task + * + * @param description Description of Event + * @param from Start of Event + * @param to End of Event + */ + public Event(String description, String from, String to) { + super(description); + this.from = from; + this.to = to; + } + + public String getStart() { + return this.from; + } + + public String getEnd() { + return this.to; + } + + @Override + public String getType() { + return "E"; + } + + @Override + public String toString() { + return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/buddy/tasks/Task.java b/src/main/java/buddy/tasks/Task.java new file mode 100644 index 000000000..772d0e0fd --- /dev/null +++ b/src/main/java/buddy/tasks/Task.java @@ -0,0 +1,121 @@ +package buddy.tasks; + +import buddy.Buddy; +import buddy.messages.Messages; + +public class Task { + protected String description; + protected boolean isDone; + + /** + * Constructor for Task class + * + * @param description Description of task + */ + public Task(String description) { + this.description = description; + this.isDone = false; + } + + /** + * Gets the description of the task + * + * @return Description of task + */ + public String getTaskName() { + return this.description; + } + + /** + * Gets the type of the task + * + * @return String with type of task based on the Override + */ + public String getType() { + return ""; + } + + /** + * Gets the status icon of the task (whether done or not) + * + * @return "X" if isDone is true and " " if isDone is false + */ + public String getStatusIcon() { + return (isDone ? "X" : " "); // mark done task with X + } + + /** + * Sets isDone + * + * @param isDone True if task is done and false if task is not done + */ + public void setDone(boolean isDone) { + this.isDone = isDone; + } + + /** + * Marks task as done with an "X" if task was not done previously + * Else tells user that task has already been completed + */ + public void markAsDone() { + System.out.println(Messages.DIVIDER); + if (!this.isDone) { + this.isDone = true; + System.out.println("Great work on completing this task! Marked as done! :)"); + } else { + System.out.println("This task had already been marked as done previously!"); + } + System.out.println(this); + System.out.println(Messages.DIVIDER); + + } + + /** + * Mark task with a " " if task was completed previously (Marks as not done) + * Else tells user that the task was not even completed previously + */ + public void markAsUndone() { + System.out.println(Messages.DIVIDER); + if (this.isDone) { + this.isDone = false; + System.out.println("Come on, don't procrastinate! Marked as undone!"); + } else { + + System.out.println("This task was previously not completed already! Please do it properly!"); + } + System.out.println(this); + System.out.println(Messages.DIVIDER); + } + + /** + * @return String to be printed out when each task is printed + */ + @Override + public String toString() { + return "[" + this.getStatusIcon() + "] " + this.description; + } + + /** + * Prints message to user after adding a task + */ + public void printAfterAddingTask() { + if (Buddy.taskCount == 1) { + System.out.println("Got it! I have added this task!: \n" + this + "\n" + "Now you have " + Buddy.taskCount + " task remaining! Almost there, buddy!"); + } else { + System.out.println("Got it! I have added this task! \n" + this + "\n" + "Now you have " + Buddy.taskCount + " tasks remaining! Let's finish them faster and relax!"); + } + } + + /** + * Prints message to user after deleting a task + */ + public void printAfterDeletingTask() { + if (Buddy.taskCount == 0) { + System.out.println("OK I have deleted this task!: \n" + this + "\n" + "CONGRATS BUDDY ON FINISHING ALL YOUR TASKS! TIME TO RELAX WITH YOUR FRIENDS AND FAMILY! :)"); + } else if (Buddy.taskCount == 1) { + System.out.println("YAY ONE LESS TO GO! I have deleted this task!: \n" + this + "\n" + "Now you have JUST " + Buddy.taskCount + " task remaining! CHOP CHOP FINISH IT"); + } else { + System.out.println("YAY ONE LESS TO GO! I have deleted this task!: \n" + this + "\n" + "Now you have " + Buddy.taskCount + " tasks remaining! Type list to see remaining tasks"); + } + } +} diff --git a/src/main/java/buddy/tasks/TaskList.java b/src/main/java/buddy/tasks/TaskList.java new file mode 100644 index 000000000..0412630a7 --- /dev/null +++ b/src/main/java/buddy/tasks/TaskList.java @@ -0,0 +1,35 @@ +package buddy.tasks; + +import buddy.Buddy; +import buddy.messages.Messages; + +import java.util.ArrayList; + +public class TaskList extends ArrayList { + /** + * Adds task to the task list + * + * @param newTask Task to add + */ + public void addTask(Task newTask) { + System.out.println(Messages.DIVIDER); + this.add(newTask); // new task is added to taskList + Buddy.taskCount++; // increments number of buddy.tasks + newTask.printAfterAddingTask(); // print message once new task is added (From Task class) + System.out.println(Messages.DIVIDER); + } + + /** + * Deletes task from the task list + * + * @param indexOfTaskToDelete The index of the task to be deleted in the list + */ + public void deleteTask(int indexOfTaskToDelete) { + System.out.println(Messages.DIVIDER); + Task taskToBeDeleted = this.get(indexOfTaskToDelete); + Buddy.taskCount--; // decrements number of buddy.tasks + taskToBeDeleted.printAfterDeletingTask(); + this.remove(indexOfTaskToDelete); // delete task from taskList + System.out.println(Messages.DIVIDER); + } +} diff --git a/src/main/java/buddy/tasks/Todo.java b/src/main/java/buddy/tasks/Todo.java new file mode 100644 index 000000000..96944db62 --- /dev/null +++ b/src/main/java/buddy/tasks/Todo.java @@ -0,0 +1,24 @@ +package buddy.tasks; + +public class Todo extends Task { + + /** + * Constructor for Todo - a type of Task + * + * @param description Description of todo + */ + public Todo(String description) { + super(description); + } + + @Override + public String getType() { + return "T"; + } + + @Override + public String toString() { + return "[T]" + super.toString(); + } +} + diff --git a/src/main/java/buddy/ui/Ui.java b/src/main/java/buddy/ui/Ui.java new file mode 100644 index 000000000..29b1b8a29 --- /dev/null +++ b/src/main/java/buddy/ui/Ui.java @@ -0,0 +1,53 @@ +package buddy.ui; + +import buddy.messages.Messages; +import buddy.storage.Storage; +import buddy.tasks.TaskList; + +import java.io.FileNotFoundException; + +public class Ui { + + /** + * Prints a greeting to greet the user. + */ + public static void greetUser() { + System.out.println(Messages.DIVIDER); + System.out.println(Messages.GREETING); + System.out.println(Messages.INTRODUCTION); + System.out.println(Messages.DIVIDER); + } + + /** + * Prints the help message + */ + public static void displayHelpMessage() { + System.out.println(Messages.HELPMESSAGE); + } + + /** + * Prints the message when user types "bye" (Saying bye) + */ + public static void sayByeToUser() { + System.out.println(Messages.DIVIDER); + System.out.println(Messages.EXITMESSAGE); + System.out.println(Messages.DIVIDER); + } + + /** + * Loads a file if there is an existing saved file with the list of tasks + * If there is no existing file, create a new file + * + * @param taskList The list of tasks + * @param storage Storage object that handles the data + */ + public static void loadFileOrCreateFile(TaskList taskList, Storage storage) { + try { + storage.loadFile(taskList); + + } catch (FileNotFoundException e) { + System.out.println("File not found"); + storage.createFile(); + } + } +} diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e..6ca1ea139 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,42 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| - +________________________________________________________________________________ +Hello there! I'm buddy +How may I assist you? +Here are the possible commands: todo, deadline, event, list, mark, unmark, find, bye +Type if you are unsure of what these commands do! +________________________________________________________________________________ +________________________________________________________________________________ +Got it! I have added this task!: +[T][ ] cs2113 +Now you have 1 task remaining! Almost there, buddy! +________________________________________________________________________________ +________________________________________________________________________________ +Got it! I have added this task! +[D][ ] cg mod (Please do by: Dec 1 2023!) +Now you have 2 buddy.tasks remaining! Let's finish them faster and relax! +________________________________________________________________________________ +________________________________________________________________________________ +Got it! I have added this task! +[E][ ] exam (from: 2pm to: 5pm) +Now you have 3 buddy.tasks remaining! Let's finish them faster and relax! +________________________________________________________________________________ +________________________________________________________________________________ +Great work on completing this task! Marked as done! :) +[T][X] cs2113 +________________________________________________________________________________ +________________________________________________________________________________ +Great work on completing this task! Marked as done! :) +[D][X] cg mod (Please do by: Dec 1 2023!) +________________________________________________________________________________ +________________________________________________________________________________ +Come on, don't procrastinate! Marked as undone! +[T][ ] cs2113 +________________________________________________________________________________ +________________________________________________________________________________ +Here is the list of buddy.tasks you have remaining! Come on buddy! +1.[T][ ] cs2113 +2.[D][X] cg mod (Please do by: Dec 1 2023!) +3.[E][ ] exam (from: 2pm to: 5pm) +________________________________________________________________________________ +________________________________________________________________________________ +Hope I was of help to you! Have a great day and see you again, buddy :) +________________________________________________________________________________ \ No newline at end of file diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb..3dfa1bb39 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,8 @@ +todo cs2113 +deadline cg mod /by 2023-12-01 +event exam /from 2pm /to 5pm +mark 1 +mark 2 +unmark 1 +list +bye diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index 087374464..54ff33dec 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -7,7 +7,7 @@ REM delete output from previous run if exist 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\buddy.main\java -Xlint:none -d ..\bin ..\src\buddy.main\java\*.java IF ERRORLEVEL 1 ( echo ********** BUILD FAILURE ********** exit /b 1