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 00000000..e8f04018 Binary files /dev/null and b/production/duke/Common/Help$1.class differ diff --git a/production/duke/Common/Help.class b/production/duke/Common/Help.class new file mode 100644 index 00000000..9f7990aa Binary files /dev/null and b/production/duke/Common/Help.class differ diff --git a/production/duke/Common/Message.class b/production/duke/Common/Message.class new file mode 100644 index 00000000..ad943af9 Binary files /dev/null and b/production/duke/Common/Message.class differ diff --git a/production/duke/Duke.class b/production/duke/Duke.class new file mode 100644 index 00000000..ff2a063f Binary files /dev/null and b/production/duke/Duke.class differ diff --git a/production/duke/data/Acronym.class b/production/duke/data/Acronym.class new file mode 100644 index 00000000..89282185 Binary files /dev/null and b/production/duke/data/Acronym.class differ diff --git a/production/duke/data/Commands.class b/production/duke/data/Commands.class new file mode 100644 index 00000000..824a615a Binary files /dev/null and b/production/duke/data/Commands.class differ diff --git a/production/duke/data/DeadLine.class b/production/duke/data/DeadLine.class new file mode 100644 index 00000000..fe07a30f Binary files /dev/null and b/production/duke/data/DeadLine.class differ diff --git a/production/duke/data/Event.class b/production/duke/data/Event.class new file mode 100644 index 00000000..636d3908 Binary files /dev/null and b/production/duke/data/Event.class differ diff --git a/production/duke/data/Task.class b/production/duke/data/Task.class new file mode 100644 index 00000000..c8427bae Binary files /dev/null and b/production/duke/data/Task.class differ diff --git a/production/duke/functions/DeleteCommand.class b/production/duke/functions/DeleteCommand.class new file mode 100644 index 00000000..6ec4611c Binary files /dev/null and b/production/duke/functions/DeleteCommand.class differ diff --git a/production/duke/functions/FindCommand.class b/production/duke/functions/FindCommand.class new file mode 100644 index 00000000..0b2a3e9c Binary files /dev/null and b/production/duke/functions/FindCommand.class differ diff --git a/production/duke/functions/ListTask$1.class b/production/duke/functions/ListTask$1.class new file mode 100644 index 00000000..ce5f6730 Binary files /dev/null and b/production/duke/functions/ListTask$1.class differ diff --git a/production/duke/functions/ListTask.class b/production/duke/functions/ListTask.class new file mode 100644 index 00000000..8c0449d6 Binary files /dev/null and b/production/duke/functions/ListTask.class differ diff --git a/production/duke/functions/SearchFilteredTaskByDateTime.class b/production/duke/functions/SearchFilteredTaskByDateTime.class new file mode 100644 index 00000000..51fcd6d2 Binary files /dev/null and b/production/duke/functions/SearchFilteredTaskByDateTime.class differ diff --git a/production/duke/parser/Parser.class b/production/duke/parser/Parser.class new file mode 100644 index 00000000..57fac8a1 Binary files /dev/null and b/production/duke/parser/Parser.class differ diff --git a/production/duke/storage/Storage.class b/production/duke/storage/Storage.class new file mode 100644 index 00000000..35f46aa8 Binary files /dev/null and b/production/duke/storage/Storage.class differ diff --git a/production/duke/storage/TaskDecoder.class b/production/duke/storage/TaskDecoder.class new file mode 100644 index 00000000..453e51ed Binary files /dev/null and b/production/duke/storage/TaskDecoder.class differ diff --git a/production/duke/storage/TaskEncoder.class b/production/duke/storage/TaskEncoder.class new file mode 100644 index 00000000..171528f8 Binary files /dev/null and b/production/duke/storage/TaskEncoder.class differ diff --git a/production/duke/ui/Ui.class b/production/duke/ui/Ui.class new file mode 100644 index 00000000..691be6b1 Binary files /dev/null and b/production/duke/ui/Ui.class differ diff --git a/src/main/Common/Help.java b/src/main/Common/Help.java new file mode 100644 index 00000000..7e5d43a8 --- /dev/null +++ b/src/main/Common/Help.java @@ -0,0 +1,64 @@ +package Common; + +import data.Commands; + +import static Common.Message.*; + +public class Help { + + /** + * Display HELP content for user. To aid user to accustom to the command supported in this DUKE Application. + * @param s is parameter comes after HELP command to understand the individual command usages. + */ + public static void HelpCommand(String[] s){ + Commands commandKey = null; + final String command; + if(s.length > 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..557a218d --- /dev/null +++ b/src/main/functions/ListTask.java @@ -0,0 +1,237 @@ +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); + }catch (DateTimeException e){ + System.out.println(BUFF_PLUS_HORRIZONTALLINE + NEWLINE_BUFFER+e.getMessage() + Message.getDateTimeFormatError() + 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/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334..00000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} diff --git a/src/main/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); + } + + +} 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