diff --git a/docs/README.md b/docs/README.md index 8077118eb..9ec092662 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,17 +2,14 @@ ## Features -### Feature-ABC +### Feature-Duke -Description of the feature. - -### Feature-XYZ - -Description of the feature. +Duke is a app helps manage tasks and deadlines, optimized for use via a +Command Line Interface (CLI) ## Usage -### `Keyword` - Describe action +### `list` - Describe action Describe the action and its outcome. @@ -27,3 +24,90 @@ Description of the outcome. ``` expected output ``` + +### `bye` - Describe action + +Describe the action and its outcome. + +Example of usage: + +`keyword (optional arguments)` + +Expected outcome: + +Description of the outcome. + +``` +expected output +``` +### `find` - Give users a way to find a task by searching for a keyword. + +Example of usage: + +`find book` + +Expected outcome: + +``` +Here are the matching tasks in your list: + 1.[T][X] read book + 2.[D][X] return book (by: June 6th) +``` + +### `todo` - tasks without any date/time attached to it + +Example of usage: + +`todo borrow book` + +Expected outcome: + +``` + Got it. I've added this task: + [T][ ] borrow book + Now you have 5 tasks in the list. + +``` + +### `event` - tasks that start at a specific date/time and ends at a specific date/time + +Example of usage: + +`event project meeting /from Mon 2pm /to 4pm` + +Expected outcome: + +``` + Got it. I've added this task: + [E][ ] project meeting (from: Mon 2pm to: 4pm) + Now you have 7 tasks in the list. +``` + +### `deadline` - tasks that need to be done before a specific date/time + +Example of usage: + +`deadline return book /by Sunday` + +Expected outcome: + + +``` + Got it. I've added this task: + [D][ ] return book (by: Sunday) + Now you have 6 tasks in the list. +``` + +### `delete` - delete task + +Example of usage: + +`delete 3` + +Expected outcome: + +``` + Noted. I've removed this task: + [E][ ] project meeting (from: Aug 6th 2pm to: 4pm) + Now you have 4 tasks in the list. +``` \ No newline at end of file diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 000000000..7f26b62df --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,20 @@ +public class Deadline extends Task { + private final String by; + + /** + * @param description description of the task + * @param by the deadline of the task + */ + public Deadline(String description, String by) { + super(description); + this.by = by; + } + + /** + * @return convert to formatted string + */ + @Override + public String toString() { + return "[D]" + super.toString() + " (by:" + by + ")"; + } +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334c..3430d2a09 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,35 @@ +import java.io.IOException; + public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + private final Storage storage; + private final TaskList tasks; + private final UI ui; + private final Parser parser = new Parser(); + + /** + * Create the Duke Object + * @param filePath an String giving the base location of the file + */ + public Duke(String filePath) throws IOException { + ui = new UI(); + storage = new Storage(filePath); + this.tasks = new TaskList(storage.load()); } + + /** + * Start to run the Duke application + */ + public void run() throws IOException{ + ui.showWelcome(); + while (!parser.isExit()) { + String fullCommand = ui.readCommand(); + ui.showLine(); + parser.parse(fullCommand); + } + } + + public static void main(String[] args) throws IOException { + new Duke("duke.txt").run(); + } + } diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 000000000..e49f76e5e --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,24 @@ +public class Event extends Task { + private final String from; + private final String to; + + /** + * @param description description of the task + * @param from the start day of the task + * @param to the end day of the task + */ + public Event(String description, String from, String to) { + super(description); + this.from = from; + this.to = to; + } + + /** + * @return convert to formatted string + * + */ + @Override + public String toString() { + return "[E]" + super.toString() + " (from:" + from + " to:" + to + ")"; + } +} diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..9f37e4e0a --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: Duke + diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 000000000..17778bd30 --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,97 @@ +import java.io.IOException; +import java.util.ArrayList; + +public class Parser { + private boolean exit = false; + + /** + * Parse the user command and store to the taskList if applicable + * @param command the user input + */ + public void parse(String command) throws IOException { + if (command.equalsIgnoreCase("list")) { + System.out.println("Here are the tasks in your list:"); + for (int i = 0; i < TaskList.list.size(); i++) { + System.out.println(i + 1 + "." + TaskList.list.get(i).toString()); + } + UI.showLine(); + } else if (command.equalsIgnoreCase("bye")) { + UI.showBye(); + Storage.save(TaskList.list); + this.exit = true; + } else if (command.toLowerCase().contains("mark")) { + try { + String[] split = command.split("\\s+"); + int toMark = Integer.parseInt(split[1]); + if (split[0].equalsIgnoreCase("mark")) { + TaskList.list.get(toMark - 1).markAsDone(); + System.out.println("Nice! I've marked this task as done: "); + } else { + TaskList.list.get(toMark - 1).markAsUnDone(); + System.out.println("OK, I've marked this task as not done yet: "); + } + System.out.println(TaskList.list.get(toMark - 1).toString() + '\n' + UI.lineBreak); + } catch (NullPointerException e) { + System.out.println("Item is not in list!"); + } + } else if (command.toLowerCase().contains("delete")) { + String[] split = command.split("\\s+"); + int toDelete = Integer.parseInt(split[1]); + TaskList.taskListDelete(toDelete - 1); + } else { + Task t; + if (command.toLowerCase().contains("deadline")) { + try { + String description = command.substring(command.indexOf(' ') + 1, command.indexOf('/')); + String ddl = command.substring(command.indexOf('/') + 1); + String by = ddl.replace("by", ""); + t = new Deadline(description, by); + TaskList.taskListAdd(t); + } catch (StringIndexOutOfBoundsException e) { + System.out.println("☹ OOPS!!! The description of a deadline cannot be empty." + '\n' + UI.lineBreak); + } + } else if (command.toLowerCase().contains("event")) { + try { + String substring = command.substring(command.indexOf(' ') + 1); + String[] info = substring.split("/"); + String from = info[1].replace("from", ""); + String to = info[2].replace("to", ""); + t = new Event(info[0], from, to); + TaskList.taskListAdd(t); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("☹ OOPS!!! The description of a event cannot be empty." + '\n' + UI.lineBreak); + } + } else if (command.toLowerCase().contains("todo")) { + if (command.indexOf(' ') == -1) { + System.out.println("☹ OOPS!!! The description of a todo cannot be empty." + '\n' + UI.lineBreak); + } else { + String description = command.substring(command.indexOf(' ') + 1); + t = new Todo(description); + TaskList.taskListAdd(t); + } + } else if (command.toLowerCase().contains("find")) { + String substring = command.substring(command.indexOf(' ') + 1); + ArrayList result=new ArrayList<>(); + for(Task k:TaskList.list){ + if(k.description.contains(substring)){ + result.add(k); + } + } + System.out.println("Here are the matching tasks in your list:"); + for(int i=0;i list) throws IOException { + FileWriter writer = new FileWriter(filePath, false); + for (int i = 0; i < list.size(); i++) { + writer.write(list.get(i).toString()); + writer.write("\r\n"); + } + writer.close(); + } +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 000000000..ec62eccdb --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,38 @@ +public class Task { + public final String description; + protected boolean isDone; + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + /** + * @return the Icon of current task + */ + public String getStatusIcon() { + return (isDone ? "X" : " "); // mark done task with X + } + + /** + * Mark the task to done + */ + public void markAsDone() { + this.isDone = true; + } + + /** + * Mark the task to unDone + */ + public void markAsUnDone() { + this.isDone = false; + } + + /** + * @return convert to formatted string + */ + @Override + public String toString() { + return "[" + getStatusIcon() + "] " + description; + } +} diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 000000000..ad619a4f4 --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,61 @@ +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +public class TaskList { + public static ArrayList list; + + /** + * Read the file and convert to taskList + * @param filePath the filepath of the data location + */ + public TaskList(String filePath) throws IOException{ + list=new ArrayList<>(); + File myObj = new File(filePath); + try { + Scanner myReader = new Scanner(myObj); + while (myReader.hasNextLine()) { + String data = myReader.nextLine(); + Task t=null; + String type=data.substring(1,2); + String mark=data.substring(4,5); + if(type.equals("T")){ + String context=data.substring(7); + t=new Todo(context); + } else if (type.equals("D")) { + String context=data.substring(7,data.indexOf("(")-1); + String by=data.substring(data.indexOf("by")+3,data.indexOf(")")); + t=new Deadline(context,by); + } else if (type.equals("E")) { + String context=data.substring(7,data.indexOf("(")-1); + String from=data.substring(data.indexOf("from")+5,data.indexOf("to")); + String to=data.substring(data.indexOf("to")+3,data.indexOf(")")); + t=new Event(context,from,to); + } + if(mark.equals("X")){ + t.markAsDone(); + } + list.add(t); + } + myReader.close(); + } catch (FileNotFoundException e) { + myObj.createNewFile(); + + } + } + public static void taskListAdd(Task t) { + list.add(t); + System.out.println("Got it. I've added this task:"); + System.out.println('\t' + t.toString()); + System.out.println("Now you have " + list.size() + " tasks in the list." + '\n' + UI.lineBreak); + } + + public static void taskListDelete(int t) { + System.out.println("Noted. I've removed this task:"); + System.out.println('\t' + list.get(t).toString()); + list.remove(t); + System.out.println("Now you have " + list.size() + " tasks in the list." + '\n' + UI.lineBreak); + } +} diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java new file mode 100644 index 000000000..931cfd4f9 --- /dev/null +++ b/src/main/java/Todo.java @@ -0,0 +1,11 @@ +public class Todo extends Task { + + public Todo(String description) { + super(description); + } + + @Override + public String toString() { + return "[T]" + super.toString(); + } +} diff --git a/src/main/java/UI.java b/src/main/java/UI.java new file mode 100644 index 000000000..1b12bd47f --- /dev/null +++ b/src/main/java/UI.java @@ -0,0 +1,23 @@ +import java.util.Scanner; + +public class UI { + static String lineBreak = "-----------------"; + public static void showWelcome(){ + System.out.println(lineBreak + '\n' + "Hello! I'm Duke" + '\n' + + "What can I do for you?" ); + } + public static String readCommand(){ + Scanner myObj = new Scanner(System.in); + return myObj.nextLine(); + } + public static void showBye(){ + System.out.println(lineBreak + '\n' + + "Bye. Hope to see you again soon!"); + } + public static void showLine(){ + System.out.println(lineBreak); + } + + + +}