diff --git a/.gitignore b/.gitignore index 2873e189e..e84827440 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ bin/ /text-ui-test/ACTUAL.TXT text-ui-test/EXPECTED-UNIX.TXT +taskfile.txt +MANIFEST.MF diff --git a/docs/README.md b/docs/README.md index 8077118eb..f5ee53304 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,29 +1,213 @@ -# User Guide +# BotBuddy -## Features +This is a simple CLI todo app written in Java. +## Quick start -### Feature-ABC +1. Ensure you have Java 11 or above installed in your Computer. -Description of the feature. +1. Download the latest ip.jar from the Releases page. -### Feature-XYZ +1. Copy the file to the folder you want to use as the home folder for this application. -Description of the feature. +1. Open a terminal, cd into the folder you put the jar file in, and use the java -jar ip.jar command to run the application. + +``` +____________________________________________________________ +Hello from BotBuddy! +What can I do for you? +____________________________________________________________ + ``` +5. Refer to the Features below for details of each command. + +## Features +Words in UPPER_CASE are the parameters to be supplied by the user. + +Typing any invalid command will show a list of valid commands. + +### 1. Adding a todo +Adds a todo to the task list. + +Fields: description + +Syntax: +``` +todo DESCRIPTION +``` +Example: +``` +____________________________________________________________ +todo buy milk +____________________________________________________________ +Got it, I've added this task: +[T][ ] buy milk +____________________________________________________________ +``` + +### 2. Adding an event +Adds an event to the task list. + +Fields: description, from, to + +Syntax: +``` +todo DESCRIPTION /from FROM_WHEN /to TO_WHEN +``` +Example: +``` +____________________________________________________________ +event My Holiday /from Wednesday /to Friday +____________________________________________________________ +Got it, I've added this task: +[E][ ] My Holiday (from: Wednesday to: Friday) +____________________________________________________________ +``` + +### 3. Adding a deadline +Adds a deadline to the task list. + +Fields: description, by + +Syntax: +``` +todo DESCRIPTION /by BY_WHEN +``` +Example: +``` +____________________________________________________________ +deadline Submit Project /by this Friday +____________________________________________________________ +Got it, I've added this task: +[D][ ] Submit Project (by: this Friday) +____________________________________________________________ +``` + +### 4. List tasks +List all the tasks currently in the task list + +Fields: none + +Syntax: +``` +list +``` +Example: +``` +____________________________________________________________ +list +____________________________________________________________ +1. [T][X] this is a todo +2. [E][X] an event (from: 1 oct to: 2 oct) +3. [D][ ] submit project (by: friday) +4. [T][ ] buy milk +5. [E][ ] My Holiday (from: Wednesday to: Friday) +6. [D][ ] Submit Project (by: this Friday) +____________________________________________________________ +``` + +The first column indicates if the task is a `[T]` todo, `[E]` event, or a `[D]` deadline. + +An `[X]` in the second column indicates that the task is marked as done. + +### 5. Mark a task as done +Marks a task in the task list as done. + +Fields: task number + +Syntax: +``` +mark TASK_NUMBER +``` +Example: +``` +____________________________________________________________ +mark 4 +____________________________________________________________ +I've marked this task as done: +[T][X] buy milk +____________________________________________________________ +``` + +### 6. Unmark a task +Unmarks a task in the task list i.e. it is undone. + +Fields: task number + +Syntax: +``` +unmark TASK_NUMBER +``` +Example: +``` +____________________________________________________________ +unmark 4 +____________________________________________________________ +I've unmarked this task: +[T][ ] buy milk +____________________________________________________________ +``` -## Usage +### 7. Delete a task +Deletes a task from the task list. -### `Keyword` - Describe action +Fields: task number -Describe the action and its outcome. +Syntax: +``` +delete TASK_NUMBER +``` +Example: +``` +____________________________________________________________ +delete 4 +____________________________________________________________ +I've deleted this task: +[T][ ] buy milk +____________________________________________________________ +``` -Example of usage: +### 8. Find a task +Searches for a task in the task list. Case sensitive. -`keyword (optional arguments)` +Fields: search string -Expected outcome: +Syntax: +``` +find SEARCH_STRING +``` +Example: +``` +____________________________________________________________ +find book +____________________________________________________________ +Here are the found tasks for 'book': +____________________________________________________________ +____________________________________________________________ +1. [T][X] read a book +5. [D][ ] return book (by: 7 oct) +____________________________________________________________ +``` -Description of the outcome. +### 9. Exit program +Exits the program +Syntax: +``` +bye +``` +Example: ``` -expected output +____________________________________________________________ +bye +____________________________________________________________ +Goodbye, hope to see you again soon! +____________________________________________________________ ``` + +### Saving data +Task list data is saved in a file automatically after any command that changes the data. + +There is no need to save manually. + +### Editing the data file +AddressBook data are saved automatically as a txt file [JAR file location]/data/taskfile.txt. +Advanced users are welcome to update data directly by editing that data file. \ No newline at end of file diff --git a/src/main/java/BotBuddy/BotBuddy.java b/src/main/java/BotBuddy/BotBuddy.java new file mode 100644 index 000000000..bd862aa87 --- /dev/null +++ b/src/main/java/BotBuddy/BotBuddy.java @@ -0,0 +1,245 @@ +package BotBuddy; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +/** + * The BotBuddy class represents the main application class for the BotBuddy program. + */ +public class BotBuddy { + + private Storage storage; + private TaskList tasks; + private Ui ui; + private Parser parser; + + /** + * Initializes the required objects and loads data from the storage file. + * + * @param filePath the relative file path of the storage file. + * @param directoryName the name of the directory in which the storage file is located. + */ + public BotBuddy(String filePath, String directoryName) { + ui = new Ui(); + parser = new Parser(); + + // check if storage file exists, if not try to create it + try { + storage = new Storage(filePath, directoryName, ui); + } catch (IOException e) { + ui.printCreateTaskFileErrorMsg(); + System.exit(1); + } + + // try to read from storage file + try { + tasks = new TaskList(storage.load()); + } catch (FileNotFoundException e) { + ui.printCreateTaskFileErrorMsg(); + System.exit(1); + } catch (BotBuddyException e) { + ui.printToUser(e.getMessage()); + System.exit(1); + } + + } + + public static void main(String[] args) { + new BotBuddy("data/taskfile.txt", "data").run(); + } + + /** + * Runs the program until the bye command is given. + */ + public void run() { + ui.printWelcomeMsg(); + String command = ""; + String parameters = ""; + do { + String userInput = ui.getUserInput(); + String[] inputArr = parser.parseInput(userInput); + command = inputArr[0]; + if (inputArr.length == 2) { + parameters = inputArr[1]; + } else { + parameters = ""; + } + + try { + parser.validateInput(command, parameters); + } catch (BotBuddyException e) { + ui.printToUser(e.getMessage()); + continue; + } + + + switch (command) { + case "todo": + addTodo(parameters); + break; + + case "event": + addEvent(parameters); + break; + + case "deadline": + addDeadline(parameters); + break; + + case "list": + listTasks(); + break; + + case "mark": + markTask(parameters); + break; + + case "unmark": + unmarkTask(parameters); + break; + + case "delete": + deleteTask(parameters); + break; + + case "find": + findTask(parameters); + break; + + case "bye": + exitProgram(); + return; + } + + // write to file here + try { + storage.store(tasks.getTaskArrayList()); + } catch (IOException e) { + ui.printTaskFileWriteErrorMsg(); + } + + } while (!command.equals("bye")); + } + + /** + * Adds a todo and prints confirmation to the user. + * + * @param description Description of the todo. + */ + public void addTodo(String description) { + int noOfTasks = Task.getNoOfTasks(); + tasks.addTodoToTaskList(description); + ui.printToUser("Got it, I've added this task:" + + System.lineSeparator() + + tasks.getTaskArrayList().get(noOfTasks)); + } + + /** + * Adds an event and prints confirmation to the user. + * + * @param unparsedEventDetails String containing description, from date, and to date of event. + */ + public void addEvent(String unparsedEventDetails) { + int noOfTasks = Task.getNoOfTasks(); + String[] eventDetails = parser.parseEventDetails(unparsedEventDetails); + tasks.addEventToTaskList(eventDetails); + ui.printToUser("Got it, I've added this task:" + + System.lineSeparator() + + tasks.getTaskArrayList().get(noOfTasks)); + } + + /** + * Adds a deadline and prints confirmation to the user. + * + * @param unparsedDeadlineDetails String containing description and by date of deadline. + */ + public void addDeadline(String unparsedDeadlineDetails) { + int noOfTasks = Task.getNoOfTasks(); + String[] deadlineDetails = parser.parseDeadlineDetails(unparsedDeadlineDetails); + tasks.addDeadlineToTaskList(deadlineDetails); + ui.printToUser("Got it, I've added this task:" + + System.lineSeparator() + + tasks.getTaskArrayList().get(noOfTasks)); + } + + /** + * Checks if there are tasks in the task list and prints them to the user if they exist. + */ + public void listTasks() { + int noOfTasks = Task.getNoOfTasks(); + if (noOfTasks == 0) { + ui.printToUser("There are currently no tasks!"); + return; + } + ui.printUnderscores(); + tasks.listTasksInTaskList(noOfTasks); + ui.printUnderscores(); + } + + /** + * Marks a task as done and prints confirmation to the user. + * + * @param taskToMark Task number to mark as done. + */ + public void markTask(String taskToMark) { + int taskIndex = Integer.parseInt(taskToMark) - 1; + tasks.markTaskInTaskList(taskIndex); + ui.printToUser("I've marked this task as done:" + + System.lineSeparator() + + tasks.getTaskArrayList().get(taskIndex)); + } + + /** + * Unmarks a task as done and prints confirmation to the user. + * + * @param taskToUnmark Task number to unmark as done. + */ + public void unmarkTask(String taskToUnmark) { + int taskIndex = Integer.parseInt(taskToUnmark) - 1; + tasks.unmarkTaskInTaskList(taskIndex); + ui.printToUser("I've unmarked this task:" + + System.lineSeparator() + + tasks.getTaskArrayList().get(taskIndex)); + } + + /** + * Deletes a task and prints confirmation to the user. + * + * @param taskToDelete Task number to delete. + */ + public void deleteTask(String taskToDelete) { + int taskIndex = Integer.parseInt(taskToDelete) - 1; + String tempMessage = String.valueOf(tasks.getTaskArrayList().get(taskIndex)); + int noOfTasks = Task.getNoOfTasks(); + tasks.removeTaskFromTaskList(taskIndex); + Task.setNoOfTasks(noOfTasks - 1); + ui.printToUser("I've deleted this task:" + + System.lineSeparator() + + tempMessage); + } + + /** + * Searches for tasks and prints them to the user. + * + * @param searchString String to search for amongst tasks. + */ + public void findTask(String searchString) { + int noOfTasks = Task.getNoOfTasks(); + ui.printToUser("Here are the found tasks for '" + searchString + "':"); + ui.printUnderscores(); + tasks.findTasksInTaskList(searchString, noOfTasks); + ui.printUnderscores(); + } + + /** + * Prints the exit message. + */ + public void exitProgram() { + ui.printExitMsg(); + } + +} diff --git a/src/main/java/BotBuddy/BotBuddyException.java b/src/main/java/BotBuddy/BotBuddyException.java new file mode 100644 index 000000000..1b26c74dd --- /dev/null +++ b/src/main/java/BotBuddy/BotBuddyException.java @@ -0,0 +1,7 @@ +package BotBuddy; + +public class BotBuddyException extends Exception { + public BotBuddyException(String s) { + super(s); + } +} diff --git a/src/main/java/BotBuddy/Deadline.java b/src/main/java/BotBuddy/Deadline.java new file mode 100644 index 000000000..06b4af914 --- /dev/null +++ b/src/main/java/BotBuddy/Deadline.java @@ -0,0 +1,31 @@ +package BotBuddy; + +/** + * Represents a deadline. + * + * @see Task + */ +public class Deadline extends Task { + + protected String by; + + /** + * Creates a deadline object. + * + * @param description Description of the deadline. + * @param by Due date of the deadline. + */ + public Deadline(String description, String by) { + super(description); + this.by = by; + } + + public String getBy() { + return by; + } + + @Override + public String toString() { + return "[D]" + super.toString() + " (by: " + by + ")"; + } +} diff --git a/src/main/java/BotBuddy/Event.java b/src/main/java/BotBuddy/Event.java new file mode 100644 index 000000000..670b2f819 --- /dev/null +++ b/src/main/java/BotBuddy/Event.java @@ -0,0 +1,38 @@ +package BotBuddy; + +/** + * Represents an event. + * + * @see Task + */ +public class Event extends Task { + + protected String from; + protected String to; + + /** + * Creates an event object. + * + * @param description Description of the event. + * @param from Start date of the event. + * @param to End date of the event. + */ + public Event(String description, String from, String to) { + super(description); + this.from = from; + this.to = to; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + @Override + public String toString() { + return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; + } +} diff --git a/src/main/java/BotBuddy/Parser.java b/src/main/java/BotBuddy/Parser.java new file mode 100644 index 000000000..976a419aa --- /dev/null +++ b/src/main/java/BotBuddy/Parser.java @@ -0,0 +1,139 @@ +package BotBuddy; + +/** + * Represents a parser object that parses various user inputs. + * + */ +public class Parser { + /** + * Parses the user input into command and parameters. + * + * @param userInput User input. + * @return Array with command in index 0 and parameters in index 1 if it exists. + */ + public String[] parseInput(String userInput) { + String[] inputArr = userInput.split(" ", 2); + return inputArr; + } + + /** + * Validates the user input based on the command and parameters given. + * + * @param command Command given. + * @param parameters Parameters given. + * @throws BotBuddyException If invalid input is found. + */ + public void validateInput(String command, String parameters) throws BotBuddyException { + switch (command) { + case "todo": + if (parameters.isEmpty()) { + throw new BotBuddyException("The description of a todo cannot be empty!"); + } + break; + + case "event": + String[] eventDetails = parameters.split("/from"); + if (eventDetails.length < 2) { + throw new BotBuddyException("Please enter in the following format:\n" + + "event 'Event Name' /from 'Start Time' /to 'End Time'"); + } + String eventName = eventDetails[0].trim(); + eventDetails = eventDetails[1].split("/to"); + if (eventDetails.length < 2) { + throw new BotBuddyException("Please enter in the following format:\n" + + "event 'Event Name' /from 'Start Time' /to 'End Time'"); + } + String eventFrom = eventDetails[0].trim(); + String eventTo = eventDetails[1].trim(); + if (eventName.isEmpty() || eventTo.isEmpty() || eventFrom.isEmpty()) { + throw new BotBuddyException("Please enter in the following format:\n" + + "event 'Event Name' /from 'Start Time' /to 'End Time'"); + } + break; + + case "deadline": + String[] deadlineDetails = parameters.split("/by"); + if (deadlineDetails.length < 2) { + throw new BotBuddyException("Please enter in the following format:\n" + + "deadline 'Deadline Name' /by 'Due Date'"); + } + String deadlineName = deadlineDetails[0].trim(); + String deadlineBy = deadlineDetails[1].trim(); + if (deadlineName.isEmpty() || deadlineBy.isEmpty()) { + throw new BotBuddyException("Please enter in the following format:\n" + + "deadline 'Deadline Name' /by 'Due Date'"); + } + break; + + case "list": + break; + + case "bye": + break; + + case "mark": + // Fallthrough + + case "unmark": + // Fallthrough + + case "delete": + if (parameters.isEmpty()) { + throw new BotBuddyException("You did not specify which task!"); + } + int taskToModify; + try { + taskToModify = Integer.parseInt(parameters); + } catch (NumberFormatException e) { + throw new BotBuddyException("The task specified should be a number!"); + } + if (taskToModify > Task.getNoOfTasks() || taskToModify < 1) { + throw new BotBuddyException("There is no such task!"); + } + break; + + case "find": + if (parameters.isEmpty()) { + throw new BotBuddyException("You cannot search for nothing! Please try again."); + } + break; + + default: + // invalid command + throw new BotBuddyException("Invalid command! Supported commands are: " + + "todo, event, deadline, list, mark, unmark, delete, find, bye"); + } + } + + /** + * Parses event details. + * + * @param parameters String containing all the event details. + * @return Array with event description, event from, and event to in indexes 0, 1, 2 respectively. + */ + public String[] parseEventDetails(String parameters) { + String[] eventDetails = parameters.split("/from"); + String eventName = eventDetails[0].trim(); + eventDetails = eventDetails[1].split("/to"); + String eventFrom = eventDetails[0].trim(); + String eventTo = eventDetails[1].trim(); + + String[] parsedEventDetails = {eventName, eventFrom, eventTo}; + return parsedEventDetails; + } + + /** + * Parses deadline details. + * + * @param parameters String containing all the deadline details. + * @return Array with deadline description and due date in indexes 0 and 1 respectively. + */ + public String[] parseDeadlineDetails(String parameters) { + String[] deadlineDetails = parameters.split("/by"); + String deadlineName = deadlineDetails[0].trim(); + String deadlineBy = deadlineDetails[1].trim(); + + String[] parsedDeadlineDetails = {deadlineName, deadlineBy}; + return parsedDeadlineDetails; + } +} diff --git a/src/main/java/BotBuddy/Storage.java b/src/main/java/BotBuddy/Storage.java new file mode 100644 index 000000000..4b924deb0 --- /dev/null +++ b/src/main/java/BotBuddy/Storage.java @@ -0,0 +1,189 @@ +package BotBuddy; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +/** + * Represents a storage file that stores application data. + */ +public class Storage { + String filePath; + String directoryName; + + /** + * Checks if the storage file exists, and creates one if it does not. + * + * @param filePath the relative file path of the storage file. + * @param directoryName the name of the directory in which the storage file is located. + * @param ui Ui object to print response to user. + * @throws IOException If IO errors occur. + */ + public Storage(String filePath, String directoryName, Ui ui) throws IOException { + this.filePath = filePath; + this.directoryName = directoryName; + File directory = new File(directoryName); + File taskFile = new File(filePath); + + if (!taskFile.exists()) { + ui.printCreateTaskFileMsg(); + if (!directory.exists()) { + directory.mkdir(); + } + taskFile.createNewFile(); + } + } + + /** + * Loads tasks from the storage file into the task list. + * + * @return Task list. + * @throws FileNotFoundException If storage file does not exist. + * @throws BotBuddyException If storage file is corrupted. + */ + public ArrayList load() throws FileNotFoundException, BotBuddyException { + ArrayList taskArrayList = new ArrayList<>(); + + File taskFile = new File(filePath); + Scanner taskScanner = new Scanner(taskFile); + + while (taskScanner.hasNext()) { + String currentTask = taskScanner.nextLine(); + if (currentTask.startsWith("[T]")) { + currentTask = currentTask.substring(3); + boolean isDone = false; + if (currentTask.startsWith("[X]")) { + isDone = true; + } + currentTask = currentTask.substring(3); + addTodoFromFile(currentTask, taskArrayList); + if (isDone) { + int noOfTasks = Task.getNoOfTasks(); + markTaskFromFile(Integer.toString(noOfTasks), taskArrayList); + } + } else if (currentTask.startsWith("[E]")) { + currentTask = currentTask.substring(3); + boolean isDone = false; + if (currentTask.startsWith("[X]")) { + isDone = true; + } + currentTask = currentTask.substring(3); + addEventFromFile(currentTask, taskArrayList); + if (isDone) { + int noOfTasks = Task.getNoOfTasks(); + markTaskFromFile(Integer.toString(noOfTasks), taskArrayList); + } + } else if (currentTask.startsWith("[D]")) { + currentTask = currentTask.substring(3); + boolean isDone = false; + if (currentTask.startsWith("[X]")) { + isDone = true; + } + currentTask = currentTask.substring(3); + addDeadlineFromFile(currentTask, taskArrayList); + if (isDone) { + int noOfTasks = Task.getNoOfTasks(); + markTaskFromFile(Integer.toString(noOfTasks), taskArrayList); + } + } else { + // this should not run + throw new BotBuddyException("File corrupted!"); + } + } + + return taskArrayList; + } + + /** + * Adds a todo from the storage file into the task list. + * + * @param parameters Details of the todo. + * @param tasks Task list. + */ + public static void addTodoFromFile(String parameters, ArrayList tasks) { + tasks.add(new Todo(parameters)); + } + + /** + * Adds an event from the storage file into the task list. + * + * @param parameters Details of the event. + * @param tasks Task list. + */ + public static void addEventFromFile(String parameters, ArrayList tasks) { + String[] eventDetails = parameters.split("/from"); + String eventName = eventDetails[0].trim(); + eventDetails = eventDetails[1].split("/to"); + String eventFrom = eventDetails[0].trim(); + String eventTo = eventDetails[1].trim(); + tasks.add(new Event(eventName, eventFrom, eventTo)); + } + + /** + * Adds a deadline from the storage file into the task list. + * + * @param parameters Details of the deadline. + * @param tasks Task list. + */ + public static void addDeadlineFromFile(String parameters, ArrayList tasks) { + String[] deadlineDetails = parameters.split("/by"); + String deadlineName = deadlineDetails[0].trim(); + String deadlineBy = deadlineDetails[1].trim(); + tasks.add(new Deadline(deadlineName, deadlineBy)); + } + + /** + * Marks a task in the task list as done if it is marked as done in the storage file. + * + * @param taskToMark Task number to mark as done. + * @param tasks Task list. + */ + public static void markTaskFromFile(String taskToMark, ArrayList tasks) { + int taskIndex = Integer.parseInt(taskToMark) - 1; + tasks.get(taskIndex).markAsDone(); + } + + /** + * Stores data from the task list into the storage file. + * + * @param taskArrayList Task list. + * @throws IOException If there are errors writing to the storage file. + */ + public void store(ArrayList taskArrayList) throws IOException { + FileWriter fileWriter = new FileWriter(filePath); + StringBuilder taskData = new StringBuilder(); + int noOfTasks = Task.getNoOfTasks(); + + for (int i = 0; i < noOfTasks; i++) { + if (taskArrayList.get(i).getClass() == Todo.class) { + Todo currentTodo = (Todo) taskArrayList.get(i); + taskData.append("[T]").append(currentTodo.getStatusIcon()); + taskData.append(currentTodo.getDescription()); + taskData.append(System.lineSeparator()); + } else if (taskArrayList.get(i).getClass() == Event.class) { + Event currentEvent = (Event) taskArrayList.get(i); + taskData.append("[E]").append(currentEvent.getStatusIcon()); + taskData.append(currentEvent.getDescription()); + taskData.append(" /from ").append(currentEvent.getFrom()); + taskData.append(" /to ").append(currentEvent.getTo()); + taskData.append(System.lineSeparator()); + } else if (taskArrayList.get(i).getClass() == Deadline.class) { + Deadline currentDeadline = (Deadline) taskArrayList.get(i); + taskData.append("[D]").append(currentDeadline.getStatusIcon()); + taskData.append(currentDeadline.getDescription()); + taskData.append(" /by ").append(currentDeadline.getBy()); + taskData.append(System.lineSeparator()); + } else { + // This should not run + System.out.println("Fatal error!"); + } + } + + fileWriter.write(taskData.toString()); + fileWriter.close(); + } + +} diff --git a/src/main/java/BotBuddy/Task.java b/src/main/java/BotBuddy/Task.java new file mode 100644 index 000000000..a31465a13 --- /dev/null +++ b/src/main/java/BotBuddy/Task.java @@ -0,0 +1,52 @@ +package BotBuddy; + +/** + * Abstract class that represents tasks. + * + */ +public abstract class Task { + protected String description; + protected boolean isDone; + + /** Number of tasks in the task list */ + private static int noOfTasks = 0; + + public Task(String description) { + this.description = description; + this.isDone = false; + noOfTasks++; + } + + public String getStatusIcon() { + if (isDone) { + return "[X]"; + } else { + return "[ ]"; + } + } + + public String getDescription() { + return description; + } + + public void markAsDone() { + isDone = true; + } + + public void markAsUndone() { + isDone = false; + } + + public static int getNoOfTasks() { + return noOfTasks; + } + + public static void setNoOfTasks(int noOfTasks) { + Task.noOfTasks = noOfTasks; + } + + @Override + public String toString() { + return getStatusIcon() + " " + getDescription(); + } +} diff --git a/src/main/java/BotBuddy/TaskList.java b/src/main/java/BotBuddy/TaskList.java new file mode 100644 index 000000000..3da48fc6e --- /dev/null +++ b/src/main/java/BotBuddy/TaskList.java @@ -0,0 +1,100 @@ +package BotBuddy; + +import java.util.ArrayList; +/** + * Represents a task list. + */ +public class TaskList { + private ArrayList taskArrayList; + + public TaskList(ArrayList taskArrayList) { + this.taskArrayList = taskArrayList; + } + + public ArrayList getTaskArrayList() { + return taskArrayList; + } + + /** + * Adds a todo to the task list. + * + * @param description Description of the todo. + */ + public void addTodoToTaskList(String description) { + taskArrayList.add(new Todo(description)); + } + + /** + * Adds an event to the task list. + * + * @param eventDetails Array with event description, event from, and event to in indexes 0, 1, 2 respectively. + */ + public void addEventToTaskList(String[] eventDetails) { + String eventName = eventDetails[0]; + String eventFrom = eventDetails[1]; + String eventTo = eventDetails[2]; + taskArrayList.add(new Event(eventName, eventFrom, eventTo)); + } + + /** + * Adds a deadline to the task list. + * + * @param deadlineDetails Array with deadline description and due date in indexes 0 and 1 respectively. + */ + public void addDeadlineToTaskList(String[] deadlineDetails) { + String deadlineName = deadlineDetails[0]; + String deadlineBy = deadlineDetails[1]; + taskArrayList.add(new Deadline(deadlineName, deadlineBy)); + } + + /** + * Prints tasks in the task list. + */ + public void listTasksInTaskList(int noOfTasks) { + for (int i = 0; i < noOfTasks; i++) { + System.out.println(i + 1 + ". " + taskArrayList.get(i)); + } + } + + /** + * Marks a task as done in the task list. + * + * @param taskIndex Task index to mark as done. + */ + public void markTaskInTaskList(int taskIndex) { + taskArrayList.get(taskIndex).markAsDone(); + } + + /** + * Unmarks a task as done in the task list. + * + * @param taskIndex Task index to unmark as done. + */ + public void unmarkTaskInTaskList(int taskIndex) { + taskArrayList.get(taskIndex).markAsUndone(); + } + + /** + * Deletes a task from the task list. + * + * @param taskIndex Task index to delete. + */ + public void removeTaskFromTaskList(int taskIndex) { + taskArrayList.remove(taskIndex); + } + + /** + * Searches for tasks in the task list. + * + * @param searchString String to search for amongst tasks. + * @param noOfTasks Number of tasks in the task list. + */ + public void findTasksInTaskList(String searchString, int noOfTasks) { + for (int i = 0; i < noOfTasks; i++) { + String currentTask = String.valueOf(taskArrayList.get(i)); + if (currentTask.contains(searchString)) { + System.out.println(i + 1 + ". " + taskArrayList.get(i)); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/BotBuddy/Todo.java b/src/main/java/BotBuddy/Todo.java new file mode 100644 index 000000000..42383e65e --- /dev/null +++ b/src/main/java/BotBuddy/Todo.java @@ -0,0 +1,22 @@ +package BotBuddy; + +/** + * Represents a todo. + * + * @see Task + */ +public class Todo extends Task { + /** + * Creates a task object. + * + * @param description Description of the todo. + */ + public Todo(String description) { + super(description); + } + + @Override + public String toString() { + return "[T]" + super.toString(); + } +} diff --git a/src/main/java/BotBuddy/Ui.java b/src/main/java/BotBuddy/Ui.java new file mode 100644 index 000000000..92a08353c --- /dev/null +++ b/src/main/java/BotBuddy/Ui.java @@ -0,0 +1,58 @@ +package BotBuddy; + +import java.util.Scanner; + +/** + * The Ui class contains methods to print messages to the user and get input from the user + * + */ +public class Ui { + public void printUnderscores() { + System.out.println("____________________________________________________________"); + } + + public void printCreateTaskFileMsg() { + printUnderscores(); + System.out.println("Task file not found! Creating one..."); + printUnderscores(); + } + + public void printCreateTaskFileErrorMsg() { + printUnderscores(); + System.out.println("Error creating task file... Exiting!"); + printUnderscores(); + } + + public void printTaskFileWriteErrorMsg() { + printUnderscores(); + System.out.println("Error writing to file!"); + printUnderscores(); + } + + public void printWelcomeMsg() { + printUnderscores(); + System.out.println("Hello from BotBuddy!"); + System.out.println("What can I do for you?"); + printUnderscores(); + } + + public void printToUser(String msg) { + printUnderscores(); + System.out.println(msg); + printUnderscores(); + } + + public String getUserInput() { + Scanner in = new Scanner(System.in); + String input = in.nextLine().trim(); + return input; + } + + public void printExitMsg() { + printUnderscores(); + System.out.println("Goodbye, hope to see you again soon!"); + printUnderscores(); + } +} + + 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/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e..c39c01d27 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,19 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| - +____________________________________________________________ +Hello from BotBuddy! +What can I do for you? +____________________________________________________________ +____________________________________________________________ +Got it, I've added this task: +[T][ ] hiok +____________________________________________________________ +____________________________________________________________ +Got it, I've added this task: +[E][ ] hue (from: hiokhiok to: huehue) +____________________________________________________________ +____________________________________________________________ +Got it, I've added this task: +[D][ ] everything (by: nowwww) +____________________________________________________________ +____________________________________________________________ +Goodbye, hope to see you again soon! +____________________________________________________________ diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb..65ed2ccd2 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,4 @@ +todo hiok +event hue /from hiokhiok /to huehue +deadline everything /by nowwww +bye \ No newline at end of file diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh old mode 100644 new mode 100755 index c9ec87003..b36790c82 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -22,12 +22,8 @@ fi # run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT java -classpath ../bin Duke < input.txt > ACTUAL.TXT -# convert to UNIX format -cp EXPECTED.TXT EXPECTED-UNIX.TXT -dos2unix ACTUAL.TXT EXPECTED-UNIX.TXT - # compare the output to the expected output -diff ACTUAL.TXT EXPECTED-UNIX.TXT +diff ACTUAL.TXT EXPECTED.TXT if [ $? -eq 0 ] then echo "Test result: PASSED" @@ -35,4 +31,4 @@ then else echo "Test result: FAILED" exit 1 -fi \ No newline at end of file +fi