diff --git a/README.md b/README.md index 303bc3d19..67d7bb3bd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Duke project template +# duke.main.Duke project template This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. @@ -14,7 +14,7 @@ Prerequisites: JDK 11, update IntelliJ to the most recent version. 1. Select the project directory, and click `OK` 1. If there are any further prompts, accept the defaults. 1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk). -1. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()`. If the setup is correct, you should see something like the output below. +1. After that, locate the `src/main/java/duke.main.Duke.java` file, right-click it, and choose `Run duke.main.Duke.main()`. If the setup is correct, you should see something like the output below. ``` Hello from diff --git a/docs/README.md b/docs/README.md index fd4406959..6609b183f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,20 +1,306 @@ # User Guide +- [Introduction](#2) +- [Setup](#3) +- [Notes](#1) +- [Features](#a) + - [Adding tasks](#a) + - [todo](#a) + - [deadline](#b) + - [event](#c) + - [Listing all tasks](#d) + - [Completing a task](#e) + - [Find](#f) + - [Description](#f) + - [Date](#g) + - [Save and exit](#i) -## Features +*** +# Introduction -### Feature 1 -Description of feature. +Your very own application to manage your to-do list! -## Usage +# Setup -### `Keyword` - Describe action +     1. Copy the jar file -Describe action and its outcome. +     2. Launch the jar file using the following command in `CMD` -Example of usage: +         `java -jar [path to your runnable jar file]` -`keyword (optional arguments)` +

+     In the event that some characters are not properly printed in the terminal, use the following commands: -Expected outcome: +         `chcp 65001` + +         `java -jar -Dfile.encoding=UTF-8 [path to your runnable jar file]` + + +*** + +# Notes + +**General Formatting:** + +     Description - Describes the functionality of the feature + +     Formatting - Describes the code formatting to use a feature + +     Examples - Examples of how to use a feature + +     Example output - Snapshot of how the usage of a feature will appear in the application +

+ +**Additional notes:** + +     The square brackets specifies that user input is required + +          `command [variable input]` + +*** + +# Features +*** +## Adding tasks: Todo +**Description:** + +     Adding a simple task using the `todo` command + +**Formatting:** + +     `todo` [task description] + +**Examples:** + +     Adding the task "read shakespeare" + +          `todo read shakespeare` + +     Adding the task "finish java quiz" + +          `todo finish java quiz` + +**Example output:** +``` +todo read shakespeare +____________________________________________________________ +Got it. I've added this task: + [T][✘] read shakespeare +Now you have 1 tasks in the list. +____________________________________________________________ +``` + +*** +## Adding tasks: Deadline + +**Description:** + +     Adding a deadline task using the `deadline` command. + +     A deadline consist of a **description** and a **date**. + +**Formatting:** + +     `deadline [task description] /by [date in format YYYY-MM-DD]` + +**Examples** + +     Adding the deadline "read shakespeare by 8 Mar 2021" + +          `deadline read shakespeare /by 2021-03-08` + +     Adding the deadline "finish java quiz by 16 Nov 2021" + +          `deadline finish java quiz /by 2021-11-16` + +**Example output** +``` +deadline read shakespeare /by 2021-03-08 +____________________________________________________________ +Got it. I've added this task: + [D][✘] read shakespeare (by: Mar-08-2021 ) +Now you have 1 tasks in the list. +____________________________________________________________ +``` +*** + +## Adding tasks: Event +**Description:** + +     Adding an event task using the `event` command. + +     An event consist of a **description** and a **date**. + +**Formatting:** + +     `event [task description] /at [date in format YYYY-MM-DD]` + +**Examples** + +     Adding the event "read shakespeare by 8 Mar 2021" + +         `event shakespeare's play /at 2021-03-08` + +     Adding the event "java quiz by 16 Nov 2021" + +          `event java quiz /at 2021-11-16` + +**Example output** +``` +event shakespeare's play /at 2021-03-08 +____________________________________________________________ +Got it. I've added this task: + [E][✘] shakespeare's play (by: Mar-08-2021 ) +Now you have 1 tasks in the list. +____________________________________________________________ +``` + + +## Listing all tasks +**Description:** + +    List all tasks (todo, deadline, event) + +**Formatting:** + +    `list` + +**Example output** +``` +list +____________________________________________________________ +Here are the tasks in your list: +1.[T][✘] read shakespeare +2.[D][✘] read shakespeare (by: Mar-08-2021 ) +3.[E][✘] shakespeare's play (at: Mar-08-2021 ) +____________________________________________________________ +``` +*** + +## Completing a task +**Description:** + +    Set the task to be done. + +**Formatting:** + +    `done [index]` + +**Examples** + +    `done 1` + +**Example output** +``` +Here are the tasks in your list: +1.[T][✘] read shakespeare +2.[D][✘] read shakespeare (by: Mar-08-2021 ) +3.[E][✘] shakespeare's play (at: Mar-08-2021 ) +____________________________________________________________ +done 1 +____________________________________________________________ +Nice! I've marked this task as done: +[✓] read shakespeare +____________________________________________________________ +list +____________________________________________________________ +Here are the tasks in your list: +1.[T][✓] read shakespeare +2.[D][✘] read shakespeare (by: Mar-08-2021 ) +3.[E][✘] shakespeare's play (at: Mar-08-2021 ) +____________________________________________________________ +``` + +## Find tasks: Description +**Description:** + +    Find specific tasks based on similar descriptions. + +**Formatting:** + +     `find [task description]` + +**Examples** + +     Find any tasks with the phrase "read shakespeare" in description + +         `find read shakespeare` + +     Find any tasks with the word book description + +        `find book` + +**Example output** +``` +find read shakespeare +____________________________________________________________ +Here are the matching tasks in your list: +1.[T][✓] read shakespeare +2.[D][✘] read shakespeare (by: Mar-08-2021 ) +____________________________________________________________ +``` + +## Find tasks: Date +**Description:** + +    Find specific tasks based on date input. + +**Formatting:** + +     Find all events that occur on a specific date + +         `findAt [Date with format YYYY-MM-DD]` + +     Find all deadlines that occurs before a specific date + +         `findBy [Date with format YYYY-MM-DD]` + +**Examples** + +     Find events happening on 10 March 2021 + +         `findAt 2021-03-10` + +     Find all deadlines that occurs before a 10 March 2021 + +         `findBy 2021-03-10` + +**Example output** +``` +Here are the tasks in your list: +1.[T][✓] read shakespeare +2.[D][✘] read shakespeare (by: Mar-08-2021 ) +3.[E][✘] shakespeare's play (at: Mar-08-2021 ) +4.[D][✘] watch wandaVision (by: Mar-10-2021 ) +5.[E][✘] homework submission (at: Mar-08-2021 ) +____________________________________________________________ +findAt 2021-03-08 +____________________________________________________________ +Here are the matching tasks in your list: +1.[E][✘] shakespeare's play (at: Mar-08-2021 ) +2.[E][✘] homework submission (at: Mar-08-2021 ) +____________________________________________________ +findBy 2021-03-10 +____________________________________________________________ +Here are the matching tasks in your list: +1.[D][✘] read shakespeare (by: Mar-08-2021 ) +2.[D][✘] watch wandaVision (by: Mar-10-2021 ) +``` + +## Save and exit +**Description:** + +    Save all tasks in file and exits + +**Formatting:** + +    `bye` + +**Example output** +``` +bye +____________________________________________________________ +File is overwritten. +Bye. Hope to see you again soon! +____________________________________________________________ +``` -`outcome` diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 000000000..fc24e7a62 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-hacker \ No newline at end of file diff --git a/list.txt b/list.txt new file mode 100644 index 000000000..d45343e60 --- /dev/null +++ b/list.txt @@ -0,0 +1,6 @@ +D false owennsdck Oct-10-2020 +D false ppp Oct-11-2020 +D false qqq Oct-12-2020 +D false eee Oct-13-2020 +E true party Sep-09-2020 +T false owen diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334c..000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..2c6354be6 --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: duke.main.Duke + diff --git a/src/main/java/duke/exceptions/DeadlineParameterExceptions.java b/src/main/java/duke/exceptions/DeadlineParameterExceptions.java new file mode 100644 index 000000000..11e3a8861 --- /dev/null +++ b/src/main/java/duke/exceptions/DeadlineParameterExceptions.java @@ -0,0 +1,5 @@ +package duke.exceptions; + +/** DeadlineParameterExceptions class to handle deadline parameter exception. */ +public class DeadlineParameterExceptions extends Exception{ +} diff --git a/src/main/java/duke/exceptions/EventParameterExceptions.java b/src/main/java/duke/exceptions/EventParameterExceptions.java new file mode 100644 index 000000000..2aa23cd18 --- /dev/null +++ b/src/main/java/duke/exceptions/EventParameterExceptions.java @@ -0,0 +1,5 @@ +package duke.exceptions; + +/** EventParameterExceptions class to handle Event parameter exception. */ +public class EventParameterExceptions extends Exception{ +} diff --git a/src/main/java/duke/exceptions/InvalidCommandExceptions.java b/src/main/java/duke/exceptions/InvalidCommandExceptions.java new file mode 100644 index 000000000..6d616a497 --- /dev/null +++ b/src/main/java/duke/exceptions/InvalidCommandExceptions.java @@ -0,0 +1,5 @@ +package duke.exceptions; + +/** InvalidCommandExceptions class to handle invalid commands exception. */ +public class InvalidCommandExceptions extends Exception{ +} diff --git a/src/main/java/duke/exceptions/InvalidIndexExceptions.java b/src/main/java/duke/exceptions/InvalidIndexExceptions.java new file mode 100644 index 000000000..5914bceba --- /dev/null +++ b/src/main/java/duke/exceptions/InvalidIndexExceptions.java @@ -0,0 +1,5 @@ +package duke.exceptions; + +/** InvalidIndexExceptions class to handle invalid index exception. */ +public class InvalidIndexExceptions extends Exception{ +} diff --git a/src/main/java/duke/exceptions/InvalidParameterLengthExceptions.java b/src/main/java/duke/exceptions/InvalidParameterLengthExceptions.java new file mode 100644 index 000000000..2a4f127ef --- /dev/null +++ b/src/main/java/duke/exceptions/InvalidParameterLengthExceptions.java @@ -0,0 +1,5 @@ +package duke.exceptions; + +/** InvalidParameterLengthExceptions class to handle insufficient parameters exception. */ +public class InvalidParameterLengthExceptions extends Exception{ +} diff --git a/src/main/java/duke/items/Deadline.java b/src/main/java/duke/items/Deadline.java new file mode 100644 index 000000000..bccae4982 --- /dev/null +++ b/src/main/java/duke/items/Deadline.java @@ -0,0 +1,61 @@ +package duke.items; + +import static duke.main.UI.convertDateToStringFormat; + +/** + * Deadline class + */ +public class Deadline extends Task { + protected String by; + + /** + * Deadline constructor + * + * @param description Description of the task + * @param byInput input String of date + */ + public Deadline(String description, String byInput) { + super(description); + this.by = byInput; + } + + /** + * Change the by attribute of Deadline + * + * @param byInput new String of date + */ + public void setBy(String byInput) { + this.by = byInput; + } + + /** + * Returns the by attribute of Deadline object + * + * @return this.by + */ + public String getBy() { + return this.by; + } + + /** + * Returns the Type of Deadline object + * + * @return String "D" + */ + @Override + public String getType() { + return "D"; + } + + /** + * Prints the Deadline object in a certain format + */ + @Override + public void print(){ + if (this.isDone) { + System.out.println("[D][√] " + description + " (by: " + by + ")"); + } else { + System.out.println("[D][X] " + description + " (by: " + by + ")"); + } + } +} diff --git a/src/main/java/duke/items/Event.java b/src/main/java/duke/items/Event.java new file mode 100644 index 000000000..6494cca50 --- /dev/null +++ b/src/main/java/duke/items/Event.java @@ -0,0 +1,60 @@ +package duke.items; + + +/** + * Event class + */ +public class Event extends Task { + private String at; + + /** + * Event constructor + * + * @param description Description of the task + * @param atInput input String of date + */ + public Event(String description, String atInput) { + super(description); + this.at = atInput; + } + + /** + * Change the by attribute of Event + * + * @param atInput new String of date + */ + public void setAt(String atInput) { + this.at = atInput; + } + + /** + * Returns the at attribute of Event object + * + * @return this.at + */ + public String getAt() { + return this.at; + } + + /** + * Returns the Type of Event object + * + * @return String "E" + */ + @Override + public String getType() { + return "E"; + } + + /** + * Prints the Event object in a certain format + */ + @Override + public void print(){ + if (this.isDone) { + System.out.println("[E][√] " + description + " (at: " + at + ")" ); + } else { + System.out.println("[E][X] " + description + " (at: " + at + ")" ); + } + } +} \ No newline at end of file diff --git a/src/main/java/duke/items/Task.java b/src/main/java/duke/items/Task.java new file mode 100644 index 000000000..71f25f487 --- /dev/null +++ b/src/main/java/duke/items/Task.java @@ -0,0 +1,255 @@ +package duke.items; + +import java.time.LocalDate; +import java.util.ArrayList; +import duke.exceptions.*; +import duke.main.UI; + +import static duke.main.Parser.*; +import static duke.main.UI.convertDateToStringFormat; +import static duke.main.UI.convertStringFormatToDate; + +/** Parent class for other classes (todo, deadline, event) */ +public class Task { + private static int numOfTasks = 0; + protected String description; + protected boolean isDone; + protected static ArrayList list = new ArrayList<>(); + + /** + * Returns the ArrayList from Task + * + * @return ArrayList + */ + public static ArrayList getList(){ + return list; + } + + /** + * Returns the number of Tasks that are in the ArrayList list + * + * @return numOfTasks + */ + public static int getNumOfTasks() { + return numOfTasks; + } + + /** + * Prints each Task in the list using print() function + */ + public static void printList(){ + for (int i =0; i= numOfTasks){ + throw new InvalidIndexExceptions(); + } + list.get(index).isDone = true; + System.out.println("Nice! I've marked this task as done: "); + System.out.println("[√] " + list.get(index).getDescription()); + } + + /** + * Task object initialisation + * + * @param description Description of the Task + */ + public Task(String description) { + this.description = description; + this.isDone = false; + } + + /** + * Prints the Task in a fixed format + */ + public void print(){ + if (this.isDone) { + System.out.println("[T][√] " + description ); + } else { + System.out.println("[T][X] " + description ); + } + } + + /** + * Returns Description of the given Task object + * + * @return Description + */ + public String getDescription() { + return description; + } + + /** + * Changes the description attribute of Task + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * Returns Type of the given Task object + * + * @return Type + */ + public String getType() { + return "T"; + } + + /** + * Returns whether the Task is done + * + * @return boolean of isDone + */ + public boolean isDone() { + return this.isDone; + } + + /** + * Changes the isDone attribute of Task + */ + public void setDone() { + this.isDone = true; + } +} \ No newline at end of file diff --git a/src/main/java/duke/items/Todo.java b/src/main/java/duke/items/Todo.java new file mode 100644 index 000000000..7d369bf1c --- /dev/null +++ b/src/main/java/duke/items/Todo.java @@ -0,0 +1,16 @@ +package duke.items; + +/** + * Todo class + */ +public class Todo extends Task { + + /** + * Todo constructor + * + * @param description Description of the task + */ + public Todo(String description) { + super(description); + } +} diff --git a/src/main/java/duke/main/Duke.java b/src/main/java/duke/main/Duke.java new file mode 100644 index 000000000..eaf3de660 --- /dev/null +++ b/src/main/java/duke/main/Duke.java @@ -0,0 +1,18 @@ +package duke.main; + + +public class Duke { + /** + * Prints welcome and goodbye message + * Calls fileHandling + * Calls run function from parser + * Main function that combines all functions from other files + */ + public static void main(String[] args) { + UI.displayWelcomeMessage(); + UI.printLine(); + Storage.fileHandling(); + Parser.run(); + UI.displayByeMessage(); + } +} diff --git a/src/main/java/duke/main/Parser.java b/src/main/java/duke/main/Parser.java new file mode 100644 index 000000000..57b8c1326 --- /dev/null +++ b/src/main/java/duke/main/Parser.java @@ -0,0 +1,211 @@ +package duke.main; + +import java.io.IOException; +import java.text.ParseException; +import java.time.format.DateTimeParseException; +import java.util.Scanner; + +import duke.exceptions.*; +import duke.items.Task; + +import static duke.main.UI.convertDateToStringFormat; + +/** Class in charge of understanding input commands */ +public class Parser { + + /** + * Check number of parameters in input command is valid + * + * @param line entire input command + * @throws InvalidParameterLengthExceptions If length of entire todo command is < 2 + */ + public static void validateTodoCommand(String line) throws InvalidParameterLengthExceptions { + if (line.split(" ").length < 2){ + throw new InvalidParameterLengthExceptions(); + } + } + + /** + * Returns the index of the character "/" in the input command + * while checking for the validity of the command + * + * @param line entire input command + * @return index of "/" in the /by indicator + * @throws DeadlineParameterExceptions If /by is missing + * @throws InvalidParameterLengthExceptions If number of parameters < 4 + */ + public static int validateDeadlineCommand(String line) throws DeadlineParameterExceptions, InvalidParameterLengthExceptions { + int indexOfSlash; + if (line.split(" ").length < 4){ + throw new InvalidParameterLengthExceptions(); + } + indexOfSlash = line.indexOf("/by"); + if (indexOfSlash == -1) { + throw new DeadlineParameterExceptions(); + } + return indexOfSlash; + } + + /** + * Returns the index of the character "/" in the input command + * while checking for the validity of the command + * + * @param line entire input command + * @return index of "/" in the /at indicator + * @throws EventParameterExceptions If /at is missing + * @throws InvalidParameterLengthExceptions If number of parameters < 4 + */ + public static int validateEventCommand(String line) throws EventParameterExceptions, InvalidParameterLengthExceptions { + int indexOfSlash; + if (line.split(" ").length < 4){ + throw new InvalidParameterLengthExceptions(); + } + indexOfSlash = line.indexOf("/at"); + if (indexOfSlash == -1){ + throw new EventParameterExceptions(); + } + return indexOfSlash; + } + + /** + * Returns the command keyword of a an input line + * + * @param line entire input command + * @return command keyword + */ + public static String getCommand(String line) { + return line.split(" ")[0]; + } + + /** + * Returns the description of a todo task input + * + * @param line entire input command + * @return String description of the todo task + */ + public static String extractTodo(String line) { + return line.substring(line.indexOf(" ") + 1); + } + + /** + * Returns the description and date of an Deadline/Event task input + * + * @param line entire input command + * @return String array containing description and date of the Deadline/Event task + * @throws DeadlineParameterExceptions If /by is missing for deadline task + * @throws EventParameterExceptions If /at is missing for event task + * @throws InvalidParameterLengthExceptions If number of parameters < 4 + */ + public static String[] extractDeadlineAndEvent(String line) throws InvalidParameterLengthExceptions, + DeadlineParameterExceptions, EventParameterExceptions { + + int indexOfSlash; + if (getCommand(line).equals("deadline")) { + indexOfSlash = validateDeadlineCommand(line); + } else { + indexOfSlash = validateEventCommand(line); + } + String[] returnList = new String[2]; + returnList[0] = line.substring(line.indexOf(" ") + 1, indexOfSlash - 1); + returnList[1] = line.substring(indexOfSlash + 4); + return returnList; + } + + /** + * Decides which functions to run based on the input command + * + * @param line entire input command + * @return integer -1 when input request to exit, else 1 + * @throws InvalidCommandExceptions If unrecognised command is used. + * @throws InvalidParameterLengthExceptions If number of parameters does not match command used. + * @throws DeadlineParameterExceptions If Deadline command format is not adhered to. + * @throws EventParameterExceptions If Event command format is not adhered to. + * @throws InvalidIndexExceptions If index out of range. + * @throws IOException If input output error occurs. + * @throws ParseException If date conversion error occurs + */ + public static int commandHandler(String line) throws InvalidCommandExceptions, InvalidParameterLengthExceptions, + DeadlineParameterExceptions, EventParameterExceptions, InvalidIndexExceptions, IOException, ParseException { + + switch (getCommand(line)) { + case ("bye"): + Storage.writeToFile(); + return -1; + + case ("list"): + UI.displayListPreamble(); + Task.printList(); + break; + case ("done"): + Task.setDone(Integer.parseInt(line.split(" ")[1]) - 1); + break; + case ("delete"): + int indexToDelete = Integer.parseInt(line.split(" ")[1]) - 1; + if (indexToDelete >= Task.getNumOfTasks()){ + throw new InvalidIndexExceptions(); + } + Task.deleteTask(indexToDelete); + UI.displayListUpdate(); + break; + case ("find"): + UI.displayFindPreamble(); + Task.findTask(line.split(" ")[1]); + break; + case ("findAt"): + UI.displayFindPreamble(); + Task.findAt(convertDateToStringFormat(line.split(" ")[1])); + break; + case ("findBy"): + UI.displayFindPreamble(); + Task.findBy(line.split(" ")[1]); + break; + case ("todo"): + Task.addTodo(line); + break; + case ("deadline"): + Task.addDeadline(line); + break; + case ("event"): + Task.addEvent(line); + break; + default: + throw new InvalidCommandExceptions(); + } + return 1; + } + + /** + * Runs loop that repeatedly calls for input command + * Runs commandHandler for each input command + * Catches error and decides error message + */ + public static void run(){ + Scanner in = new Scanner(System.in); + while (true) { + String line; + line = in.nextLine(); + UI.printLine(); + try { + if (commandHandler(line) == -1) { + break; + } + } catch (InvalidCommandExceptions e) { + UI.InvalidCommandErrorMessage(); + } catch (InvalidParameterLengthExceptions e){ + UI.InvalidParameterLengthErrorMessage(line); + } catch (EventParameterExceptions e){ + UI.EventParameterErrorMessage(); + } catch (DeadlineParameterExceptions e){ + UI.DeadlineParameterErrorMessage(); + } catch (InvalidIndexExceptions e){ + UI.InvalidIndexErrorMessage(); + } catch (DateTimeParseException e){ + UI.InvalidDateErrorMessage(line); + } catch (ParseException | IOException e){ + e.printStackTrace(); + } + UI.printLine(); + } + } +} + diff --git a/src/main/java/duke/main/Storage.java b/src/main/java/duke/main/Storage.java new file mode 100644 index 000000000..5fd1a51fd --- /dev/null +++ b/src/main/java/duke/main/Storage.java @@ -0,0 +1,131 @@ +package duke.main; + +import duke.items.Deadline; +import duke.items.Event; +import duke.items.Task; +import duke.items.Todo; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Scanner; + +/** + * Class in charge of file IO + */ +public class Storage { + + /** + * Handles the file IO process + */ + public static void fileHandling(){ + try { + loadFile(); + } catch (FileNotFoundException e) { + createFile(); + } + } + + /** + * Loads data into current list of tasks + * + * @param line Each line (1 line represents 1 task) in saved records (list.txt) + */ + public static void loadTask(String line){ + String[] arr = line.split("\t"); + switch(arr[0]){ + case ("T"): + Todo todo = new Todo(arr[2]); + if (arr[1].equals("true")) { + todo.setDone(); + } + Task.addTask(todo); + break; + case ("D"): + Deadline deadline = new Deadline(arr[2], arr[3]); + if (arr[1].equals("true")) { + deadline.setDone(); + } + Task.addTask(deadline); + break; + case ("E"): + Event event = new Event(arr[2], arr[3]); + if (arr[1].equals("true")) { + event.setDone(); + } + Task.addTask(event); + break; + } + } + + /** + * Reads input from the file list.txt + * + * @throws FileNotFoundException If file does not exist + */ + public static void loadFile() throws FileNotFoundException { + File f = new File("list.txt"); // create a File for the given file path + Scanner s = new Scanner(f); // create a Scanner using the File as the source + while (s.hasNext()) { + loadTask(s.nextLine()); + } + } + + /** + * Writes every task that exists within the Task list into the given format in list.txt + * + * @throws IOException If write errors occurs + */ + public static void writeToFile() throws IOException { + createFile(); + FileWriter fw = new FileWriter("list.txt"); + for (int i=0; i buffer = Task.getList(); + fw.write(formWriteData(buffer.get(i))); + } + fw.close(); + } + + + /** + * Returns the formatted String (of a task), to be stored in a .txt file + * + * @param task Current task to be formatted into String + * @return Formatted String + */ + public static String formWriteData(Task task) { + + switch (task.getType()) { + case ("T"): + return (task.getType() + "\t" + task.isDone() + "\t" + task.getDescription() + "\n"); + case ("D"): + Deadline temp1 = (Deadline) (task); + return (temp1.getType() + "\t" + temp1.isDone() + "\t" + temp1.getDescription() + "\t" + temp1.getBy() + "\n"); + default: + Event temp2 = (Event) (task); + return (temp2.getType() + "\t" + temp2.isDone() + "\t" + temp2.getDescription() + "\t" + temp2.getAt() + "\n"); + } + } + + /** + * Creates file if file does not exist + * + * @throws IllegalArgumentException If input errors occur + */ + public static void createFile(){ + try { + File myObj = new File("list.txt"); + if (myObj.createNewFile()) { + System.out.println("File created: " + myObj.getName()); + } else { + System.out.println("File is overwritten."); + } + } catch (IOException e) { + System.out.println("An error occurred."); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/duke/main/UI.java b/src/main/java/duke/main/UI.java new file mode 100644 index 000000000..6a9c50869 --- /dev/null +++ b/src/main/java/duke/main/UI.java @@ -0,0 +1,156 @@ +package duke.main; + +import duke.items.Task; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +import static duke.main.Parser.getCommand; + +/** Class in charge of UI printing */ +public class UI { + private static final String DEADLINE_TEMPLATE = "deadline /by "; + private static final String EVENT_TEMPLATE = "event /at "; + private static final String TODO_TEMPLATE = "todo read book"; + private static final String DATE_TEMPLATE = ""; + public static void printLine() { + System.out.println("____________________________________________________________"); + } + + /** + * Prints the welcome message. + */ + public static void displayWelcomeMessage(){ + String logo = " ____ _ \n" + + "| _ \\ _ _| | _____ \n" + + "| | | | | | | |/ / _ \\\n" + + "| |_| | |_| | < __/\n" + + "|____/ \\__,_|_|\\_\\___|\n"; + System.out.println("Hello from\n" + logo); + System.out.println("Hello! I'm duke.main.Duke\nWhat can I do for you?"); + } + + /** + * Prints the goodbye message + */ + public static void displayByeMessage(){ + System.out.println("Bye. Hope to see you again soon!"); + UI.printLine(); + } + + /** + * Printing the output when using the list function + */ + public static void displayListPreamble() { + if (Task.getNumOfTasks() != 0){ + System.out.println("Here are the tasks in your list:"); + } + } + + /** + * Printing the output when using the find function + */ + public static void displayFindPreamble() { + if (Task.getNumOfTasks() != 0){ + System.out.println("Here are the matching tasks in your list:"); + } + else { + System.out.println("There are no matching task in your list:"); + } + } + + /** + * Prints the updated number of tasks in list + */ + public static void displayListUpdate() { + if (Task.getNumOfTasks() == 0){ + System.out.println("There are no tasks in your list"); + } + else { + System.out.println("Now you have " + Task.getNumOfTasks() + " tasks in the list."); + } + } + + /** + * Error message for invalid commands + */ + public static void InvalidCommandErrorMessage(){ + System.out.println(" ☹ OOPS!!! Invalid Command :-("); + } + + /** + * Error message for too little input parameters + */ + public static void InvalidParameterLengthErrorMessage(String line){ + System.out.println(" ☹ OOPS!!! Insufficient number of inputs for command: " + getCommand(line)); + System.out.println(" Example inputs:"); + switch (getCommand(line)){ + + case ("deadline"): + System.out.println(" \t " + DEADLINE_TEMPLATE); + break; + case ("event"): + System.out.println(" \t " + EVENT_TEMPLATE); + break; + case ("todo"): + System.out.println(" \t " + TODO_TEMPLATE); + break; + } + } + + /** + * Error message for invalid date format + */ + public static void InvalidDateErrorMessage(String line){ + String[] arr = line.split(" "); + System.out.println(" ☹ OOPS!!! Invalid format for date: " + arr[arr.length-1]); + System.out.println(" Input format:"); + System.out.println(" \t " + DATE_TEMPLATE); + } + + /** + * Error message when the /at indicator is not present when event command is used + */ + public static void EventParameterErrorMessage(){ + System.out.println(" ☹ OOPS!!! For \"event\" command please input \"/at\""); + } + + /** + * Error message when the /by indicator is not present when deadline command is used + */ + public static void DeadlineParameterErrorMessage(){ + System.out.println(" ☹ OOPS!!! For \"deadline\" command please input \"/by\""); + } + + /** + * Error message when the the integer parameter is out of range + */ + public static void InvalidIndexErrorMessage(){ + System.out.println(" ☹ OOPS!!! Index is out of range"); + } + + + /** + * Returns a String in the formatted version of the date input + * + * @param date date in the YYYY-MM-DD format + * @return String in the MMM-DD-YYYY date format + */ + public static String convertDateToStringFormat(String date){ + LocalDate myDateObj = LocalDate.parse(date); + DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("MMM-dd-yyyy "); + return myDateObj.format(myFormatObj); + } + + /** + * Returns a LocalDate object based on the String input + * + * @param input date in the MMM-DD-YYYY format + * @return LocalDate object + */ + public static LocalDate convertStringFormatToDate(String input){ + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM-d-yyyy "); + return LocalDate.parse(input, formatter); + } + +} diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index 087374464..2de2c0f7d 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -15,7 +15,7 @@ IF ERRORLEVEL 1 ( REM no error here, errorlevel == 0 REM run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT -java -classpath ..\bin Duke < input.txt > ACTUAL.TXT +java -classpath ..\bin duke.main.Duke < input.txt > ACTUAL.TXT REM compare the output to the expected output FC ACTUAL.TXT EXPECTED.TXT