From 40a3acb59088b347af30c20db27c3a7cb3a8039e Mon Sep 17 00:00:00 2001 From: Sai sam Phyo linn Date: Wed, 15 Sep 2021 13:50:57 +0800 Subject: [PATCH 1/9] level 1 --- src/main/java/Duke.java | 22 ++++++++++++++++------ text-ui-test/EXPECTED.TXT | 20 +++++++++++++------- text-ui-test/input.txt | 3 +++ 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334..b4efd3da 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,20 @@ +import java.util.*; + public class Duke { public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + + String greeting = "Hello! I'm Duke \n\tWhat can I do for you?"; + String valediction = "Bye. Hope to see you again soon!"; + String horiLine = "\t-----------------------------------------"; + String buff = "\t"; + System.out.println(horiLine + "\n" + buff + greeting + "\n" + horiLine); + Scanner myObj = new Scanner(System.in); + String userInput = myObj.nextLine(); // Read user input + while(!userInput.equals("bye")){ + System.out.println(horiLine + "\n" + buff + userInput + "\n" + horiLine); + userInput = myObj.nextLine(); + } + + System.out.println(horiLine + "\n" + buff + valediction + "\n" + horiLine); } } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6..cf3aa88a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,13 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| - + ----------------------------------------- + Hello! I'm Duke + What can I do for you? + ----------------------------------------- + ----------------------------------------- + list + ----------------------------------------- + ----------------------------------------- + blah + ----------------------------------------- + ----------------------------------------- + Bye. Hope to see you again soon! + ----------------------------------------- diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29b..b480b434 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,3 @@ +list +blah +bye From 6e1c90692c1ed8ab48d716be990bd265c1a63ed1 Mon Sep 17 00:00:00 2001 From: Sai sam Phyo linn Date: Wed, 15 Sep 2021 16:54:48 +0800 Subject: [PATCH 2/9] Trim and case insensitive for valediction --- src/main/java/Duke.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index b4efd3da..baaff1cc 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -10,8 +10,8 @@ public static void main(String[] args) { System.out.println(horiLine + "\n" + buff + greeting + "\n" + horiLine); Scanner myObj = new Scanner(System.in); String userInput = myObj.nextLine(); // Read user input - while(!userInput.equals("bye")){ - System.out.println(horiLine + "\n" + buff + userInput + "\n" + horiLine); + while(!userInput.trim().equalsIgnoreCase("bye")){ + System.out.println(horiLine + "\n" + buff + userInput.trim() + "\n" + horiLine); userInput = myObj.nextLine(); } From 641a167a3c720893a45336779f69c6835f3fe61b Mon Sep 17 00:00:00 2001 From: Sai sam Phyo linn Date: Wed, 15 Sep 2021 20:14:34 +0800 Subject: [PATCH 3/9] level 2 --- src/main/java/Duke.java | 9 ++++++++- src/main/java/Task.java | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index baaff1cc..b5b24af7 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -10,9 +10,16 @@ public static void main(String[] args) { System.out.println(horiLine + "\n" + buff + greeting + "\n" + horiLine); Scanner myObj = new Scanner(System.in); String userInput = myObj.nextLine(); // Read user input + Task newlist = new Task(); + while(!userInput.trim().equalsIgnoreCase("bye")){ - System.out.println(horiLine + "\n" + buff + userInput.trim() + "\n" + horiLine); + newlist.addTask(userInput); + if(userInput.trim().equalsIgnoreCase("list")){ + System.out.println(newlist.showList()); + } +// System.out.println(horiLine + "\n" + buff + userInput.trim() + "\n" + horiLine); // echo function userInput = myObj.nextLine(); + } System.out.println(horiLine + "\n" + buff + valediction + "\n" + horiLine); diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 00000000..19c9a181 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,30 @@ +public class Task { + + private String[] itemList = new String[100]; + private int indx = 0; + String horiLine = "\t-----------------------------------------"; + String buff = "\t"; + + public Task(){} + + public void addTask(String item){ + if(!(item.trim().equalsIgnoreCase("list") || item.trim().equalsIgnoreCase("bye") + || item.trim().isEmpty())){ + itemList[indx] = item; + indx++; + System.out.println(horiLine + "\n" + buff + "added: " + item + "\n" + horiLine); + } + } + + public String showList(){ + String output = horiLine; + + for(int i = 0; i < indx; i++){ + String tem = itemList[i]; + int indx = i + 1; + output += ("\n" + buff + Integer.toString(indx) + ". "+ tem + "\n"); + } + output += horiLine; + return output; + } +} From f76d8177b4b3f3ac1d9a8509b790d9e400160833 Mon Sep 17 00:00:00 2001 From: Sai sam Phyo linn Date: Wed, 15 Sep 2021 20:20:58 +0800 Subject: [PATCH 4/9] minor changes to output string for list function --- src/main/java/Task.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 19c9a181..7ddab359 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -22,9 +22,9 @@ public String showList(){ for(int i = 0; i < indx; i++){ String tem = itemList[i]; int indx = i + 1; - output += ("\n" + buff + Integer.toString(indx) + ". "+ tem + "\n"); + output += ("\n" + buff + Integer.toString(indx) + ". "+ tem ); } - output += horiLine; + output += ("\n" + horiLine); return output; } } From 2c67bebc192c622d4b3b62369a089ceae252894d Mon Sep 17 00:00:00 2001 From: Sai sam Phyo linn Date: Wed, 15 Sep 2021 22:47:56 +0800 Subject: [PATCH 5/9] Level 3 --- src/main/java/Duke.java | 11 ++++++---- src/main/java/ListTask.java | 42 +++++++++++++++++++++++++++++++++++++ src/main/java/Task.java | 35 +++++++++++++------------------ 3 files changed, 64 insertions(+), 24 deletions(-) create mode 100644 src/main/java/ListTask.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index b5b24af7..ffdfc40a 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -10,13 +10,16 @@ public static void main(String[] args) { System.out.println(horiLine + "\n" + buff + greeting + "\n" + horiLine); Scanner myObj = new Scanner(System.in); String userInput = myObj.nextLine(); // Read user input - Task newlist = new Task(); + ListTask newlist = new ListTask(); while(!userInput.trim().equalsIgnoreCase("bye")){ newlist.addTask(userInput); - if(userInput.trim().equalsIgnoreCase("list")){ - System.out.println(newlist.showList()); - } +// if(userInput.trim().equalsIgnoreCase("list")){ +// System.out.println(newlist.showList()); +// } +// if(userInput.trim().equalsIgnoreCase("done")){ +//// newlist.setDone(true); +// } // System.out.println(horiLine + "\n" + buff + userInput.trim() + "\n" + horiLine); // echo function userInput = myObj.nextLine(); diff --git a/src/main/java/ListTask.java b/src/main/java/ListTask.java new file mode 100644 index 00000000..f55069e9 --- /dev/null +++ b/src/main/java/ListTask.java @@ -0,0 +1,42 @@ +public class ListTask extends Task{ + + private Task[] itemList = new Task[100]; + private int indx = 0; + String horiLine = "\t-----------------------------------------"; + String buff = "\t"; + + public ListTask(){} + + public void addTask(String item){ + String[] tmp = item.trim().split(" "); + switch (tmp[0].trim()){ + case "done": + itemList[Integer.parseInt(tmp[1]) - 1].setDone(true); + System.out.println("Nice! I've marked this task as done: " + "\n" + + "[X] " + itemList[Integer.parseInt(tmp[1]) - 1].getDescription()); + break; + + case "list": + System.out.println(showList()); + break; + + default: + itemList[indx] = new Task(item); + indx++; + System.out.println(horiLine + "\n" + buff + "added: " + item + "\n" + horiLine); + break; + } + } + + public String showList(){ + String output = horiLine; + + for(int i = 0; i < indx; i++){ + String tem = itemList[i].getDescription(); + int indx = i + 1; + output += ("\n" + buff + Integer.toString(indx) + ".["+ itemList[i].getStatusIcon() +"] "+ tem ); + } + output += ("\n" + horiLine); + return output; + } +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 7ddab359..d17171ca 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,30 +1,25 @@ public class Task { - private String[] itemList = new String[100]; - private int indx = 0; - String horiLine = "\t-----------------------------------------"; - String buff = "\t"; + private String description; + private boolean isDone; + public Task(){} - public void addTask(String item){ - if(!(item.trim().equalsIgnoreCase("list") || item.trim().equalsIgnoreCase("bye") - || item.trim().isEmpty())){ - itemList[indx] = item; - indx++; - System.out.println(horiLine + "\n" + buff + "added: " + item + "\n" + horiLine); - } + public Task(String des){ + description = des; + isDone = false; + } + + public void setDone(boolean done){ + isDone = done; } - public String showList(){ - String output = horiLine; + public String getStatusIcon(){ + return (isDone ? "X" : " "); + } - for(int i = 0; i < indx; i++){ - String tem = itemList[i]; - int indx = i + 1; - output += ("\n" + buff + Integer.toString(indx) + ". "+ tem ); - } - output += ("\n" + horiLine); - return output; + public String getDescription(){ + return description; } } From dd0c22f1e66bcb58868d2b8a1076971c674443f4 Mon Sep 17 00:00:00 2001 From: Sai sam Phyo linn Date: Thu, 30 Sep 2021 18:04:23 +0800 Subject: [PATCH 6/9] update on outofbound and checking for actual number with try and catch --- src/main/java/ListTask.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/java/ListTask.java b/src/main/java/ListTask.java index f55069e9..d2deb81c 100644 --- a/src/main/java/ListTask.java +++ b/src/main/java/ListTask.java @@ -11,9 +11,21 @@ public void addTask(String item){ String[] tmp = item.trim().split(" "); switch (tmp[0].trim()){ case "done": - itemList[Integer.parseInt(tmp[1]) - 1].setDone(true); - System.out.println("Nice! I've marked this task as done: " + "\n" - + "[X] " + itemList[Integer.parseInt(tmp[1]) - 1].getDescription()); + try { + if ((Integer.parseInt(tmp[1]) - 1) < indx) { + itemList[Integer.parseInt(tmp[1]) - 1].setDone(true); + System.out.println(buff + "Nice! I've marked this task as done: " + "\n" + + buff + "[X] " + itemList[Integer.parseInt(tmp[1]) - 1].getDescription()); + }else if (indx > 0) { + System.out.println(buff + "Item No. " + Integer.parseInt(tmp[1]) + " is not added in the list yet." + "\n" + + buff + "Select between " + 0 + " and " + indx + "to mark as done."); + }else{ + System.out.println(buff + "Empty! No item in the list."); + } + }catch (NumberFormatException e){ + System.out.println("This is not a number!"); + System.out.println(e.getMessage()); + } break; case "list": From 1cdc9e19664455c4eb3081057bd5771ce8920159 Mon Sep 17 00:00:00 2001 From: Sai sam Phyo linn Date: Mon, 4 Oct 2021 15:55:18 +0800 Subject: [PATCH 7/9] level 4 --- src/main/java/DeadLine.java | 20 ++++++++ src/main/java/Event.java | 23 ++++++++++ src/main/java/ListTask.java | 91 ++++++++++++++++++++++++++++--------- src/main/java/Task.java | 11 ++++- 4 files changed, 122 insertions(+), 23 deletions(-) create mode 100644 src/main/java/DeadLine.java create mode 100644 src/main/java/Event.java diff --git a/src/main/java/DeadLine.java b/src/main/java/DeadLine.java new file mode 100644 index 00000000..3e53e4b5 --- /dev/null +++ b/src/main/java/DeadLine.java @@ -0,0 +1,20 @@ +public class DeadLine extends Task{ + private String date; + + public DeadLine(String des, String acro, String dat){ + super(des,acro); + date = dat; + } + + @Override + public String getDate(){ + return date; + } + + public void setClock(String input){ + date = input; + } + + + +} diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 00000000..5a0cf551 --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,23 @@ +public class Event extends DeadLine{ + private String clock; + + public Event(String des, String acro, String dat, String hour) { + super(des, acro, dat); + clock = hour; + } + + + @Override + public String getClock() { + return clock; + } + + public void setClock(String input){ + clock = input; + } + + @Override + public String getDate() { + return super.getDate(); // getting date from deadline class + } +} diff --git a/src/main/java/ListTask.java b/src/main/java/ListTask.java index d2deb81c..bfc89612 100644 --- a/src/main/java/ListTask.java +++ b/src/main/java/ListTask.java @@ -8,20 +8,11 @@ public class ListTask extends Task{ public ListTask(){} public void addTask(String item){ - String[] tmp = item.trim().split(" "); - switch (tmp[0].trim()){ + String[] tmp = item.trim().split(" "), tmp_string; + switch (tmp[0].trim().toLowerCase()){ case "done": try { - if ((Integer.parseInt(tmp[1]) - 1) < indx) { - itemList[Integer.parseInt(tmp[1]) - 1].setDone(true); - System.out.println(buff + "Nice! I've marked this task as done: " + "\n" + - buff + "[X] " + itemList[Integer.parseInt(tmp[1]) - 1].getDescription()); - }else if (indx > 0) { - System.out.println(buff + "Item No. " + Integer.parseInt(tmp[1]) + " is not added in the list yet." + "\n" + - buff + "Select between " + 0 + " and " + indx + "to mark as done."); - }else{ - System.out.println(buff + "Empty! No item in the list."); - } + setTaskDone(tmp); }catch (NumberFormatException e){ System.out.println("This is not a number!"); System.out.println(e.getMessage()); @@ -31,24 +22,82 @@ public void addTask(String item){ case "list": System.out.println(showList()); break; - - default: - itemList[indx] = new Task(item); + case "todo": + tmp_string = item.split("todo"); + itemList[indx] = new Task(tmp_string[1],"T"); + indx++; + printMessage("T"); + break; + case "event": + tmp_string = item.split("(?i)event | (?i)/at"); // (?i) ignore case sensitivity + String[] tmp_s = tmp_string[2].trim().split(" "); + itemList[indx] = new Event(tmp_string[1],"E",tmp_s[0],tmp_s[1]); + indx++; + printMessage("E"); + break; + case "deadline": + tmp_string = item.split("(?i)deadline | (?i)/by"); // (?i) ignore case sensitivity + itemList[indx] = new DeadLine(tmp_string[1],"D",tmp_string[2]); indx++; - System.out.println(horiLine + "\n" + buff + "added: " + item + "\n" + horiLine); + printMessage("D"); break; +// default: +// break; } } public String showList(){ - String output = horiLine; + StringBuilder output = new StringBuilder(horiLine); for(int i = 0; i < indx; i++){ - String tem = itemList[i].getDescription(); + String tem = itemList[i].getDescription().trim(); + String acro = itemList[i].getAcronym(); + String status = itemList[i].getStatusIcon(); int indx = i + 1; - output += ("\n" + buff + Integer.toString(indx) + ".["+ itemList[i].getStatusIcon() +"] "+ tem ); + output.append("\n").append(buff).append(indx).append(".[").append(acro).append("]").append("[").append(status).append("] ").append(tem); + if(acro.equals("E")){ + output.append(" (at: ").append(itemList[i].getDate()).append(" ").append(itemList[i].getClock()).append(")"); + }else if(acro.equals("D")){ + output.append(" (by:").append(itemList[i].getDate()).append(")"); + } } - output += ("\n" + horiLine); - return output; + + output.append("\n").append(horiLine); + return output.toString(); } + + public void setTaskDone(String[] str){ + if ((Integer.parseInt(str[1]) - 1) < indx) { + itemList[Integer.parseInt(str[1]) - 1].setDone(true); + System.out.println(buff + "Nice! I've marked this task as done: " + + "\n" + buff + "[X] " + itemList[Integer.parseInt(str[1]) - 1].getDescription()); + }else if (indx >= 2 ) { + System.out.println(buff + "Item No. " + Integer.parseInt(str[1]) + " is not in the list yet." + + "\n" + buff + "Try between " + 1 + " and " + indx + " to mark as done." + "\n" + showList()); + }else if(indx == 1){ + System.out.println(buff + "Item No. " + Integer.parseInt(str[1]) + " is not in the list yet." + + "\n" + buff + "Select 1 to mark as done." + "\n" + showList()); + }else{ + System.out.println(buff + "Empty! No item in the list."); + } + } + + public void printMessage(String acron){ + + if(acron.equals("T")) { + System.out.println(horiLine + "\n" + buff + "Got it. I've added this task: " + + "\n" + buff + " [T][ ] " + itemList[indx - 1].getDescription() + "\n" + buff + + "Now you have " + (indx) + " tasks in the list." + "\n" + horiLine); + }else if(acron.equals("D")){ + System.out.println(horiLine + "\n" + buff + "Got it. I've added this task: " + + "\n" + buff + " [D][ ] "+ itemList[indx - 1].getDescription() + " (by: "+ itemList[indx - 1].getDate() +" )" + + "\n"+ buff +"Now you have "+ (indx) +" tasks in the list." + "\n" + horiLine); + }else if(acron.equals("E")){ + System.out.println(horiLine + "\n" + buff + "Got it. I've added this task: " + + "\n" + buff + " [E][ ] "+ itemList[indx - 1].getDescription() +" (at: "+ itemList[indx - 1].getDate() +" "+ itemList[indx - 1].getClock() + ")" + + "\n"+ buff +"Now you have "+ (indx) +" tasks in the list." + "\n" + horiLine); + } + } + + } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index d17171ca..d0c515f3 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -2,12 +2,14 @@ public class Task { private String description; private boolean isDone; - + // T for todo, E for Events, D for deadlines + private String acronym; public Task(){} - public Task(String des){ + public Task(String des, String acr){ description = des; + acronym = acr; isDone = false; } @@ -15,6 +17,9 @@ public void setDone(boolean done){ isDone = done; } + public String getDate() { return ""; } // not using but implemented here just for overriding purposes + public String getClock() { return ""; } // not using but implemented here just for overriding purposes + public String getStatusIcon(){ return (isDone ? "X" : " "); } @@ -22,4 +27,6 @@ public String getStatusIcon(){ public String getDescription(){ return description; } + + public String getAcronym() { return acronym; } } From a3cacba198f61ced88bf8226d89da1353ac592a6 Mon Sep 17 00:00:00 2001 From: Sai sam Phyo linn Date: Mon, 8 Nov 2021 17:58:10 +0800 Subject: [PATCH 8/9] level 9 and 2 Individual features --- .gitignore | 5 + production/duke/Common/Help$1.class | Bin 0 -> 1036 bytes production/duke/Common/Help.class | Bin 0 -> 4775 bytes production/duke/Common/Message.class | Bin 0 -> 13081 bytes production/duke/Duke.class | Bin 0 -> 2263 bytes production/duke/data/Acronym.class | Bin 0 -> 919 bytes production/duke/data/Commands.class | Bin 0 -> 1385 bytes production/duke/data/DeadLine.class | Bin 0 -> 1110 bytes production/duke/data/Event.class | Bin 0 -> 1065 bytes production/duke/data/Task.class | Bin 0 -> 1144 bytes production/duke/functions/DeleteCommand.class | Bin 0 -> 1163 bytes production/duke/functions/FindCommand.class | Bin 0 -> 1683 bytes production/duke/functions/ListTask$1.class | Bin 0 -> 1100 bytes production/duke/functions/ListTask.class | Bin 0 -> 9356 bytes .../SearchFilteredTaskByDateTime.class | Bin 0 -> 1901 bytes production/duke/parser/Parser.class | Bin 0 -> 1461 bytes production/duke/storage/Storage.class | Bin 0 -> 4071 bytes production/duke/storage/TaskDecoder.class | Bin 0 -> 2826 bytes production/duke/storage/TaskEncoder.class | Bin 0 -> 3418 bytes production/duke/ui/Ui.class | Bin 0 -> 1949 bytes src/main/Common/Help.java | 64 +++++ src/main/Common/Message.java | 269 ++++++++++++++++++ src/main/Duke.java | 44 +++ src/main/data/Acronym.java | 5 + src/main/data/Commands.java | 8 + src/main/data/DeadLine.java | 41 +++ src/main/data/Event.java | 34 +++ src/main/data/Task.java | 70 +++++ src/main/functions/DeleteCommand.java | 32 +++ src/main/functions/FindCommand.java | 28 ++ src/main/functions/ListTask.java | 235 +++++++++++++++ .../SearchFilteredTaskByDateTime.java | 38 +++ src/main/java/DeadLine.java | 20 -- src/main/java/Duke.java | 30 -- src/main/java/Event.java | 23 -- src/main/java/ListTask.java | 103 ------- src/main/java/Task.java | 32 --- src/main/parser/Parser.java | 30 ++ src/main/storage/Storage.java | 93 ++++++ src/main/storage/TaskDecoder.java | 58 ++++ src/main/storage/TaskEncoder.java | 77 +++++ src/main/ui/Ui.java | 64 +++++ 42 files changed, 1195 insertions(+), 208 deletions(-) create mode 100644 production/duke/Common/Help$1.class create mode 100644 production/duke/Common/Help.class create mode 100644 production/duke/Common/Message.class create mode 100644 production/duke/Duke.class create mode 100644 production/duke/data/Acronym.class create mode 100644 production/duke/data/Commands.class create mode 100644 production/duke/data/DeadLine.class create mode 100644 production/duke/data/Event.class create mode 100644 production/duke/data/Task.class create mode 100644 production/duke/functions/DeleteCommand.class create mode 100644 production/duke/functions/FindCommand.class create mode 100644 production/duke/functions/ListTask$1.class create mode 100644 production/duke/functions/ListTask.class create mode 100644 production/duke/functions/SearchFilteredTaskByDateTime.class create mode 100644 production/duke/parser/Parser.class create mode 100644 production/duke/storage/Storage.class create mode 100644 production/duke/storage/TaskDecoder.class create mode 100644 production/duke/storage/TaskEncoder.class create mode 100644 production/duke/ui/Ui.class create mode 100644 src/main/Common/Help.java create mode 100644 src/main/Common/Message.java create mode 100644 src/main/Duke.java create mode 100644 src/main/data/Acronym.java create mode 100644 src/main/data/Commands.java create mode 100644 src/main/data/DeadLine.java create mode 100644 src/main/data/Event.java create mode 100644 src/main/data/Task.java create mode 100644 src/main/functions/DeleteCommand.java create mode 100644 src/main/functions/FindCommand.java create mode 100644 src/main/functions/ListTask.java create mode 100644 src/main/functions/SearchFilteredTaskByDateTime.java delete mode 100644 src/main/java/DeadLine.java delete mode 100644 src/main/java/Duke.java delete mode 100644 src/main/java/Event.java delete mode 100644 src/main/java/ListTask.java delete mode 100644 src/main/java/Task.java create mode 100644 src/main/parser/Parser.java create mode 100644 src/main/storage/Storage.java create mode 100644 src/main/storage/TaskDecoder.java create mode 100644 src/main/storage/TaskEncoder.java create mode 100644 src/main/ui/Ui.java diff --git a/.gitignore b/.gitignore index f69985ef..76de3b95 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /.gradle/ /build/ src/main/resources/docs/ +gradle # MacOS custom attributes files created by Finder .DS_Store @@ -15,3 +16,7 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT +/build.gradle +/gradlew +/gradlew.bat +/settings.gradle diff --git a/production/duke/Common/Help$1.class b/production/duke/Common/Help$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e8f0401824f6784be04d596058e256abd7cba5bb GIT binary patch literal 1036 zcmZ{iZBNr+6o&7zvhJlwMMVTrl*x-POi@4t(QPemVQhxZ5yKZt+d#3jr0wvliT(f+ z{Q)ML_*EquV+=pQA7wmeA?Y-ltoQv~r_VXhdbdA+eLn;+2Q`E97)e9Hg*2@$GLA~f zFlD`Dt%SoG~A{UILt@I9z8P5r!@SC zGrHdjOncekj&#{}_ojA?eS_v{p6U9b<87_l(Y9|%n5M&Pb{LiYFp_Xn#x2aq=)(ya zvzU`{8}kANxjXL~-d4Wm>n(G8*|A+q3j#loafi1puq?9NWm#gm$8w*gz*1x>VNO5~ zKfUke`H$r&9l7Fpc2IJSFtjNVB|fdbxnrA=fNVzx^>c*zIKt$<;kLN5Z(?$z`p3-$ zic+oDG>-D`8-%;_bFjk;PVt5);|rJ`yDwOZlUZmp@+s3a~|YATstXi_z) zYE`X43$a>1TgR(M0-_UXTrUYexGvyUhIEho_{RA!&v;w|- zgK+pGbAYbT{7Za=DAqqfTxnyHuscSHFd1WtP>L~4n2Iq&sC4YkGIwm3nLGCPFsI}G zW6YVDdzrIs{)8;j^f0Hr^m?58~cdn9acnF=mfhRD@E$ksAkMJBX$Y0_W zUX#DUTf8HGkB>MYPta5#*$!ujrUPAcouO+U{p%9#SpA38xb|Oxh{5)tA)F-_F-&@{ QT^Yu8@(dlPkV8rR26(2$E&u=k literal 0 HcmV?d00001 diff --git a/production/duke/Common/Help.class b/production/duke/Common/Help.class new file mode 100644 index 0000000000000000000000000000000000000000..9f7990aaa236d339f83cbdc24e9002842805f6e5 GIT binary patch literal 4775 zcmcgwTW=f375-M1&5LM9k>g8}UM7wb%8E@&axQk9CY43XW=u)8NGWxlHXV^eaiirf zvAdKk6wPDNJ{Ij`(Y_Qgnzsn88x&~J$Dn--5FjsY|3`zO-x-p!WIK=Kg0p+(?97=t z-=6tq4*&7LzkUYb4d?_erSU9YO(T!jk=WtatZ>8`(yq&~5 zX?!2^NnA@}A&Ei~#UvJ!xSqs~BuYuVn}&m%36v99N?_SRrsVr3T<~-hnaIJhw_M+i z-*#|h>ioKc(S@LH96VKaeY4zYZJ4mCH#}-4%0W$g>pFC$-cydoO_w%~mluLoEAaC- zjMu*EU`(E((th2+>8ZQr5B0Xrd)nX3SK`q1H?PWAiCVwO#N!PdI2?8Iz>AXSnN97@ zhnt<2@#EsXnrX*w;B!ESlQ{W=Q5>XuW85^m;#FP8I^UaF#E!=+v94_`>9%z!ft3Vq zu~Q}Jgf+A1isLD9CMOQiv1Jp*OGaSfh$qAly;uxQ*2eDp)1b*H(-3 zH>)>RSJtlI$e@Zf2j?Cl@lF0@7zr0LSjT%A`~Y_n_+bWj@xJ4%rY;WZN~hMu1r;<@ zVP(0fdZ@jr(y4mj8B0G(z>hNcF+OmdR}?&;z$%qFU(Mh|VgaU|+S2i3KELQI)2(POO^R4F?E`@p*@MaUL2~Ordw+=jTM6A3D_&7Ip7L0HcUXLG|8Sw%*NTzXy*Y(=WURVLbq6t3c?VVLcc zmh2s(65{W_md&EODjAXuZW1ah;AVx-7HzdhaDxrLKMe)b%KZAFjnme%zS*JYo>9JT znQSh;7ZdJ^=APN-Hp_WCdY6n(VyiV}KkWl4;90%ex8v~~CdZyW#k9LvMkeyt2-?g*Kb|MqXiwz!(I&GP-{ajsdWKi&SGZb`A6w1lNJkjq0>{#Ejae<~H1#V(1wa)taW>@k}>hyT*i`=PW(jK|m)SHxv}F-8mGXQvIfr62UX%Ss{=|n4wG1>{nR3SyZ~+_S`O$biov(q~(oW zGr&ci!A~SJ8e4dnFFF{1m=mpR$XSJX*?|U=v#bm8>?dxAx^xptX0A*uTMnL?I)5N% z>}8uAF%H(+ZRWi?VosOX)?UY~G#tD*^?2*^kEMxcCo4N{Tx&8>oRpbN%Jg_hWfC}Y zw?uo~6J1|>Hj8HcfJc?xC^nqek)T7rPIX6fgZwR~!7-<2bc=cDNejVYHO;oAk>|7D zlcvcO`pl+@%iJSY8oe1U2H_eB953K3|45K)g!w-cQ{KPBTAojb&!f|S!N@1}^>=wc zW|avj%9(BhnmET=3NK=k8g_QRqOnox{^OLVKO6l6#-~T;9^l9Wj4s{Bv5BKg7e2+Y z@_i(i_mC{_A@#}wq;ns$2e8K?1COy>Wm#mo&GJ6WCQHcjGnQYl{F>!=EPvd?*hJ<5 zj^9Th;t4C(MSRMNcSIbwB8MECc-o2!B2HNGvWO?Gcu~Y>tawhuQ&v19;%O^pD1M4F zlt1B2&k{0)1dc%P`N-Z+(Eo8H@ib21BwL(jn`hbTjD`CpJdY+dZDJKs`%`K^B6>e3 ze!s-a_!YAF4bJ1Yn8xpM0rzncAM=CkVFrK39R7w&_&Z+1=Xf3e#ASSeEBKOF{TuJl z8t^KPVuJH|iMB>)dzAL3Sm*bk)oDIQ@GrbV%QE}Vd+jb#{{qIp#;F8yUt=VJ{PhG9 iqyNRV^!}BknHg(fmJJDLv8_C=P`G_hx1_ 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 literal 0 HcmV?d00001 diff --git a/production/duke/Duke.class b/production/duke/Duke.class new file mode 100644 index 0000000000000000000000000000000000000000..ff2a063f32a4d14fd9d5a8e375aa327e8d91883c GIT binary patch literal 2263 zcmaJ@>2ecC5dKCMthHHVV|;MLTrtE4pg=AX5hoxpIFW(G2eHXDmIisP)vnlG`N&1? z>j{#)0KcJvOhHv1AkUCDNh;)%Rwo0(cd_70n$h3kLE6Mi6?wEGmJWxjLDiidh+f zMAfEBu4<=eY;Fx#tvGfN3iRY|RNZ`Ndv1`cBEUR zJ>PbVnc-Q1WY#OtS7*+4)#Yk=LHW~i!6BzR=jEj{D}7t<>r7D*7>o_MwwJzPJ1RZl zE=$KQT$SPCh1I;OXbki$JUWe4sX1|_QI-rB?SSBN=c^?}-F9tA8_;f>U8YdcB z)!bAgj*QGX+mtyw1uO1-ohY`FqKbKO`jUJa2U^7Q2PAgD8i@a&%g}}MJ!sd zv1FiR!NHP1*E!D%gV2|iNfj=7g`jgg%I$D1c&He-X~D-ZgNqz&&ANpEOBO<$wouj7 zvNpV8VHIl@KGmGh@VSLA@TG-Y8fH?*&n_&;P^NW;HE|+b4K3at%DWyH>dL~B$}{;5 zthmK!MfcxU$yyMqGHd7QdOdEDtL({;$CNCyCCs7n5_&ai;80Weof*aHJ`|R@emg zKV6S+&;WnnvyjkJf>c6JlIY8^5=n#}B78GOxcdi5>H_m4>qv||MBCgtlJ~HUq#(Kd z9t@K0bEE4>-Ge#u2e#Gl%xxT-yo-)wHSD;L&IjlMYS?)jeRb}x`{>!=-XVg$IF1+i z(&_IwpSCuP(&s61z_Uqo@^2@lyEyuKsI!OKy*P$T zO#g#;g9Xun^hKb@>YzIr#%r6PQ%L-aPU1a^6kbQB4l_gZf=4?ZVqmU&|2huTa8P?q vL@6~Ri^ELpNaVqam2rkXHL|ft^G$ruul~2;Tl|RcnBptkw{w4$zjyx!(UdIa literal 0 HcmV?d00001 diff --git a/production/duke/data/Acronym.class b/production/duke/data/Acronym.class new file mode 100644 index 0000000000000000000000000000000000000000..892821857c8b475c2cb32ce6fb885798d750230a GIT binary patch literal 919 zcmZuv?{Csj6g`g?TDp!O6{pOp6Q=_c|?D z+!Tl>I`YD9>9B;YX?V)O4jD3?BOdWu%Lzxpr(uJFZTem@Xlvb8=WW|&$iBOZNu6+i z;*J^e<;u0Bx;Hv2ZNd&g(+j+4hhgbI^sg&j1~vNVk?OSV4FVobLSjvbS7LGw`p2#lk$@NR0rz}99yemJe+!*wZS2u$ zsJlg>03b^uq$M3dZdvFT2&8cnOJKM~UWu%Dj49YxB+j9HCXeAZohg}92w%kV48M(p zj2f0&{f6W@RDn;-;qOqyyg*?EcV(VdLnzU)4uxJot8T2EA@xP3Y76#H2xeTiAqH9VqN0+0U!F(9t8 literal 0 HcmV?d00001 diff --git a/production/duke/data/Commands.class b/production/duke/data/Commands.class new file mode 100644 index 0000000000000000000000000000000000000000..824a615ac3505eea820fc63d81d881b7ffee4d64 GIT binary patch literal 1385 zcmZuwU31e`5IwRL>spbCFa#P1g?wTsByLKev<@LotRx0uL*y7dJSmPz&DipcWAlUf z1ysyHrwpAu_aF78)7`ZJhak=DnX|ih@7Z1Hpa1^)8^AAk9*2%i6I;j|$QW=;+`u-Q z9fc{Af;*hCt1!b@P?%+Ws4&O)NMWAQRk+FcSRut&R7f+H6c!ktC@eBQRk+2tr?AB6 z87OPe^QEGrVaz@ByMAV?-D>&4;c=D%Zo%Vtxs)$y7;!32k*LZ$xx8E8Bf6KX5XAD1 z>y(-AI_?vK?Lsk6P$@XiG+3K^PVP~8cdxX+v#TMxS*1*4wvu!A9Z!S(;>^9V*M75C zKh}^;rO!t7t@dG^;2l?*85&-EpsR6!_g_ott8X{Buf*q-EOS#9mibG`Sl9;@PMlhrg;hMW z@GE|^FokIgGi+wr%(0ngbCXSqO`6RDn?*La*eqdM!?~~HV~MoM zzlw->&7{8YCq_=7bAIGh{$27|{Ve*y?@65YL0Np`3ZnD^#=_#{2gLr6@bGnCj~mFc zbgW6veJHHseqV?-PL1&M??>p>q!Il9^$u|%rY>Yuh&3W4A>>?4$e0k@5OQ8fQVF>r z;=1<^8V|0&CzB>i^TZq4 PSY$A)2iPEA1iAkKy#D|2 literal 0 HcmV?d00001 diff --git a/production/duke/data/DeadLine.class b/production/duke/data/DeadLine.class new file mode 100644 index 0000000000000000000000000000000000000000..fe07a30fe2984ac21d40c6b22dfe584ffe619ac4 GIT binary patch literal 1110 zcmah{O>fgc5PcgvF;1Np(k3O8Qks5{xJ?a6h(i$)BI+qZNQrvi#8zrZ?80DDTn@2FuoFw)5!k=)pVs3lVWgHEsxgO zvG9z&Rjd$dVMPH`#XULsD6scmv02*ErHm$CVo%9jZ8snRZ#eKI~^Oo+%+V@%rcKD3i|wcRD#1;W3=#75$S zKfoVlJTtqENH_6i=H9dSoO|z?{q_6DPXKS=*_gq0871u4*u|cXUg+qhj$W0pUqVfw z&>4iCF9Ox(XL&8Xfedn=3tlLIyk_ggIPEZ8aQ%L zhRteYnV|@jP12SlzT4h^{nc*HUCL;rBJY#A1a?iHyz^wIIMmKIC#gUqLppUPbG=0) zs`<3%G;#H>N(LpvX6*3ioZ%0gM^10fD5t$JHx1%#fscuKo==$Fu+rka?#T-9(Dn5;KZonJtBhRD;rnqUiltKy=Quh)rLM*5%RaBLbQdlIaP1xQ3lEO-DO3h~d_G!*7esr#&=(L#0+#gpz3}o( zV6M@Tv8?YVxvJX^!XVxeFl%dv0+~0x4x37iAoSl|oVERaOSZc_aT+~Ob`NDgPSi7oca;h3+@(PR;MtPARCt@?TBdwyNrOzJwaWj_jMfBEF7cJM; zuA&8IS>v4^$aAgA!gCVYnGks`8Zf8wanFi8NKFu!CwI!0QYVPcyYg~R#(pa}qXETc z@1pPd`+;(!pzgY*Y_~Cw8#aoVu`!2|4I8sG{R5w>09dNYs-A;JAL@Pk#P{NfqvYFR zg`d2@pTUHou-q96s#i|nnkSZ1869SIuAGFd`xD~3E?Z#C>BAz*+}lY37ExiQnr||y z<~HFb*RpDM*9S1%jR8#893V4dRgh(kgA5iZt;~xqa#zvpYSN#wNy06PR)Wg7O}Pg5 zcd(Ss+hK0-UCv#am{8QG%bashQ!7c;keb6?TA(hv%!)+&zRrP?`vaNJ$UE6D$U3=i z#G91&--1;QOe`p+!25h_!LWBNR7qLEgOoWklgzKIGR8=oW29_K;{QGrG~R3|8RN|_ muWf#W)oUi3)6Lu0Ha{Lt-b}499c#LEZ>-fEihiQi)&2pzxThfi literal 0 HcmV?d00001 diff --git a/production/duke/functions/DeleteCommand.class b/production/duke/functions/DeleteCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..6ec4611ce20fbae672321e737082ba8157142b51 GIT binary patch literal 1163 zcmcIjOHUI~6#i~oI&?a;SZDz$74TK6Fp3Il0UxLdNkNh#Mt7HXtQV#;&CDGF{uOs_ zT)5JOfF`>4HyPu((;}9{rPK7zIp?0ocg}a_$FDEn0L)`q!+9NjxRAs}T+(qFMI}vX zC@JNNjySF+FpZgBm^!ZEx`tT|HyGjz!Vz+bAzGZ;WQZ-hb&DZg5stMMG`B2ogKybn z$yD4Lw>P;bl-@DMkU{W2bT~RO(!EQ1uXHwZ_mB2=kdRkV0C+ zO#`k%`D2c^O$^!M%2b=Ya57J~wyl~Z#xlaGxt>Q#mB$S&WhtA^&5nbL2HfT7mu=B0n+7bV{RoAE%IsP@4P= D;erM< literal 0 HcmV?d00001 diff --git a/production/duke/functions/FindCommand.class b/production/duke/functions/FindCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..0b2a3e9c4fc160f9b731d20cbd91223edb24d909 GIT binary patch literal 1683 zcmaJ>T~`}b6x}x;Oc;i*6lkN?)?y_Iw5eJ}2%)ch3v z13vpwz^>);!KePDuI0zRlcX7>nunWv&)MgmefBwbp8oagZvYnYt&S<&((tB^2yTra zi?>EFkGIuwTf;jV-qoRDF@g7VEMZwk9xFN$cwfgVK2QN4Ca{*k9UTSS)o@S4y1>wi zWn2ELKs24H2*e6b-4qxvTDDngAMKj%w%l#fk}Ntk*{n#{Qsjcz{TQT+phVR zV|%%E%dQukqa$h8^Ndo*O|$d8})7``{t3rNU<(`nNuL9jUJjEfrLeux=>&u6c(fq7^So2xYF%( zAv0$S?6mqt&W2*icBOl4O1qIO`>tg-@~cdFIfPOdu7n6F|7h8lwZkph3Z&EUk%s#M z!)2>sOTX<>;ljUUd10de&7ySE%TC*^nd_En+C-=uH&id@0~`3* zz$S_YwooFs=ZXqU4g&5=Z=W(4cz{m?#8nNS8u$!l4ci7jM@6NmYWTvy4jvkKgfBT& zdmIA+j^|efzQ#8K(=VJD4$Q!=RO~i=Y>>U%tK`72;hV1X9k<)=-gYLP2?^DQunXG0 z^h)LroCuElLlU!t!&Dz1boIgRfm!p39&4EXUDK<%R!a>xhw==r*L}(y&< zfw^8&L(Y8W(fJYTUlP2DpeKA+L(=Qkdp#Wv>G2Dfs9+?V3Xf31X*O90i3bmAdZ5|B z!z78if4dWGD<|PakI$}fu)hCGT93#3le~Oqu>BcGI0zYDjn<0VUp)JRrAhDB* zJ;rcSe~gh67{?f0j%QQx6O8=?V<8ng#drkOpa1@2AvuwpJV8>?i9yl1#t$?w$u)^t zRF4+~@fljj5&aY68nPPZ^Ur8ppfQ3Q1l|mGxqko&zomKr literal 0 HcmV?d00001 diff --git a/production/duke/functions/ListTask$1.class b/production/duke/functions/ListTask$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ce5f6730d01d5274de6772db3bbf5c28fabe53ea GIT binary patch literal 1100 zcmaKq-A~g{7>9plW!*-RfhZHdP$nOKFi`;!M912(g|ZPgM+`TXu0o--r0ww5L~pz^ z(LcaM6K_?FF~$%RzI^r15*Ned3VOvowZEKtu&1Fyk**T)$?3W#xyUx$(Ui>V%%nA8MBNW zLt&_lJSGKn-)}fZV7ZQ;`SmB$qXOijMLs|j%da8MH#JJy8mdGZ4K+q8g&HS~ zg_T{2YXxSNp`vEZy_U2hwMQsQs~D3Tv literal 0 HcmV?d00001 diff --git a/production/duke/functions/ListTask.class b/production/duke/functions/ListTask.class new file mode 100644 index 0000000000000000000000000000000000000000..8c0449d644e3fcd9906b23d6e75375cccde9cd0d GIT binary patch literal 9356 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 H`@H`HmM|5S literal 0 HcmV?d00001 diff --git a/production/duke/functions/SearchFilteredTaskByDateTime.class b/production/duke/functions/SearchFilteredTaskByDateTime.class new file mode 100644 index 0000000000000000000000000000000000000000..51fcd6d2d1b60b92f374c454c3dd1ac24fe69d2a GIT binary patch literal 1901 zcma)7TUT2}6#gb8IdC{oqy?H{Ra&XsN+@2ifXKDB8lW1a7p-=Z49TJ4B%YjrdGgKW zS}tGoiC^HeK2XuMTz&Q@b-AkF%t^}COCILT?ETH&`}_9HN;0japDo;Qi-Gc0ZcSDm&DR!Xpw`?iHN`ONuG&dw3o2JF zs?a0QKakp#+cH^{UOt%)eAmlQg_dgI7LzHr5=@!m0*2GY`&~X6rsGTCLm=?&7f=(}#+j;l{RfAhVB_W!VUA;kJbjEqo-_n&0)wYCY49J8OSAhtNB2M-WHfK&=E<-Mva+JS)0c*;H9`6Y?sU%laj+M#VaaF{;)rjOH9(3y4K3a~u;_UsPq0*Sza6m3j(YLJN~* zYC8qx3G_DVII3j*_V*Y$Pr7(ZL(z(%Xg#M#VZlu@$D<&Y!mM*an6-VOw6#_8lFO=6 zk$I|qKIc}-MOo9$p4*_RjR#3!qR!&rX$iY=^6@!r8C*vny7?sQUj)p61jh?pCHWQn z#)ck4{AAp{9OK5=ju$z1LI5t}C9YcVGG1X2ZWfzpf<@a8zaet(F`AZ#enE6)cpou= z$!H?FkGQ}tN_u7qJVEnhED_s7%g?a)(7KEMMC=Ki$#^2ZhqgVmU){r*T{t6&*giTU zxbq{%>i8E7{*uObhWN9m;s5$>r1KoB=+ac8&{QVT&asPsHr;5W2E$~3o&0A>VU>ux zB<7M@nZ&*#wQq14-{Mt#kA6e{CMnKxPaiH(ma>^$=4==bi0Vg73xF$ljbA+*z#s){ zW{e@uBFyqs|$WsDdCm@11 KxamzZd+Tp~mfVT} literal 0 HcmV?d00001 diff --git a/production/duke/parser/Parser.class b/production/duke/parser/Parser.class new file mode 100644 index 0000000000000000000000000000000000000000..57fac8a14bf9ae1950ed48d47a211ea1b50197c9 GIT binary patch literal 1461 zcmb_cU2oD*7=8`|3Z-)!Q*a+Dn^S?g)$f^LyxFqs0_GByd3}I0=tA3Bipl`#$gUewJUqfBXcnhdmuSN*QeE*u+B}TX-ao#~D1)QAQ<$ zs)lV1PZ`qhEXVTSGt8AMXAH@Gw<8!9>XsvphjvSNr@YlCO}_57dH;-imXycJq~Eg! z5`D?Nf$+=|b=4S_mEwT=;?VV)zU%QWaqN`q7yL6feajZ6;**F|l4_N}(&tXsZ2F$% zbcrR~A@i}cGpxkA67JmfZ0`HQW7wL(1!{8=gi;AmM7^mJ3?fbJzAJO8PsC}yvssN3 zjVM9(NR>AWXIKqInu)?t8FysXB{D*|rw7*Hvd^y=^rk!X+TzfXL&^mM*p+D*$iZNk z@0bnqik{NZk!@?(F|Z3$!!rZV@xs7Mykf{qKpI|4)f=j%(P)%9osx3x^=!MuiA>cp znKQ%UwB8S`3(@wevC|31wVwv&o}Z|BISg-aXh9qcb)-0rb#0qys{^koyP8)lRpj=i zRIv;nXA|7-ajz*p4TaMdwSQT)$Z4vTr>`U;e}?A&k5|J6vhnK~bUq+-LL%~s5$5XE?QckaAvxgCl`ThH zhTSTmdS63kt}{n}uc$8#c26ejP8W&<$gQslQ4o@rW8{g`5;TmGWC>~N(( zET(hW^lh0Ziv!`B9Vpya4nog2S1rPiMuOO}5@Q@)wZik(jW(D$&!6$DYxV|rsW3!f z@+B5E1Y28BAv-RBhN<7PnSJ9|C$?gzEz!13XKr5Ls;de+E1_9kUoabOw2o)i6!s)r zZ-%y0D%(LgEq)Z0_QiHd=lq3pH>*}7v^|%5$v7dy5P$4yDU9@Ta;wqi z&C;S7tWTe&LA_%=(C~SMe8paM&9LbcM6n-Uud-krH5(1ftyRdOgd$j9^v>N3E#EaA z5;mT4CenHsNmR@YS|3V%RM;OI5)(p1+RT143R7f0{w7h3xXqoaI!PMo6|d=6qs&w= zlIWk5bY=!L?b0RNzyuyKa2Q7nJcuLYu|L^~u-06+N)bgGzF^>s_>zV%8+aMF4SZNM z$8n6gDPjhW%ECi9X5e8wqTv+-U%^*3ylUVzd`-jG4SWON)bK3>-^OhX-!brAOfu|| z-`?07_@21_=zc6?#^x>aQ|9f`nn3U}V!Fde%lHQLFHHsX$ud}Xm^ zSr7`-+tly1t!0r^N{>b~>#9|6N#-vmU$nY(*Hsd(bGB`b! zAnS;U_36Z3x_b7siIVg?YgO5Je7dehZ{3tEM@9Q!e^pHPl~`27>D;;%gjSt&c}>#Q zt?Y~JuOatonROB|JnPl#o?BY5f`I*tf@JqBYgN2jwK?Cb%P!loVD_Z+*`ym{&2gE+ z)aw{2aB|)gGon1_HC>(=zrwE-Udo@iSATk5DTVv%=DIcOxm7c~Vux#d3qsQk8JEYl z$(RpJnBKFfCsOC!BvQH+y-B2^uGMXE+n8k^`sY2}yPhvza^+|$hF&plYen0w@t~j2V`-YZfV*7xOb?SCOuRIJQj)$(G|Uw z{|`&MqiTt71<6S=#HEYA*RcGMSEY7G>0xPWj%oOf^y)t-9PJ)4w!7i+Y>69NTo-d@ zmA8~z8vdj(SoXa2W`j*^-gPa1)-i)Xn%EoZVo7Yo$HLR5TVvZh8Y?DUD2*%ytVeN? z*Mn`u(@i@*9ooGzGMbo}H65p7ht{-)x0yy;_O~52g|YuE$3yuLFU7zhbUC2;rpp-} zjXY(ekq2!w@)(Xrp2QsUyx~q@lFup5p5mC{I5hcZWG1gn-9h#}PBS>p=P4%b zY5oD6;A|uo$4Qhpqar>+^SnsnqaC9bc0^JWn;6*fSL|5I76vOz15=e2w7(#ya0mHK zJH{DVGx+mlOC{7th7KS&mvxQxgE$rUJeJvE;$DX%&J>_KTee7#t|eStui$kbJae2IWx{NDo3q1-93!`zkps)iAryo7Te*-iinOXn< literal 0 HcmV?d00001 diff --git a/production/duke/storage/TaskDecoder.class b/production/duke/storage/TaskDecoder.class new file mode 100644 index 0000000000000000000000000000000000000000..453e51ede8d6cc72f04523fe60075bc19b81443a GIT binary patch literal 2826 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 literal 0 HcmV?d00001 diff --git a/production/duke/ui/Ui.class b/production/duke/ui/Ui.class new file mode 100644 index 0000000000000000000000000000000000000000..691be6b1f210782543aa64e53e79cca80b55a3c8 GIT binary patch literal 1949 zcmcIkZBH9V5PsGWe7Beco6?3fP1mGNzyYpF+CmZ%%8P+Zjft=gYJ_w;>@8es-_d)a zwPdM(sf|jIS}8xEKdS2N*)fMiKXUf%?aa+Q^UU1N{PXW$?*YtXOUFYzQp;nGYxtTY zi*M5SR>Qnb@`8pZ>iIN{XB-@hN_ei8#~NO6Ea5w)UQT0$VPd7WzHYrL)hgEJ_Rfy^ zdb?a*E|tu3ks()lW1rYY({>MyO6WW8;WLJjRnHAV+YNW^W+XMNG7Kq<;*N$jhIF~O zr@S=~!1bPBeK1&O81SNyVZ00Nc*ZNj4GCS^EkaK@F2h*&WfVG1qf)nBSNim7bYrJj zteWKwYpYnPEN>A0@a}S{xMr?a&FwPLSae(`d_f_mrgs?zSG|U0xKVOkS&mu<(y!VF zP158_Ufpi)+P_f#=DXGq~;ne#|UhyKoF4rBEOS#*)3YNwv6&^5{=&}? zhO&$Gv0W!#g;*p%%OJhNH^jbW%~;auO8&8C+Z=KYpfi+++^-#fBHK}SZI zqTz`jJzuoFXo>4p`nrPtwlG`AzIP%U;zas^}nH?mIs{QBxD$G~*DISmI+n?&$RI|yZq;pXM7s=9J4rh0MA zP}dx*q0^*MGv0GeHly;>T={FLCI|8~H?uT$HB2CfF;EASl)^a4A1CBbNWPhnCrG}P zkUu4F>P_;^sY1t3Iud=nA=1<5>B}0$WvYj1{erBYV1RbOaN#Z3Tcpk~@CS)0d`T;( zC&-kO={?$Ix~8~~DUuY-bPp!PAOQiBg)7J6Vj1{)% 1){ + command = s[1].trim().toUpperCase(); + }else{ + command = "BREAKTHROUGH"; + } + try{ + commandKey = Commands.valueOf(command); + }catch (IllegalArgumentException e){ + commandKey = Commands.BREAKTHROUGH; + } + + switch (commandKey){ + case DONE: + System.out.println(HELP_DONE); + break; + case TODO: + System.out.println(HELP_TODO); + break; + case LIST: + System.out.println(HELP_LIST); + break; + case DEADLINE: + System.out.println(HELP_DEADLINE); + break; + case EVENT: + System.out.println(HELP_EVENT); + break; + case FIND: + System.out.println(HELP_FIND); + break; + case SAVE: + System.out.println(HELP_SAVE); // Individual Feature + break; + case DELETE: + System.out.println(HELP_DELETE); + break; + case VIEW: + System.out.println(HELP_VIEW); // Individual Feature + break; + case BYE: + System.out.println(HELP_BYE); + break; + case BREAKTHROUGH: + System.out.println(Message.getListOfCommandForUser()); + break; + + } + } +} diff --git a/src/main/Common/Message.java b/src/main/Common/Message.java new file mode 100644 index 00000000..f1e7db19 --- /dev/null +++ b/src/main/Common/Message.java @@ -0,0 +1,269 @@ +package Common; + +import static ui.Ui.*; + +import data.Acronym; +import data.DeadLine; +import data.Event; +import data.Task; +import parser.Parser; +import storage.Storage; + +import java.util.List; + +public class Message { + + /* + *A collection of System Messages + */ + private final static String FILE_PATH_ERROR = BUFFER + " File Path Error!"; + private final static String FILE_IO_ERROR = BUFFER + " File IO ERROR while loading data!"; + private final static String FILE_EXTENSION_ERROR = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + + "Set file extention to .txt to archive the data from current session." + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + private final static String DATA_LOADED_FROM_FILE = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "User Data file exists in the " + + Storage.getAbsFilePath(true) + NEWLINE_BUFFER +"Data loaded into the DUKE Application successfully!" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + private final static String NO_DATA_FILE_FOUND = NEWLINE_BUFFER +"File do not exist! Unable load data from " + + Storage.getAbsFilePath(true) + " to the ArrayList." + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + private final static String NO_ARCHIVE_FILE = NEWLINE_BUFFER +" Unable to write to archive file upon user Save command: " + + Storage.getAbsFilePath(false) + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + + private final static String NULL_POINTER_ERROR = NEWLINE_BUFFER + "Invalid Selection! " + + NEWLINE_BUFFER + "Choose correct the number from the list " + NEWLINE; + private final static String NUMBER_EXCEPTION = NEWLINE_BUFFER +"This is not a number! or Single Digit number! Please Enter a Number"; + private final static String INCORRECT_COMMAND = "Incorrect Command! Use HELP to find out more"; + private final static String DATE_TIME_FORMAT_ERROR = NEWLINE_BUFFER +" error in date time format " + + "example usage 01/01/2021 0000 or 21/12/2022 2359" +NEWLINE+ BUFF_PLUS_HORRIZONTALLINE; + private final static String ARRAYINDEXOUTOFBOUND = NEWLINE_BUFFER + "Missing Argument! " + + NEWLINE_BUFFER + "Command is expecting argument " + NEWLINE; + private final static String BYE_ERROR = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + + "BYE Command do not take any arguments" + NEWLINE_BUFFER + + "eg BYE or bye" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + private final static String OUT_OF_RANGE = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + + "OUT OF RANGE! Please check the task list again" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + /* + * A collection of USER HELP Command messages + */ + private final static String LIST_OF_COMMAND_FOR_USER = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Supported Command for HELP:" + + NEWLINE_BUFFER + "DONE, LIST, TODO, EVENT,DEADLINE, SAVE, DELETE, HELP, FIND, VIEW, BYE" + + NEWLINE_BUFFER + "Example use of HELP command: HELP DONE or HELP LIST" + NEWLINE + + NEWLINE_BUFFER +"The User command listed above are case insensitive so user can use them without worries " + NEWLINE_BUFFER + + "but arguments which follows after the user command has specific format to follow. " + NEWLINE_BUFFER + + "You may familiarise the usage of command through HELP usercommand"+ NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_DONE = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of DONE command: " + + NEWLINE_BUFFER + "done 'Task No' Task No is a positive index number from tasklist. A tasklist can be invoke using LIST command." + NEWLINE_BUFFER + + "eg done 1 or done 2" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_TODO = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of TODO command: " + + NEWLINE_BUFFER + "todo 'Task Description' eg todo meeting or Todo cut hair" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_LIST = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of LIST command: " + + NEWLINE_BUFFER + "LIST is a standalone command which takes no arguments. eg LIST or list" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_DEADLINE = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of DEADLINE command: " + + NEWLINE_BUFFER + "deadline 'Task description' /by 'timestamp' " + NEWLINE_BUFFER + + "eg deadline 'project submission' /by '01/01/2022 1900'" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_EVENT = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of EVENT command: " + + NEWLINE_BUFFER + "event 'Task description' /at 'timestamp' " + NEWLINE_BUFFER + + "eg event 'food fare' /at '01/03/2022 0900'" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_FIND = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of FIND command: " + + NEWLINE_BUFFER + "FIND 'keyword'. A Keyword search looks for words in the description of the task in the Tasklist" + NEWLINE_BUFFER + + "eg find 'food' or Find 'meeting'" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_SAVE = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of SAVE command: " + + NEWLINE_BUFFER + "SAVE 'new file name'.txt " + NEWLINE_BUFFER + + "Save command is a way to archive the tasklist to a new file location in the current session, " + NEWLINE_BUFFER + + "rather than keeping them in the current data file." + NEWLINE_BUFFER + + "eg Save 'userdatabackup.txt' or SAVE 'data_backup.txt'" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_DELETE = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of DELETE command: " + + NEWLINE_BUFFER + "DELETE 'Task No'. Task No is a positive index number from tasklist. A tasklist can be invoke using LIST command." + NEWLINE_BUFFER + + "eg DELETE 1 or delete 2" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_VIEW = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of VIEW command: " + + NEWLINE_BUFFER + "VIEW 'TIMESTAMP'. VIEW is a command to look up a specific date schedule." + NEWLINE_BUFFER + + "eg VIEW '01/02/2022' or VIEW '12/01/2021'" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + public final static String HELP_BYE = BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + "Usage of BYE command: " + + NEWLINE_BUFFER + "BYE is a standalone command to end the current session of this DUKE application." + NEWLINE_BUFFER + + "eg BYE or bye" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + + /* + *methods to call these help Strings + */ + + /** + * Display Task removal message from tasklist when delete command is called + * This removal message methods is called before the actual task deleted. + * @param itemlist takes in as readonly param from ListTask class Task holder but can still be called setter/getter to change value + * @param idx is a specific index from the task list to be removed + */ + public static void taskremovedinMessage(final List itemlist, int idx) + { + System.out.println(BUFF_PLUS_HORRIZONTALLINE + "\n" + BUFFER +"Noted. I've removed this task: " + + "\n" + BUFFER + " ["+itemlist.get(idx).getAcronym()+"]["+itemlist.get(idx).getStatusIcon()+"] " + + itemlist.get(idx).getDescription() + + "\n"+ BUFFER +"Now you have "+ (itemlist.size()-1) +" tasks in the list"); + } + + /** + * Display Task being added into the tasklist from ListTask class task holder + * @param it takes in as readonly param from ListTask class Task holder but can still be called setter/getter to change value + */ + public static void taskAddedinMessage(final List it) + { + if(it.get(it.size()-1).getAcronym().equals(Acronym.T)) { + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER+ "Got it. I've added this task: " + + NEWLINE_BUFFER + " ["+it.get(it.size()-1).getAcronym()+"][ ] " + it.get(it.size()-1).getDescription() + + NEWLINE_BUFFER + "Now you have " + (it.size()) + " tasks in the list." + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + }else{ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER+ "Got it. I've added this task: " + + NEWLINE_BUFFER + " ["+it.get(it.size()-1).getAcronym()+"][ ] " + it.get(it.size()-1).getDescription() +" " + + it.get(it.size()-1).displayDateTime() + NEWLINE_BUFFER + "Now you have " + (it.size()) + + " tasks in the list." + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + } + + /** + * Display Task set to complete message from ListTask when DONE command is called + * This setTaskDoneMessage methods is called after the actual task set as DONE. + * @param it takes in as readonly param from ListTask class Task holder but can still be called setter/getter to change value + * @param idx is a specific index from the task list to be set as Done + */ + public static void setTaskDoneMessage(final List it, int idx) + { + if(it.get(idx).getAcronym().equals(Acronym.T)){ + System.out.println(new StringBuilder().append(BUFF_PLUS_HORRIZONTALLINE).append(NEWLINE_BUFFER) + .append("Nice! I've marked this task as done: ") + .append(NEWLINE_BUFFER).append("[").append(it.get(idx).getStatusIcon()) + .append("] ").append(it.get(idx).getDescription()).append(NEWLINE).append(BUFF_PLUS_HORRIZONTALLINE)); + }else{ + System.out.println(new StringBuilder().append(BUFF_PLUS_HORRIZONTALLINE).append(NEWLINE_BUFFER) + .append("Nice! I've marked this task as done: ") + .append(NEWLINE_BUFFER).append("[").append(it.get(idx).getStatusIcon()) + .append("] ").append(it.get(idx).getDescription()).append(" ") + .append(it.get(idx).displayDateTime()).append(NEWLINE).append(BUFF_PLUS_HORRIZONTALLINE)); + } + + } + /** + * Display Task that are already set as completed message from ListTask when DONE command is called + * This getTaskDoneMessage methods is called when the actual task is already set to DONE. + * @param it takes in as readonly param from ListTask class Task holder but can still be called setter/getter to change value + * @param idx is a specific index from the task list to be set as Done + */ + public static void getTaskDoneMessage(final List it, int idx) + { + if(it.get(idx).getAcronym().equals(Acronym.T)){ + System.out.println(new StringBuilder().append(BUFF_PLUS_HORRIZONTALLINE).append(NEWLINE_BUFFER) + .append("The task you selected is already marked as completed: ") + .append(NEWLINE_BUFFER).append("[").append(it.get(idx).getStatusIcon()) + .append("] ").append(it.get(idx).getDescription()).append(NEWLINE).append(BUFF_PLUS_HORRIZONTALLINE)); + }else{ + System.out.println(new StringBuilder().append(BUFF_PLUS_HORRIZONTALLINE).append(NEWLINE_BUFFER) + .append("The task you selected is already marked as completed: ") + .append(NEWLINE_BUFFER).append("[").append(it.get(idx).getStatusIcon()) + .append("] ").append(it.get(idx).getDescription()).append(" ") + .append(it.get(idx).displayDateTime()).append(NEWLINE).append(BUFF_PLUS_HORRIZONTALLINE)); + } + } + + /** + * View and Find Command is used to call this displayTaskAfterFiltered method through ViewScheduleByDate and FindKeywordCommand method respectively + * Display the List of Task which already filtered by keywords Search or filtered by specific date + * @param tks is a List of task passed FindKeywordCommand method from FindCommand Class + * @param type can be VIEW or FIND command but not both, specified by User. + * @param date is only use for VIEW command, FIND command will just leave a blank for date param + */ + public static void displayTaskAfterFiltered(final List tks, String type, String date){ + String header = ""; + if(type.equalsIgnoreCase("view")){ + header = "Here are the Tasks schedule for the date: " + date; + } + if(type.equalsIgnoreCase("find")){ + header = "Here are the matching Task in your list: "; + } + StringBuilder output = new StringBuilder(BUFF_PLUS_HORRIZONTALLINE + + NEWLINE_BUFFER + header); + for(int i = 0; i < (tks.size()); i++){ + String desc = tks.get(i).getDescription().trim(); + Acronym acro = tks.get(i).getAcronym(); + String status = tks.get(i).getStatusIcon(); + String time = tks.get(i).displayDateTime(); + int indx = i + 1; + output.append(NEWLINE_BUFFER).append(indx).append(".[").append(acro).append("]") + .append("[").append(status).append("] ").append(desc); + if(acro.equals(Acronym.E)){ + output.append(" (at: ").append(time).append(" )"); + }else if(acro.equals(Acronym.D)){ + output.append(" (by: ").append(time).append(" )"); + } + } + if(tks.isEmpty()){ + output.append(NEWLINE_BUFFER).append("NO Task Matches your query!"); + } + output.append(NEWLINE).append(BUFF_PLUS_HORRIZONTALLINE); + System.out.println(output); + } + + public static String showFilePathErrorMessage() { + return FILE_PATH_ERROR; + } + + public static String showFileIOErrorMessage() + { + return FILE_IO_ERROR; + } + + public static String incorrectSelection() + { + return NULL_POINTER_ERROR; + } + + public static String getDateTimeFormatError() + { + return DATE_TIME_FORMAT_ERROR; + } + + public static String getIncorrectCommand() + { + return INCORRECT_COMMAND; + } + + public static String getNumberException() + { + return NUMBER_EXCEPTION; + } + + public static String getListOfCommandForUser() + { + return LIST_OF_COMMAND_FOR_USER; + } + + public static String getArrayindexoutofbound() + { + return ARRAYINDEXOUTOFBOUND; + } + + public static String getByeError() + { + return BYE_ERROR; + } + + public static String getFileExtensionError() + { + return FILE_EXTENSION_ERROR; + } + + public static String getDataLoadedFromFile() + { + return DATA_LOADED_FROM_FILE; + } + + public static String getNoDataFileFound() + { + return NO_DATA_FILE_FOUND; + } + + public static String getNoArchiveFile() + { + return NO_ARCHIVE_FILE; + } + + public static String getOutOfRange() + { + return OUT_OF_RANGE; + } +} diff --git a/src/main/Duke.java b/src/main/Duke.java new file mode 100644 index 00000000..b47a5d2e --- /dev/null +++ b/src/main/Duke.java @@ -0,0 +1,44 @@ +import Common.Message; +import data.Commands; +import functions.ListTask; +import storage.Storage; +import ui.Ui; + +import static ui.Ui.BUFFER; + +import java.io.IOException; +import java.nio.file.InvalidPathException; + +public class Duke { + private Storage storage; + private Ui ui; + private ListTask newlist = new ListTask(); + public Duke(String filePath) { + ui = new Ui(); + try{ + storage = new Storage(filePath); + newlist.init(); + }catch (InvalidPathException p){ + System.out.println(BUFFER+p.getMessage() + Message.showFilePathErrorMessage()); + }catch (IOException o){ + System.out.println(BUFFER+o.getMessage() + Message.showFileIOErrorMessage()); + } + + } + + public void run() { + ui.showWelcomeMessage(); + String userInput = ui.readUserInput(); // Read user input + while(!userInput.trim().equalsIgnoreCase(Commands.BYE.toString())){ + newlist.addTask(userInput, storage); + userInput = ui.readUserInput(); + } + ui.showValedicMessage(); + } + + public static void main(String[] args) + { + (new Duke("data/userdata.txt")).run(); + } + +} diff --git a/src/main/data/Acronym.java b/src/main/data/Acronym.java new file mode 100644 index 00000000..c5e44144 --- /dev/null +++ b/src/main/data/Acronym.java @@ -0,0 +1,5 @@ +package data; + +public enum Acronym { + T, E, D +} diff --git a/src/main/data/Commands.java b/src/main/data/Commands.java new file mode 100644 index 00000000..b3c4aff1 --- /dev/null +++ b/src/main/data/Commands.java @@ -0,0 +1,8 @@ +package data; + +/** + * List of commands supported in this DUKE Application. Some are user command and some are system usage behind the scene + */ +public enum Commands { + DONE, LIST, TODO, EVENT, DEADLINE, SAVE, DELETE, HELP, FIND, VIEW, BREAKTHROUGH, BYE +} diff --git a/src/main/data/DeadLine.java b/src/main/data/DeadLine.java new file mode 100644 index 00000000..f486aaf2 --- /dev/null +++ b/src/main/data/DeadLine.java @@ -0,0 +1,41 @@ +package data; + +import parser.Parser; + +import java.time.DateTimeException; +import java.time.LocalDateTime; + +public class DeadLine extends Task{ + protected String date; + private LocalDateTime bywhen; + private String dateTimeForStorage; + + /** + * deadline class constructor mainly called from ListTask class for adding deadline Task + * @param des Description of the task + * @param acro Acronym of the Task, in this case D out of (T,E,D) + * @param dat TimeStamp of the task + */ + public DeadLine(String des, Acronym acro, String dat){ + super(des,acro); + bywhen = Parser.parseStringDateTimetoLocaLDateTime(dat); + date = Parser.parseDateForDisplay(bywhen); + dateTimeForStorage = Parser.parseDateForStorage(bywhen); + + } + + @Override + public String displayDateTime(){ + return date; + } + + public String getDateTimeForStorage() + { + return dateTimeForStorage; + } + + public LocalDateTime getbywhen(){ + return bywhen; + } + +} diff --git a/src/main/data/Event.java b/src/main/data/Event.java new file mode 100644 index 00000000..eae79f66 --- /dev/null +++ b/src/main/data/Event.java @@ -0,0 +1,34 @@ +package data; + +import parser.Parser; + +import java.time.DateTimeException; +import java.time.LocalDateTime; + +public class Event extends Task{ + private String clock; + private LocalDateTime atwhen; + private String dateTimeForStorage; + + public Event(String des, Acronym acro, String hour) { + super(des, acro); + dateTimeForStorage = hour; + atwhen = Parser.parseStringDateTimetoLocaLDateTime(hour); + clock = Parser.parseDateForDisplay(atwhen); + + } + + @Override + public String displayDateTime(){ + return clock; + } + + public String getDateTimeForStorage() + { + return dateTimeForStorage; + } + + public LocalDateTime getAtwhen(){ + return atwhen; + } +} diff --git a/src/main/data/Task.java b/src/main/data/Task.java new file mode 100644 index 00000000..ad9af109 --- /dev/null +++ b/src/main/data/Task.java @@ -0,0 +1,70 @@ +package data; + +public class Task { + + private String description; + private boolean isDone; + // T for todo, E for Events, D for deadlines + private Acronym acronym; + + public Task(){} + + /** + * Constructor for Task Class with 2 param to set for description and acronym + * At the start of this method called task is set to false. + * @param des is for description of the task + * @param acr is for acronym of the task (T,E,D) + */ + public Task(String des, Acronym acr){ + description = des; + acronym = acr; + isDone = false; + } + + /** + * Setter for isDone variable. Task mark as DONE + * @param done is passed so that in future can implement for user to mark as undone if necessary + */ + public void setDone(boolean done){ + isDone = done; + } + + /** + * Method to show whether the task is completed or not in the task list + * @return a String type X for done and " " for not yet done + */ + public String getStatusIcon(){ + return (isDone ? "X" : " "); + } + + /** + * Method to show the completeness of the task in the task list + * @return return boolean status depending on isDone status + */ + public boolean getDone(){ + return isDone; + } + + /** + * Method to show the description of the task in the task list + * @return return String type description variable + */ + public String getDescription(){ + return description; + } + + /** + * Method to get the acronym of the task + * @return return Acronym type. Acronym is an Enumeration containing T, E, D + */ + public Acronym getAcronym() { return acronym; } + + /** + * Method to display date and time but here in Task class there are no date or time variable + * this is just a empty method to be overridden by Class Event and DeadLine + * @return "" return nothing + */ + public String displayDateTime(){ + return ""; + } +} diff --git a/src/main/functions/DeleteCommand.java b/src/main/functions/DeleteCommand.java new file mode 100644 index 00000000..38077f8d --- /dev/null +++ b/src/main/functions/DeleteCommand.java @@ -0,0 +1,32 @@ +package functions; + +import Common.Message; +import data.Task; + +import static ui.Ui.BUFF_PLUS_HORRIZONTALLINE; + +import java.util.List; + + +public class DeleteCommand extends ListTask{ + + /** + * Instead of a class constructor, I have created a static method since there aren't any variable usages. + * From this method, taskremovedinMessage method from Message class is called + * @param item takes in as param from ListTask class Task holder but can still be called setter/getter to change value + * @param idx is a specific index from the task list to be removed + */ + public static void deleteTask(List item, int idx) + { + int idxTodelete = idx -1; + if(idxTodelete < item.size() && idxTodelete >= 0) + { + Message.taskremovedinMessage(item,idxTodelete); + item.remove(idxTodelete); + + }else { + throw new NullPointerException(Message.incorrectSelection()); + } + System.out.println(BUFF_PLUS_HORRIZONTALLINE); + } +} diff --git a/src/main/functions/FindCommand.java b/src/main/functions/FindCommand.java new file mode 100644 index 00000000..249da5f6 --- /dev/null +++ b/src/main/functions/FindCommand.java @@ -0,0 +1,28 @@ +package functions; + +import Common.Message; +import data.Task; + +import java.util.*; + +public class FindCommand extends ListTask { + + /** + * Instead of a class constructor, I have created a static method since there aren't any variable usages. + * From this method, displayTaskAfterFiltered method from Message class is called + * @param key set of string is passed to this method From ListTask class when FIND command is called + * @param itemList takes in as readonly param from ListTask class Task holder but can still be called setter/getter to change value + */ + public static void FindKeywordCommand(Set key, final List itemList){ + List temporaryList = new ArrayList<>(); + for(Task tem : itemList){ + Set splitWordsInEachTask = new HashSet<>(Arrays.asList(tem.getDescription().split(" "))); + if(!Collections.disjoint(key,splitWordsInEachTask)){ + temporaryList.add(tem); + } + } + Message.displayTaskAfterFiltered(temporaryList,"find",""); + } + + +} diff --git a/src/main/functions/ListTask.java b/src/main/functions/ListTask.java new file mode 100644 index 00000000..9a5c6686 --- /dev/null +++ b/src/main/functions/ListTask.java @@ -0,0 +1,235 @@ +package functions; + +import Common.Help; +import Common.Message; +import data.DeadLine; +import data.Event; +import data.Task; +import data.Acronym; +import data.Commands; +import storage.Storage; +import ui.Ui.*; + +import java.io.IOException; +import java.nio.file.InvalidPathException; +import java.time.DateTimeException; +import java.util.*; + +import static ui.Ui.*; + +public class ListTask +{ + + private List itemList; + private int indx = 0; + + public ListTask(){ + itemList = new ArrayList<>(); + } + + public void init() throws IOException + { + try{ + Storage.load(itemList); + indx = itemList.size(); + }catch (InvalidPathException p){ + System.out.println(BUFFER +p.getMessage() + NEWLINE_BUFFER + Message.showFilePathErrorMessage()); + }catch (IOException o){ + System.out.println(BUFFER+o.getMessage() + NEWLINE_BUFFER + Message.showFileIOErrorMessage()); + } + + } + /** + * user input into command for execution. + * + * @param item full user input string + * @param s the storage passed to invoke saving task to external file based on the user input + */ + public void addTask(String item, Storage s) + { + String[] tmp = item.trim().split(" "), tmp_string; + final String command = tmp[0].trim().toUpperCase(); + Commands commandKey = null; + try{ + commandKey = Commands.valueOf(command); + }catch (IllegalArgumentException e){ + System.out.println(BUFFER + Message.getIncorrectCommand()); + commandKey = Commands.BREAKTHROUGH; + } + switch (commandKey){ + case DONE: + tmp_string = item.split("(?i)done"); + try { + setTaskDone(tmp_string[1].trim()); + s.appendTaskListToExternal(itemList); + }catch (NumberFormatException e){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + e.getMessage() + + Message.getNumberException() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + }catch (ArrayIndexOutOfBoundsException i){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + i.getMessage() + Message.getArrayindexoutofbound() + NEWLINE + showList()); + }catch (Error t){ + System.out.println(t.getMessage()); + } + break; + + case LIST: + System.out.println(showList()); + break; + case TODO: + tmp_string = item.split("(?i)todo"); + try{ + itemList.add(new Task(tmp_string[1],Acronym.T)); + indx++; + Message.taskAddedinMessage(itemList); + s.appendSingleTaskToExternal(itemList.get(itemList.size()-1)); + }catch (ArrayIndexOutOfBoundsException a){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + a.getMessage() + NEWLINE_BUFFER + + Message.getArrayindexoutofbound() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + break; + case EVENT: + tmp_string = item.split("(?i)event | (?i)/at"); // (?i) ignore case sensitivity + try{ + itemList.add(new Event(tmp_string[1],Acronym.E,tmp_string[2].trim())); + indx++; + Message.taskAddedinMessage(itemList); + s.appendSingleTaskToExternal(itemList.get(itemList.size()-1)); + }catch (DateTimeException d){ + System.out.println(d.getMessage() + Message.getDateTimeFormatError()); + }catch (ArrayIndexOutOfBoundsException a){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + a.getMessage() + NEWLINE_BUFFER + + Message.getArrayindexoutofbound() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + + break; + case DEADLINE: + tmp_string = item.split("(?i)deadline | (?i)/by"); // (?i) ignore case sensitivity + try{ + itemList.add(new DeadLine(tmp_string[1],Acronym.D,tmp_string[2].trim())); + indx++; + Message.taskAddedinMessage(itemList); + s.appendSingleTaskToExternal(itemList.get(itemList.size()-1)); + }catch (DateTimeException d){ + System.out.println(d.getMessage() + Message.getDateTimeFormatError()); + }catch (ArrayIndexOutOfBoundsException a){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + a.getMessage() + NEWLINE_BUFFER + + Message.getArrayindexoutofbound() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + break; + case SAVE: //for archiving + tmp_string = item.split("(?i)save"); + DoArchiveFile(tmp_string,s); + break; + case DELETE: + tmp_string = item.trim().split("(?i)delete"); + DoDeleteCommand(tmp_string,s); + break; + case HELP: + String[] tmp_str = item.split(" "); + Help.HelpCommand(tmp_str); + break; + case FIND: + tmp_string = item.split("(?i)FIND"); + try{ + Set key = new HashSet<>(Arrays.asList(tmp_string[1].trim().split(" "))); + functions.FindCommand.FindKeywordCommand(key,itemList); + }catch (ArrayIndexOutOfBoundsException a){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + a.getMessage() + NEWLINE_BUFFER + + Message.getArrayindexoutofbound() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + break; + case VIEW: + tmp_string = item.split("(?i)VIEW"); + try{ + SearchFilteredTaskByDateTime.ViewScheduleByDate(tmp_string[1].trim(),itemList); + }catch (ArrayIndexOutOfBoundsException a){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + a.getMessage() + NEWLINE_BUFFER + + Message.getArrayindexoutofbound() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + break; + case BYE: + if(tmp.length > 1){ + System.out.println(Message.getByeError()); + } + break; + case BREAKTHROUGH: + System.out.println(BUFFER + item.trim() + " is not a command!" + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + break; + } + } + + + public String showList() + { + StringBuilder output = new StringBuilder(BUFF_PLUS_HORRIZONTALLINE); + + for(int i = 0; i < indx; i++){ + String tem = itemList.get(i).getDescription().trim(); + Acronym acro = itemList.get(i).getAcronym(); + String status = itemList.get(i).getStatusIcon(); + int indx = i + 1; + output.append(NEWLINE).append(BUFFER).append(indx).append(".[").append(acro).append("]") + .append("[").append(status).append("] ").append(tem); + if(acro.equals(Acronym.E)){ + output.append(" (at: ").append(itemList.get(i).displayDateTime()).append(")"); + }else if(acro.equals(Acronym.D)){ + output.append(" (by: ").append(itemList.get(i).displayDateTime()).append(")"); + } + } + + output.append(NEWLINE).append(BUFF_PLUS_HORRIZONTALLINE); + return output.toString(); + } + + /** + * setTaskDone Method to set individual Task as DONE. + * setTaskDone method can detect if the number specify by user is not within the range of list, it will throw new error + * setTaskDone can also detect if the task is already marked as done before, if it's already marked, it will not call task done setter. + * This method also called 3 different methods from Message Class to display information to User + * @param str should be + integer within the range of list Task holder, (specify by User) + */ + public void setTaskDone(String str) + { + int idxToSetAsDone = (Integer.parseInt(str) - 1); + if ( idxToSetAsDone < (itemList.size()) && idxToSetAsDone >= 0) { + if(!itemList.get(idxToSetAsDone).getDone()){ + itemList.get(idxToSetAsDone).setDone(true); + Message.setTaskDoneMessage(itemList,idxToSetAsDone); + }else{ + Message.getTaskDoneMessage(itemList,idxToSetAsDone); + } + }else{ + throw new Error(Message.getOutOfRange()); + } + } + + public void DoDeleteCommand(String[] tmp, Storage s){ + try{ + DeleteCommand.deleteTask(itemList,Integer.parseInt(tmp[1].trim())); + indx--; + s.appendTaskListToExternal(itemList); + }catch (NumberFormatException e){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + e.getMessage() + + Message.getNumberException() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + }catch (NullPointerException f){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + f.getMessage()+ showList()); + }catch (ArrayIndexOutOfBoundsException a){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + a.getMessage() + NEWLINE_BUFFER + + Message.getArrayindexoutofbound() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + } + + public void DoArchiveFile(String[] s,Storage st){ + try{ + if(!(s.length > 2) && s[1].contains(".txt")){ + st.getNewFilePathForArchiving(s[1].trim()); + st.archiveTaskListToNewFIle(itemList); + }else{ + System.out.println(Message.getFileExtensionError()); + } + }catch(ArrayIndexOutOfBoundsException o){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + o.getMessage() + NEWLINE_BUFFER + + Message.getArrayindexoutofbound() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + } +} diff --git a/src/main/functions/SearchFilteredTaskByDateTime.java b/src/main/functions/SearchFilteredTaskByDateTime.java new file mode 100644 index 00000000..658bc10e --- /dev/null +++ b/src/main/functions/SearchFilteredTaskByDateTime.java @@ -0,0 +1,38 @@ +package functions; + +import Common.Message; +import data.Acronym; +import data.DeadLine; +import data.Event; +import data.Task; +import parser.Parser; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; + +public class SearchFilteredTaskByDateTime extends ListTask{ + /** + * One of the feature to be implemented in DUKE by me. when user used view command, DUKE will return schedule of a specific date + * @param date user wants to see what kind of schedule he/she has for the specific date + * @param list takes in as readonly param from ListTask class Task holder but can still be called setter/getter to change value + */ + public static void ViewScheduleByDate(String date, final List list){ + List temporaryList = new ArrayList<>(); + LocalDate newDateToView = Parser.parseStringDatetoLocaLDate(date); + for(Task singleItem : list){ + if(singleItem.getAcronym().equals(Acronym.D)){ + DeadLine task = (DeadLine)singleItem; + if(task.getbywhen().toLocalDate().equals(newDateToView)){ + temporaryList.add(singleItem); + } + }else if(singleItem.getAcronym().equals(Acronym.E)){ + Event task = (Event) singleItem; + if(task.getAtwhen().toLocalDate().equals(newDateToView)){ + temporaryList.add(singleItem); + } + } + } + Message.displayTaskAfterFiltered(temporaryList,"view", date); + } +} diff --git a/src/main/java/DeadLine.java b/src/main/java/DeadLine.java deleted file mode 100644 index 3e53e4b5..00000000 --- a/src/main/java/DeadLine.java +++ /dev/null @@ -1,20 +0,0 @@ -public class DeadLine extends Task{ - private String date; - - public DeadLine(String des, String acro, String dat){ - super(des,acro); - date = dat; - } - - @Override - public String getDate(){ - return date; - } - - public void setClock(String input){ - date = input; - } - - - -} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index ffdfc40a..00000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,30 +0,0 @@ -import java.util.*; - -public class Duke { - public static void main(String[] args) { - - String greeting = "Hello! I'm Duke \n\tWhat can I do for you?"; - String valediction = "Bye. Hope to see you again soon!"; - String horiLine = "\t-----------------------------------------"; - String buff = "\t"; - System.out.println(horiLine + "\n" + buff + greeting + "\n" + horiLine); - Scanner myObj = new Scanner(System.in); - String userInput = myObj.nextLine(); // Read user input - ListTask newlist = new ListTask(); - - while(!userInput.trim().equalsIgnoreCase("bye")){ - newlist.addTask(userInput); -// if(userInput.trim().equalsIgnoreCase("list")){ -// System.out.println(newlist.showList()); -// } -// if(userInput.trim().equalsIgnoreCase("done")){ -//// newlist.setDone(true); -// } -// System.out.println(horiLine + "\n" + buff + userInput.trim() + "\n" + horiLine); // echo function - userInput = myObj.nextLine(); - - } - - System.out.println(horiLine + "\n" + buff + valediction + "\n" + horiLine); - } -} diff --git a/src/main/java/Event.java b/src/main/java/Event.java deleted file mode 100644 index 5a0cf551..00000000 --- a/src/main/java/Event.java +++ /dev/null @@ -1,23 +0,0 @@ -public class Event extends DeadLine{ - private String clock; - - public Event(String des, String acro, String dat, String hour) { - super(des, acro, dat); - clock = hour; - } - - - @Override - public String getClock() { - return clock; - } - - public void setClock(String input){ - clock = input; - } - - @Override - public String getDate() { - return super.getDate(); // getting date from deadline class - } -} diff --git a/src/main/java/ListTask.java b/src/main/java/ListTask.java deleted file mode 100644 index bfc89612..00000000 --- a/src/main/java/ListTask.java +++ /dev/null @@ -1,103 +0,0 @@ -public class ListTask extends Task{ - - private Task[] itemList = new Task[100]; - private int indx = 0; - String horiLine = "\t-----------------------------------------"; - String buff = "\t"; - - public ListTask(){} - - public void addTask(String item){ - String[] tmp = item.trim().split(" "), tmp_string; - switch (tmp[0].trim().toLowerCase()){ - case "done": - try { - setTaskDone(tmp); - }catch (NumberFormatException e){ - System.out.println("This is not a number!"); - System.out.println(e.getMessage()); - } - break; - - case "list": - System.out.println(showList()); - break; - case "todo": - tmp_string = item.split("todo"); - itemList[indx] = new Task(tmp_string[1],"T"); - indx++; - printMessage("T"); - break; - case "event": - tmp_string = item.split("(?i)event | (?i)/at"); // (?i) ignore case sensitivity - String[] tmp_s = tmp_string[2].trim().split(" "); - itemList[indx] = new Event(tmp_string[1],"E",tmp_s[0],tmp_s[1]); - indx++; - printMessage("E"); - break; - case "deadline": - tmp_string = item.split("(?i)deadline | (?i)/by"); // (?i) ignore case sensitivity - itemList[indx] = new DeadLine(tmp_string[1],"D",tmp_string[2]); - indx++; - printMessage("D"); - break; -// default: -// break; - } - } - - public String showList(){ - StringBuilder output = new StringBuilder(horiLine); - - for(int i = 0; i < indx; i++){ - String tem = itemList[i].getDescription().trim(); - String acro = itemList[i].getAcronym(); - String status = itemList[i].getStatusIcon(); - int indx = i + 1; - output.append("\n").append(buff).append(indx).append(".[").append(acro).append("]").append("[").append(status).append("] ").append(tem); - if(acro.equals("E")){ - output.append(" (at: ").append(itemList[i].getDate()).append(" ").append(itemList[i].getClock()).append(")"); - }else if(acro.equals("D")){ - output.append(" (by:").append(itemList[i].getDate()).append(")"); - } - } - - output.append("\n").append(horiLine); - return output.toString(); - } - - public void setTaskDone(String[] str){ - if ((Integer.parseInt(str[1]) - 1) < indx) { - itemList[Integer.parseInt(str[1]) - 1].setDone(true); - System.out.println(buff + "Nice! I've marked this task as done: " - + "\n" + buff + "[X] " + itemList[Integer.parseInt(str[1]) - 1].getDescription()); - }else if (indx >= 2 ) { - System.out.println(buff + "Item No. " + Integer.parseInt(str[1]) + " is not in the list yet." - + "\n" + buff + "Try between " + 1 + " and " + indx + " to mark as done." + "\n" + showList()); - }else if(indx == 1){ - System.out.println(buff + "Item No. " + Integer.parseInt(str[1]) + " is not in the list yet." - + "\n" + buff + "Select 1 to mark as done." + "\n" + showList()); - }else{ - System.out.println(buff + "Empty! No item in the list."); - } - } - - public void printMessage(String acron){ - - if(acron.equals("T")) { - System.out.println(horiLine + "\n" + buff + "Got it. I've added this task: " - + "\n" + buff + " [T][ ] " + itemList[indx - 1].getDescription() + "\n" + buff - + "Now you have " + (indx) + " tasks in the list." + "\n" + horiLine); - }else if(acron.equals("D")){ - System.out.println(horiLine + "\n" + buff + "Got it. I've added this task: " - + "\n" + buff + " [D][ ] "+ itemList[indx - 1].getDescription() + " (by: "+ itemList[indx - 1].getDate() +" )" - + "\n"+ buff +"Now you have "+ (indx) +" tasks in the list." + "\n" + horiLine); - }else if(acron.equals("E")){ - System.out.println(horiLine + "\n" + buff + "Got it. I've added this task: " - + "\n" + buff + " [E][ ] "+ itemList[indx - 1].getDescription() +" (at: "+ itemList[indx - 1].getDate() +" "+ itemList[indx - 1].getClock() + ")" - + "\n"+ buff +"Now you have "+ (indx) +" tasks in the list." + "\n" + horiLine); - } - } - - -} diff --git a/src/main/java/Task.java b/src/main/java/Task.java deleted file mode 100644 index d0c515f3..00000000 --- a/src/main/java/Task.java +++ /dev/null @@ -1,32 +0,0 @@ -public class Task { - - private String description; - private boolean isDone; - // T for todo, E for Events, D for deadlines - private String acronym; - - public Task(){} - - public Task(String des, String acr){ - description = des; - acronym = acr; - isDone = false; - } - - public void setDone(boolean done){ - isDone = done; - } - - public String getDate() { return ""; } // not using but implemented here just for overriding purposes - public String getClock() { return ""; } // not using but implemented here just for overriding purposes - - public String getStatusIcon(){ - return (isDone ? "X" : " "); - } - - public String getDescription(){ - return description; - } - - public String getAcronym() { return acronym; } -} diff --git a/src/main/parser/Parser.java b/src/main/parser/Parser.java new file mode 100644 index 00000000..6ea73b79 --- /dev/null +++ b/src/main/parser/Parser.java @@ -0,0 +1,30 @@ +package parser; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class Parser { + + public static String parseDateForStorage(LocalDateTime dateNTime) + { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy HHmm"); + return dateNTime.format(formatter); + } + + public static LocalDateTime parseStringDateTimetoLocaLDateTime (String dateNTime) + { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy HHmm"); + return LocalDateTime.parse(dateNTime, formatter); + } + public static LocalDate parseStringDatetoLocaLDate (String dateNTime) + { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy"); + return LocalDate.parse(dateNTime, formatter); + } + public static String parseDateForDisplay (LocalDateTime dateNTime) + { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy hhmm a"); + return dateNTime.format(formatter); + } +} diff --git a/src/main/storage/Storage.java b/src/main/storage/Storage.java new file mode 100644 index 00000000..cd56c9ca --- /dev/null +++ b/src/main/storage/Storage.java @@ -0,0 +1,93 @@ +package storage; + +import Common.Message; +import data.Task; + +import java.io.*; +import java.nio.file.*; +import java.util.List; + +import static ui.Ui.*; + +public class Storage +{ + // original file + private static String filePath; + private static String homeLoc = System.getProperty("user.home"); + private static String AbsoluteFilePath; + private static Path path; + + //new file for archiving + private static String newAbsFilePath; + private static Path newPath; + + public Storage(String fpath) + { + this.filePath = fpath; + } + + final public void getNewFilePathForArchiving(String newFilepath){ + newAbsFilePath = Paths.get(homeLoc,"duke/data/", newFilepath).toString(); + newPath = Paths.get(newAbsFilePath); // for future use if user wanting to load from archived file + } + + public static void initFilePath() + { + AbsoluteFilePath = Paths.get(homeLoc, "duke", filePath).toString(); + path = Paths.get(AbsoluteFilePath); + + } + + public static String getAbsFilePath(boolean initialFIle) + { + if(initialFIle){ + return AbsoluteFilePath; + }else{ + return newAbsFilePath; + } + } + public static void load(List lt) throws InvalidPathException, IOException + { + initFilePath(); + try{ + TaskDecoder.decodeTaskListToLoad(Files.readAllLines(path),lt); + System.out.println(Message.getDataLoadedFromFile()); + } catch (IOException e){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER +e.getMessage() + + Message.getNoDataFileFound()); + } + + } + + public void appendSingleTaskToExternal(Task taskToSave) + { + try { + TaskEncoder.encodeTask(taskToSave, AbsoluteFilePath); + } catch (IOException e) { + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER +e.getMessage() + + NEWLINE_BUFFER +" Unable to append individual task to external file: "+ AbsoluteFilePath + + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + } + + public void appendTaskListToExternal(List taskToSave) + { + try { + TaskEncoder.encodeTaskList(taskToSave,AbsoluteFilePath); + } catch (IOException e) { + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER +e.getMessage() + + NEWLINE_BUFFER +" Unable to save list of task to external file: "+ AbsoluteFilePath + + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + } + } + + public void archiveTaskListToNewFIle(List taskToSave) + { + try { + TaskEncoder.encodeTaskList(taskToSave,newAbsFilePath); + } catch (IOException e) { + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER +e.getMessage() + + Message.getNoArchiveFile()); + } + } +} diff --git a/src/main/storage/TaskDecoder.java b/src/main/storage/TaskDecoder.java new file mode 100644 index 00000000..03d34902 --- /dev/null +++ b/src/main/storage/TaskDecoder.java @@ -0,0 +1,58 @@ +package storage; + +import data.Acronym; +import data.DeadLine; +import data.Event; +import data.Task; + + +import java.io.IOException; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TaskDecoder { + public static final Pattern TASK_DATA_ARGS_FORMAT = // '/' forward slashes are reserved for delimiter prefixes + Pattern.compile("((^[DE]) \\| ([0-1]) \\| (.*\\|) (.*))|((^[T]) \\| ([0-1]) \\| (.*))"); + + + public static void decodeTaskListToLoad(List encodedTaskList, List task) throws IOException + { + for (String encodedTask : encodedTaskList){ + task.add(decodeTaskFromStringLineByLine(encodedTask)); + } + + } + + private static Task decodeTaskFromStringLineByLine(String encodedTask) { + final Matcher matcher = TASK_DATA_ARGS_FORMAT.matcher(encodedTask); + if (!matcher.matches()) { + System.out.println("Data are not in the correct format. Unable to write to ArrayList From File"); + } + Task newTask = null; + String[] data = encodedTask.split("[|]"); + String acro = data[0].trim(); + String isDone = data[1].trim(); + String taskDesc = data[2].trim(); + // Can be put in a separate method + if (acro.equals(Acronym.T.toString())) { // Todo Task + newTask = new Task(taskDesc,Acronym.T); + if (isDone.equals("1")) { + newTask.setDone(true); + } + } else if (acro.equals(Acronym.D.toString())) { //Deadline Task + String deadLineTimeStamp = data[3].trim(); + newTask = new DeadLine(taskDesc,Acronym.D,deadLineTimeStamp); + if (isDone.equals("1")) { + newTask.setDone(true); + } + } else if (acro.equals(Acronym.E.toString())) { //Event Task + String eventTimeStamp = data[3].trim(); + newTask = new Event(taskDesc, Acronym.E,eventTimeStamp); + if (isDone.equals("1")) { + newTask.setDone(true); + } + } + return newTask; + } +} diff --git a/src/main/storage/TaskEncoder.java b/src/main/storage/TaskEncoder.java new file mode 100644 index 00000000..ffaab38a --- /dev/null +++ b/src/main/storage/TaskEncoder.java @@ -0,0 +1,77 @@ +package storage; + +import data.Acronym; +import data.DeadLine; +import data.Event; +import data.Task; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class TaskEncoder { + + public static void encodeTaskList(List toSave, String pathOfFileToSave) throws IOException { + final List encodedTaskList = new ArrayList<>(); + File newfile = new File(pathOfFileToSave); + if(!newfile.exists()){ + newfile.createNewFile(); + } + FileWriter fw = new FileWriter(newfile, false); + BufferedWriter bw = new BufferedWriter(fw); + for(Task individualTask : toSave){ + encodedTaskList.add(encodeAcroToString(individualTask)); + } + for(String singleTask : encodedTaskList){ + bw.write(singleTask); + bw.newLine(); + } + bw.close(); + } + + public static void encodeTask(Task toSave, String pathOfFileToSave) throws IOException { + try { + String encodedTask = encodeAcroToString(toSave); + FileWriter fw = new FileWriter(pathOfFileToSave, true); + BufferedWriter bw = new BufferedWriter(fw); + bw.write( encodedTask); + bw.newLine(); + bw.close(); + } catch (Exception e){ + System.out.println(e.getMessage()); + } + + } + + private static String encodeAcroToString(Task task){ + StringBuilder encodedNewString = new StringBuilder(); + if (task.getAcronym().equals(Acronym.T)){ + encodedNewString.append(Acronym.T); + encodedNewString = appendEncodedTask(encodedNewString, task); + } + else if (task.getAcronym().equals(Acronym.D)){ + encodedNewString.append(Acronym.D); + encodedNewString = appendEncodedTask(encodedNewString, task); + DeadLine d = (DeadLine)task; + encodedNewString.append(" | "); + encodedNewString.append(d.getDateTimeForStorage()); + } + else if (task.getAcronym().equals(Acronym.E)){ + encodedNewString.append(Acronym.E); + encodedNewString = appendEncodedTask(encodedNewString, task); + Event e = (Event)task; + encodedNewString.append(" | "); + encodedNewString.append(e.getDateTimeForStorage()); + } + return encodedNewString.toString(); + } + + private static StringBuilder appendEncodedTask(StringBuilder sb, Task task){ + sb.append(" | ").append(task.getDone() ? "1" : "0"); + sb.append(" | ").append(task.getDescription()); + return sb; + } +} diff --git a/src/main/ui/Ui.java b/src/main/ui/Ui.java new file mode 100644 index 00000000..151ca2c1 --- /dev/null +++ b/src/main/ui/Ui.java @@ -0,0 +1,64 @@ +package ui; + +import java.io.InputStream; +import java.io.PrintStream; +import java.util.Scanner; + +public class Ui { + /** + * This is a place for improving User experience and the basic structure of DUKE Application + */ + public static final String BUFF_PLUS_HORRIZONTALLINE = "\t-----------------------------------------------------------------------------------------"; + public static final String BUFFER = "\t"; + public static final String NEWLINE = "\n"; + public static final String NEWLINE_BUFFER = "\n\t"; + private final PrintStream out; + private final Scanner in; + private final String GREETING_MESSAGE = + BUFF_PLUS_HORRIZONTALLINE + + NEWLINE + BUFFER + + " ____ _ " + NEWLINE_BUFFER + + "| _ \\ _ _| | _____ " + NEWLINE_BUFFER + + "| | | | | | | |/ / _ \\" + NEWLINE_BUFFER + + "| |_| | |_| | < __/" + NEWLINE_BUFFER + + "|____/ \\__,_|_|\\_\\___|" + NEWLINE + NEWLINE_BUFFER + + "Hello! I'm Duke" + NEWLINE_BUFFER + + "What can I do for you?" + NEWLINE_BUFFER + + "This is a Improved version done by Sam" + NEWLINE + + BUFF_PLUS_HORRIZONTALLINE; + + private final String VALEDICTION = BUFFER + "Bye. Hope to see you again soon!" + + NEWLINE + BUFF_PLUS_HORRIZONTALLINE; + + + public Ui() { + this(System.in, System.out); + } + + public Ui(InputStream in, PrintStream out) { + this.in = new Scanner(in); + this.out = out; + } + + /** + * Method to read from the System.in + * @return return String type + */ + public String readUserInput() + { + out.println(BUFFER +"Enter your query: "); + return in.nextLine(); + } + + public void showWelcomeMessage() + { + out.println(GREETING_MESSAGE); + } + + public void showValedicMessage() + { + out.println(VALEDICTION); + } + + +} From 702411c79595256634357b000f37293be13a2b12 Mon Sep 17 00:00:00 2001 From: Sai sam Phyo linn Date: Mon, 8 Nov 2021 23:43:49 +0800 Subject: [PATCH 9/9] fixed bug Dattime parse error --- src/main/functions/ListTask.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/functions/ListTask.java b/src/main/functions/ListTask.java index 9a5c6686..557a218d 100644 --- a/src/main/functions/ListTask.java +++ b/src/main/functions/ListTask.java @@ -145,6 +145,8 @@ public void addTask(String item, Storage s) }catch (ArrayIndexOutOfBoundsException a){ System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER + a.getMessage() + NEWLINE_BUFFER + Message.getArrayindexoutofbound() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); + }catch (DateTimeException e){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER+e.getMessage() + Message.getDateTimeFormatError() + NEWLINE + BUFF_PLUS_HORRIZONTALLINE); } break; case BYE: