diff --git a/docs/README.md b/docs/README.md index 8077118eb..b8e70f33e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,28 +2,174 @@ ## Features -### Feature-ABC +### Feature - Adding of Task - Todo, Event, Deadline -Description of the feature. +You can now add a task of any one of the three types. -### Feature-XYZ -Description of the feature. +### Feature - Deletion of Task + +Delete any task according to its index in the list of tasks. + +### Feature - Unmark/mark any task. + +Mark or unmark any task in the list of task. + +### Feature - List all tasks. + +List all the current tasks in the list. + +### Feature - Find a task, given a specific search word. + +Enter a word and search for all tasks that contain this word. ## Usage -### `Keyword` - Describe action +### `todo` - Describe action + +Describe the action and its outcome. + +Example of usage: + +`todo enter description here` + +Expected outcome: + +Description of the outcome. + +``` +Got it. I've added this task: +[T][ ]enter description here +Now you have 1 tasks in the list. +``` + +### `deadline` - Describe action Describe the action and its outcome. Example of usage: -`keyword (optional arguments)` +`deadline ip assignment /by today 2359` Expected outcome: Description of the outcome. ``` -expected output +Got it. I've added this task: +[D][ ]ip assignment (by today 2359) +Now you have 1 tasks in the list. ``` + +### `event` - Describe action + +Describe the action and its outcome. + +Example of usage: + +`event final exam /at 29 February 9pm` + +Expected outcome: + +Description of the outcome. + +``` +Got it. I've added this task: +[E][ ]final exam (at 29 February 9pm) +Now you have 3 tasks in the list. +``` + + +### `find` - Describe action + +Describe the action and its outcome. + +Example of usage: + +`find final` + +Expected outcome: + +Description of the outcome. + +``` +Here are the matching tasks in your list: +3.[E][ ]final exam (at 29 February 9pm) +``` + +### `mark` - Describe action + +Describe the action and its outcome. + +Example of usage: + +`mark 3` + +Expected outcome: + +Description of the outcome. + +``` +[T][ ]enter description here +[D][ ]ip assignment (by today 2359) +[E][X]final exam (at 29 February 9pm) +``` + +### `unmark` - Describe action + +Describe the action and its outcome. + +Example of usage: + +`unmark 3` + +Expected outcome: + +Description of the outcome. + +``` +[T][ ]enter description here +[D][ ]ip assignment (by today 2359) +[E][ ]final exam (at 29 February 9pm) +``` + +### `list` - Describe action + +Describe the action and its outcome. + +Example of usage: + +`list` + +Expected outcome: + +Description of the outcome. + +``` +Here are the tasks in your list : +1.[T][ ]enter description here +2.[D][ ]ip assignment (by today 2359) +3.[E][ ]final exam (at 29 February 9pm) +``` + +### `delete` - Describe action + +Describe the action and its outcome. + +Example of usage: + +`delete 2` + +Expected outcome: + +Description of the outcome. + +``` +Noted. I've removed this task: +[D][ ]ip assignment (by today 2359) +Now you have 2 tasks in the list. +[T][ ]enter description here +[E][ ]final exam (at 29 February 9pm) + +``` + diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334c..000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..6e864153e --- /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/src/main/java/duke/Duke.class b/src/main/java/duke/Duke.class new file mode 100644 index 000000000..96c9150b3 Binary files /dev/null and b/src/main/java/duke/Duke.class differ diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java new file mode 100644 index 000000000..7850cd6a5 --- /dev/null +++ b/src/main/java/duke/Duke.java @@ -0,0 +1,42 @@ +package duke; +import duke.tasklist.*; + +public class Duke { + + private Storage storage; + private TaskList tasks; + private Ui ui; + + public Duke(String filePath) { + ui = new Ui(); + storage = new Storage(filePath); + try { + tasks = new TaskList(storage.loadTaskList()); + } catch (DukeException e) { + ui.showLoadingError("Error in loading text file of tasks!"); + tasks = new TaskList(); + } + } + public void run() { + ui.showWelcome(); + boolean endProgram = false; + + while (!endProgram) { + try { + String command = ui.readCommand(); + int continueProgram = Parser.parse(command,tasks,storage); + if (continueProgram == 0) { + endProgram = true; + } + } catch (DukeException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + new Duke("tasks.txt").run(); + } + +} + diff --git a/src/main/java/duke/DukeException.class b/src/main/java/duke/DukeException.class new file mode 100644 index 000000000..cb02d3346 Binary files /dev/null and b/src/main/java/duke/DukeException.class differ diff --git a/src/main/java/duke/DukeException.java b/src/main/java/duke/DukeException.java new file mode 100644 index 000000000..6ed6f9d70 --- /dev/null +++ b/src/main/java/duke/DukeException.java @@ -0,0 +1,9 @@ +package duke; +public class DukeException extends Exception{ + + + public DukeException(String message) { + super(message); + } + +} diff --git a/src/main/java/duke/File.class b/src/main/java/duke/File.class new file mode 100644 index 000000000..55dc58c0f --- /dev/null +++ b/src/main/java/duke/File.class @@ -0,0 +1,4 @@ +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Scanner; + diff --git a/src/main/java/duke/Parser.java b/src/main/java/duke/Parser.java new file mode 100644 index 000000000..06eabcf30 --- /dev/null +++ b/src/main/java/duke/Parser.java @@ -0,0 +1,142 @@ +package duke; +import duke.Storage; +import duke.tasklist.*; + +import java.io.IOException; +import java.util.ArrayList; + +/** + * Parser helps to make sense of the user input and uses methods from TaskList to do operations on the ArrayList of tasks. + */ +public class Parser { + public static int parse(String userInput, TaskList l,Storage s) throws DukeException { + String desc; + int index; + String by; + switch (userInput.split(" ")[0]) { + case "find": + String keyword = userInput.split(" ")[1]; + l.find(keyword); + return 1; + + + case "todo": + desc = userInput.substring(5); + if (desc.isEmpty() || desc.isBlank()) { + throw new DukeException("Oops! Description cannot be empty."); + } + desc = l.addTodo(desc); + try { + if (l.getTaskSize() == 1) { + s.writeToFile(desc); + } + else { + s.appendData(desc); + } + } catch (IOException e) { + System.out.println("Error while appending to text file."); + } + + return 1; + + + case "event": + index = userInput.indexOf("/"); + desc = userInput.substring(6,index); + if (desc.isEmpty() || desc.isBlank()) { + throw new DukeException("Oops! Description cannot be empty."); + } + index++; + by = userInput.substring(index); + if (by.isEmpty() || by.isBlank()) { + throw new DukeException("Oops! You need a date for event."); + } + desc = l.addEvent(desc,by); + try { + if (l.getTaskSize() == 1) { + s.writeToFile(desc); + } + else { + s.appendData(desc); + } + + } catch (IOException e) { + System.out.println("Error while appending to text file."); + } + return 1; + + + case "deadline": + index = userInput.indexOf("/"); + desc = userInput.substring(9,index); + if (desc.isEmpty() || desc.isBlank()) { + throw new DukeException("Oops! Description cannot be empty."); + } + index++; + by = userInput.substring(index); + if (by.isEmpty() || by.isBlank()) { + throw new DukeException("Oops! You need a date for deadline."); + } + desc = l.addDeadline(desc,by); + try { + if (l.getTaskSize() == 1) { + s.writeToFile(desc); + } + else { + s.appendData(desc); + } + } catch (IOException e) { + System.out.println("Error while appending to text file."); + } + return 1; + + + + case "mark": + String[] arrOfStr = userInput.split(" ", 0); + String indexValue = arrOfStr[1]; + int indexValue2 = Integer.parseInt(indexValue) - 1; + //index given is out of array size + if (indexValue2 > l.getTaskSize()-1 || indexValue2 < 0){ + throw new DukeException("Index given is out of bounds."); + } + ArrayList taskList = l.markTask(indexValue2); + s.updateFile(taskList); + return 1; + + case "unmark": + arrOfStr = userInput.split(" ", 0); + indexValue = arrOfStr[1]; + indexValue2 = Integer.parseInt(indexValue) - 1; + //index given is out of array size + if (indexValue2 > l.getTaskSize()-1 || indexValue2 < 0){ + throw new DukeException("Index given is out of bounds."); + } + taskList = l.unmarkTask(indexValue2); + s.updateFile(taskList); + return 1; + + case "delete": + arrOfStr = userInput.split(" ", 0); + indexValue = arrOfStr[1]; + indexValue2 = Integer.parseInt(indexValue) - 1; + //index given is out of array size + if (indexValue2 > l.getTaskSize()-1 || indexValue2 < 0){ + throw new DukeException("Index given is out of bounds."); + } + taskList = l.deleteTask(indexValue2); + s.updateFile(taskList); + return 1; + + case "list": + l.printList(); + return 1; + + case "bye": + return 0; + + default: + throw new DukeException("Oops! I do not recognize this command. Please try again."); + } + } +} diff --git a/src/main/java/duke/Storage.java b/src/main/java/duke/Storage.java new file mode 100644 index 000000000..0e9ef5e17 --- /dev/null +++ b/src/main/java/duke/Storage.java @@ -0,0 +1,181 @@ +package duke; + +import duke.tasklist.Task; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Scanner; +import duke.tasklist.*; + +/** + * Storage class is used to load tasks from the file and saving them to taskList + * We also have different functions which we will use in our commands to update the text file as we update the taskList. + */ +public class Storage { + private String filePath; + private File file; + private Scanner input; + + + /** + * reads in the link to our text file and saves it to variable input + * if text file does not exist, we create a new file + * @param filePath + */ + public Storage(String filePath) { + try { + this.filePath = filePath; + this.file = new File(filePath); + if (this.file.createNewFile()) { + System.out.println("File is created!"); + }else{ + System.out.println("File exists, reading it to taskList!"); } + input = new Scanner(file); + } catch (FileNotFoundException e) { + createFileAndDirectory(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public String getFilePath() { + return this.filePath; + } + + + public void createFileAndDirectory() { + try { + file.createNewFile(); + throw new IOException(); + } catch (IOException e) { + System.out.println("Error creating file."); + } + } + + /** + * function reads in our text file and saves it to an ArrayList of tasks. + * + * @return + * @throws DukeException + */ + public ArrayList loadTaskList() throws DukeException { + ArrayList taskList = new ArrayList<>(); + if (!file.exists() || !file.isFile()) { + return taskList; + } + + while (input.hasNext()){ + String nextString = input.nextLine(); + String[] splitString = nextString.split("\\|"); + String typeTask = splitString[0].replaceAll(" ",""); + String marked = splitString[1].replaceAll(" ",""); + String desc = splitString[2]; + System.out.println(typeTask); + System.out.println(marked); + System.out.println(desc); + String todo = "T"; + String deadline = "D"; + String event = "E"; + String toMark = "1"; + if (typeTask.equals(todo)) { + taskList.add(new Todo(desc)); + if (marked.equals(toMark)) { + taskList.get(taskList.size()-1).markTask(); + } + } + + else if (typeTask.equals(deadline)) { + String deadlineDate = splitString[3]; + taskList.add(new Deadline(desc,deadlineDate)); + if (marked.equals(toMark)) { + taskList.get(taskList.size()-1).markTask(); + } + } + + else if (typeTask.equals(event)) { + String eventDate = splitString[3]; + taskList.add(new Event(desc,eventDate)); + if (marked.equals(toMark)) { + taskList.get(taskList.size()-1).markTask(); + } + } + } + input.close(); + return taskList; + } + + /** + * Function to append one line of data to our text file + * For adding of tasks + * @param textToAppend + * @throws IOException + */ + public void appendData(String textToAppend) throws IOException { + String filePath = this.filePath; + FileWriter fw = new FileWriter(filePath,true); + fw.write(System.getProperty( "line.separator" )); + fw.write(textToAppend); + fw.close(); + } + + /** + * Function to write the first line to a text file. + * @param textToAdd + * @throws IOException + */ + + public void writeToFile(String textToAdd) throws IOException { + filePath = this.filePath; + FileWriter fw = new FileWriter(filePath); + fw.write(textToAdd); + fw.close(); + } + + /** + * Function to completely erase text file and update it according to our ArrayList. + * Used when we delete tasks, mark/unmark tasks + * @param taskList + */ + public void updateFile(ArrayList taskList) { + for (int i = 0; i taskList; + + + public TaskList(ArrayList a) { + this.taskList = a; + } + + public TaskList() { + this.taskList = new ArrayList(); + } + + public int getTaskSize() { + return this.taskList.size(); + } + + public void printList() { + System.out.println("Here are the tasks in your list : "); + for (int i = 0; i deleteTask(int indexValue2) { + + Task removedTask = taskList.get(indexValue2); + taskList.remove(indexValue2); + System.out.println("Noted. I've removed this task:"); + System.out.println(removedTask.toString()); + System.out.println("Now you have " + taskList.size() + " tasks in the list."); + return this.taskList; + } + + public String addTodo(String desc) { + + System.out.println("Got it. I've added this task:"); + taskList.add(new Todo(desc)); + System.out.println(taskList.get(taskList.size()-1).toString()); + System.out.println("Now you have " + taskList.size() + " tasks in the list."); + String textToAdd = "T" + "|" + " 0 " + "|" + desc; + // return this string so Storage can use to add to text file + return textToAdd; + + } + + public String addDeadline(String desc, String by) { + taskList.add(new Deadline(desc, by)); + System.out.println("Got it. I've added this task:"); + System.out.println(taskList.get(taskList.size() - 1).toString()); + System.out.println("Now you have " + taskList.size() + " tasks in the list."); + String textToAdd = "D" + "|" + " 0 " + "|" + desc + "|" + by; + return textToAdd; + + } + + public String addEvent(String desc, String by) { + + taskList.add(new Event(desc,by)); + System.out.println("Got it. I've added this task:"); + System.out.println(taskList.get(taskList.size()-1).toString()); + System.out.println("Now you have " + taskList.size() + " tasks in the list."); + + String textToAdd = "E" + "|" + " 0 " + "|" + desc + "|" + by; + return textToAdd; + } + + public ArrayList markTask(int indexValue2) { + taskList.get(indexValue2).markTask(); + return(this.taskList); + } + + public ArrayList unmarkTask(int indexValue2) { + taskList.get(indexValue2).unmarkTask(); + return(this.taskList); + } + + public void find(String keyword){ + System.out.println("Here are the matching tasks in your list: "); + for (int i = 0; i