diff --git a/README.md b/README.md
index 8715d4d91..17aa12446 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,149 @@
-# 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.
-
-## Setting up in Intellij
-
-Prerequisites: JDK 11, update Intellij to the most recent version.
-
-1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first)
-1. Open the project into Intellij as follows:
- 1. Click `Open`.
- 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).
- In the same dialog, set the **Project language level** field to the `SDK default` option.
-3. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output:
- ```
- Hello from
- ____ _
- | _ \ _ _| | _____
- | | | | | | | |/ / _ \
- | |_| | |_| | < __/
- |____/ \__,_|_|\_\___|
- ```
+# Anna
+
+Anna is a chatbot that helps you to organise your tasks. It can add,
+delete and mark done tasks you've listed. It can also help you keep track of deadlines
+and calender events.
+
+Anna runs on a simple CLI interface that is lightweight and cross-platform friendly.
+Anna is also designed to be friendly to first time users by being capable of handling missing inputs
+
+## Setting up
+
+Prerequisites: JDK 11
+1. Download the ip.jar under 'Releases'
+2. Extract the file into a folder you wish to keep it (e.g. `C:\Users\\Desktop\AnnaBot`)
+3. Open a terminal (e.g Command Prompt for Windows) and navigate to the previous directory
+4. Run the jar file using command `java -jar ip.jar`
+#### Example (Windows Command Prompt):
+```
+C:\Users\user> cd Desktop\AnnaBot
+C:\Users\user\Desktop\AnnaBot> java -jar ip.jar
+Hi it's Anna!
+What do you need to do?
+You may load existing data using the load command
+```
+
+## Commands
+To interact with Anna, please use the following commands
+
+### exit the program: `bye`
+This command exits the running instance.
+```
+bye
+Go away Anna
+O-kay bye......
+```
+### view the current tasklist: `list`
+`list` will show the current tasklist in order of addition (oldest task first)
+```
+todo task1
+Okay! I've added: [T] task1
+event task2 /from today /to tomorrow
+Okay! I've added: [E] task2
+list
+Here's what we've gotta do:
+1. [T][ ] task1
+2. [E][ ] task2
+ Start: from today
+ End: to tomorrow
+We currently have 2 tasks
+```
+
+### Mark task as done: `mark `
+Sets a given task as completed. Yay!
+```
+mark 1
+Okay I've marked item 1 as done:
+1. [T][X] task1
+```
+
+### Mark task as not done: `unmark `
+Sets a given task as not done
+```
+unmark 1
+Oh we aren't done with item 1?
+1. [T][ ] task1
+```
+
+### Create a simple todo task: `todo `
+Creates a standard todo task and adds it into the tasklist
+```
+todo task1
+Okay! I've added: [T] task1
+```
+Anna will prompt you if you forget to input the name of the task
+```
+todo
+What are you referring to?
+task1
+Okay! I've added: [T] task1
+```
+### Create a task with a deadline: `deadline /by `
+Creates a task with a deadline and adds it into the tasklist
+```
+deadline task2 /by 5 jan
+Okay! I've added: [D] task2
+```
+Anna will prompt you for the deadline if it is missing
+```
+deadline task2
+When is this due by?
+5 jan
+Okay! I've added: [D] task2
+```
+### Create a task with start and end dates:
`event /from /to `
+Creates a task with start and end times and adds it into the tasklist
+```
+event task3 /from today /to tomorrow
+Okay! I've added: [E] task3
+```
+Similarly to `deadline`, Anna will prompt you if you are missing date details
+```
+event task3 /to tomorrow
+When does this event start?
+today
+Okay! I've added: [E] task3
+```
+### Remove a task: `delete `
+The given task will be deleted from the tasklist
+```
+delete 1
+Okay! I've deleted task: 1
+```
+### Loading and Saving of tasklist
+Anna also supports import/export of your tasklist in the form of a .txt file. This can be helpful if you want to refer to the tasklist in a future date!
+
+`save` exports the current tasklist into a tasklist.txt file
+```
+save
+Successfully exported TaskList!
+Written to: C:\Users\lhyao\Desktop\TaskList.txt
+```
+`load` imports a previous tasklist into the program's tasklist
+Anna looks for a `TaskList.txt` file in the same directory to import from
+```
+load
+Okay! I've added: [D] task2
+Okay! I've added: [D] task2
+Okay! I've added: [E] task3
+Okay! I've added: [E] task3
+Okay! I've added: [T] task1
+```
+## Usage Example
+
+#### Input Example 1
+`deadline ip /by tonight`
+
+#### Expected Output 1
+`Okay! I've added: [D] ip`
+
+#### Input Example 2
+`list`
+
+#### Expected Output 2
+```
+Here's what we've gotta do:
+1. [D][ ] ip
+ Deadline: tonight
+We currently have 1 tasks
+```
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
index 8077118eb..2bf0ce7b7 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,29 +1,149 @@
-# User Guide
+# Anna
-## Features
+Anna is a chatbot that helps you to organise your tasks. It can add,
+delete and mark done tasks you've listed. It can also help you keep track of deadlines
+and calender events.
-### Feature-ABC
+Anna runs on a simple CLI interface that is lightweight and cross-platform friendly.
+Anna is also designed to be friendly to first time users by being capable of handling missing inputs
-Description of the feature.
+## Setting up
-### Feature-XYZ
+Prerequisites: JDK 11
+1. Download the ip.jar under 'Releases'
+2. Extract the file into a folder you wish to keep it (e.g. `C:\Users\\Desktop\AnnaBot`)
+3. Open a terminal (e.g Command Prompt for Windows) and navigate to the previous directory
+4. Run the jar file using command `java -jar ip.jar`
+#### Example (Windows Command Prompt):
+```
+C:\Users\user> cd Desktop\AnnaBot
+C:\Users\user\Desktop\AnnaBot> java -jar ip.jar
+Hi it's Anna!
+What do you need to do?
+You may load existing data using the load command
+```
-Description of the feature.
+## Commands
+To interact with Anna, please use the following commands
-## Usage
+### exit the program: `bye`
+This command exits the running instance.
+```
+bye
+Go away Anna
+O-kay bye......
+```
+### view the current tasklist: `list`
+`list` will show the current tasklist in order of addition (oldest task first)
+```
+todo task1
+Okay! I've added: [T] task1
+event task2 /from today /to tomorrow
+Okay! I've added: [E] task2
+list
+Here's what we've gotta do:
+1. [T][ ] task1
+2. [E][ ] task2
+ Start: from today
+ End: to tomorrow
+We currently have 2 tasks
+```
-### `Keyword` - Describe action
+### Mark task as done: `mark `
+Sets a given task as completed. Yay!
+```
+mark 1
+Okay I've marked item 1 as done:
+1. [T][X] task1
+```
-Describe the action and its outcome.
+### Mark task as not done: `unmark `
+Sets a given task as not done
+```
+unmark 1
+Oh we aren't done with item 1?
+1. [T][ ] task1
+```
+
+### Create a simple todo task: `todo `
+Creates a standard todo task and adds it into the tasklist
+```
+todo task1
+Okay! I've added: [T] task1
+```
+Anna will prompt you if you forget to input the name of the task
+```
+todo
+What are you referring to?
+task1
+Okay! I've added: [T] task1
+```
+### Create a task with a deadline: `deadline /by `
+Creates a task with a deadline and adds it into the tasklist
+```
+deadline task2 /by 5 jan
+Okay! I've added: [D] task2
+```
+Anna will prompt you for the deadline if it is missing
+```
+deadline task2
+When is this due by?
+5 jan
+Okay! I've added: [D] task2
+```
+### Create a task with start and end dates:
`event /from /to `
+Creates a task with start and end times and adds it into the tasklist
+```
+event task3 /from today /to tomorrow
+Okay! I've added: [E] task3
+```
+Similarly to `deadline`, Anna will prompt you if you are missing date details
+```
+event task3 /to tomorrow
+When does this event start?
+today
+Okay! I've added: [E] task3
+```
+### Remove a task: `delete `
+The given task will be deleted from the tasklist
+```
+delete 1
+Okay! I've deleted task: 1
+```
+### Loading and Saving of tasklist
+Anna also supports import/export of your tasklist in the form of a .txt file. This can be helpful if you want to refer to the tasklist in a future date!
-Example of usage:
+`save` exports the current tasklist into a tasklist.txt file
+```
+save
+Successfully exported TaskList!
+Written to: C:\Users\lhyao\Desktop\TaskList.txt
+```
+`load` imports a previous tasklist into the program's tasklist
+Anna looks for a `TaskList.txt` file in the same directory to import from
+```
+load
+Okay! I've added: [D] task2
+Okay! I've added: [D] task2
+Okay! I've added: [E] task3
+Okay! I've added: [E] task3
+Okay! I've added: [T] task1
+```
+## Usage Example
-`keyword (optional arguments)`
+#### Input Example 1
+`deadline ip /by tonight`
-Expected outcome:
+#### Expected Output 1
+`Okay! I've added: [D] ip`
-Description of the outcome.
+#### Input Example 2
+`list`
+#### Expected Output 2
```
-expected output
-```
+Here's what we've gotta do:
+1. [D][ ] ip
+ Deadline: tonight
+We currently have 1 tasks
+```
\ No newline at end of file
diff --git a/src/main/java/Commands.java b/src/main/java/Commands.java
new file mode 100644
index 000000000..f0ce889f1
--- /dev/null
+++ b/src/main/java/Commands.java
@@ -0,0 +1,178 @@
+import tasktypes.Todo;
+import tasktypes.*;
+
+import java.util.ArrayList;
+import java.util.Scanner;
+
+public class Commands {
+
+ public static final int DEADLINE_PARAM_INDEX = 1;
+ static final String TASK_NO_EXIST = "Task does not exist!";
+ static final String DELETE_TASK_MESSAGE = "Okay! I've deleted task: ";
+ public static final String DEADLINE_USERINPUT_PREFIX = "/by";
+ public static final boolean STATUSTYPE_DONE = true;
+ static final int STARTDATE_INDEX = 0;
+ static final int ENDDATE_INDEX = 1;
+ public static final String SHOWLIST_HEADER = "Here's what we've gotta do:";
+ public static final String SEARCH_NO_RESULT = "We don't have that in the list!";
+ public static final String INVALID_COMMAND_MESSAGE = "I didn't get that!";
+ public static final String EMPTY_TASKLIST_MESSAGE = "We are free! Let's go play!";
+ public static final int USERINPUT_DUEDATE_INDEX = 1;
+ public static final int USERINPUT_DESCRIPTION_INDEX = 0;
+ public static final int INVALID_INDEX = -99;
+
+ /**
+ * Prints out a message stating that the input command is not a valid command
+ */
+ public static void invalidCommand() {
+ System.out.println(INVALID_COMMAND_MESSAGE);
+ }
+
+ /**
+ * Shows the current tasklist contents
+ * Prints out a unique message if the tasklist is empty
+ */
+ public static void showList() {
+ if (TaskList.getNumTasks() == USERINPUT_DESCRIPTION_INDEX) {
+ System.out.println(EMPTY_TASKLIST_MESSAGE);
+ } else {
+ String showList_footer = "We currently have " + TaskList.getNumTasks() + " tasks";
+ Ui.printList(TaskList.getList(), SHOWLIST_HEADER, showList_footer);
+ }
+ }
+
+ /**
+ * Marks a given task in the tasklist as done or not done depending on parameter statusType
+ *
+ * @param userInput the input from the user
+ * @param statusType input true for done, false for notDone
+ */
+ public static void markTask(String userInput, boolean statusType) {
+ int itemNum = INVALID_INDEX;
+ try {
+ itemNum = Ui.getItemNumber(userInput);
+ } catch (DukeException d) {
+ System.out.println(d.getMessage());
+ }
+ if (itemNum == INVALID_INDEX) {
+ return;
+ } else if (itemNum > USERINPUT_DESCRIPTION_INDEX && itemNum <= TaskList.getNumTasks()) {
+ if (statusType == STATUSTYPE_DONE) {
+ TaskList.markDone(itemNum - USERINPUT_DUEDATE_INDEX);
+ System.out.println("Okay I've marked item " + itemNum + " as done:");
+ TaskList.printItem(itemNum - USERINPUT_DUEDATE_INDEX);
+ } else {
+ TaskList.markNotDone(itemNum - USERINPUT_DUEDATE_INDEX);
+ System.out.println("Oh we aren't done with item " + itemNum + "?");
+ TaskList.printItem(itemNum - USERINPUT_DUEDATE_INDEX);
+ }
+ } else {
+ System.out.println(TASK_NO_EXIST);
+ }
+ }
+
+ /**
+ * Removes a given task from the tasklist based on the input message
+ *
+ * @param userInput user's input
+ */
+ public static void deleteTask(String userInput) {
+ int itemIndex;
+ try {
+ itemIndex = Ui.getItemIndex(userInput);
+ } catch (DukeException d) {
+ System.out.println(d.getMessage());
+ return;
+ }
+ if (itemIndex <= TaskList.getNumTasks() - USERINPUT_DUEDATE_INDEX) {
+ TaskList.deleteTask(itemIndex);
+ System.out.println(DELETE_TASK_MESSAGE + (itemIndex + USERINPUT_DUEDATE_INDEX));
+ } else {
+ System.out.println(TASK_NO_EXIST);
+ }
+ }
+
+ /**
+ * takes in user's description and adds a Todo task to the tasklist
+ *
+ * @param userInput description of the todo
+ */
+ public static void addTodoTask(String userInput) {
+ String itemDescription = Ui.getItemDescription(userInput);
+ Todo newTask = new Todo(itemDescription);
+ TaskList.addItem(newTask);
+ }
+
+ /**
+ * takes in user's description and adds a deadline task to the tasklist
+ * if the user has not supplied a deadline, method will request for the deadline
+ *
+ * @param userInput description of the deadline task
+ */
+ public static void addDeadlineTask(String userInput) {
+ String itemDescription, dueDate;
+ if (userInput.contains(DEADLINE_USERINPUT_PREFIX)) {
+ itemDescription = userInput.split(" ", 2)[DEADLINE_PARAM_INDEX];
+ itemDescription = itemDescription.split(DEADLINE_USERINPUT_PREFIX, 2)[USERINPUT_DESCRIPTION_INDEX];
+ dueDate = userInput.split(DEADLINE_USERINPUT_PREFIX, 2)[USERINPUT_DUEDATE_INDEX];
+ } else {
+ itemDescription = Ui.getItemDescription(userInput);
+ dueDate = Ui.getDueDate(userInput);
+ }
+ Deadline newTask = new Deadline(itemDescription, dueDate);
+ TaskList.addItem(newTask);
+ }
+
+ /**
+ * takes in user's input and adds an event task to the tasklist
+ * if the user has not supplied start and/or end dates, method will request for the dates
+ *
+ * @param userInput description of the event task
+ */
+ public static void addEventTask(String userInput) {
+ String itemDescription = Ui.getItemDescription(userInput);
+ String[] StartEndDates = Ui.getStartEndDates(userInput);
+ String startDate = StartEndDates[STARTDATE_INDEX];
+ String endDate = StartEndDates[ENDDATE_INDEX];
+ Event newTask = new Event(itemDescription, startDate, endDate);
+ TaskList.addItem(newTask);
+ }
+
+ /**
+ * Checks if searchTerm can be found inside taskDescription.
+ *
+ * @param searchTerm String to be found in the taskDescription
+ * @param taskDescription String where searchTerm is to be found in
+ * @return true if taskDescription contains searchTerm
+ */
+ public static boolean containsSearchTerm(String searchTerm, String taskDescription) {
+ return taskDescription.contains(searchTerm);
+ }
+
+ /**
+ * Searches the current tasklist for a user-supplied String
+ * Will print out the list of items that match the user input if exists.
+ * Else will print out a no items found message
+ *
+ * @param userInput the String to be searched for
+ */
+ public static void searchTask(String userInput) {
+ String searchTerm = Ui.getItemDescription(userInput);
+ ArrayList resultsList = new ArrayList<>();
+ int searchResults = USERINPUT_DESCRIPTION_INDEX;
+ for (int i = USERINPUT_DUEDATE_INDEX; i <= TaskList.getNumTasks(); ++i) {
+ String taskDescription = TaskList.getItem(i - USERINPUT_DUEDATE_INDEX).getDescription();
+ if (containsSearchTerm(searchTerm, taskDescription)) {
+ resultsList.add(TaskList.getItem(i - USERINPUT_DUEDATE_INDEX));
+ searchResults += USERINPUT_DUEDATE_INDEX;
+ }
+ }
+ if (searchResults == USERINPUT_DESCRIPTION_INDEX) {
+ System.out.println(SEARCH_NO_RESULT);
+ } else {
+ String resultsList_header = "We have " + searchResults + " results!";
+ Ui.printList(resultsList, resultsList_header, "");
+ }
+ }
+
+}
diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java
index 5d313334c..564fbcb88 100644
--- a/src/main/java/Duke.java
+++ b/src/main/java/Duke.java
@@ -1,10 +1,30 @@
+import java.util.Scanner;
+
public class Duke {
+ public static final String EXIT_CMD = "exit";
+ public static final String BYE_CMD = "bye";
public static void main(String[] args) {
- String logo = " ____ _ \n"
- + "| _ \\ _ _| | _____ \n"
- + "| | | | | | | |/ / _ \\\n"
- + "| |_| | |_| | < __/\n"
- + "|____/ \\__,_|_|\\_\\___|\n";
- System.out.println("Hello from\n" + logo);
+ Ui.welcome();
+ Scanner in = new Scanner(System.in);
+
+ boolean isExit = false;
+ while (!isExit) {
+ String userInput = in.nextLine().trim();
+ String inputCommand = Parser.ParseInputCommand(userInput);
+ switch (inputCommand) {
+ case EXIT_CMD:
+ case BYE_CMD:
+ isExit = true;
+ Ui.endSavePrompt();
+ break;
+ default:
+ Parser.ParseCommand(inputCommand,userInput);
+ break;
+ }
+ }
}
}
+
+
+
+
diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java
new file mode 100644
index 000000000..b1ea276ef
--- /dev/null
+++ b/src/main/java/DukeException.java
@@ -0,0 +1,5 @@
+public class DukeException extends Exception {
+ DukeException(String errorMessage) {
+ System.out.println(errorMessage);
+ }
+}
diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java
new file mode 100644
index 000000000..1e2c6daa5
--- /dev/null
+++ b/src/main/java/Storage.java
@@ -0,0 +1,97 @@
+import tasktypes.Deadline;
+import tasktypes.Event;
+import tasktypes.Todo;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Scanner;
+
+public class Storage {
+ public static final String TASKLIST_EXPORT_PATH = "TaskList.txt";
+ public static final String WRITTEN_TO_PATH_PREFIX = "Written to: ";
+ public static final String SUCCESS_EXPORT = "Successfully exported TaskList!";
+ public static final String EXPORT_ERROR_PREFIX = "Error occurred while writing to ";
+ public static final String TASKTYPE_READ_ERROR = "Error reading TaskType";
+ public static final int DESCRIPTION_INDEX = 9;
+ public static final int DEADLINE_INDEX = 9;
+ public static final int STARTDATE_INDEX = 6;
+ public static final int ENDDATE_INDEX = 4;
+ public static final String EXISTING_DATA_NOT_FOUND = "Existing data not found!";
+
+ /**
+ * creates a file in a specified export path
+ * @return a File object pertaining to the created file
+ */
+ public static File createFile() {
+ return new File(TASKLIST_EXPORT_PATH);
+ }
+
+ /**
+ * finds an existing tasklist.txt file and reads from it to populate the current instance's tasklist
+ * returns an error message if the existing file does not exist
+ */
+ public static void readFromExistingData() {
+ File existingData = new File(TASKLIST_EXPORT_PATH);
+ try {
+ Scanner s = new Scanner(existingData);
+ String itemDescription;
+ while (s.hasNext()) {
+ String newLine = s.nextLine();
+ String TaskType = String.valueOf(newLine.charAt(3));
+
+ switch (TaskType) {
+ case (Todo.TYPE_ICON):
+ itemDescription = newLine.substring(DESCRIPTION_INDEX);
+ Todo task = new Todo(itemDescription);
+ TaskList.addItem(task);
+ break;
+ case (Deadline.TYPE_ICON):
+ itemDescription = newLine.substring(DESCRIPTION_INDEX);
+ String dueDate = s.nextLine().trim();
+ dueDate = dueDate.substring(DEADLINE_INDEX);
+ Deadline deadline = new Deadline(itemDescription, dueDate);
+ TaskList.addItem(deadline);
+ break;
+ case (Event.TYPE_ICON):
+ itemDescription = newLine.substring(DESCRIPTION_INDEX);
+ String startDate = s.nextLine().trim();
+ startDate = startDate.substring(STARTDATE_INDEX);
+ String endDate = s.nextLine().trim();
+ endDate = endDate.substring(ENDDATE_INDEX);
+ Event event = new Event(itemDescription,startDate, endDate);
+ TaskList.addItem(event);
+ break;
+ default:
+ System.out.println(TASKTYPE_READ_ERROR);
+ return;
+ }
+ }
+ } catch (FileNotFoundException f) {
+ System.out.println(EXISTING_DATA_NOT_FOUND);
+ }
+ }
+
+ /**
+ * exports the current tasklist into a text file at the specified export path
+ *
+ */
+ public static void writeToTaskList() {
+ File exportTaskList = createFile();
+ try {
+ FileWriter writeTaskList = new FileWriter(TASKLIST_EXPORT_PATH);
+ int numTasks = TaskList.getNumTasks();
+ for (int i = 0; i < numTasks; ++i) {
+ writeTaskList.write(i + 1 + ".");
+ writeTaskList.write(TaskList.getItem(i).getTask());
+ writeTaskList.write(System.lineSeparator());
+ }
+ writeTaskList.close();
+ System.out.println(SUCCESS_EXPORT);
+ System.out.println(WRITTEN_TO_PATH_PREFIX + exportTaskList.getCanonicalPath());
+ } catch (IOException e) {
+ System.out.println(EXPORT_ERROR_PREFIX + exportTaskList.getAbsolutePath());
+ }
+ }
+}
diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java
new file mode 100644
index 000000000..35b11e6e3
--- /dev/null
+++ b/src/main/java/TaskList.java
@@ -0,0 +1,83 @@
+import tasktypes.Task;
+
+import java.util.ArrayList;
+
+public class TaskList {
+ private static final ArrayList TaskList = new ArrayList<>(10);
+ private static int NumTasks = 0;
+
+ /**
+ * Returns the current tasklist
+ * @return TaskList currently stored in the method
+ */
+ public static ArrayList getList() {
+ return TaskList;
+ }
+
+ /**
+ * Adds a Task to the tasklist, increments the number of tasks in the list then echos the task added
+ * @param newTask Task to be added to the list
+ */
+ public static void addItem (Task newTask) {
+ TaskList.add(newTask);
+ NumTasks += 1;
+ System.out.println("Okay! I've added: [" + newTask.getTypeIcon() +"] " + newTask.getDescription());
+ }
+
+ /**
+ * gets the number of tasks in the list
+ * @return the number of tasks in the list currently
+ */
+ public static int getNumTasks() {
+ return NumTasks;
+ }
+
+ /**
+ * marks a task's status as done
+ * @param index index of the task in the tasklist
+ */
+ public static void markDone (int index) {
+ if (TaskList.get(index).getStatusIcon().equals(" ")) {
+ TaskList.get(index).markDone();
+ }
+ }
+
+ /**
+ * marks a task's status as not done
+ * @param index index of the task in the tasklist
+ */
+ public static void markNotDone (int index) {
+ if (TaskList.get(index).getStatusIcon().equals("X")) {
+ TaskList.get(index).markNotDone();
+ }
+ }
+
+ /**
+ * get a task item from the tasklist
+ * @param index index of the task in the tasklist
+ * @return returns a Task object from the tasklist according to the index
+ */
+ public static Task getItem (int index) {
+ return TaskList.get(index);
+ }
+
+ /**
+ * prints out a task in a pre-set format
+ * @param index index of the task in the tasklist
+ */
+ public static void printItem (int index) {
+ System.out.print(index+1 + ". ");
+ System.out.println(TaskList.get(index).getTask());
+ }
+
+ /**
+ * removes a task from the tasklist and decrements the counter for number of tasks
+ * @param index index of the task in the tasklist
+ */
+ public static void deleteTask(int index) {
+ TaskList.remove(index);
+ NumTasks -= 1;
+ }
+
+
+}
diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java
new file mode 100644
index 000000000..96d8ef535
--- /dev/null
+++ b/src/main/java/Ui.java
@@ -0,0 +1,229 @@
+import tasktypes.Task;
+import java.util.ArrayList;
+import java.util.InputMismatchException;
+import java.util.Scanner;
+
+public class Ui {
+ public static final String EXIT_MESSAGE = "Go away Anna\nO-kay bye......";
+ static final int DESCRIPTION_INDEX = 1;
+ public static final String STARTDATE_USERINPUT_PREFIX = "/from";
+ public static final String ENDDATE_USERINPUT_PREFIX = "/to";
+ public static final String DEADLINE_USERINPUT_PREFIX = "/by";
+ static final int STARTDATE_INDEX = 0;
+ static final int ENDDATE_INDEX = 1;
+ private static final String WELCOME_MESSAGE = "Hi it's Anna!\nWhat do you need to do?";
+ public static final String WELCOME_LOAD_PROMPT = "You may load existing data using the load command";
+ public static final String ITEM_NUMBER_PROMPT = "What is the number of the item in the list?";
+ public static final String REJECTED_NON_NUMBER_INPUT = "Please enter a number";
+ public static final String DUEDATE_PROMPT = "When is this due by?";
+ public static final String EVENT_START_PROMPT = "When does this event start?";
+ public static final String EVENT_END_PROMPT = "When does this event end?";
+ public static final String ITEM_DESCRIPTION_PROMPT = "What are you referring to?";
+ public static final int EVENT_STARTMARKER_LENGTH = 5;
+ public static final int EVENT_ENDMARKER_LENGTH = 3;
+ public static final int INVALID_INDEX = -99;
+ public static final String END_SAVE_PROMPT = "Wait, do you want to save the current list?\n Type yes if so";
+
+ /**
+ * prints a welcome message on startup.
+ * Also prompts user if they would like to load an existing file
+ */
+ public static void welcome() {
+ System.out.println(WELCOME_MESSAGE);
+ System.out.println(WELCOME_LOAD_PROMPT);
+ }
+
+ /**
+ * gets the description from the user for a new task object
+ * will prompt the user if additional information is required
+ * @param userInput input string from the user
+ * @return returns the description of the task
+ */
+ public static String getItemDescription(String userInput) {
+ Scanner in = new Scanner(System.in);
+ String description;
+ try {
+ description = userInput.split(" ", 2)[DESCRIPTION_INDEX];
+ } catch (ArrayIndexOutOfBoundsException e) {
+ System.out.println(ITEM_DESCRIPTION_PROMPT);
+ description = in.nextLine().trim();
+ }
+ if (description.contains("/")) {
+ description = description.split("/",2)[0];
+ description = description.trim();
+ }
+ return description;
+ }
+
+ /**
+ * gets the item number for the user supplied command to act on
+ * @param userInput command input from the user
+ * @return returns number of the item in the tasklist (1-based)
+ * @throws DukeException if user's input is not valid or out of bounds
+ */
+ public static int getItemNumber(String userInput) throws DukeException {
+ Scanner in = new Scanner(System.in);
+ int itemNumber = INVALID_INDEX;
+ try {
+ itemNumber = Integer.parseInt(userInput.split(" ", 2)[1]);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ Ui.printList(TaskList.getList(),"","");
+ System.out.println(ITEM_NUMBER_PROMPT);
+ try {
+ itemNumber = in.nextInt();
+ } catch (InputMismatchException i) {
+ throw new DukeException(REJECTED_NON_NUMBER_INPUT);
+ }
+ } catch (NumberFormatException n) {
+ throw new DukeException(REJECTED_NON_NUMBER_INPUT);
+ }
+ return itemNumber;
+ }
+
+ /**
+ * gets the item index for the user supplied command to act on
+ * @param userInput command input from the user
+ * @return returns index of the item in the tasklist (0-based)
+ * @throws DukeException if user's input is not valid or out of bounds
+ */
+ public static int getItemIndex(String userInput) throws DukeException{
+ int itemIndex = INVALID_INDEX;
+ while (itemIndex <= 0) {
+ itemIndex = getItemNumber(userInput);
+ }
+ return itemIndex - 1;
+ }
+
+ /**
+ * gets a duedate for the creation of a new deadline object
+ * will prompt the user if additional information is required
+ * @param userInput command input from the user
+ * @return duedate of the deadline object
+ */
+ public static String getDueDate(String userInput) {
+ Scanner in = new Scanner(System.in);
+ String dueDate;
+ if (userInput.contains(DEADLINE_USERINPUT_PREFIX)) {
+ dueDate = userInput.substring(userInput.indexOf(DEADLINE_USERINPUT_PREFIX)).trim();
+ } else {
+ System.out.println(DUEDATE_PROMPT);
+ dueDate = in.nextLine().trim();
+ }
+ return dueDate;
+ }
+
+ /**
+ * gets the index of the startdate marker in the user supplied input
+ * @param userInput user supplied input
+ * @return index of the startdate marker, else -99 if not found
+ */
+ public static int getStartMarkerIndex(String userInput) {
+ if (userInput.contains(STARTDATE_USERINPUT_PREFIX)) {
+ return userInput.indexOf(STARTDATE_USERINPUT_PREFIX);
+ } else {
+ return INVALID_INDEX;
+ }
+ }
+
+ /**
+ * gets the index of the enddate marker in the user supplied input
+ * @param userInput user supplied input
+ * @return index of the enddate marker, else -99 if not found
+ */
+ public static int getEndMarkerIndex(String userInput) {
+ if (userInput.contains(ENDDATE_USERINPUT_PREFIX)) {
+ return userInput.indexOf(ENDDATE_USERINPUT_PREFIX);
+ } else {
+ return INVALID_INDEX;
+ }
+ }
+ /**
+ * gets the startdate from the user supplied input
+ * will prompt the user to enter the startdate if not found
+ * @param userInput user supplied command input
+ * @return startdate of the event
+ */
+ public static String getStartDate(String userInput) {
+ Scanner in = new Scanner (System.in);
+ int startMarkerIndex = getStartMarkerIndex(userInput);
+ int endMarkerIndex = getEndMarkerIndex(userInput);
+ if (startMarkerIndex == INVALID_INDEX) {
+ System.out.println(EVENT_START_PROMPT);
+ return in.nextLine().trim();
+ } else {
+ if (endMarkerIndex == INVALID_INDEX) {
+ return userInput.substring(startMarkerIndex + EVENT_STARTMARKER_LENGTH).trim();
+ } else {
+ return userInput.substring(startMarkerIndex + EVENT_STARTMARKER_LENGTH,endMarkerIndex).trim();
+ }
+ }
+ }
+
+ /**
+ * gets the enddate from the user supplied input
+ * will prompt the user to enter the enddate if not found
+ * @param userInput user supplied command input
+ * @return enddate of the event
+ */
+ public static String getEndDate(String userInput) {
+ Scanner in = new Scanner (System.in);
+ int startMarkerIndex = getStartMarkerIndex(userInput);
+ int endMarkerIndex = getEndMarkerIndex(userInput);
+ if (endMarkerIndex == INVALID_INDEX) {
+ System.out.println(EVENT_END_PROMPT);
+ return in.nextLine().trim();
+ } else {
+ if (startMarkerIndex > endMarkerIndex) {
+ return userInput.substring(endMarkerIndex + EVENT_ENDMARKER_LENGTH,startMarkerIndex).trim();
+ } else {
+ return userInput.substring(endMarkerIndex + EVENT_ENDMARKER_LENGTH).trim();
+ }
+ }
+ }
+ /**
+ * gets the start and end dates for the creation of a new event object
+ * will prompt the user if additional information is required
+ * @param userInput command input from the user
+ * @return a string array containing the start and end dates respectively
+ */
+ public static String[] getStartEndDates(String userInput) {
+ String[] StartEndDates = new String[2];
+ StartEndDates[STARTDATE_INDEX] = getStartDate(userInput);
+ StartEndDates[ENDDATE_INDEX] = getEndDate(userInput);
+ return StartEndDates;
+ }
+
+ /**
+ * prints a given arrayList of Tasks with a header and footer if required
+ * @param itemList arrayList of Task objects
+ * @param header line to print before the arrayList. input empty string if not required
+ * @param footer line to print after the arrayList. input empty string if not required
+ */
+ public static void printList(ArrayList itemList, String header, String footer) {
+ if (!header.isBlank()) {
+ System.out.println(header);
+ }
+ for (int i = 0 ; i < itemList.size(); ++i) {
+ System.out.print((i+1)+ ". ");
+ System.out.println(itemList.get(i).getTask());
+ }
+ if (!footer.isBlank()) {
+ System.out.println(footer);
+ }
+ }
+ /**
+ * Checks with the user if the data should be saved before shutdown of the program
+ * prints the exit message afterwards
+ */
+ public static void endSavePrompt() {
+ Scanner in = new Scanner(System.in);
+ if (!TaskList.getList().isEmpty()) {
+ System.out.println(END_SAVE_PROMPT);
+ String saveDecision = in.nextLine().trim().toLowerCase();
+ if (saveDecision.equals("yes")) {
+ Storage.writeToTaskList();
+ }
+ }
+ System.out.println(EXIT_MESSAGE);
+ }
+}
diff --git a/src/main/java/tasktypes/Deadline.java b/src/main/java/tasktypes/Deadline.java
new file mode 100644
index 000000000..7e1ac5f76
--- /dev/null
+++ b/src/main/java/tasktypes/Deadline.java
@@ -0,0 +1,26 @@
+package tasktypes;
+
+public class Deadline extends Task {
+ public static final String TYPE_ICON = "D";
+ protected String dueDate;
+
+ public Deadline(String description, String dueDate) {
+ super(description);
+ this.dueDate = dueDate;
+ }
+
+ @Override
+ public String getTypeIcon() {
+ return TYPE_ICON;
+ }
+
+ public String getDueDate() {
+ return dueDate;
+ }
+
+ @Override
+ public String getTask() {
+ return taskTypeIcon() + isDoneIcon() + " " + getDescription()
+ + System.lineSeparator() + " Deadline: " + getDueDate();
+ }
+}
diff --git a/src/main/java/tasktypes/Event.java b/src/main/java/tasktypes/Event.java
new file mode 100644
index 000000000..cee15ef3c
--- /dev/null
+++ b/src/main/java/tasktypes/Event.java
@@ -0,0 +1,31 @@
+package tasktypes;
+
+public class Event extends Task{
+ public static final String TYPE_ICON = "E";
+ String startDate, endDate;
+ public Event(String description, String startDate, String endDate) {
+ super(description);
+ this.startDate = startDate;
+ this.endDate = endDate;
+ }
+
+ @Override
+ public String getTypeIcon() {
+ return TYPE_ICON;
+ }
+
+ public String getStartDate() {
+ return startDate;
+ }
+
+ public String getEndDate() {
+ return endDate;
+ }
+
+ @Override
+ public String getTask() {
+ return taskTypeIcon() + isDoneIcon() + " " + getDescription() + System.lineSeparator()
+ + " Start: " + getStartDate() + System.lineSeparator()
+ + " End: " + getEndDate();
+ }
+}
diff --git a/src/main/java/tasktypes/Task.java b/src/main/java/tasktypes/Task.java
new file mode 100644
index 000000000..cb1feeea5
--- /dev/null
+++ b/src/main/java/tasktypes/Task.java
@@ -0,0 +1,45 @@
+package tasktypes;
+
+public class Task {
+ protected String description;
+ protected boolean isDone;
+ protected int listIndex;
+
+ public Task(String description) { //ok to leave as public?
+ this.description = description;
+ this.isDone = false;
+ }
+
+ public String getStatusIcon() {
+ return (isDone ? "X" : " "); // mark done task with X
+ }
+
+ public String getTypeIcon() {
+ return "NULL";
+ }
+
+ public String taskTypeIcon() { return "[" + getTypeIcon() + "]";}
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public void markDone() {
+ isDone = true;
+ }
+
+ public void markNotDone() {
+ isDone = false;
+ }
+
+ public String isDoneIcon() { return "[" + getStatusIcon() + "]";}
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getTask() {
+ return taskTypeIcon() + isDoneIcon() + " " + getDescription();
+ }
+
+}
diff --git a/src/main/java/tasktypes/Todo.java b/src/main/java/tasktypes/Todo.java
new file mode 100644
index 000000000..0869172a1
--- /dev/null
+++ b/src/main/java/tasktypes/Todo.java
@@ -0,0 +1,15 @@
+package tasktypes;
+
+public class Todo extends Task {
+
+ public static final String TYPE_ICON = "T";
+
+ public Todo(String description) {
+ super(description);
+ }
+
+ @Override
+ public String getTypeIcon() {
+ return TYPE_ICON;
+ }
+}