diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..f91f64602 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,12 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# Linux start script should use lf +/gradlew text eol=lf + +# These are Windows script files and should use crlf +*.bat text eol=crlf + +# Binary files should be left untouched +*.jar binary + diff --git a/.gitignore b/.gitignore index 2873e189e..a189f150d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,9 @@ bin/ /text-ui-test/ACTUAL.TXT text-ui-test/EXPECTED-UNIX.TXT + +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md deleted file mode 100644 index 8e359a014..000000000 --- a/CONTRIBUTORS.md +++ /dev/null @@ -1,9 +0,0 @@ -# Contributors - -Display | Name | Github Profile | Homepage ----|:---:|:---:|:---: -![](https://avatars0.githubusercontent.com/u/22460123?s=100) | Jeffry Lum | [Github](https://github.com/j-lum/) | [Homepage](https://se.kasugano.moe) -![](https://avatars0.githubusercontent.com/u/1673303?s=100) | Damith C. Rajapakse | [Github](https://github.com/damithc/) | [Homepage](https://www.comp.nus.edu.sg/~damithch/) -# I would like to join this list. How can I help the project - -For more information, please refer to our [contributor's guide](https://oss-generic.github.io/process/). diff --git a/MANIFEST.MF b/MANIFEST.MF new file mode 100644 index 000000000..3871b5b14 --- /dev/null +++ b/MANIFEST.MF @@ -0,0 +1 @@ +Main-Class: AirBorder diff --git a/README.md b/README.md deleted file mode 100644 index 90aa7f092..000000000 --- a/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# 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 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. -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 - ____ _ - | _ \ _ _| | _____ - | | | | | | | |/ / _ \ - | |_| | |_| | < __/ - |____/ \__,_|_|\_\___| - ``` diff --git a/airborder/.gitignore b/airborder/.gitignore new file mode 100644 index 000000000..3ddbf4c44 --- /dev/null +++ b/airborder/.gitignore @@ -0,0 +1,32 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Kotlin ### +.kotlin + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/airborder/.idea/.gitignore b/airborder/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/airborder/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/airborder/.idea/codeStyles/Project.xml b/airborder/.idea/codeStyles/Project.xml new file mode 100644 index 000000000..1bec35e57 --- /dev/null +++ b/airborder/.idea/codeStyles/Project.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/airborder/.idea/codeStyles/codeStyleConfig.xml b/airborder/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 000000000..79ee123c2 --- /dev/null +++ b/airborder/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/airborder/.idea/inspectionProfiles/Project_Default.xml b/airborder/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..df543e3a3 --- /dev/null +++ b/airborder/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/airborder/.idea/kotlinc.xml b/airborder/.idea/kotlinc.xml new file mode 100644 index 000000000..8226e5387 --- /dev/null +++ b/airborder/.idea/kotlinc.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/airborder/.idea/libraries/KotlinJavaRuntime.xml b/airborder/.idea/libraries/KotlinJavaRuntime.xml new file mode 100644 index 000000000..d39de7615 --- /dev/null +++ b/airborder/.idea/libraries/KotlinJavaRuntime.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/airborder/.idea/misc.xml b/airborder/.idea/misc.xml new file mode 100644 index 000000000..31e1ebce6 --- /dev/null +++ b/airborder/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/airborder/.idea/modules.xml b/airborder/.idea/modules.xml new file mode 100644 index 000000000..5647397e2 --- /dev/null +++ b/airborder/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/airborder/.idea/vcs.xml b/airborder/.idea/vcs.xml new file mode 100644 index 000000000..6c0b86358 --- /dev/null +++ b/airborder/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/data/.txt b/data/.txt new file mode 100644 index 000000000..ba96d8d62 --- /dev/null +++ b/data/.txt @@ -0,0 +1 @@ +[ToDo] fly (Done) diff --git a/data/tasks.txt b/data/tasks.txt new file mode 100644 index 000000000..2b0d3a353 --- /dev/null +++ b/data/tasks.txt @@ -0,0 +1,2 @@ +[D][ ] submit report (by: 2024-10=31) +[E][ ] project meeting (from: 2023 to: 2025) diff --git a/docs/README.md b/docs/README.md index 47b9f984f..c9e80ac74 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,30 +1,112 @@ -# Duke User Guide +# AirBorder User Guide -// Update the title above to match the actual product name +Welcome to AirBorder, a sophisticated customer service chatbot designed to streamline your international air travel experience. This guide provides comprehensive instructions on using all functionalities of AirBorder. -// Product screenshot goes here +## Table of Contents -// Product intro goes here +- [Getting Started](#getting-started) +- [Features](#features) + - [Adding Tasks](#adding-tasks) + - [Listing Tasks](#listing-tasks) + - [Marking and Unmarking Tasks](#marking-and-unmarking-tasks) + - [Deleting Tasks](#deleting-tasks) + - [Finding Tasks](#finding-tasks) + - [Exiting the Program](#exiting-the-program) +- [Command Summary](#command-summary) +- [FAQ](#faq) +- [Support](#support) -## Adding deadlines +## Getting Started -// Describe the action and its outcome. +To use AirBorder, ensure that you have Java 17 or newer installed on your computer. Download the latest version of AirBorder from the releases page, and run it using the following command in your terminal: -// Give examples of usage +```bash +java -jar main.jar +``` + +## Features + +### Adding Tasks + +AirBorder supports three types of tasks: + +- **ToDo**: Adds a task without a specific due date. + ``` + todo Apply for ETA at gov.uk + ``` +- **Deadline**: Adds a task that needs to be completed by a specific date. + ``` + deadline Check in closes by 2024-12-31 18:00 + ``` +- **Event**: Adds an event with a start and end date. + ``` + event Traveldoc validity from 2024-10-15 to 2034-10-14 + ``` + +### Listing Tasks + +To view all your tasks in a list: +``` +list +``` + +### Marking and Unmarking Tasks + +To mark a task as completed: +``` +mark 1 +``` -Example: `keyword (optional arguments)` +To mark the task as not completed: +``` +unmark 1 +``` -// A description of the expected outcome goes here +### Deleting Tasks +To remove a task from your list: ``` -expected output +delete 1 ``` -## Feature ABC +### Finding Tasks + +To find tasks containing specific keywords: +``` +find ETA +``` + +### Exiting the Program + +To exit AirBorder: +``` +exit +``` + +## Command Summary + +| Command | Description | Example | +|-----------------------------------------------|------------------------------------------------|------------------------------------------------| +| `todo DESCRIPTION` | Adds a todo task | `Apply for ETA at gov.uk` | +| `deadline DESCRIPTION by DATE` | Adds a task with a deadline | `deadline ` | +| `event DESCRIPTION from START_DATE to END_DATE` | Adds an event | `Traveldoc validity from 2024-10-15 to 2034-10-14` | +| `list` | Displays all tasks | `list` | +| `mark INDEX` | Marks the specified task as done | `mark 1` | +| `unmark INDEX` | Marks the specified task as not done | `unmark 1` | +| `delete INDEX` | Deletes the specified task | `delete 1` | +| `find KEYWORD` | Finds tasks containing the keyword | `find ETA` | +| `exit` | Exits the program | `exit` | + +## FAQ + +**Q: Can AirBorder handle recurring tasks?** +A: Currently, AirBorder does not support recurring tasks. Each task must be entered manually. -// Feature details +**Q: What date formats does AirBorder accept?** +A: AirBorder accepts dates in YYYY-MM-DD format. Please ensure you adhere to this format to avoid any errors. +## Support -## Feature XYZ +For support or further assistance, please email us at support@airborder.com or visit our GitHub repository to open an issue. -// Feature details \ No newline at end of file +Thank you for choosing AirBorder for your international travel needs! diff --git a/src/MANIFEST.MF b/src/MANIFEST.MF new file mode 100644 index 000000000..3871b5b14 --- /dev/null +++ b/src/MANIFEST.MF @@ -0,0 +1 @@ +Main-Class: AirBorder diff --git a/src/main/MANIFEST.MF b/src/main/MANIFEST.MF new file mode 100644 index 000000000..3871b5b14 --- /dev/null +++ b/src/main/MANIFEST.MF @@ -0,0 +1 @@ +Main-Class: AirBorder diff --git a/src/main/java/.idea/.gitignore b/src/main/java/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/src/main/java/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/src/main/java/.idea/artifacts/main_jar.xml b/src/main/java/.idea/artifacts/main_jar.xml new file mode 100644 index 000000000..f10e6571d --- /dev/null +++ b/src/main/java/.idea/artifacts/main_jar.xml @@ -0,0 +1,10 @@ + + + $PROJECT_DIR$/out/artifacts/main_jar + + + + + + + \ No newline at end of file diff --git a/src/main/java/.idea/libraries/airborder.xml b/src/main/java/.idea/libraries/airborder.xml new file mode 100644 index 000000000..e814387f4 --- /dev/null +++ b/src/main/java/.idea/libraries/airborder.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/.idea/misc.xml b/src/main/java/.idea/misc.xml new file mode 100644 index 000000000..07115cdf1 --- /dev/null +++ b/src/main/java/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/.idea/modules.xml b/src/main/java/.idea/modules.xml new file mode 100644 index 000000000..122a9054e --- /dev/null +++ b/src/main/java/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/java/.idea/vcs.xml b/src/main/java/.idea/vcs.xml new file mode 100644 index 000000000..c2365ab11 --- /dev/null +++ b/src/main/java/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/AirBorder.java b/src/main/java/AirBorder.java new file mode 100644 index 000000000..f85b07a89 --- /dev/null +++ b/src/main/java/AirBorder.java @@ -0,0 +1,160 @@ +import java.io.IOException; +import java.util.regex.Pattern; +import java.util.ArrayList; + +/** + * Main application class that orchestrates the running of the AirBorder task manager. + */ +public class AirBorder { + private final Ui ui; + private final Storage storage; + + /** + * Initializes the application by setting up the user interface and storage. + */ + public AirBorder() { + ui = new Ui(); + storage = new Storage("./data/tasks.txt"); + + } + + /** + * Starts the application and remains in the command processing loop until 'exit' command is issued. + */ + public void run() { + ui.showWelcomeMessage(); + boolean exit = false; + while (!exit) { + String command = ui.readCommand(); + try { + exit = processCommand(command); + } catch (Exception e) { + ui.showError("An error occurred: " + e.getMessage()); + } + } + ui.showExitMessage(); + ui.close(); + } + + /** + * Processes user commands. + * + * @param command The command string entered by the user. + * @return true if the command is "exit", signaling the end of the application run. + */ + private boolean processCommand(String command) throws IOException { + // Trim and convert the entire command to lower case for uniform processing + command = command.trim().toLowerCase(); + String[] parts = command.split("\\s+", 2); // Split by spaces, limiting to two parts + String commandWord = parts[0]; + String arguments = parts.length > 1 ? parts[1] : ""; + + try { + switch (commandWord) { + case "todo": + case "deadline": + case "event": + handleTaskCommand(commandWord, arguments); + break; + case "list": + ui.showTaskList(); // Directly calls Task.getAllTasks() internally + break; + case "delete": + handleDeleteCommand(arguments); + break; + case "mark": + case "unmark": + handleMarkCommand(commandWord, arguments); + break; + case "find": + ArrayList foundTasks = Task.findTasks(arguments); + ui.showFoundTasks(foundTasks); + break; + case "exit": + return true; // Signal to exit the application + default: + throw new IllegalArgumentException("Unrecognized command! Please try again."); + } + } catch (IllegalArgumentException e) { + ui.showError(e.getMessage()); + } + return false; // Continue running unless "exit" command is issued + } + + /** + * Handles adding tasks based on command type. + * + * @param type The type of task command (todo, deadline, event). + * @param description Description and possibly date information for the task. + */ + + private String[] parseCommandDetails(String description, String keyword) throws IllegalArgumentException { + // Using a regex that handles multiple spaces and is case-insensitive for the keyword + String[] parts = description.split("\\s+" + Pattern.quote(keyword) + "\\s+", 2); + if (parts.length < 2) { + throw new IllegalArgumentException("Error: Missing '" + keyword + "' with required details."); + } + return parts; + } + + private void handleTaskCommand(String type, String description) throws IOException { + Task newTask = null; + try { + switch (type) { + case "todo": + newTask = new ToDo(description); + break; + case "deadline": + // Ensure we use "by" as the keyword for deadlines + String[] deadlineParts = parseCommandDetails(description, "by"); + newTask = new Deadline(deadlineParts[0], deadlineParts[1]); + break; + case "event": + // Parsing description for event with "from" and "to" + String[] eventDescriptionParts = parseCommandDetails(description, "from"); + String[] eventTimeParts = parseCommandDetails(eventDescriptionParts[1], "to"); + newTask = new Event(eventDescriptionParts[0], eventTimeParts[0], eventTimeParts[1]); + break; + } + Task.addTask(newTask); + storage.save(Task.getAllTasks()); + ui.showTaskAdded(newTask); + } catch (IllegalArgumentException e) { + ui.showError(e.getMessage()); + } + } + + /** + * Handles the deletion of a task. + * + * @param indexStr The index string of the task to delete. + */ + private void handleDeleteCommand(String indexStr) throws IOException { + int index = Integer.parseInt(indexStr.trim()) - 1; + Task removedTask = Task.deleteTask(index); + storage.save(Task.getAllTasks()); + ui.showTaskDeleted(removedTask); + } + + /** + * Handles marking a task as done or not done. + * + * @param commandWord The command word (mark or unmark). + * @param indexStr The index string of the task to update. + */ + private void handleMarkCommand(String commandWord, String indexStr) throws IOException { + int index = Integer.parseInt(indexStr.trim()) - 1; + Task task = Task.getTask(index); + if (commandWord.equals("mark")) { + task.markAsDone(); + } else { + task.markAsNotDone(); + } + storage.save(Task.getAllTasks()); + ui.showTaskUpdated(task); + } + + public static void main(String[] args) { + new AirBorder().run(); + } +} 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/MANIFEST.MF b/src/main/java/MANIFEST.MF new file mode 100644 index 000000000..3871b5b14 --- /dev/null +++ b/src/main/java/MANIFEST.MF @@ -0,0 +1 @@ +Main-Class: AirBorder diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..275e4d989 --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: AirBorder + diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 000000000..0326a5382 --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,103 @@ +import java.io.IOException; +import java.io.FileWriter; +import java.io.FileReader; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.Files; +import java.util.ArrayList; + +/** + * Handles loading and saving tasks to and from a file. + */ +public class Storage { + private final Path path; + + /** + * Constructs a Storage object that manages the file used to store task data. + * @param filepath Path to the file used for storing task data. + */ + public Storage(String filepath) { + this.path = Paths.get(filepath).toAbsolutePath().normalize(); + ensureDirectoryExists(path.getParent()); + } + + /** + * Ensures that the directory for the storage file exists. + * @param directoryPath Path to the directory to check and create if needed. + */ + private void ensureDirectoryExists(Path directoryPath) { + try { + Files.createDirectories(directoryPath); + } catch (IOException e) { + System.err.println("Error creating storage directory: " + e.getMessage()); + } + } + + /** + * Loads tasks from the file into an ArrayList. + * @return ArrayList containing all loaded tasks. + * @throws IOException If an I/O error occurs reading from the file. + */ + public ArrayList load() throws IOException { + ArrayList tasks = new ArrayList<>(); + if (Files.exists(path)) { + try (BufferedReader reader = Files.newBufferedReader(path)) { + String line; + while ((line = reader.readLine()) != null) { + Task task = parseTask(line); + if (task != null) tasks.add(task); + } + } + } + return tasks; + } + + /** + * Saves the list of tasks to the file. + * @param tasks ArrayList of Task objects to save. + * @throws IOException If an I/O error occurs writing to the file. + */ + public void save(ArrayList tasks) throws IOException { + try (BufferedWriter writer = Files.newBufferedWriter(path)) { + for (Task task : tasks) { + writer.write(task.toString() + System.lineSeparator()); + } + } + } + + /** + * Parses a line from the storage file into a Task object. + * @param line The line from the file to parse. + * @return The Task object represented by the line, or null if the line is invalid. + */ + private Task parseTask(String line) { + String[] parts = line.split(" \\| "); + if (parts.length < 3) return null; // Basic validation to ensure data integrity + String type = parts[0].trim(); // 'T', 'D', or 'E' indicating the task type + boolean isDone = parts[1].trim().equals("1"); // '1' if done, '0' otherwise + String description = parts[2].trim(); + Task task = null; + switch (type) { + case "T": + task = new ToDo(description); + break; + case "D": + if (parts.length < 4) return null; // Ensure there's a deadline part + String deadline = parts[3].trim(); + task = new Deadline(description, deadline); + break; + case "E": + if (parts.length < 5) return null; // Ensure there are start and end times + String startTime = parts[3].trim(); + String endTime = parts[4].trim(); + task = new Event(description, startTime, endTime); + break; + default: + return null; // Invalid task type + } + if (isDone) { + task.markAsDone(); // Set the task as done if it was stored as done + } + return task; + } +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 000000000..3ac647b66 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,194 @@ +import java.util.ArrayList; + +/** + * Abstract class representing the general form of a task. + */ +public abstract class Task { + protected String description; + protected boolean isDone; + + /** + * Constructor for creating a new Task. + * + * @param description The description of the task. + */ + public Task(String description) { + this.description = description; + this.isDone = false; + } + + /** + * Gets the specific type of the task. + * + * @return A string representing the type of the task. + */ + public abstract String getTaskType(); + + /** + * Gets the status icon indicating whether the task is done. + * + * @return A string ("X" or " ") indicating the completion status of the task. + */ + public String getStatusIcon() { + return isDone ? "X" : " "; + } + + /** + * Marks the task as done. + */ + public void markAsDone() { + isDone = true; + } + + /** + * Marks the task as not done. + */ + public void markAsNotDone() { + isDone = false; + } + + /** + * Returns a string representation of the task, showing its type, status, and description. + * + * @return A formatted string of the task details. + */ + @Override + public String toString() { + return "[" + getTaskType() + "][" + getStatusIcon() + "] " + description; + } + + // Static methods and fields for task list management + private static final ArrayList tasks = new ArrayList<>(); + + /** + * Searches for tasks containing the specified keyword in their descriptions. + * + * @param keyword The keyword to search for in the task descriptions. + * @return An ArrayList of tasks that contain the keyword in their descriptions. + */ + public static ArrayList findTasks(String keyword) { + ArrayList foundTasks = new ArrayList<>(); + for (Task task : tasks) { + if (task.description.toLowerCase().contains(keyword.toLowerCase())) { + foundTasks.add(task); + } + } + return foundTasks; + } + + /** + * Adds a task to the static task list. + * + * @param task The task to be added. + */ + public static void addTask(Task task) { + tasks.add(task); + } + + /** + * Deletes a task from the static task list by index. + * + * @param index The index of the task to delete. + * @return The removed task. + */ + public static Task deleteTask(int index) { + return tasks.remove(index); + } + + /** + * Gets a task from the static task list by index. + * + * @param index The index of the task to retrieve. + * @return The retrieved task. + */ + public static Task getTask(int index) { + return tasks.get(index); + } + + /** + * Returns all tasks in the static task list. + * + * @return An ArrayList of all tasks. + */ + public static ArrayList getAllTasks() { + return tasks; + } + + /** + * Returns the number of tasks in the static task list. + * + * @return The size of the task list. + */ + public static int size() { + return tasks.size(); + } + + /** + * Checks if the static task list is empty. + * + * @return true if the list is empty, false otherwise. + */ + public static boolean isEmpty() { + return tasks.isEmpty(); + } +} + +/** + * Represents a task without any date/time attached to it. + */ +class ToDo extends Task { + public ToDo(String description) { + super(description); + } + + @Override + public String getTaskType() { + return "T"; + } +} + +/** + * Represents a task that needs to be completed before a specific date/time. + */ +class Deadline extends Task { + private final String by; + + public Deadline(String description, String by) { + super(description); + this.by = by; + } + + @Override + public String getTaskType() { + return "D"; + } + + @Override + public String toString() { + return super.toString() + " (by: " + by + ")"; + } +} + +/** + * Represents an event that starts and ends at specific times. + */ +class Event extends Task { + private final String from; + private final String to; + + public Event(String description, String from, String to) { + super(description); + this.from = from; + this.to = to; + } + + @Override + public String getTaskType() { + return "E"; + } + + @Override + public String toString() { + return super.toString() + " (from: " + from + " to: " + to + ")"; + } +} diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 000000000..c00ebd450 --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,129 @@ +import java.util.Scanner; +import java.util.ArrayList; +/** + * Handles all user interface operations, including displaying messages and reading user input. + */ +public class Ui { + private final Scanner scanner; + + /** + * Initializes the user interface by setting up the scanner used for input. + */ + public Ui() { + this.scanner = new Scanner(System.in); + } + + /** + * Displays a welcome message at the start of the application. + */ + public void showWelcomeMessage() { + System.out.println("____________________________________________________________"); + System.out.println(" Welcome aboard AirBorder."); + System.out.println(" Ready to assist you with your travel needs!"); + System.out.println("____________________________________________________________"); + } + + /** + * Displays a line separator for better readability in the command line interface. + */ + public void showLine() { + System.out.println("____________________________________________________________"); + } + + /** + * Shows tasks currently on the list. + */ + public void showTaskList() { + System.out.println("____________________________________________________________"); + if (Task.isEmpty()) { + System.out.println(" No tasks to show."); + } else { + System.out.println(" Here are the tasks in your list:"); + for (int i = 0; i < Task.size(); i++) { + System.out.println((i + 1) + ". " + Task.getTask(i)); + } + } + System.out.println("____________________________________________________________"); + } + + /** + * Displays a message indicating successful addition of a task. + * + * @param task The task that was added. + */ + public void showTaskAdded(Task task) { + System.out.println("____________________________________________________________"); + System.out.println(" Got it. I've added this task:"); + System.out.println(" " + task); + System.out.println(" Now you have " + Task.size() + " tasks in the list."); + System.out.println("____________________________________________________________"); + } + + /** + * Displays a message when a task is successfully deleted. + * + * @param removedTask The task that was removed. + */ + public void showTaskDeleted(Task removedTask) { + System.out.println("____________________________________________________________"); + System.out.println(" Noted. I've removed this task:"); + System.out.println(" " + removedTask); + System.out.println(" Now you have " + Task.size() + " tasks in the list."); + System.out.println("____________________________________________________________"); + } + + public void showTaskUpdated(Task task) { + System.out.println("____________________________________________________________"); + System.out.println(" Noted. I've updated this task:"); + System.out.println(" " + task); + System.out.println("____________________________________________________________"); + } + + /** + * Displays the tasks found based on the search criteria. + * + * @param foundTasks The list of tasks that matched the search criteria. + */ +public void showFoundTasks(ArrayList foundTasks) { + if (foundTasks.isEmpty()) { + System.out.println("No tasks found with your search criteria."); + } else { + System.out.println("Here are the matching tasks in your list:"); + for (int i = 0; i < foundTasks.size(); i++) { + System.out.println((i + 1) + ". " + foundTasks.get(i)); + } + } +} + + + /** + * Displays an error message. + * + * @param message The error message to display. + */ + public void showError(String message) { + System.out.println(" ERROR: " + message); + } + + /** + * Displays a goodbye message when the application is closing. + */ + public void showExitMessage() { + System.out.println(" Bye. Hope to see you across the border for your on-ground needs/connections!"); + } + + /** + * Closes the scanner object and any other resources used for user interaction. + */ + public void close() { + scanner.close(); + } + + /** + * Reads a command from the user. + * @return The command input by the user. + */ + public String readCommand() { + return scanner.nextLine().trim(); + } +} diff --git a/src/main/java/data/tasks.txt b/src/main/java/data/tasks.txt new file mode 100644 index 000000000..9d258f75e --- /dev/null +++ b/src/main/java/data/tasks.txt @@ -0,0 +1 @@ +[D][ ] something (by: 3) diff --git a/src/main/java/out/.idea/.gitignore b/src/main/java/out/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/src/main/java/out/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/src/main/java/out/.idea/libraries/airborder.xml b/src/main/java/out/.idea/libraries/airborder.xml new file mode 100644 index 000000000..289005f41 --- /dev/null +++ b/src/main/java/out/.idea/libraries/airborder.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/out/.idea/misc.xml b/src/main/java/out/.idea/misc.xml new file mode 100644 index 000000000..31e1ebce6 --- /dev/null +++ b/src/main/java/out/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/out/.idea/modules.xml b/src/main/java/out/.idea/modules.xml new file mode 100644 index 000000000..6d6886dab --- /dev/null +++ b/src/main/java/out/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/java/out/.idea/vcs.xml b/src/main/java/out/.idea/vcs.xml new file mode 100644 index 000000000..4fce1d86b --- /dev/null +++ b/src/main/java/out/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/out/AirBorder.class b/src/main/java/out/AirBorder.class new file mode 100644 index 000000000..13850524f Binary files /dev/null and b/src/main/java/out/AirBorder.class differ diff --git a/src/main/java/out/Deadline.class b/src/main/java/out/Deadline.class new file mode 100644 index 000000000..9108a8b7f Binary files /dev/null and b/src/main/java/out/Deadline.class differ diff --git a/src/main/java/out/Event.class b/src/main/java/out/Event.class new file mode 100644 index 000000000..4352356a7 Binary files /dev/null and b/src/main/java/out/Event.class differ diff --git a/src/main/java/out/MANIFEST.MF b/src/main/java/out/MANIFEST.MF new file mode 100644 index 000000000..3871b5b14 --- /dev/null +++ b/src/main/java/out/MANIFEST.MF @@ -0,0 +1 @@ +Main-Class: AirBorder diff --git a/src/main/java/out/Storage.class b/src/main/java/out/Storage.class new file mode 100644 index 000000000..26644912d Binary files /dev/null and b/src/main/java/out/Storage.class differ diff --git a/src/main/java/out/Task.class b/src/main/java/out/Task.class new file mode 100644 index 000000000..e6c09731f Binary files /dev/null and b/src/main/java/out/Task.class differ diff --git a/src/main/java/out/ToDo.class b/src/main/java/out/ToDo.class new file mode 100644 index 000000000..6dbe99b32 Binary files /dev/null and b/src/main/java/out/ToDo.class differ diff --git a/src/main/java/out/Ui.class b/src/main/java/out/Ui.class new file mode 100644 index 000000000..2069209eb Binary files /dev/null and b/src/main/java/out/Ui.class differ diff --git a/src/main/java/out/airborder.jar b/src/main/java/out/airborder.jar new file mode 100644 index 000000000..a2054e5f9 Binary files /dev/null and b/src/main/java/out/airborder.jar differ diff --git a/src/main/java/out/artifacts/main_jar/data/tasks.txt b/src/main/java/out/artifacts/main_jar/data/tasks.txt new file mode 100644 index 000000000..f1f9351ff --- /dev/null +++ b/src/main/java/out/artifacts/main_jar/data/tasks.txt @@ -0,0 +1 @@ +[D][ ] c (by: 3) diff --git a/src/main/java/out/artifacts/main_jar/main.jar b/src/main/java/out/artifacts/main_jar/main.jar new file mode 100644 index 000000000..bc2a904fc Binary files /dev/null and b/src/main/java/out/artifacts/main_jar/main.jar differ diff --git a/src/main/java/out/data/tasks.txt b/src/main/java/out/data/tasks.txt new file mode 100644 index 000000000..06abd4271 --- /dev/null +++ b/src/main/java/out/data/tasks.txt @@ -0,0 +1 @@ +[T][ ] 1 diff --git a/src/main/java/out/production/main/.idea/.gitignore b/src/main/java/out/production/main/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/src/main/java/out/production/main/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/src/main/java/out/production/main/.idea/artifacts/main_jar.xml b/src/main/java/out/production/main/.idea/artifacts/main_jar.xml new file mode 100644 index 000000000..f10e6571d --- /dev/null +++ b/src/main/java/out/production/main/.idea/artifacts/main_jar.xml @@ -0,0 +1,10 @@ + + + $PROJECT_DIR$/out/artifacts/main_jar + + + + + + + \ No newline at end of file diff --git a/src/main/java/out/production/main/.idea/libraries/airborder.xml b/src/main/java/out/production/main/.idea/libraries/airborder.xml new file mode 100644 index 000000000..e814387f4 --- /dev/null +++ b/src/main/java/out/production/main/.idea/libraries/airborder.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/out/production/main/.idea/misc.xml b/src/main/java/out/production/main/.idea/misc.xml new file mode 100644 index 000000000..07115cdf1 --- /dev/null +++ b/src/main/java/out/production/main/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/out/production/main/.idea/modules.xml b/src/main/java/out/production/main/.idea/modules.xml new file mode 100644 index 000000000..122a9054e --- /dev/null +++ b/src/main/java/out/production/main/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/java/out/production/main/.idea/vcs.xml b/src/main/java/out/production/main/.idea/vcs.xml new file mode 100644 index 000000000..c2365ab11 --- /dev/null +++ b/src/main/java/out/production/main/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/out/production/main/AirBorder.class b/src/main/java/out/production/main/AirBorder.class new file mode 100644 index 000000000..722c1eca5 Binary files /dev/null and b/src/main/java/out/production/main/AirBorder.class differ diff --git a/src/main/java/out/production/main/Deadline.class b/src/main/java/out/production/main/Deadline.class new file mode 100644 index 000000000..93d16f640 Binary files /dev/null and b/src/main/java/out/production/main/Deadline.class differ diff --git a/src/main/java/out/production/main/Event.class b/src/main/java/out/production/main/Event.class new file mode 100644 index 000000000..3f5b428eb Binary files /dev/null and b/src/main/java/out/production/main/Event.class differ diff --git a/src/main/java/out/production/main/MANIFEST.MF b/src/main/java/out/production/main/MANIFEST.MF new file mode 100644 index 000000000..3871b5b14 --- /dev/null +++ b/src/main/java/out/production/main/MANIFEST.MF @@ -0,0 +1 @@ +Main-Class: AirBorder diff --git a/src/main/java/out/production/main/META-INF/MANIFEST.MF b/src/main/java/out/production/main/META-INF/MANIFEST.MF new file mode 100644 index 000000000..275e4d989 --- /dev/null +++ b/src/main/java/out/production/main/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: AirBorder + diff --git a/src/main/java/out/production/main/Storage.class b/src/main/java/out/production/main/Storage.class new file mode 100644 index 000000000..2b214ea20 Binary files /dev/null and b/src/main/java/out/production/main/Storage.class differ diff --git a/src/main/java/out/production/main/Task.class b/src/main/java/out/production/main/Task.class new file mode 100644 index 000000000..6689b378e Binary files /dev/null and b/src/main/java/out/production/main/Task.class differ diff --git a/src/main/java/out/production/main/ToDo.class b/src/main/java/out/production/main/ToDo.class new file mode 100644 index 000000000..c38a7e23b Binary files /dev/null and b/src/main/java/out/production/main/ToDo.class differ diff --git a/src/main/java/out/production/main/Ui.class b/src/main/java/out/production/main/Ui.class new file mode 100644 index 000000000..baf6c0bdc Binary files /dev/null and b/src/main/java/out/production/main/Ui.class differ diff --git a/src/main/java/out/production/main/data/tasks.txt b/src/main/java/out/production/main/data/tasks.txt new file mode 100644 index 000000000..687490eb6 --- /dev/null +++ b/src/main/java/out/production/main/data/tasks.txt @@ -0,0 +1 @@ +[E][ ] traveldoc validity (from: 2024-10-15 to: 2034-10-14) diff --git a/src/main/java/out/production/main/tasks.txt b/src/main/java/out/production/main/tasks.txt new file mode 100644 index 000000000..9b9cd9e93 --- /dev/null +++ b/src/main/java/out/production/main/tasks.txt @@ -0,0 +1,2 @@ +T | 0 | Read book +D | 0 | Submit assignment | Friday diff --git a/src/main/java/tasks.txt b/src/main/java/tasks.txt new file mode 100644 index 000000000..9b9cd9e93 --- /dev/null +++ b/src/main/java/tasks.txt @@ -0,0 +1,2 @@ +T | 0 | Read book +D | 0 | Submit assignment | Friday