diff --git a/README.md b/README.md index 8715d4d91..6095ffb21 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,8 @@ Prerequisites: JDK 11, update Intellij to the most recent version. | | | | | | | |/ / _ \ | |_| | |_| | < __/ |____/ \__,_|_|\_\___| + + ``` + +wang silang diff --git a/docs/README.md b/docs/README.md index 8077118eb..c5818a880 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,29 +1,171 @@ -# User Guide +# Duke: Your Personal Agenda Assistant 📑 -## Features +Duke is a Java personal agenda keeper. He is smart enough to assist in your daily activity planning. Below are his functionalities: -### Feature-ABC +1. [Add Task](#add) + 1. [Todo](#t) + 2. [Event](#e) + 3. [Deadline](#d) +2. [Mark/Unmark Task](#mum) + 1. [Mark Task](#mt) + 2. [Unmark Task](#u) +3. [Delete Task](#dt) +4. [List Task](#lt) +5. [Find Task](#ft) +6. [Exit](#end) +-------------------------------------------------------------------- +# NOTE: +* Follow the input format as mentioned below to avoid errors. +-------------------------------------------------------------------- -Description of the feature. +# 1. Add Task -### Feature-XYZ +You can add 3 types of tasks, Todos, Events and Deadlines. -Description of the feature. +## 1.1. Todo +* COMMAND: todo {task} -## Usage -### `Keyword` - Describe action +Input: -Describe the action and its outcome. +```todo return book``` -Example of usage: +Output: +``` +As per requested Sire, this task has been added to your calendar. +[T][ ] return book +You now have 7 items left +``` + + +## 1.2. Event +* COMMAND: event {task} \from {string} \to {string} + +Input: + +```event meeting with friend /from 4pm /to 6pm``` + +Output: +``` +As per requested Sire, this task has been added to your calendar. +[E][ ] meeting with friend (from: 4pm to: 6pm) +You now have 8 items left +``` + +## 1.3. Deadline +* Command: deadline {task} \by {string} + +Input: + +```deadline finish CS2113 assignment/by Sunday``` + +Output: +``` +As per requested Sire, this task has been added to your calendar. +[D][ ] finish CS2113 assignmen (by: Sunday) +You now have 9 items left +``` + + +# 2. Mark/Unmark Task + +Mark the task at the index keyed in by users as done, or unmark it as unfinished. +For index of all current tasks, please see [List Task](#lt). + +## 2.1. Mark Task +* COMMAND: mark {enter task_index} + +Input: + +```mark 1``` + +Output: + +``` +Sir, your task has been marked as completed. +[T][X] Finish CS2113 iP +``` + +## 2.2. Unmark Task +* COMMAND: unmark {enter task_index} + +Input: + +```unmark 2``` + +Output: + +``` +Sir, your task has been unmarked as requested. +[T][ ] sleep +``` + +# 3. Delete Task + +Delete task at keyed in index as follows: + +* COMMAND: delete {enter task_index} + +Input: + +```delete 1``` + +Output: + +``` +Sire, I have removed this task from your schedule +[T][X] Finish CS2113 iP +You now have 8 items left +``` + +# 4. List Task + +List all tasks in the list as follows: + +* COMMAND: list + +Input: + +```list``` -`keyword (optional arguments)` +Output: -Expected outcome: +``` +Your current list of items as requested, sir. +1.[T][ ] sleep +2.[E][ ] project meeting (from: Mon 2pm to: 4pm) +3.[T][ ] return book +4.[E][ ] meeting with friend (from: 4pm to: 6pm) +``` + +# 5. Find Task + +Find the desired tasks by keying in a term they contain as follows: -Description of the outcome. +* COMMAND: find {keyword} +Input: + +```find friend``` + +Output: ``` -expected output +Here are the matching items Sire: +[E][ ] meeting with friend (from: 4pm to: 6pm) ``` + + +# 6. Exit + +Exit the program as follows: + +Input: + +```bye``` + +Output: +``` +Glad I could be of help! +``` + +# End of user guide diff --git a/src/.idea/workspace.xml b/src/.idea/workspace.xml new file mode 100644 index 000000000..a4dceeceb --- /dev/null +++ b/src/.idea/workspace.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + { + "keyToString": { + "RunOnceActivity.OpenProjectViewOnStart": "true", + "RunOnceActivity.ShowReadmeOnStart": "true", + "WebServerToolWindowFactoryState": "false", + "last_opened_file_path": "/Users/wangsilang/Desktop/Codes/CS2113/iP/ip/src", + "node.js.detected.package.eslint": "true", + "node.js.detected.package.tslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "node.js.selected.package.tslint": "(autodetect)", + "vue.rearranger.settings.migration": "true" + } +} + + + + + 1676455852136 + + + + + + \ 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/Duke/Duke.java b/src/main/java/Duke/Duke.java new file mode 100644 index 000000000..0d358eaff --- /dev/null +++ b/src/main/java/Duke/Duke.java @@ -0,0 +1,46 @@ +package Duke; + +public class Duke { + private Ui ui; + private Storage storage; + private TaskList tasklist; + private Parser parser; + private final int PARSERINDEX = 1; + + public Duke(String filePath) { + ui = new Ui(); + storage = new Storage(); + tasklist = new TaskList(filePath); + parser = new Parser(); + } + + public void run() { + ui.greet(); + while (parser.getIsRunning()) { + String commandToBeParsed = ui.readCommand(); + String commandParsed = parser.parseCommand(commandToBeParsed); + if (commandParsed.startsWith("B")) { // bye from user, terminate program + parser.setIsRunning(false); + } else if (commandParsed.startsWith("L")) { // print list + tasklist.printCurrentList(); + } else if (commandParsed.startsWith("F")) { // find tasks in list + tasklist.printTasksFound(commandParsed.substring(PARSERINDEX)); + } else if (commandParsed.startsWith("M")) { // mark task + tasklist.mark(commandParsed.substring(PARSERINDEX)); + } else if (commandParsed.startsWith("U")) { // unmark task + tasklist.unmark(commandParsed.substring(PARSERINDEX)); + } else if (commandParsed.startsWith("D")) { // delete task + tasklist.delete(commandParsed.substring(PARSERINDEX)); + } else if (commandParsed.startsWith("XNC")) { // null command error + ui.printErrorMessage("Sire, I am not trained to understand gibberish."); + } else { // task keyed in by users + tasklist.addTask(commandParsed.substring(PARSERINDEX)); + } + } + ui.bye(); + } + + public static void main(String[] args) { + new Duke("dukeData.txt").run(); + } +} diff --git a/src/main/java/Duke/Exception/EmptyDeadlineException.java b/src/main/java/Duke/Exception/EmptyDeadlineException.java new file mode 100644 index 000000000..9dfeae63b --- /dev/null +++ b/src/main/java/Duke/Exception/EmptyDeadlineException.java @@ -0,0 +1,4 @@ +package Duke.Exception; + +public class EmptyDeadlineException extends Exception { +} diff --git a/src/main/java/Duke/Exception/EmptyEventsException.java b/src/main/java/Duke/Exception/EmptyEventsException.java new file mode 100644 index 000000000..be113f705 --- /dev/null +++ b/src/main/java/Duke/Exception/EmptyEventsException.java @@ -0,0 +1,4 @@ +package Duke.Exception; + +public class EmptyEventsException extends Exception { +} diff --git a/src/main/java/Duke/Exception/EmptyToDoException.java b/src/main/java/Duke/Exception/EmptyToDoException.java new file mode 100644 index 000000000..502c680e1 --- /dev/null +++ b/src/main/java/Duke/Exception/EmptyToDoException.java @@ -0,0 +1,4 @@ +package Duke.Exception; + +public class EmptyToDoException extends Exception { +} diff --git a/src/main/java/Duke/Exception/NullCommandException.java b/src/main/java/Duke/Exception/NullCommandException.java new file mode 100644 index 000000000..3e080511a --- /dev/null +++ b/src/main/java/Duke/Exception/NullCommandException.java @@ -0,0 +1,4 @@ +package Duke.Exception; + +public class NullCommandException extends Exception { +} diff --git a/src/main/java/Duke/Parser.java b/src/main/java/Duke/Parser.java new file mode 100644 index 000000000..4a63ee71b --- /dev/null +++ b/src/main/java/Duke/Parser.java @@ -0,0 +1,65 @@ +package Duke; + +import Duke.Exception.NullCommandException; +import Duke.Task.Task; + +public class Parser { + private boolean isRunning = true; + + /** + * Parse the input from user to determine what to do with the given input by appending + * a characteristic letter in front. + * + * @param line input from user to be parsed. + * @return a string of user's input with characteristic letter appended to the front. + * @throws NullCommandException If input is in invalid format. + */ + public String parseCommand(String line) { + if (line.equals("bye")) { + return "B"; + } else if (line.equals("list")) { + return "L"; + } else if (line.startsWith("mark")) { + return "M" + line; + } else if (line.startsWith("unmark")) { + return "U" + line; + } else if (line.startsWith("delete")) { + return "D" + line; + } else if (line.startsWith("find")) { + return "F" + line; + } else { + try { + Task newTask = new Task(line); + if (line.startsWith("todo")) { + return "T" + line; + } else if (line.startsWith("deadline")) { + return "A" + line; + } else if (line.startsWith("event")) { + return "E" + line; + } else { + throw new NullCommandException(); + } + } catch (NullCommandException e) { + return "XNC"; + } + } + } + + /** + * Gets the boolean value of parser object, for termination check of program + * + * @return boolean value of isRunning. + */ + public boolean getIsRunning() { + return this.isRunning; + } + + /** + * Sets the boolean value of parser object, to terminate the program + * + * @param bool boolean value of parser object to be set. + */ + public void setIsRunning(boolean bool) { + this.isRunning = bool; + } +} diff --git a/src/main/java/Duke/Storage.java b/src/main/java/Duke/Storage.java new file mode 100644 index 000000000..22caa1c9d --- /dev/null +++ b/src/main/java/Duke/Storage.java @@ -0,0 +1,133 @@ +package Duke; + +import Duke.Exception.EmptyDeadlineException; +import Duke.Exception.EmptyEventsException; +import Duke.Exception.EmptyToDoException; +import Duke.Task.Deadlines; +import Duke.Task.Events; +import Duke.Task.Task; +import Duke.Task.ToDos; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +public class Storage { + private static final int BRACKETSKIP_INDEX = 7; + private static final int FIRSTBRACKET_FRONT = 0; + private static final int FIRSTBRACKET_BACK = 3; + private static final int SECONDBRACKET_FRONT = 3; + private static final int SECONDBRACKET_BACK = 6; + + + private static void writeToFile(String filePath, String textToAdd) throws IOException { + FileWriter fw = new FileWriter(filePath); + fw.write(textToAdd); + fw.close(); + } + + /** + * Write the data to the default file location + * + * @param taskToBeStored info to be written to the file. + * @throws IOException If default file location is invalid. + */ + public static void dukeDataStorage(String taskToBeStored) { + File f = new File("dukeData.txt"); + try { + if (!f.exists()) { + f.createNewFile(); + } + writeToFile("dukeData.txt", taskToBeStored); + } catch (IOException e) { + System.out.println("File creation of writing invalid"); + } + } + + /** + * Parse data stored in file into String object. + * + * @param filePath file path of data file to be read. + * @return String object representing all the data in the data file. + * @throws FileNotFoundException If file path is invalid. + */ + public static String parseFileContentsToString(String filePath) throws FileNotFoundException { + File f = new File(filePath); // create a File for the given file path + String fileContent = ""; + if (!f.exists()) { // for first log in, there is no file + return fileContent; + } + Scanner s = new Scanner(f); // create a Scanner using the File as the source + while (s.hasNext()) { + String taskStored = s.nextLine(); + fileContent = fileContent + taskStored + System.lineSeparator(); + } + return fileContent; + } + + /** + * Parse data stored in an arraylist to a single String object to be stored in data file. Used + * in writing to data file. + * + * @param list arraylist to be parsed. + * @return String object representing all the data in the data file. + */ + public static String arraylistToStringConverter(ArrayList list) { + String output = ""; + for (Task t : list) { + output = output + t.toString() + System.lineSeparator(); + } + return output; + } + + /** + * Parse data stored as a single String object into an arrayList. Used in reading from data file. + * + * @param fileContent a String object representing data in the file. + * @return arraylist which stores all the tasks stored in file as elements. + * @throws EmptyDeadlineException If task read is empty. + * @throws EmptyToDoException If task read is empty. + * @throws EmptyEventsException If task read is empty. + */ + public static ArrayList stringToArraylistConverter(String fileContent) { + ArrayList list = new ArrayList<>(); + if (fileContent.equals("")) { + return list; + } + String[] bufferArray = fileContent.split(System.lineSeparator()); + for (String t : bufferArray) { + Task task = new Task(t); + try { + if (t.substring(FIRSTBRACKET_FRONT, FIRSTBRACKET_BACK).equals("[T]")) { + String todoDetail = "todo " + t.substring(BRACKETSKIP_INDEX); + task = new ToDos(todoDetail); + task.setMark(t.substring(SECONDBRACKET_FRONT, SECONDBRACKET_BACK)); + } else if (t.substring(FIRSTBRACKET_FRONT, FIRSTBRACKET_BACK).equals("[D]")) { + String deadlineDetail = "deadline " + t.substring(BRACKETSKIP_INDEX, t.indexOf("(")) + "/" + + t.substring(t.indexOf("(") + 1, t.indexOf(")")); + task = new Deadlines(deadlineDetail); + task.setMark(t.substring(SECONDBRACKET_FRONT, SECONDBRACKET_BACK)); + } else { + String eventDetail = "event " + t.substring(BRACKETSKIP_INDEX, t.indexOf("(")) + "/" + + t.substring(t.indexOf("(") + 1, t.indexOf("to")) + "/" + + t.substring(t.indexOf("to"), t.indexOf(")")); + eventDetail = eventDetail.replace(":", ""); + task = new Events(eventDetail); + task.setMark(t.substring(SECONDBRACKET_FRONT, SECONDBRACKET_BACK)); + } + } catch (EmptyToDoException e) { + System.out.println("Corrupt todo detected, it is empty"); + } catch (EmptyDeadlineException e) { + System.out.println("Corrupt Deadline detected, it is empty"); + } catch (EmptyEventsException e) { + System.out.println("Corrupt Events detected, it is empty"); + } + list.add(task); + } + return list; + } +} + diff --git a/src/main/java/Duke/Task/Deadlines.java b/src/main/java/Duke/Task/Deadlines.java new file mode 100644 index 000000000..78835cf91 --- /dev/null +++ b/src/main/java/Duke/Task/Deadlines.java @@ -0,0 +1,44 @@ +package Duke.Task; + +import Duke.Exception.EmptyDeadlineException; +import Duke.Task.Task; + +public class Deadlines extends Task { + private static final int DEADLINE_INDEX = 9; + private static final int COLON_INDEX = 2; + private String endTime; + private String taskLabel = "[D]"; + + /** + * Represents a Deadlines object which is identified by the type D. Contains description and deadline info. + */ + public Deadlines(String input) throws EmptyDeadlineException { + super(input.substring(DEADLINE_INDEX, input.indexOf('/') - 1)); // Sanitize input by removing "deadline" at the start + super.setTaskLabel(taskLabel); + endTime = "(" + getEndTime(input) + ")"; + if (input.substring(DEADLINE_INDEX, input.indexOf('/') - 1).isEmpty()) { + throw new EmptyDeadlineException(); + } + } + + // Method of StringBuffer operation taken from + // https://www.geeksforgeeks.org/insert-a-string-into-another-string-in-java/ + /** + * Returns the deadline of the task. + * + * @param input user input to be parsed. + * @return deadline of the tasked from parsing. + */ + @Override + public String getEndTime(String input) { + String deadline = input.substring(input.indexOf('/') + 1); // endTime of task is the string after '/' + StringBuffer deadlineCorrectFormat = new StringBuffer(deadline); // convert to StringBuffer for inserting ':' + deadlineCorrectFormat.insert(COLON_INDEX, ":"); + return deadlineCorrectFormat.toString(); + } + + @Override + public String toString() { + return this.taskLabel + this.mark + " " + this.description + " " + this.endTime; + } +} diff --git a/src/main/java/Duke/Task/Events.java b/src/main/java/Duke/Task/Events.java new file mode 100644 index 000000000..7fbd77d5d --- /dev/null +++ b/src/main/java/Duke/Task/Events.java @@ -0,0 +1,63 @@ +package Duke.Task; + +import Duke.Exception.EmptyEventsException; + +public class Events extends Task { + private static final int EVENT_INDEX = 6; + private static final int FIRST_COLON_INDEX = 4; + private static final int SECOND_COLON_INDEX = 2; + private String timeLine; + private String taskLabel = "[E]"; + /** + * Represents an Events object which is identified by the type E. Contains description, start time + * and end time. + */ + public Events(String input) throws EmptyEventsException { + super(input.substring(EVENT_INDEX, input.indexOf('/') - 1)); + super.setTaskLabel(taskLabel); + timeLine = "(" + getStartTime(input) + getEndTime(input) + ")"; + if (input.substring(EVENT_INDEX, input.indexOf('/') - 1).isEmpty()) { + throw new EmptyEventsException(); + } + } + + public String[] splitInput(String input) { + String[] inputAfterSplit = input.split("/", 3); // split twice to generate three strings + return inputAfterSplit; + } + + /** + * Returns the starting time of the task. + * + * @param input user input to be parsed. + * @return starting time of the tasked from parsing. + */ + @Override + public String getStartTime(String input) { + String[] inputAfterSplit = splitInput(input); + String startTime = inputAfterSplit[1]; + StringBuffer startTimeCorrectFormat = new StringBuffer(startTime); + startTimeCorrectFormat.insert(FIRST_COLON_INDEX, ":"); + return startTimeCorrectFormat.toString(); + } + + /** + * Returns the ending time of the task. + * + * @param input user input to be parsed. + * @return ending time of the tasked from parsing. + */ + @Override + public String getEndTime(String input) { + String[] inputAfterSplit = splitInput(input); + String startTime = inputAfterSplit[2]; + StringBuffer endTimeCorrectFormat = new StringBuffer(startTime); // convert to StringBuffer for inserting ':' + endTimeCorrectFormat.insert(SECOND_COLON_INDEX, ":"); + return endTimeCorrectFormat.toString(); + } + + @Override + public String toString() { + return this.taskLabel + this.mark + " " + this.description + " " + this.timeLine; + } +} diff --git a/src/main/java/Duke/Task/Task.java b/src/main/java/Duke/Task/Task.java new file mode 100644 index 000000000..38729d433 --- /dev/null +++ b/src/main/java/Duke/Task/Task.java @@ -0,0 +1,49 @@ +package Duke.Task; + +/** + * Represents a Task object which is identified by the type of task it is (taskLabel), its content (description) + * and whether it is completed or not (mark). + */ +public class Task { + protected String taskLabel; + protected String description; + protected String mark; + + public Task(String input) { + this.description = input; + this.taskLabel = "To be replaced by labels"; + this.mark = "[ ]"; + } + + public String getTaskLabel() { + return taskLabel; + } + + public String getDescription() { + return description; + } + + public String getStartTime(String input) { + return "To be overridden by subclass' methods"; + } + + public String getEndTime(String input) { + return "To be overridden by subclass' methods"; + } + + public void setTaskLabel(String taskLabel) { + this.taskLabel = taskLabel; + } + + public void markTask() { + this.mark = "[X]"; + } + + public void unmarkTask() { + this.mark = "[ ]"; + } + + public void setMark(String mark) { + this.mark = mark; + } +} diff --git a/src/main/java/Duke/Task/ToDos.java b/src/main/java/Duke/Task/ToDos.java new file mode 100644 index 000000000..8a06b2588 --- /dev/null +++ b/src/main/java/Duke/Task/ToDos.java @@ -0,0 +1,24 @@ +package Duke.Task; + +import Duke.Exception.EmptyToDoException; +import Duke.Ui; + +/** + * Represents a ToDos object which is identified by the type of task T. Contains only description. + */ +public class ToDos extends Task { + private static final int TODOS_INDEX = 5; + private String taskLabel = "[T]"; + + public ToDos(String input) throws EmptyToDoException { + super(input.substring(TODOS_INDEX)); // for ToDos tasks, description = input + super.setTaskLabel(taskLabel); + if (input.substring(TODOS_INDEX).isEmpty()) { + throw new EmptyToDoException(); + } + } + @Override + public String toString() { + return this.taskLabel + this.mark + " " + this.description; + } +} diff --git a/src/main/java/Duke/TaskList.java b/src/main/java/Duke/TaskList.java new file mode 100644 index 000000000..9c8995967 --- /dev/null +++ b/src/main/java/Duke/TaskList.java @@ -0,0 +1,129 @@ +package Duke; + +import Duke.Exception.EmptyDeadlineException; +import Duke.Exception.EmptyEventsException; +import Duke.Exception.EmptyToDoException; +import Duke.Exception.NullCommandException; +import Duke.Task.Deadlines; +import Duke.Task.Events; +import Duke.Task.Task; +import Duke.Task.ToDos; + +import java.io.FileNotFoundException; +import java.util.ArrayList; + +public class TaskList { + private static final int MARK_INDEX = 5; + private static final int UNMARK_INDEX = 7; + private static final int DELETE_INDEX = 7; + + private static final int FIND_INDEX = 5; + public static ArrayList list; + + /** + * Represents an arraylist of Task objects that can be modified. + */ + public TaskList(String filepath) { + try { + list = Storage.stringToArraylistConverter(Storage.parseFileContentsToString(filepath)); + } catch (FileNotFoundException e) { + System.out.println("Illegal file path"); + } + } + + /** + * Adds a Task object to the TaskList. + * + * @param line input from user indicating the task to be added. + * @throws EmptyToDoException If line is empty. + * @throws EmptyDeadlineException If line is empty. + * @throws EmptyEventsException If line is empty. + * @throws IndexOutOfBoundsException If line's input format violates that of Deadlines or Events object. + */ + public void addTask(String line) { + Ui.addTaskSuccess(); + try { + Task newTask = new Task(line); + if (line.startsWith("todo")) { + newTask = new ToDos(line); + } else if (line.startsWith("deadline")) { + newTask = new Deadlines(line); + } else if (line.startsWith("event")) { + newTask = new Events(line); + } + this.list.add(newTask); + Ui.printTask(newTask); + Ui.printListSize(this.list); + Storage.dukeDataStorage(Storage.arraylistToStringConverter(this.list)); + } catch (EmptyToDoException e) { + System.out.println("Sire, you have yet to tell me what is it you want to do."); + } catch (EmptyDeadlineException e) { + System.out.println("Sire, what is it that is due your specified time?"); + } catch (EmptyEventsException e) { + System.out.println("Sire, your event is unclear. Please specify."); + } catch (StringIndexOutOfBoundsException e) { + System.out.println("Don't hold back Sire. I am here to serve."); + } + } + + /** + * Deletes the Task object from the TaskList. + * + * @param task input from user indicating the task to be deleted. + */ + public void delete(String task) { + String indexOfTask = task.substring(DELETE_INDEX); + Ui.deleteSuccess(this.list, indexOfTask); + this.list.remove(Integer.parseInt(indexOfTask) - 1); + Ui.printListSize(this.list); + Storage.dukeDataStorage(Storage.arraylistToStringConverter(this.list)); + } + + /** + * Marks the Task object in the TaskList as done. + * + * @param task input from user indicating the task to be marked. + */ + public void mark(String task) { + String indexOfTask = task.substring(MARK_INDEX); // get the number of task to be marked + Task taskToBeMarked = this.list.get(Integer.parseInt(indexOfTask) - 1); // convert from 1-based to 0-based + taskToBeMarked.markTask(); + Ui.markSuccess(list, indexOfTask); + Storage.dukeDataStorage(Storage.arraylistToStringConverter(this.list)); + } + + /** + * Unmarks the Task object in the TaskList as undone. + * + * @param task input from user indicating the task to be unmarked. + */ + public void unmark(String task) { + String indexOfTask = task.substring(UNMARK_INDEX); + Task taskToBeUnmarked = this.list.get(Integer.parseInt(indexOfTask) - 1); + taskToBeUnmarked.unmarkTask(); + Ui.unmarkSuccess(list, indexOfTask); + Storage.dukeDataStorage(Storage.arraylistToStringConverter(this.list)); + } + + /** + * Prints the Task object in the TaskList. + * + * @param task task object to be printed. + */ + public void printTasksFound (String task) { + String taskToBeFound = task.substring(FIND_INDEX); + Ui.findSuccess(); + for (int i = 0; i < this.list.size(); ++i) { + if (this.list.get(i).getDescription().contains(taskToBeFound)) { + Ui.printTask(this.list.get(i)); + } + } + } + + /** + * Prints the current TaskList. + */ + public void printCurrentList() { + Ui.printCurrentList(this.list); + } +} diff --git a/src/main/java/Duke/Ui.java b/src/main/java/Duke/Ui.java new file mode 100644 index 000000000..aeff93d2d --- /dev/null +++ b/src/main/java/Duke/Ui.java @@ -0,0 +1,110 @@ +package Duke; + +import Duke.Task.Task; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Scanner; + + +public class Ui { + private Scanner scanner; + public Ui() { + this.scanner = new Scanner(System.in); + } + + public void greet() { + String logo = " ____ _ \n" + + "| _ \\ _ _| | _____ \n" + + "| | | | | | | |/ / _ \\\n" + + "| |_| | |_| | < __/\n" + + "|____/ \\__,_|_|\\_\\___|\n"; + System.out.println("Hello from\n" + logo); + try { + printFileContents("dukeData.txt"); + } catch (FileNotFoundException e) { + printErrorMessage("File not found"); + } + System.out.println("How may I be of service today?"); + } + + public void bye() { + System.out.println("Glad I could be of help!"); + } + + public String readCommand() { + return scanner.nextLine(); + } + + public static void addTaskSuccess() { + System.out.println("As per requested Sire, this task has been added to your calendar."); + } + + public static void printTask(Task task) { + System.out.println(task); + } + + public static void markSuccess(ArrayList list, String indexOfTask) { + System.out.println("Sir, your task has been marked as completed."); + System.out.println(list.get(Integer.parseInt(indexOfTask) - 1)); + } + + public static void unmarkSuccess(ArrayList list, String indexOfTask) { + System.out.println("Sir, your task has been unmarked as requested."); + System.out.println(list.get(Integer.parseInt(indexOfTask) - 1)); + } + + public static void deleteSuccess(ArrayList list, String indexOfTask) { + System.out.println("Sire, I have removed this task from your schedule"); + System.out.println(list.get(Integer.parseInt(indexOfTask) - 1)); + } + + public static void findSuccess() { + System.out.println("Here are the matching items Sire:"); + } + + /** + * Prints out the number of elements in the list. + * + * @param list arraylist whose number of elements is to be printed out. + */ + public static void printListSize(ArrayList list) { + System.out.println("You now have " + list.size() + " items left"); + } + + /** + * Prints out all tasks currently in the list. + * + * @param list arraylist whose elements are to be printed out. + */ + public static void printCurrentList(ArrayList list) { + System.out.println("Your current list of items as requested, sir."); + for (int i = 0; i < list.size(); ++i) { + System.out.println((i + 1) + "." + list.get(i)); + } + } + + /** + * Prints out all tasks saved in the data file. + * + * @param filePath file path of the data file whose content is to be printed out. + * @throws FileNotFoundException If file path is invalid. + */ + public void printFileContents(String filePath) throws FileNotFoundException { + File f = new File(filePath); // create a File for the given file path + if (!f.exists()) { // for first log in, there is no file + return; + } + System.out.println("Good day sire, I have listed down your current plan below for you:"); + Scanner s = new Scanner(f); // create a Scanner using the File as the source + while (s.hasNext()) { + String taskStored = s.nextLine(); + System.out.println(taskStored); + } + } + public void printErrorMessage(String errorMessage) { + System.out.println(errorMessage); + } +} + diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..76381b309 --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: Duke.Duke + diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e..15687aa33 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -5,3 +5,5 @@ Hello from | |_| | |_| | < __/ |____/ \__,_|_|\_\___| +How may I be of service? +Glad I could be of help! diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb..441df48b6 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,2 @@ +todo CS2113 assignment +bye \ No newline at end of file