diff --git a/Daiyan.png b/Daiyan.png
new file mode 100644
index 000000000..bf71a0cff
Binary files /dev/null and b/Daiyan.png differ
diff --git a/README.md b/README.md
index af0309a9e..fad32bcad 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,17 @@
-# Duke project template
+# CS2103T Individual Project
+This is a project by NUS school of computing for the mod CS2103T. I named the main file after Daiyan from Girl's Frontline (An mobile RPG game i adore). The project is currently unfinished and will take the course of this semester to complete.
+```
+ ____ ____ _ __ __ ____ __ _
+| _) \ / () \ | |\ \/ // () \ | \| |
+|____//__/\__\|_| |__|/__\/__\|_|\__|
+```
+__________________________________________
+![Daiyan](https://github.com/lyhthaddeus/ip/blob/master/Daiyan.png)
-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.
+Hello I'm Daiyan
+What can I do for you?
+__________________________________________
-## Setting up in Intellij
+[More information on Daiyan](https://iopwiki.com/wiki/Daiyan)
-Prerequisites: JDK 17, 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 17** (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.
-1. 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
- ____ _
- | _ \ _ _| | _____
- | | | | | | | |/ / _ \
- | |_| | |_| | < __/
- |____/ \__,_|_|\_\___|
- ```
-
-**Warning:** Keep the `src\main\java` folder as the root folder for Java files (i.e., don't rename those folders or move Java files to another folder outside of this folder path), as this is the default location some tools (e.g., Gradle) expect to find Java files.
diff --git a/data/storage.txt b/data/storage.txt
new file mode 100644
index 000000000..0be97bc8d
--- /dev/null
+++ b/data/storage.txt
@@ -0,0 +1,2 @@
+T | false | task 1
+E | false | task 1 | 1 | 2
diff --git a/src/main/java/Controller/Parser.java b/src/main/java/Controller/Parser.java
new file mode 100644
index 000000000..dcfc35365
--- /dev/null
+++ b/src/main/java/Controller/Parser.java
@@ -0,0 +1,100 @@
+package Controller;
+
+import java.io.IOException;
+import java.util.Scanner;
+import DataStructure.TaskList;
+import TaskObjects.*;
+
+import Enums.CommandTypes;
+import Exception.InvalidInputException;
+import Exception.SyntaxException;
+
+public class Parser {
+
+ private TaskList taskList;
+ private static final String LINE_BREAK = "\n__________________________________________\n";
+
+ public Parser() {
+ }
+
+ public void start() {
+ Scanner scanner = new Scanner(System.in);
+ String input;
+ System.out.print("How may I assist you commander?" + LINE_BREAK);
+ this.taskList = Storage.load();
+
+ while(true) {
+ input = scanner.nextLine().trim();
+ String[] parsed = input.split(" ", 2);
+ CommandTypes commandTypes = CommandTypes.fromString(parsed[0]);
+
+ try {
+ switch (commandTypes) {
+ case BYE, Q:
+ System.out.println("Bye, hope to see you again Commander." + LINE_BREAK);
+ return;
+ case LIST, LS:
+ taskList.getList();
+ break;
+ case MARK:
+ if (parsed.length < 2) {
+ throw new SyntaxException("mark", "mark ");
+ }
+ taskList.mark(parsed[1]);
+ break;
+ case UNMARK:
+ if (parsed.length < 2) {
+ throw new SyntaxException("unmark", "unmark ");
+ }
+ taskList.unmarked(parsed[1]);
+ break;
+ case DELETE, DEL:
+ if (parsed.length < 2) {
+ throw new SyntaxException("delete", "delete ");
+ }
+ taskList.delete(parsed[1]);
+ break;
+ case TODO:
+ if (parsed.length < 2) {
+ throw new SyntaxException("Todo", "todo ");
+ }
+ taskList.add(new Todo(parsed[1], false));
+ break;
+ case DEADLINE:
+ if (parsed.length < 2) {
+ throw new SyntaxException("Deadline", "deadline /by ");
+ }
+ String[] deadlinePartition = parsed[1].split("/by");
+ if (deadlinePartition.length < 2) {
+ throw new SyntaxException("Deadline", "deadline /by ");
+ }
+ String deadlineDescription = deadlinePartition[0].trim();
+ String deadlineBy = deadlinePartition[1].trim();
+ taskList.add(new Deadline(deadlineDescription, false,deadlineBy));
+ break;
+ case EVENT:
+ if (parsed.length < 2) {
+ throw new SyntaxException("Event", "event /from /to ");
+ }
+ String[] eventPartition1 = parsed[1].split("/from");
+ if (eventPartition1.length < 2) {
+ throw new SyntaxException("Event", "event /from /to ");
+ }
+ String eventDescription = eventPartition1[0].trim();
+ String[] eventPartition2 = eventPartition1[1].split("/to");
+ if (eventPartition2.length < 2) {
+ throw new SyntaxException("Event", "event /from /to ");
+ }
+ String eventFrom = eventPartition2[0].trim();
+ String eventTo = eventPartition2[1].trim();
+ taskList.add(new Event(eventDescription, false, eventFrom, eventTo));
+ break;
+ default:
+ throw new InvalidInputException("Sorry Commander, but I do not understand your orders.");
+ }
+ } catch (InvalidInputException e) {
+ System.out.println(e.getMessage() + LINE_BREAK);
+ }
+ }
+ }
+}
diff --git a/src/main/java/Controller/Storage.java b/src/main/java/Controller/Storage.java
new file mode 100644
index 000000000..e5cf5fae2
--- /dev/null
+++ b/src/main/java/Controller/Storage.java
@@ -0,0 +1,88 @@
+package Controller;
+
+import DataStructure.TaskList;
+import TaskObjects.*;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import Exception.InvalidInputException;
+import Exception.StorageSyntaxException;
+
+public class Storage {
+ private static final String PATH = "./data/storage.txt";
+
+ public static TaskList load() {
+ TaskList taskList = new TaskList<>();
+ File file = new File(PATH);
+
+ if (!file.isFile()) {
+ return taskList;
+ }
+
+ try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
+ String readerPointer = reader.readLine();
+ while (readerPointer != null) {
+ Task task = parser(readerPointer);
+ if (task != null) {
+ taskList.load(task);
+ }
+ readerPointer = reader.readLine();
+ }
+ } catch (IOException e) {
+ System.out.println("Sorry Commander, there appears to be an error fetching previous task: " + e.getMessage());
+ }
+
+ return taskList;
+ }
+
+ public static void save(List extends Task> taskList) {
+ File file = new File(PATH);
+ file.getParentFile().mkdirs();
+
+ try {
+ if (!file.isFile()) {
+ file.createNewFile();
+ }
+
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))){
+ for (Task task : taskList) {
+ writer.write(task.toFileFormat());
+ writer.newLine();
+ }
+ }
+ } catch (IOException e) {
+ System.out.println("Sorry Commander, there is an error with saving tasks: " + e.getMessage());
+ }
+ }
+
+ private static Task parser(String input) {
+ String[] split = input.split(" \\| ");
+
+ String type = split[0].trim();
+ boolean isCompleted = split[1].trim().equals("1");
+ String description = split[2].trim();
+
+ Task returnTask;
+ try {
+ switch (type) {
+ case "T":
+ returnTask = new Todo(description, isCompleted);
+ break;
+ case "D":
+ returnTask = new Deadline(description, isCompleted, split[3].trim());
+ break;
+ case "E":
+ returnTask = new Event(description, isCompleted, split[3].trim(), split[4].trim());
+ break;
+ default:
+ throw new StorageSyntaxException();
+ }
+ } catch (InvalidInputException e) {
+ System.out.println(e.getMessage());
+ return null;
+ }
+
+ return returnTask;
+ }
+
+}
diff --git a/src/main/java/Daiyan.java b/src/main/java/Daiyan.java
new file mode 100644
index 000000000..8ebd4435e
--- /dev/null
+++ b/src/main/java/Daiyan.java
@@ -0,0 +1,14 @@
+import Controller.Parser;
+
+public class Daiyan {
+
+ public static void main(String[] args) {
+ String asciiArt = " ____ ____ _ __ __ ____ __ _ \n" +
+ "| _) \\ / () \\ | |\\ \\/ // () \\ | \\| |\n" +
+ "|____//__/\\__\\|_| |__|/__\\/__\\|_|\\__|";
+ System.out.println(asciiArt);
+ System.out.println("__________________________________________\nHello I'm Daiyan\nWhat can I do for you?\n__________________________________________\n");
+ Parser parser = new Parser();
+ parser.start();
+ }
+}
diff --git a/src/main/java/DataStructure/TaskList.java b/src/main/java/DataStructure/TaskList.java
new file mode 100644
index 000000000..e54c07f05
--- /dev/null
+++ b/src/main/java/DataStructure/TaskList.java
@@ -0,0 +1,85 @@
+package DataStructure;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import Controller.Storage;
+import TaskObjects.Task;
+
+public class TaskList {
+
+ private List TaskList;
+
+ public TaskList() {
+ this.TaskList = new ArrayList<>();
+ }
+
+ private static final String LINE_BREAK = "\n__________________________________________\n";
+
+
+ public void load(T task) {
+ this.TaskList.add(task);
+ }
+
+ public void add(T task) {
+ this.TaskList.add(task);
+ Storage.save(this.TaskList);
+
+ System.out.println("Task has been successfully added");
+ System.out.println(task.toString());
+ this.count();
+ }
+
+ public void delete(String ids) {
+ int id = Integer.parseInt(ids);
+ T deleted = this.TaskList.remove(id - 1);
+ Storage.save(this.TaskList);
+
+ System.out.println("Commander, the task has been successfully deleted");
+ System.out.println(deleted.toString());
+ this.count();
+ }
+
+ public void mark(String ids) {
+ int id = Integer.parseInt(ids);
+ this.TaskList.get(id - 1).markDone();
+ Storage.save(this.TaskList);
+
+ System.out.println("Commander, task " + ids + " has been marked completed");
+ System.out.println(TaskList.get(id - 1).toString() + LINE_BREAK);
+ }
+
+ public void unmarked(String ids) {
+ int id = Integer.parseInt(ids);
+ this.TaskList.get(id - 1).markUndone();
+ Storage.save(this.TaskList);
+
+ System.out.println("Commander, taks " + ids + " has been mark incomplete");
+ System.out.println(TaskList.get(id - 1).toString() + LINE_BREAK);
+ }
+
+ public void count() {
+ int count = this.TaskList.size();
+ System.out.println("Commander, you currently have " + count + " tasks" + LINE_BREAK);
+ }
+
+ public void getList() {
+ System.out.println(this.toString() + LINE_BREAK);
+ }
+
+ public String toString() {
+ if (TaskList.isEmpty()) {
+ return "Commander, currently you have no outstanding task";
+ }
+ StringBuilder result = new StringBuilder();
+ int count = 0;
+ for (T command: TaskList) {
+ count++;
+ result.append(count).append(". ").append(command).append("\n");
+ }
+
+ return result.toString();
+ }
+
+}
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/Enums/CommandTypes.java b/src/main/java/Enums/CommandTypes.java
new file mode 100644
index 000000000..339031af3
--- /dev/null
+++ b/src/main/java/Enums/CommandTypes.java
@@ -0,0 +1,25 @@
+package Enums;
+
+public enum CommandTypes {
+ TODO,
+ DEADLINE,
+ EVENT,
+ MARK,
+ UNMARK,
+ LIST,
+ LS,
+ BYE,
+ Q,
+ DELETE,
+ DEL,
+ INVALID;
+
+ // Static method to map a command string to the corresponding enum
+ public static CommandTypes fromString(String command) {
+ try {
+ return CommandTypes.valueOf(command.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ return CommandTypes.INVALID;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/Exception/InvalidInputException.java b/src/main/java/Exception/InvalidInputException.java
new file mode 100644
index 000000000..5dbfba691
--- /dev/null
+++ b/src/main/java/Exception/InvalidInputException.java
@@ -0,0 +1,7 @@
+package Exception;
+
+public class InvalidInputException extends Exception {
+ public InvalidInputException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/main/java/Exception/StorageSyntaxException.java b/src/main/java/Exception/StorageSyntaxException.java
new file mode 100644
index 000000000..36df7cd1d
--- /dev/null
+++ b/src/main/java/Exception/StorageSyntaxException.java
@@ -0,0 +1,8 @@
+package Exception;
+
+public class StorageSyntaxException extends InvalidInputException{
+
+ public StorageSyntaxException() {
+ super("Apologies Commander, there appear to be an issue with the storage file");
+ }
+}
diff --git a/src/main/java/Exception/SyntaxException.java b/src/main/java/Exception/SyntaxException.java
new file mode 100644
index 000000000..9e103e6ae
--- /dev/null
+++ b/src/main/java/Exception/SyntaxException.java
@@ -0,0 +1,7 @@
+package Exception;
+
+public class SyntaxException extends InvalidInputException {
+ public SyntaxException(String type, String style) {
+ super("Apologies Commander, invalid " + type + " format. Please use (" + style + ").");
+ }
+}
diff --git a/src/main/java/Interface/ICommand.java b/src/main/java/Interface/ICommand.java
new file mode 100644
index 000000000..70fdd8383
--- /dev/null
+++ b/src/main/java/Interface/ICommand.java
@@ -0,0 +1,10 @@
+package Interface;
+
+public interface ICommand {
+ public void markDone();
+ public void markUndone();
+ public String toString();
+
+ public String toFileFormat();
+
+}
diff --git a/src/main/java/TaskObjects/Deadline.java b/src/main/java/TaskObjects/Deadline.java
new file mode 100644
index 000000000..b456a25cf
--- /dev/null
+++ b/src/main/java/TaskObjects/Deadline.java
@@ -0,0 +1,27 @@
+package TaskObjects;
+
+import Exception.InvalidInputException;
+
+public class Deadline extends Task {
+
+ private String byWhen;
+
+ public Deadline(String description, boolean isCompleted, String by) throws InvalidInputException {
+ super(description, isCompleted, "D");
+ this.byWhen = by;
+
+ if (description.isBlank() || byWhen.isBlank()) {
+ throw new InvalidInputException("Sorry Commander, but there is missing data");
+ }
+ }
+
+ @Override
+ public String toFileFormat() {
+ return super.toFileFormat() + " | " + this.byWhen;
+ }
+
+ @Override
+ public String toString() {
+ return "[D]" + super.toString() + " (by: " + this.byWhen + ")";
+ }
+}
diff --git a/src/main/java/TaskObjects/Event.java b/src/main/java/TaskObjects/Event.java
new file mode 100644
index 000000000..9a4c6cb3c
--- /dev/null
+++ b/src/main/java/TaskObjects/Event.java
@@ -0,0 +1,28 @@
+package TaskObjects;
+
+import Exception.InvalidInputException;
+public class Event extends Task {
+
+ private String from;
+ private String to;
+
+ public Event (String description, boolean isCompleted , String from, String to) throws InvalidInputException {
+ super(description, isCompleted,"E");
+ this.from = from;
+ this.to = to;
+ if (description.isBlank() || from.isBlank() || to.isBlank()) {
+ throw new InvalidInputException("Sorry Commander, but there is missing data");
+ }
+ }
+
+ @Override
+ public String toFileFormat() {
+ return super.toFileFormat() + " | " + this.from + " | " + this.to;
+ }
+
+ @Override
+ public String toString() {
+ return "[E]" + super.toString() + " (from: " + this.from + " to: " + this.to + ")";
+ }
+
+}
diff --git a/src/main/java/TaskObjects/Task.java b/src/main/java/TaskObjects/Task.java
new file mode 100644
index 000000000..64797d543
--- /dev/null
+++ b/src/main/java/TaskObjects/Task.java
@@ -0,0 +1,44 @@
+package TaskObjects;
+
+import Exception.InvalidInputException;
+import Interface.ICommand;
+
+public abstract class Task implements ICommand {
+
+ private String description = "";
+ private boolean isCompleted;
+ private final String type;
+
+ public Task(String description, boolean isCompleted, String type) throws InvalidInputException {
+ this.description = description;
+ this.isCompleted = isCompleted;
+ this.type = type;
+ if (description == null || type == null) {
+ throw new InvalidInputException("Sorry Commander, but there is missing data");
+ }
+ }
+
+ private String getDescription() {
+ return this.description;
+ }
+ private String getStatus() {
+ return (isCompleted? "X" : " ");
+ }
+
+ public void markDone() {
+ this.isCompleted = true;
+ }
+
+ public void markUndone() {
+ this.isCompleted = false;
+ }
+
+ public String toFileFormat() {
+ return this.type + " | " + this.isCompleted + " | " + this.description;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + this.getStatus() + "] " + this.getDescription();
+ }
+}
diff --git a/src/main/java/TaskObjects/Todo.java b/src/main/java/TaskObjects/Todo.java
new file mode 100644
index 000000000..1f3d0b82b
--- /dev/null
+++ b/src/main/java/TaskObjects/Todo.java
@@ -0,0 +1,14 @@
+package TaskObjects;
+
+import Exception.InvalidInputException;
+public class Todo extends Task {
+
+ public Todo(String description, boolean isCompleted) throws InvalidInputException {
+ super(description, isCompleted,"T");
+ }
+
+ @Override
+ public String toString() {
+ return "[T]" + super.toString();
+ }
+}
diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT
index 657e74f6e..6918e8304 100644
--- a/text-ui-test/EXPECTED.TXT
+++ b/text-ui-test/EXPECTED.TXT
@@ -1,7 +1,83 @@
-Hello from
- ____ _
-| _ \ _ _| | _____
-| | | | | | | |/ / _ \
-| |_| | |_| | < __/
-|____/ \__,_|_|\_\___|
+ ____ ____ _ __ __ ____ __ _
+| _) \ / () \ | |\ \/ // () \ | \| |
+|____//__/\__\|_| |__|/__\/__\|_|\__|
+__________________________________________
+Hello I'm Daiyan
+What can I do for you?
+__________________________________________
+
+How may I assist you commander?
+__________________________________________
+Commander, currently you have no outstanding task
+__________________________________________
+
+Task has been successfully added
+[T][ ] task
+Commander, you currently have 1 tasks
+__________________________________________
+
+Task has been successfully added
+[D][ ] task (by: 1600)
+Commander, you currently have 2 tasks
+__________________________________________
+
+Task has been successfully added
+[E][ ] task (from: 1600 to: 1900)
+Commander, you currently have 3 tasks
+__________________________________________
+
+1. [T][ ] task
+2. [D][ ] task (by: 1600)
+3. [E][ ] task (from: 1600 to: 1900)
+
+__________________________________________
+
+Commander, the task has been successfully deleted
+[T][ ] task
+Commander, you currently have 2 tasks
+__________________________________________
+
+1. [D][ ] task (by: 1600)
+2. [E][ ] task (from: 1600 to: 1900)
+
+__________________________________________
+
+Sorry Commander, but I do not understand your orders.
+__________________________________________
+
+Sorry Commander, but I do not understand your orders.
+__________________________________________
+
+Apologies Commander, invalid mark format. Please use (mark ).
+__________________________________________
+
+Apologies Commander, invalid unmark format. Please use (unmark ).
+__________________________________________
+
+Apologies Commander, invalid delete format. Please use (delete ).
+__________________________________________
+
+Apologies Commander, invalid Todo format. Please use (todo ).
+__________________________________________
+
+Apologies Commander, invalid Deadline format. Please use (deadline /by ).
+__________________________________________
+
+Apologies Commander, invalid Event format. Please use (event /from /to ).
+__________________________________________
+
+Apologies Commander, invalid Event format. Please use (event /from /to ).
+__________________________________________
+
+Apologies Commander, invalid Deadline format. Please use (deadline /by ).
+__________________________________________
+
+Sorry Commander, but there is missing data
+__________________________________________
+
+Sorry Commander, but there is missing data
+__________________________________________
+
+Bye, hope to see you again Commander.
+__________________________________________
diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt
index e69de29bb..7d16fc8e7 100644
--- a/text-ui-test/input.txt
+++ b/text-ui-test/input.txt
@@ -0,0 +1,20 @@
+list
+todo task
+deadline task /by 1600
+event task /from 1600 /to 1900
+list
+delete 1
+ls
+
+abc
+mark
+unmark
+delete
+todo
+deadline
+event
+event qwerty
+deadline qwerty
+deadline /by qwerty
+event test /from /to qwerty
+bye
diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat
index 087374464..5c026cd89 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 Daiyan < input.txt > ACTUAL.TXT
REM compare the output to the expected output
FC ACTUAL.TXT EXPECTED.TXT