diff --git a/README.md b/README.md index 8715d4d91..1a4b1ecb1 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,150 @@ -# Duke project template +# Arsdorint chatbot -This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. +This is Arsdorint chatbot, a member of Arsdorint Team, and an adaptation application of CS2113 Project Duke) -## Setting up in Intellij +## User Guide -Prerequisites: JDK 11, update Intellij to the most recent version. +1. To download the application, click on this link. +2. The chatbot contains the following feature + + List + + Todo + + Deadline + + Event + + Mark + + Unmark + + Date + + Find + + Bye -1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first) -1. Open the project into Intellij as follows: - 1. Click `Open`. - 1. Select the project directory, and click `OK`. - 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: +## Feature - List +- This function will list all the tasks inputed by the user. +- Example: +>>> list +Here are the tasks in your list: + +____________________________________________________________ +____________________________LIST____________________________ +1.[T][ ] midterm + Now you have 1 task in the list. +____________________________________________________________ + + +## Feature - Todo +- This function will add a task that the user want to do, with a tickbox to mark if the task is done yet or not. +- Example: +>>> todo midterm +____________________________________________________________ + +Got it. I've added this task: + +[T][ ] midterm + Now you have 1 task in the list. +____________________________________________________________ + + +## Feature - Deadline +- This function will add a deadline that the user need to complete, with a tickbox to mark if the deadline is finished or not. +- Example: +>>> deadline midterm /by tommorrow +____________________________________________________________ + +Got it. I've added this task: + +[D][ ] midterm (by tommorrow) + Now you have 2 tasks in the list. +____________________________________________________________ + +or +>>> deadline midterm /2023-03-04 +____________________________________________________________ + +Got it. I've added this task: + +[D][ ] midterm (4 Mar 2023) + Now you have 4 tasks in the list. +____________________________________________________________ + +## Feature - Event +- This function will add an event that the user need to attend, with a tickbox to mark if the user have attended or not. +- Example: +>>> event Open House /on Sunday +____________________________________________________________ + +Got it. I've added this task: + +[E][ ] Open House (on Sunday) + Now you have 5 tasks in the list. +____________________________________________________________ + +or +>>> event NUS football match /2023-03-05 +____________________________________________________________ + +Got it. I've added this task: + +[E][ ] NUS football match (5 Mar 2023) + Now you have 6 tasks in the list. +____________________________________________________________ + +## Feature - Mark +- This function will mark a task as done by tick a "X" into the tickbox. +- Example: +>>> mark 2 +____________________________________________________________ + +Got it. I've marked this task as done: + +[D][X] midterm (by tommorrow) + Now you have 5 unmarked tasks in the list. +____________________________________________________________ + +## Feature - Unmark +- This function will mark a task as not done yet by leaving the tickbox empty. +- Example: +>>> unmark 2 +____________________________________________________________ + +Got it. I've marked this task as not done yet: + +[D][ ] midterm (by tommorrow) + Now you have 0 marked tasks in the list. +____________________________________________________________ + +## Feature - Date +- This function will find if a date is in the task list yet. The date should be in the format of YYYY-MM-DD with YYYY is the year, MM is the month and DD is the day. +- Example: +>>> date /2023-03-04 +____________________________________________________________ +1 task happen on this date +____________________________________________________________ + +## Feature - Find +- This function will find if the task the user want to search is in the list yet, and list all task with that name +- Example: +>>> find Open House +____________________________________________________________ +Here are the matching tasks in your list, with 1 task as followed: +[E][ ] Open House (at Sunday) + +____________________________________________________________ + +## Feature - Bye + - This function will help the chatbot to say bye to the user, and end up the conversation. + - Example: + >>> bye +____________________________________________________________ + Bye. Hope to see you again soon! + + +____________________________________________________________ + +### That's all about Arsdorint chatbot! Hope you enjoy our product, and leave some comments to help us improve the chatbot! Thank you so much! ``` Hello from - ____ _ - | _ \ _ _| | _____ - | | | | | | | |/ / _ \ - | |_| | |_| | < __/ - |____/ \__,_|_|\_\___| + ___ _ _ + / _ \ _____ _____ ___| | ___ _____ _ _____ _| |_ + / /_\ \ / ___| / __/ / _ | / _ \ / ___| | | | _ \ |_ _| + / _____ \ | / __\ \ | |_| | | |_| | | / | | | | | | | | + /_/ \_\ |_| /____/ \_____| \___/ |_| |_| |_| |_| |_| + ``` diff --git a/docs/README.md b/docs/README.md index 8077118eb..f8a6e1fde 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,29 +1,184 @@ -# User Guide +# Arsdorint chatbot -## Features +This is Arsdorint chatbot, a member of Arsdorint Team, and an adaptation application of CS2113 Project Duke) -### Feature-ABC +## User Guide -Description of the feature. +1. To download the application, click [here](https://github.com/arsdorintbp2003/ip/releases/tag/A-Released). +2. Copy the file path after your download. (ie: C:\Users\YourPC\GitHub\ip_jar) +3. Open your terminal, if the current path is not where you keep the file (ie: C:\Users\YourPC), just type `cd` + the remaining path (ie: 'cd GitHub\ip_jar`) to access the file path. +4. Initializing the application by typing `java -jar ip.jar`, and enjoy using the chatbot. +5. The chatbot contains the following feature + + List + + Todo + + Deadline + + Event + + Mark + + Unmark + + Date + + Find + + Bye -### Feature-XYZ +## Feature - List +- This function will list all the tasks inputed by the user. +- Example: -Description of the feature. +``` +>>> list +Here are the tasks in your list: + +____________________________________________________________ +____________________________LIST____________________________ +1.[T][ ] midterm + Now you have 1 task in the list. +____________________________________________________________ +``` + +## Feature - Todo +- This function will add a task that the user want to do, with a tickbox to mark if the task is done yet or not. +- Example: + +``` +>>> todo midterm +____________________________________________________________ + +Got it. I've added this task: + +[T][ ] midterm + Now you have 1 task in the list. +____________________________________________________________ +``` + +## Feature - Deadline +- This function will add a deadline that the user need to complete, with a tickbox to mark if the deadline is finished or not. +- Example: + +``` +>>> deadline midterm /by tommorrow +____________________________________________________________ -## Usage +Got it. I've added this task: + +[D][ ] midterm (by tommorrow) + Now you have 2 tasks in the list. +____________________________________________________________ +``` + +or -### `Keyword` - Describe action +``` +>>> deadline midterm /2023-03-04 +____________________________________________________________ -Describe the action and its outcome. +Got it. I've added this task: + +[D][ ] midterm (4 Mar 2023) + Now you have 4 tasks in the list. +____________________________________________________________ +``` -Example of usage: +## Feature - Event +- This function will add an event that the user need to attend, with a tickbox to mark if the user have attended or not. +- Example: -`keyword (optional arguments)` +``` +>>> event Open House /on Sunday +____________________________________________________________ -Expected outcome: +Got it. I've added this task: + +[E][ ] Open House (on Sunday) + Now you have 5 tasks in the list. +____________________________________________________________ +``` -Description of the outcome. +or ``` -expected output +>>> event NUS football match /2023-03-05 +____________________________________________________________ + +Got it. I've added this task: + +[E][ ] NUS football match (5 Mar 2023) + Now you have 6 tasks in the list. +____________________________________________________________ ``` + +## Feature - Mark +- This function will mark a task as done by tick a "X" into the tickbox. +- Example: + +``` +>>> mark 2 +____________________________________________________________ + +Got it. I've marked this task as done: + +[D][X] midterm (by tommorrow) + Now you have 5 unmarked tasks in the list. +____________________________________________________________ +``` + +## Feature - Unmark +- This function will mark a task as not done yet by leaving the tickbox empty. +- Example: + +``` +>>> unmark 2 +____________________________________________________________ + +Got it. I've marked this task as not done yet: + +[D][ ] midterm (by tommorrow) + Now you have 0 marked tasks in the list. +____________________________________________________________ +``` + +## Feature - Date +- This function will find if a date is in the task list yet. The date should be in the format of YYYY-MM-DD with YYYY is the year, MM is the month and DD is the day. +- Example: + +``` +>>> date 2022-03-04 +____________________________________________________________ +1 task occurs on this date: +[D][ ] Open House (4 Mar 2022) +``` + +## Feature - Find +- This function will find if the task the user want to search is in the list yet, and list all task with that name +- Example: + +``` +>>> find Open House +____________________________________________________________ +Here are the matching tasks in your list, with 1 task as followed: +[E][ ] Open House (on Sunday) + +____________________________________________________________ +``` + +## Feature - Bye + - This function will help the chatbot to say bye to the user, and end up the conversation. + - Example: + + ``` + >>> bye +____________________________________________________________ + Bye. Hope to see you again soon! + + +____________________________________________________________ +``` + +### That's all about Arsdorint chatbot! Hope you enjoy our product, and leave some comments to help us improve the chatbot! Thank you so much! + ``` + Hello from + ___ _ _ + / _ \ _____ _____ ___| | ___ _____ _ _____ _| |_ + / /_\ \ / ___| / __/ / _ | / _ \ / ___| | | | _ \ |_ _| + / _____ \ | / __\ \ | |_| | | |_| | | / | | | | | | | | + /_/ \_\ |_| /____/ \_____| \___/ |_| |_| |_| |_| |_| + + ``` diff --git a/src/main/java/Arsdorint/Arsdorint.java b/src/main/java/Arsdorint/Arsdorint.java new file mode 100644 index 000000000..b99ff8ba8 --- /dev/null +++ b/src/main/java/Arsdorint/Arsdorint.java @@ -0,0 +1,104 @@ +package Arsdorint; +import Arsdorint.UI.TextUI; +import Arsdorint.command.*; +import Arsdorint.data.StorageClass; +import Arsdorint.data.TaskList; +import Arsdorint.parser.TaskParser; + +import static Arsdorint.MessageList.MESSAGE_NEW_FILE; + +/** + * Start of Arsdorint application + * Initializes the application and interact with the users + */ +public class Arsdorint { + public static String logo = " ___ _ _\n" + + " / _ \\ _____ _____ ___| | ___ _____ _ _____ _| |_\n" + + " / /_\\ \\ / ___| / __/ / _ | / _ \\ / ___| | | | _ \\ |_ _|\n" + + " / _____ \\ | / __\\ \\ | |_| | | |_| | | / | | | | | | | |\n" + + "/_/ \\_\\ |_| /____/ \\_____| \\___/ |_| |_| |_| |_| |_|\n"; + + private TextUI UI; + private StorageClass storage; + private TaskList taskList; + + /** + * Print exit message and exits + */ + public void exit() { + UI.showExitMessage(); + UI.input.close(); + System.exit(0); + } + + public static void main(String[] args) { + new Arsdorint().run(); + } + + /** + * Run the program until termination / exit + */ + public void run() { + start(); + mainLoop(); + exit(); + } + + + /** + * Set up the required objects, print hello message + */ + private void start() { + this.UI = new TextUI(); + UI.showHelloMessage(); + this.storage = new StorageClass(); + try { + this.taskList = storage.load(); + UI.showToUser(MESSAGE_NEW_FILE); + } catch (StorageClass.StorageException e) { + UI.showToUser(e.getMessage()); + this.taskList = new TaskList(); + } + } + + /** + * Read user command and execute until exit command is detected + */ + private void mainLoop() { + Command command; + do { + String userCommandText = UI.getUserCommand(); + command = new TaskParser(taskList).parsedCommand(userCommandText); + CommandRes res = executeCommand(command); + UI.showResToUser(res); + save(); + } while (!CommandExit.isExit(command)); + } + + /** + * Save and catch error + */ + private void save() { + try { + storage.save(taskList); + } catch (StorageClass.StorageException e) { + UI.showToUser(e.getMessage()); + } + } + + /** + * Execute the command + * + * @param command the input command that the user typed in + */ + private CommandRes executeCommand(Command command) { + try { + command.setTaskList(taskList); + return command.execute(); + } catch (Exception err) { + UI.showToUser(err.getMessage()); + throw new RuntimeException(err); + } + } +} + diff --git a/src/main/java/Arsdorint/MessageList.java b/src/main/java/Arsdorint/MessageList.java new file mode 100644 index 000000000..c11254250 --- /dev/null +++ b/src/main/java/Arsdorint/MessageList.java @@ -0,0 +1,51 @@ +package Arsdorint; + +public class MessageList { + public static final String EXIT_MESSAGE = " Bye. Hope to see you again soon!\n"; + public static final String HELLO_MESSAGE = + " Hello! I'm Arsdorint, a member of Arsdorint Team.\n" + + " Please Type The Command As Follow:\n"; + public static final String COMMAND_LIST_MESSAGE = + "> Type \"list\" to list all the tasks. \n" + + "> Type \"mark\" follow by a number x to mark tasks x in the list. \n" + + "> Type \"unmark\" follow by a number y to unmark tasks y in the list. \n" + + "> Type \"todo\" follow by a string x to add a work that need to be done. \n" + + "> Type \"deadline x /y\" with x is the type of work, y is the time or date of the deadline. \n" + + "> Type \"event x /y\" with x is the event, y is the time or date of that event. \n" + + "> Type \"date YYYY-MM-DD\" to know how many tasks occurs in day DD, month MM, year YYYY. \n" + + "> Type \"delete\" follow by a number z to delete task z in the the list. \n" + + "> Type \"bye\" to exit. \n"; + public static final String QUESTION = " What can I do for you?"; + public static final String MESSAGE_NEW_FILE = "File created"; + public static final String MESSAGE_OVERWRITE_FILE = "File overwritten"; + public static final String MESSAGE_LOAD_FILE = "File loaded"; + public static final String MESSAGE_NO_FILE = "There is no existing file"; + public static final String MESSAGE_WRONG_FILE = "The storage files entry is invalid. Please save to overwrite"; + public static final String MESSAGE_DIVIDER = + "____________________________________________________________________________________________________"; + public static final String MESSAGE_DIVIDER_LIST = + "________________________________________________LIST________________________________________________"; + public static final String MESSAGE_DELETE = "Noted. I've removed this task:"; + public static final String MESSAGE_UNKNOWN = "unknown message"; + + public static final String ERROR_MESSAGE_BYE = " "; + public static final String ERROR_MESSAGE_LIST = " "; + public static final String ERROR_MESSAGE_MARK = + "=( OOPS!!! The description of a mark cannot be empty.\n" + "Syntax for mark\n\t" + + ">>> mark \n" + "Note: item index must exist in the current list"; + public static final String ERROR_MESSAGE_UNMARK = + "=( OOPS!!! The description of an unmark cannot be empty.\n" + "Syntax for unmark\n\t" + + ">>> unmark \n" + "Note: item index must exist in the current list"; + public static final String ERROR_MESSAGE_TODO = + "=( OOPS!!! The description of a todo cannot be empty.\n" + "Syntax for todo\n\t>>> todo "; + public static final String ERROR_MESSAGE_DEADLINE = + "=( OOPS!!! The description of a deadline cannot be empty.\n" + + "Syntax for deadline\n\t>>> deadline />> event / taskListTarget = new ArrayList<>(); + protected Command(String commandType) { + this.commandType = commandType; + } + /** + * Execution of the command + */ + public abstract CommandRes execute(); + + /** + * Check if the key is contained in the index of the tasks + */ + public boolean contains(final int[] arr, final int key) { + for (final int i : arr) { + if (i == key) { + return true; + } + } + return false; + } + + /** + * Set the tasklist that the command will act on + */ + public void setTaskList(TaskList taskList) { + this.taskList = taskList; + } + + /** + * Count the target list that the command act on + */ + protected int targetCount() { + return (int) taskListTarget.stream().count(); + } +} diff --git a/src/main/java/Arsdorint/command/CommandDate.java b/src/main/java/Arsdorint/command/CommandDate.java new file mode 100644 index 000000000..03076768a --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandDate.java @@ -0,0 +1,39 @@ +package Arsdorint.command; +import Arsdorint.data.TaskList; +import Arsdorint.task.Task; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.stream.Collectors; + + +public class CommandDate extends Command { + public CommandDate(LocalDate date) { + super(COMMAND_NAME); + this.date = date; + } + public static final String COMMAND_NAME = "delete"; + public static final String SYNTAX = "Syntax for date\n\t>>>date "; + public LocalDate date; + + /** + * Execution of the "date" command + * + * @return printing the list of command happens on that date + * + */ + @Override + public CommandRes execute() { + ArrayList task = new ArrayList<>(TaskList.list.stream().filter(i -> !i.isDateNull()).filter + (i -> i.getDate().equals(this.date)).collect(Collectors.toList())); + long count = task.stream().count(); + String messageTop = count + " " + TaskList.printTasksOrTask((int) count) + + printOccursOrOccur((int) count) + " on this date"; + return new CommandRes(messageTop, task, ""); + } + private String printOccursOrOccur(int count) { + return (count == 1) ? "occurs" : "occur"; + } +} + + diff --git a/src/main/java/Arsdorint/command/CommandDeadline.java b/src/main/java/Arsdorint/command/CommandDeadline.java new file mode 100644 index 000000000..131cb7dfe --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandDeadline.java @@ -0,0 +1,36 @@ +package Arsdorint.command; + +import Arsdorint.data.TaskList; +import Arsdorint.task.Deadline; +import Arsdorint.task.Task; + +import java.util.ArrayList; + +public class CommandDeadline extends Command { + public CommandDeadline(String description, String date) { + super(COMMAND_NAME); + this.description = description; + this.date = date; + } + + public static final String COMMAND_NAME = "deadline"; + public static final String SYNTAX = "Syntax for deadline\n\t>>> deadline / task = new ArrayList(); + + /** + * Execution of the "deadline" command + * + * @return printing the deadline's added status to the user + * + */ + @Override + public CommandRes execute() { + Task added = new Deadline(description, date); + TaskList.list.add(added); + task.add(added); + return new CommandRes(MESSAGE_TOP, task, TaskList.getAllMessage()); + } +} diff --git a/src/main/java/Arsdorint/command/CommandDelete.java b/src/main/java/Arsdorint/command/CommandDelete.java new file mode 100644 index 000000000..aab9cb655 --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandDelete.java @@ -0,0 +1,42 @@ +package Arsdorint.command; + +import Arsdorint.MessageList; +import Arsdorint.data.TaskList; +import Arsdorint.task.Task; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static Arsdorint.MessageList.MESSAGE_DELETE; + +public class CommandDelete extends Command { + + public CommandDelete(int...idx) { + super(COMMAND_NAME); + this.idx = idx; + } + public static final String COMMAND_NAME = "delete"; + public static final String SYNTAX = "Syntax for delete item \n\t>>> delete \n"; + public static final String MESSAGE_TOP = MESSAGE_DELETE; + public int[] idx; + + /** + * Execution of the "delete" command + * + * @return @return printing the task's deleted status to the user + * + */ + @Override + public CommandRes execute() { + ArrayList task = new ArrayList(IntStream.range(0, TaskList.list.size()).filter + (i -> contains(idx, i)).mapToObj(i -> TaskList.list.get(i)).collect(Collectors.toList())); + Arrays.sort(idx); + for (int i = idx.length - MessageList.OFFSET; i > -MessageList.OFFSET; i--) { + TaskList.list.remove(idx[i]); + } + return new CommandRes(MESSAGE_TOP, task, TaskList.getAllMessage()); + } +} diff --git a/src/main/java/Arsdorint/command/CommandEvent.java b/src/main/java/Arsdorint/command/CommandEvent.java new file mode 100644 index 000000000..faf2dcd6b --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandEvent.java @@ -0,0 +1,36 @@ +package Arsdorint.command; + +import Arsdorint.data.TaskList; +import Arsdorint.task.Event; +import Arsdorint.task.Task; + +import java.util.ArrayList; + +public class CommandEvent extends Command { + public CommandEvent(String description, String date) { + super(COMMAND_NAME); + this.description = description; + this.date = date; + } + + public static final String COMMAND_NAME = "event"; + public static final String SYNTAX = "Syntax for event\n\t>>> event / task = new ArrayList(); + + /** + * Execution of the event command + * + * @return printing the event's added status to the user + * + */ + @Override + public CommandRes execute() { + Task added = new Event(description, date); + TaskList.list.add(added); + task.add(added); + return new CommandRes(MESSAGE_TOP, task, TaskList.getAllMessage()); + } +} diff --git a/src/main/java/Arsdorint/command/CommandExit.java b/src/main/java/Arsdorint/command/CommandExit.java new file mode 100644 index 000000000..f729dba03 --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandExit.java @@ -0,0 +1,25 @@ +package Arsdorint.command; + +public class CommandExit extends Command { + public CommandExit() { + super(COMMAND_NAME); + } + + public static final String COMMAND_NAME = "exit"; + public static final String MESSAGE_TOP = " Bye. Hope to see you again soon!\n"; + public static boolean isExit(Command command) { + return command.commandType.equalsIgnoreCase("COMMAND_NAME"); + } + + /** + * Execution of the exit command + * + * @return printing the exit of command + * + */ + @Override + public CommandRes execute() { + return new CommandRes(MESSAGE_TOP); + } +} + diff --git a/src/main/java/Arsdorint/command/CommandFind.java b/src/main/java/Arsdorint/command/CommandFind.java new file mode 100644 index 000000000..ec34c098f --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandFind.java @@ -0,0 +1,40 @@ +package Arsdorint.command; + +import Arsdorint.data.TaskList; +import Arsdorint.task.Task; + +import java.util.ArrayList; +import java.util.stream.Collectors; + +public class CommandFind extends Command { + + public CommandFind(String key) { + super(COMMAND_NAME); + this.key = key; + } + public static final String COMMAND_NAME = "find"; + public static final String SYNTAX = "Find syntax\n\t>>>find "; + public String key; + + /** + * Execution of the "find" command + * + * @return printing the task that match the user's search, or print "no tasks" command in case there are no tasks + * match what user search + * + */ + @Override + public CommandRes execute() { + ArrayList task = new ArrayList<>(TaskList.list.stream().filter(i -> i.description + .equals(this.key)).collect(Collectors.toList())); + int count = (int) task.stream().count(); + String messageTop; + if (count != 0) { + messageTop = "Here are the matching tasks in your list, with " + + count + " " + TaskList.printTasksOrTask(count) + " as followed:"; + } else { + messageTop = "There are no tasks matching your search"; + } + return new CommandRes(messageTop, task, ""); + } +} diff --git a/src/main/java/Arsdorint/command/CommandList.java b/src/main/java/Arsdorint/command/CommandList.java new file mode 100644 index 000000000..14e9a0e9a --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandList.java @@ -0,0 +1,26 @@ +package Arsdorint.command; + +import Arsdorint.MessageList; +import Arsdorint.data.TaskList; + +import static Arsdorint.MessageList.MESSAGE_DIVIDER_LIST; + +public class CommandList extends Command { + public CommandList() { + super(COMMAND_NAME); + } + + public static final String COMMAND_NAME = "list"; + public static final String SYNTAX = "Here's your task in the list: "; + + /** + * Execution of the "list" command + * + * @return printing the list of command + * + */ + @Override + public CommandRes execute() { + return new CommandRes(MESSAGE_DIVIDER_LIST, TaskList.list, TaskList.getAllMessage()); + } +} diff --git a/src/main/java/Arsdorint/command/CommandMark.java b/src/main/java/Arsdorint/command/CommandMark.java new file mode 100644 index 000000000..c8b9763f3 --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandMark.java @@ -0,0 +1,41 @@ +package Arsdorint.command; + +import Arsdorint.MessageList; +import Arsdorint.data.TaskList; +import Arsdorint.task.Task; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class CommandMark extends Command { + public CommandMark(int...idx) { + super(COMMAND_NAME); + this.idx = idx; + } + + public static final String COMMAND_NAME = "mark"; + public static final String SYNTAX = "Syntax for mark\n\t" + + ">>> mark \n" + "Note: item index must exist in the current list"; + public static final String MESSAGE_TOP = "\nGot it. I've marked this task as done:\n" + "\t"; + public int[] idx; + + /** + * Execution of the "mark" command + * + * @return printing the task to be marked with an "X" in its box + * + */ + @Override + public CommandRes execute() { + for (int i = 0; i < idx.length; i++) { + TaskList.list.get(idx[i]).setIsDone(true); + } + ArrayList task = new ArrayList(IntStream.range(0, TaskList.list.size()).filter + (i -> contains(idx, i)).mapToObj(i -> TaskList.list.get(i)).collect(Collectors.toList())); + + return new CommandRes(MESSAGE_TOP, task, TaskList.getUnmarkedMessage()); + } +} + diff --git a/src/main/java/Arsdorint/command/CommandRes.java b/src/main/java/Arsdorint/command/CommandRes.java new file mode 100644 index 000000000..9e9a8927c --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandRes.java @@ -0,0 +1,59 @@ +package Arsdorint.command; + +import Arsdorint.MessageList; +import Arsdorint.task.Task; + +import javax.crypto.spec.OAEPParameterSpec; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.IntStream; + +/** + * Represent the result of the command + */ +public class CommandRes { + public String messageTop = ""; + public String messageBottom = ""; + public List task; + + /** + * Initialization without task + * + * @param strTop the first string to be shown + */ + public CommandRes(String strTop) { + this.messageTop = strTop; + } + + /** + * Initialization with task + * + * @param strTop the first string to be shown + * @param task the list of all tasks + * @param strBottom the last string to be shown + */ + public CommandRes(String strTop, ArrayList task, String strBottom) { + this.messageTop = strTop; + this.messageBottom = strBottom; + this.task = task; + } + + /** + * Print the task + */ + public String[] printTask() { + if (task == null) { + return new String[]{}; + } else if (messageTop.equals(MessageList.MESSAGE_DIVIDER_LIST)) { + return IntStream.range(0, task.size()).mapToObj(i -> + (i + MessageList.OFFSET + "." + task.get(i))).toArray(String[]::new); + } else { + return task.stream().map(Task::toString).toArray(String[]::new); + } + } + + public Optional> getTask() { + return Optional.ofNullable(task); + } +} diff --git a/src/main/java/Arsdorint/command/CommandToDo.java b/src/main/java/Arsdorint/command/CommandToDo.java new file mode 100644 index 000000000..6af0637b1 --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandToDo.java @@ -0,0 +1,37 @@ +package Arsdorint.command; + +import Arsdorint.data.TaskList; +import Arsdorint.task.Deadline; +import Arsdorint.task.Task; +import Arsdorint.task.Todo; + +import java.util.ArrayList; + +public class CommandToDo extends Command { + public CommandToDo(String description) { + super(COMMAND_NAME); + this.description = description; + } + + public static final String COMMAND_NAME = "todo"; + public static final String SYNTAX = "Syntax for todo\n\t>>> todo "; + public static final String MESSAGE_TOP = "\nGot it. I've added this task:\n" + "\t"; + public String description; + + public ArrayList task = new ArrayList(); + + /** + * Execution of the "todo" command + * + * @return printing the task to be including in the list + * + */ + @Override + public CommandRes execute() { + Task added = new Todo(description); + TaskList.list.add(added); + task.add(added); + return new CommandRes(MESSAGE_TOP, task, TaskList.getAllMessage()); + } +} + diff --git a/src/main/java/Arsdorint/command/CommandUnmark.java b/src/main/java/Arsdorint/command/CommandUnmark.java new file mode 100644 index 000000000..1f0070962 --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandUnmark.java @@ -0,0 +1,40 @@ +package Arsdorint.command; + +import Arsdorint.data.TaskList; +import Arsdorint.task.Task; + +import java.util.ArrayList; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class CommandUnmark extends Command { + public CommandUnmark(int...idx) { + super(COMMAND_NAME); + this.idx = idx; + } + + public static final String COMMAND_NAME = "unmark"; + public static final String SYNTAX = "Syntax for unmark\n\t" + + ">>> unmark \n" + "Note: item index must exist in the current list"; + public static final String MESSAGE_TOP = "\nGot it. I've marked this task as not done yet:\n" + "\t"; + public int[] idx; + + /** + * Execution of the "unmark" command + * + * @return printing the task to be unmarked with an empty of "X" in its box + * + */ + @Override + public CommandRes execute() { + for (int i = 0; i < idx.length; i++) { + TaskList.list.get(idx[i]).setIsDone(false); + } + ArrayList task = new ArrayList(IntStream.range(0, TaskList.list.size()).filter + (i -> contains(idx, i)).mapToObj(i -> TaskList.list.get(i)).collect(Collectors.toList())); + + return new CommandRes(MESSAGE_TOP, task, TaskList.getMarkedMessage()); + } +} + + diff --git a/src/main/java/Arsdorint/command/CommandWrong.java b/src/main/java/Arsdorint/command/CommandWrong.java new file mode 100644 index 000000000..ed0d952fa --- /dev/null +++ b/src/main/java/Arsdorint/command/CommandWrong.java @@ -0,0 +1,29 @@ +package Arsdorint.command; + +import static Arsdorint.MessageList.MESSAGE_DIVIDER; + +public class CommandWrong extends Command { + public CommandWrong(String message) { + super(COMMAND_NAME); + this.top = top; + } + + public CommandWrong(String top, String bottom) { + this(top); + this.bottom = bottom; + } + public static final String COMMAND_NAME = "wrong command"; + public String top = "=( OOPS!!! I'm sorry, but I don't know what that means :-(\n" + MESSAGE_DIVIDER; + public String bottom = "Error: Lack / Wrong description format of the command"; + + /** + * Execution in case the command is not in the command list + * + * @return printing the COMMAND_WRONG message + * + */ + @Override + public CommandRes execute() { + return new CommandRes(this.top, null, this.bottom); + } +} diff --git a/src/main/java/Arsdorint/command/StorageException.java b/src/main/java/Arsdorint/command/StorageException.java new file mode 100644 index 000000000..99a00abc0 --- /dev/null +++ b/src/main/java/Arsdorint/command/StorageException.java @@ -0,0 +1,4 @@ +package Arsdorint.command; + +public class StorageException extends Exception { +} diff --git a/src/main/java/Arsdorint/data/StorageClass.java b/src/main/java/Arsdorint/data/StorageClass.java new file mode 100644 index 000000000..095e06161 --- /dev/null +++ b/src/main/java/Arsdorint/data/StorageClass.java @@ -0,0 +1,62 @@ +package Arsdorint.data; + +import Arsdorint.task.Task; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import static Arsdorint.MessageList.*; + +/** + * Represent the middleman class between the main and the encoding, decoding + */ +public class StorageClass { + public StorageClass() { + path = Paths.get(STORAGE_FILE_NAME); + } + public static final String STORAGE_DIRECTORY = "./storage"; + public static final String STORAGE_FILE_NAME = "./storage/arsdorintTask.txt"; + private final Path path; + private static final String ERROR_SAVING_MESSAGE = "Error saving to "; + private static final String ERROR_LOADING_MESSAGE = "Error loading to "; + private static final String ERROR_PARSING_MESSAGE = "Error parsing "; + + /** + * Method to save the file + */ + public void save(TaskList taskList) throws StorageException { + try { + List encodedTaskList = TaskListEncoder.encodeList(taskList); + Files.write(path, encodedTaskList); + } catch (IOException err) { + File newFile = new File(STORAGE_DIRECTORY); + newFile.mkdir(); + save(taskList); + throw new StorageException(ERROR_SAVING_MESSAGE + path + MESSAGE_NEW_FILE); + } + } + public TaskList load() throws StorageException { + TaskList list = new TaskList(); + try { + ArrayList decodedList = TaskListDecoder.decodeFile(STORAGE_FILE_NAME); + list.data = decodedList; + return list; + } catch (IOException err) { + throw new StorageException(ERROR_LOADING_MESSAGE + path); + } catch (TaskListDecoder.DecodeException err) { + throw new StorageException(ERROR_PARSING_MESSAGE + path); + } + } + + public static class StorageException extends Exception { + public StorageException(String message) { + super(message); + } + } + +} diff --git a/src/main/java/Arsdorint/data/TaskList.java b/src/main/java/Arsdorint/data/TaskList.java new file mode 100644 index 000000000..d3464898f --- /dev/null +++ b/src/main/java/Arsdorint/data/TaskList.java @@ -0,0 +1,33 @@ +package Arsdorint.data; + +import Arsdorint.task.Task; + +import java.util.ArrayList; + +/* Represent the TaskList, and some functions to deal with messages */ +public class TaskList { + public ArrayList data; + + public TaskList() { + } + public static final int MAX_NUM_OF_TASKS = 100; + public static ArrayList list = new ArrayList(MAX_NUM_OF_TASKS); + public static String getAllMessage() { + int count = TaskList.list.size(); + return "\t" + "Now you have " + count + " " + printTasksOrTask(count) + " in the list."; + } + + public static String getMarkedMessage() { + int count = (int) TaskList.list.stream().filter(i-> i.isDone).count(); + return "\t" + "Now you have " + count + " marked " + printTasksOrTask(count) + " in the list."; + } + + public static String getUnmarkedMessage() { + int count = (int) TaskList.list.stream().filter(i-> !i.isDone).count(); + return "\t" + "Now you have " + count + " unmarked " + printTasksOrTask(count) + " in the list."; + } + + public static String printTasksOrTask(int num) { + return ((num == 1) ? "task" : "tasks"); + } +} diff --git a/src/main/java/Arsdorint/data/TaskListDecoder.java b/src/main/java/Arsdorint/data/TaskListDecoder.java new file mode 100644 index 000000000..8f806e395 --- /dev/null +++ b/src/main/java/Arsdorint/data/TaskListDecoder.java @@ -0,0 +1,63 @@ +package Arsdorint.data; + +import Arsdorint.task.Deadline; +import Arsdorint.task.Event; +import Arsdorint.task.Task; +import Arsdorint.task.Todo; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +import static Arsdorint.task.Event.TYPE_EVENT; +import static Arsdorint.task.Todo.TYPE_TODO; + +public class TaskListDecoder { + private static final String PARSE_LIMITER = "\\|"; + + /** + * Read the class that handles decoding task from a line in the file and add Task to the TaskList + * + * @param path the path of the file + * @return TaskList + */ + public static ArrayList decodeFile(String path) throws DecodeException, IOException { + ArrayList taskListData = new ArrayList<>(); + File file = new File(path); + Scanner fileReader = new Scanner(file); + while (fileReader.hasNextLine()) { + taskListData.add(decodeLine(fileReader.nextLine())); + } + fileReader.close(); + return taskListData; + } + + private static Task decodeLine(String nextLine) throws DecodeException { + try { + Task add; + String[] parsedString = nextLine.split(PARSE_LIMITER); + String command = parsedString[0].trim(); + boolean isDone = Boolean.valueOf(parsedString[1]); + String description = parsedString[2]; + switch (command) { + case Todo.TYPE_TODO: + add = new Todo(isDone,description); + return add; + case Event.TYPE_EVENT: + add = new Event(isDone, description, parsedString[3]); + return add; + case Deadline.TYPE_DEADLINE: + add = new Deadline(isDone, description, parsedString[3]); + return add; + default: + throw new DecodeException(); + } + } catch (Exception err) { + throw new DecodeException(); + } + } + public static class DecodeException extends Exception { + } + +} diff --git a/src/main/java/Arsdorint/data/TaskListEncoder.java b/src/main/java/Arsdorint/data/TaskListEncoder.java new file mode 100644 index 000000000..def342923 --- /dev/null +++ b/src/main/java/Arsdorint/data/TaskListEncoder.java @@ -0,0 +1,38 @@ +package Arsdorint.data; +import Arsdorint.task.Task; + +import java.util.ArrayList; +import java.util.List; +/** + * Represent the class that handles encode task from TaskList to file + */ + +public class TaskListEncoder { + private static final String SEPARATOR = " | "; + + /** + * Encode the tasklist + * + * @param list tasklist to be represent in strings + * @return ArrayList of String (each string is a task to be saved) + */ + + public static List encodeList(TaskList list) { + final List encodedTasks = new ArrayList<>(); + list.data.stream().forEach(task -> encodedTasks.add(encodeTask(task))); + return encodedTasks; + } + + private static String encodeTask(Task task) { + final StringBuilder encodedTaskBuilder = new StringBuilder(); + + encodedTaskBuilder.append(task.getType()); + encodedTaskBuilder.append(SEPARATOR); + encodedTaskBuilder.append(task.isDone() ? "true" : "false"); + encodedTaskBuilder.append(SEPARATOR); + encodedTaskBuilder.append(task.description); + encodedTaskBuilder.append(SEPARATOR); + encodedTaskBuilder.append(task.isDateNull() ? task.getDate() : ""); + return encodedTaskBuilder.toString(); + } +} diff --git a/src/main/java/Arsdorint/parser/TaskParser.java b/src/main/java/Arsdorint/parser/TaskParser.java new file mode 100644 index 000000000..fdb7d50ac --- /dev/null +++ b/src/main/java/Arsdorint/parser/TaskParser.java @@ -0,0 +1,221 @@ +package Arsdorint.parser; + +import Arsdorint.command.*; +import Arsdorint.data.TaskList; +import Arsdorint.task.Deadline; +import Arsdorint.task.Event; +import Arsdorint.task.Todo; + +import java.time.LocalDate; +import java.time.format.DateTimeParseException; + +import static Arsdorint.MessageList.*; + +/** + * A class that handle the parsing of command + */ + +public class TaskParser { + private TaskList taskList; + + /** + * Parser instance take in the taskList to be manipulated + */ + public TaskParser(TaskList taskList) { + this.taskList = taskList; + } + + /** + * Parse user input string + * + * @param input The user input string + * @return Command and its arguments + */ + public Command parsedCommand(String input) { + String[] command = input.split(" "); + if (command.length == 0) { + return new CommandWrong(MESSAGE_UNKNOWN, COMMAND_LIST_MESSAGE); + } + final String arguments = input.replaceFirst(command[0], "").trim(); + String lowerCaseLine = command[0].toLowerCase(); + if (lowerCaseLine.equals("bye")) { + return new CommandExit(); + } + else if (lowerCaseLine.contains("list")) { + System.out.println("Here are the tasks in your list:\n"); + return new CommandList(); + } + else if (lowerCaseLine.equalsIgnoreCase("mark")) { + return mark(arguments); + } + else if (lowerCaseLine.equalsIgnoreCase("unmark")) { + return unmark(arguments); + } + else if (lowerCaseLine.equalsIgnoreCase("todo")) { + return addToDo(arguments); + } + else if (lowerCaseLine.equalsIgnoreCase("deadline")) { + return addDeadline(arguments); + } + else if (lowerCaseLine.equalsIgnoreCase("event")) { + return addEvent(arguments); + } + else if (lowerCaseLine.equalsIgnoreCase("find")) { + return addFind(arguments); + } + //add command when user don't type the instruction's Arsdorint.command + else if (lowerCaseLine.equalsIgnoreCase("delete")) { + return delete(arguments); + } else if (lowerCaseLine.equalsIgnoreCase("date")) { + return addDate(arguments); + } else { + return new CommandWrong(MESSAGE_UNKNOWN, COMMAND_LIST_MESSAGE); + } + } + + public static void fileParser(String input) throws ArsdorintFileException { + String[] parsedLine = input.split(""); + String[] parsedTrim = new String[parsedLine.length]; + + for (int i = 0; i < parsedLine.length; i++) { + parsedTrim[i] = parsedLine[i].trim(); + } + switch (parsedLine[0]) { + case Todo.TYPE_TODO: + todoParser(parsedTrim); + break; + case Deadline.TYPE_DEADLINE: + deadlineParser(parsedTrim); + break; + case Event.TYPE_EVENT: + eventParser(parsedTrim); + break; + default: + throw new ArsdorintFileException(); + } + } + + public Command mark(String command) { + try { + String[] parsed = command.split(" "); + if (parsed.length < 1) { + throw new ArsdorintException(); + } return new CommandMark(strToIntArr(parsed)); + } catch (NumberFormatException | IndexOutOfBoundsException | ArsdorintException err) { + return new CommandWrong(CommandMark.SYNTAX); + } + } + + public Command unmark(String command) { + try { + String[] parsed = command.split(" "); + if (parsed.length < 1) { + throw new ArsdorintException(); + } return new CommandUnmark(strToIntArr(parsed)); + } catch (NumberFormatException | IndexOutOfBoundsException | ArsdorintException err) { + return new CommandWrong(CommandUnmark.SYNTAX); + } +} + + public Command delete(String command) { + try { + String[] parsed = command.split(" "); + if (parsed.length < 1) { + throw new ArsdorintException(); + } return new CommandDelete(strToIntArr(parsed)); + } catch (NumberFormatException | IndexOutOfBoundsException | ArsdorintException err) { + return new CommandWrong(CommandDelete.SYNTAX); + } + } + + public Command addToDo(String taskDescription) { + try { + String[] parsed = taskDescription.split("/"); + if (parsed[0].equals("")) { + throw new ArsdorintException("Error: Empty Todo Description."); + } + return new CommandToDo(taskDescription); + } catch (ArrayIndexOutOfBoundsException | ArsdorintException | NumberFormatException err) { + return new CommandWrong(CommandToDo.SYNTAX); + } + } + + public Command addDeadline(String taskDescription) { + try { + String[] parsed = taskDescription.split("/"); + if (!(parsed.length == 2)) { + throw new ArsdorintException("Error: Empty Deadline Description."); + } + return new CommandDeadline(parsed[0].trim(), parsed[1].trim()); + } catch (ArrayIndexOutOfBoundsException | ArsdorintException | NumberFormatException err) { + return new CommandWrong(CommandDeadline.SYNTAX); + } + } + + public Command addEvent(String taskDescription) { + try { + String[] parsed = taskDescription.split("/"); + if (!(parsed.length == 2)) { + throw new ArsdorintException("Error: Empty Event Description."); + } + return new CommandEvent(parsed[0].trim(), parsed[1].trim()); + } catch (ArrayIndexOutOfBoundsException | ArsdorintException | NumberFormatException err) { + return new CommandWrong(CommandEvent.SYNTAX); + } + } + + public Command addDate(String taskDescription) { + try { + return new CommandDate(LocalDate.parse(taskDescription)); + } catch (DateTimeParseException err) { + return new CommandWrong(CommandDate.SYNTAX); + } + } + + public Command addFind(String taskDescription) { + try { + if (taskDescription.equals("")) { + throw new ArsdorintException(); + } + return new CommandFind(taskDescription); + } catch (ArsdorintException err) { + return new CommandWrong(CommandFind.SYNTAX); + } + } + + private static void todoParser(String[] parsed) throws ArsdorintFileException { + + if (!(parsed.length == 3)) { + throw new ArsdorintFileException(); + } + TaskList.list.add(new Todo(Boolean.valueOf(parsed[1]), parsed[2])); + } + + private static void deadlineParser(String[] parsed) throws ArsdorintFileException { + if (!(parsed.length == 4)) { + throw new ArsdorintFileException(); + } + TaskList.list.add(new Deadline(Boolean.valueOf(parsed[1]), parsed[2], parsed[3])); + } + + private static void eventParser(String[] parsed) throws ArsdorintFileException { + if (!(parsed.length == 4)) { + throw new ArsdorintFileException(); + } + TaskList.list.add(new Event(Boolean.valueOf(parsed[1]), parsed[2], parsed[3])); + } + + + private int[] strToIntArr(String[] parsed) throws ArsdorintException { + int[] intArr = new int[parsed.length]; + for (int i = 0; i < parsed.length; i++) { + intArr[i] = Integer.parseInt(parsed[i]) - OFFSET; + if (intArr[i] < 0 | intArr[i] > TaskList.list.size()) { + throw new ArsdorintException(); + } + } + return intArr; + } + + +} diff --git a/src/main/java/Arsdorint/task/Deadline.java b/src/main/java/Arsdorint/task/Deadline.java new file mode 100644 index 000000000..f523fe225 --- /dev/null +++ b/src/main/java/Arsdorint/task/Deadline.java @@ -0,0 +1,61 @@ +package Arsdorint.task; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +public class Deadline extends Task { + public static final String TYPE_DEADLINE = "D"; + public String dateString; + public LocalDate date; + public Deadline(String description, String date) { + super(description); + this.taskType = "[D]"; + this.taskName = TYPE_DEADLINE; + try { + this.date = LocalDate.parse(date); + } catch (DateTimeParseException err) { + this.date = null; + this.dateString = date; + } + } + + /** + * Initiate with status + */ + public Deadline(boolean status, String description, String date) { + this(description, date); + this.isDone = status; + } + @Override + public String toSave() { + return (this.taskName + VERTICAL_BAR + binaryRes() + VERTICAL_BAR + + this.description + VERTICAL_BAR + printDate("yyyy-MM-dd") + "\n"); + } + + @Override + public String toString() { + return (this.taskType + this.getStatus() + " " + this.description + "\t(" + printDate("d MMM yyy") + ")"); + } + + /** + * A boolean function to check if the date input is null or not + * + * @return true if the date is null + */ + @Override + public boolean isDateNull() { + return (this.date == null ? true : false); + } + + /** + * Print the date in right format (DDDD-MM-YY) + */ + public String printDate(String pattern) { + return (this.date == null) ? this.dateString : this.date.format(DateTimeFormatter.ofPattern(pattern)); + } + public LocalDate getDate() { + return this.date; + } + +} diff --git a/src/main/java/Arsdorint/task/Event.java b/src/main/java/Arsdorint/task/Event.java new file mode 100644 index 000000000..8aa218864 --- /dev/null +++ b/src/main/java/Arsdorint/task/Event.java @@ -0,0 +1,59 @@ +package Arsdorint.task; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +public class Event extends Task { + public static final String TYPE_EVENT = "E"; + public String dateString; + public LocalDate date; + public Event(String description, String date) { + super(description); + try { + this.date = LocalDate.parse(date); + } catch (DateTimeParseException err) { + this.date = null; + this.dateString = date; + } + this.taskType = "[E]"; + this.taskName = TYPE_EVENT; + } + + + /** + * Initiate with status + */ + public Event(boolean status, String description, String date) { + this(description, date); + this.isDone = status; + } + + @Override + public String toSave() { + return (this.taskName + VERTICAL_BAR + binaryRes() + VERTICAL_BAR + + this.description + VERTICAL_BAR + printDate("yyyy-MM-dd") + "\n"); + } + + @Override + public String toString() { + return (this.taskType + this.getStatus() + " " + this.description + "\t(" + printDate("d MMM yyy") + ")"); + } + + /** + * A boolean function to check if the date input is null or not + * + * @return true if the date is null + */ + @Override + public boolean isDateNull() { + return (this.date == null ? true : false); + } + + public String printDate(String date) { + return (this.date == null) ? this.dateString : this.date.format(DateTimeFormatter.ofPattern(date)); + } + public LocalDate getDate() { + return this.date; + } +} diff --git a/src/main/java/Arsdorint/task/Task.java b/src/main/java/Arsdorint/task/Task.java new file mode 100644 index 000000000..1284263a1 --- /dev/null +++ b/src/main/java/Arsdorint/task/Task.java @@ -0,0 +1,76 @@ +package Arsdorint.task; + +import java.time.LocalDate; + +public abstract class Task { + // initial number of task must be set to 0 + public static final String VERTICAL_BAR = " | "; + public static final String PARSE_LIMITER = "\\|"; + public static int numOfTasks = 0; + public String description; + public boolean isDone; + public String taskType = "[ ]"; + public String taskName; + public LocalDate date; + + public Task(String description) { + this.description = description; + this.isDone = false; + numOfTasks++; + } + + /** + * toString for viewing + */ + public String toString() { + return (this.taskType + this.getStatus() + " " + this.description); + } + + /** + * Get the status of the task ([X] as marked and [ ] as unmarked) + * + * @return [X] if the task is done, else [ ] + */ + public String getStatus() { + return (isDone) ? "[X]" : "[ ]"; + } + + /** + * Show the result in binary format (1 and 0) + * + * @return true 1 if the task is done, else 0 + */ + public int binaryRes() { + return (isDone) ? 1 : 0; + } + + public String toSave() { + return (this.taskName + VERTICAL_BAR + binaryRes() + VERTICAL_BAR + this.description + "\n"); + } + + /** + * A boolean function to check if the date input is null or not + * + * @return true if the date is null + */ + public boolean isDateNull() { + return (this.date == null ? true : false); + } + + public LocalDate getDate() { + return this.date; + } + + public void setIsDone(boolean status) { + this.isDone = status; + } + + public String getType() { + return this.taskName; + } + + public boolean isDone() { + return this.isDone; + } +} + diff --git a/src/main/java/Arsdorint/task/Todo.java b/src/main/java/Arsdorint/task/Todo.java new file mode 100644 index 000000000..359eae0c5 --- /dev/null +++ b/src/main/java/Arsdorint/task/Todo.java @@ -0,0 +1,18 @@ +package Arsdorint.task; + +public class Todo extends Task { + public static final String TYPE_TODO = "T"; + public Todo(String description) { + super(description); + this.taskName = TYPE_TODO; + this.taskType = "[T]"; + } + + /** + * Initiate with status + */ + public Todo(boolean status, String description) { + this(description); + this.isDone = status; + } +} 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/storage/arsdorintTask.txt b/storage/arsdorintTask.txt new file mode 100644 index 000000000..4dbee1dfe --- /dev/null +++ b/storage/arsdorintTask.txt @@ -0,0 +1,8 @@ +<<<<<<< HEAD +T | 0 | midterm +D | 0 | midterm | by tommorrow +D | 0 | midterm | 2023-3-4 +D | 0 | midterm | 2023-03-04 +E | 0 | Open House | at Sunday +E | 0 | NUS football match | 2023-03-05 + diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e..ee91b5110 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,100 @@ Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| + ___ _ _ + / _ \ _____ _____ ___| | ___ _____ _ _____ _| |_ + / /_\ \ / ___| / __/ / _ | / _ \ / ___| | | | _ \ |_ _| + / _____ \ | / __\ \ | |_| | | |_| | | / | | | | | | | | +/_/ \_\ |_| /____/ \_____| \___/ |_| |_| |_| |_| |_| +____________________________________________________________ + Hello! I'm TaskList, a member of TaskList Team. + Please Type The Command As Follow: + +> Type "list" to list all the tasks. +> Type "mark" follow by a number x to mark x tasks in the list. +> Type "unmark" follow by a number y to unmark y tasks in the list. +> Type "todo" follow by a string x to add a work that need to be done. +> Type "deadline /x y" with x is the type of work, y is the time or date of the deadline. +> Type "event x /y" with x is the event, y is the time or date of that event. +> Type "bye" to exit. + + What can I do for you? +____________________________________________________________ + +=( OOPS!!! I'm sorry, but I don't know what that means :-( +____________________________________________________________ + +____________________________________________________________ + + +____________________________________________________________ + +Got it. I've added this task: + +[T][ ] CS2113 tp CS2113 tp + Now you have 3 tasks in the list. +____________________________________________________________ + +____________________________________________________________ + +Got it. I've added this task: + +[E][ ] Valentine (at 14th February) + Now you have 4 tasks in the list. +____________________________________________________________ + +Here are the tasks in your list: + +____________________________LIST____________________________ +1.[T][ ] CS2113 ip +2.[T][ ] CS2113 tp +3.[T][ ] CS2113 tp CS2113 tp +4.[E][ ] Valentine (at 14th February) +____________________________________________________________ + +____________________________________________________________ + +Got it. I've added this task: + +[D][ ] EE2026 (by next-week) + Now you have 5 tasks in the list. +____________________________________________________________ + +Nice! I've marked this task as done: + +____________________________LIST____________________________ +1.[T][ ] CS2113 ip +2.[T][ ] CS2113 tp +3.[T][X} CS2113 tp CS2113 tp +4.[E][ ] Valentine (at 14th February) +5.[D][ ] EE2026 (by next-week) +____________________________________________________________ + +Nice! I've marked this task as done: + +____________________________LIST____________________________ +1.[T][ ] CS2113 ip +2.[T][X} CS2113 tp +3.[T][X} CS2113 tp CS2113 tp +4.[E][ ] Valentine (at 14th February) +5.[D][ ] EE2026 (by next-week) +____________________________________________________________ + +OK, I've marked this task as not done yet: + +____________________________LIST____________________________ +1.[T][ ] CS2113 ip +2.[T][X} CS2113 tp +3.[T][X} CS2113 tp CS2113 tp +4.[E][ ] Valentine (at 14th February) +5.[D][ ] EE2026 (by next-week) +____________________________________________________________ + +Here are the tasks in your list: + +____________________________LIST____________________________ +1.[T][ ] CS2113 ip +2.[T][X} CS2113 tp +3.[T][X} CS2113 tp CS2113 tp +4.[E][ ] Valentine (at 14th February) +5.[D][ ] EE2026 (by next-week) +____________________________________________________________ diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb..a194a32ea 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,10 @@ +boook +todo CS2113 ip +toDO CS2113 tp +EvenT Valentine /at 14th February +list +Deadline EE2026 /by next-week +Mark 3 +marK 2 +unmark 3 +list \ No newline at end of file