diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 296d262..5bdb560 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -2,8 +2,9 @@ \ No newline at end of file diff --git a/FEATURES.md b/FEATURES.md index 3cff608..0a498f5 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -5,13 +5,14 @@ - Persistence ## Section 2: Headlining Features - +- Task Queue +- Themes +- Menu bar ## Section 3: Power Ups - - -## Section 3: Power Ups - +- Quotes & Notes +- Progress Bar +- Sort By Name & Description ## Section 4: Quality of Life diff --git a/PA05_UML_Diagram.drawio.png b/PA05_UML_Diagram.drawio.png new file mode 100644 index 0000000..d3e84bd Binary files /dev/null and b/PA05_UML_Diagram.drawio.png differ diff --git a/README.md b/README.md index 91646fe..b14fec4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,28 @@ -# 3500 PA05 Project Repo +Java Journal! +This bullet journal program allows you to write and save task and events for a week. +You can save these to a file for later. This journa also supports adding a limit for how many +tasks you can have in a day. This is a great way to keep track of your tasks and events for the week! -[PA Write Up](https://markefontenot.notion.site/PA-05-8263d28a81a7473d8372c6579abd6481) +GUI: + +- https://ibb.co/Qk6m2nH + +SOLID Principles: + +- Single Responsibility Principle: Each class is only responsible for a single job in the bullet + journal. +- Open/Closed Principle: The controller class and its supporting model classes are open for + extension but closed for modification. This is because the Journal class can be extended to + add more functionality, but the classes do not need to be modified to add more functionality. +- Liskov Substitution Principle: This application makes use of an abstract "Commitment" class. + This allows for the use of the "Commitment" class to be used in place of its subclasses. +- Interface Segregation Principle: Interfaces and classes in this BuJo project contain only the methods + that they require to function. +- Dependency Inversion Principle: The controller class is injected with the Week that it displays. + This allows for the controller to be independent of the Week class. + +Possible Extensions: + +- With my "initButton" method in the controller class, we could add a popup that allows a user to + enter a quote to be saves on the main screen. This popup would save its data to the Week class, + where it would be persisted. \ No newline at end of file diff --git a/build.gradle b/build.gradle index 27b9ec9..73b1af5 100644 --- a/build.gradle +++ b/build.gradle @@ -47,13 +47,14 @@ javafx { dependencies { // Jackson - implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.15.1' - + implementation("com.fasterxml.jackson.core:jackson-databind:2.15.0") + // JavaFX implementation('org.controlsfx:controlsfx:11.1.2') // JUnit testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' + testImplementation 'junit:junit:4.13.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' // TestFX diff --git a/pa05_sketch_sections123.png b/pa05_sketch_sections123.png new file mode 100644 index 0000000..083e687 Binary files /dev/null and b/pa05_sketch_sections123.png differ diff --git a/src/main/java/cs3500/pa05/Driver.java b/src/main/java/cs3500/pa05/Driver.java new file mode 100644 index 0000000..7250a25 --- /dev/null +++ b/src/main/java/cs3500/pa05/Driver.java @@ -0,0 +1,52 @@ +package cs3500.pa05; + +import cs3500.pa05.controller.BujoController; +import cs3500.pa05.model.Week; +import cs3500.pa05.view.BujoView; +import javafx.application.Application; +import javafx.scene.Scene; +import javafx.stage.Stage; + +/** + * Represents a Java Bullet Journal game application + */ +public class Driver extends Application { + + /** + * Starts the GUI for a game of Java Bullet Journal and initialized the module, + * view and controller + * + * @param stage the JavaFX stage to add elements to + */ + @Override + public void start(Stage stage) { + stage.setTitle("Bullet Journal!"); + + // instantiate a simple welcome GUI view + Week week = new Week(); + BujoController controller = new BujoController(week, stage); + BujoView view = new BujoView(controller); + + try { + // load and place the view's scene onto the stage + Scene scene = view.load(); + stage.setScene(scene); + + controller.run(); + + // render the stage + stage.show(); + } catch (IllegalStateException exc) { + System.err.println("Unable to load GUI."); + } + } + + /** + * Entry point for a game of Java Bullet Journal + * + * @param args the command line arguments (unused) + */ + public static void main(String[] args) { + launch(); + } +} diff --git a/src/main/java/cs3500/pa05/controller/BujoController.java b/src/main/java/cs3500/pa05/controller/BujoController.java new file mode 100644 index 0000000..b1e68fd --- /dev/null +++ b/src/main/java/cs3500/pa05/controller/BujoController.java @@ -0,0 +1,388 @@ +package cs3500.pa05.controller; + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import cs3500.pa05.model.BujoFileWriter; +import cs3500.pa05.model.Day; +import cs3500.pa05.model.Event; +import cs3500.pa05.model.Task; +import cs3500.pa05.model.Time; +import cs3500.pa05.model.Week; +import cs3500.pa05.model.WeekJson; +import cs3500.pa05.view.BujoView; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Scanner; +import javafx.fxml.FXML; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.MenuButton; +import javafx.scene.control.TextField; +import javafx.scene.layout.VBox; +import javafx.stage.Popup; +import javafx.stage.Stage; + +/** + * Represents a controller for a Java Bullet Journal + */ +public class BujoController { + private Week week; + + private final Stage stage; + + @FXML + private Button taskButton; + + @FXML + private Button eventButton; + + @FXML + private Button openButton; + + @FXML + private Button saveButton; + + @FXML + private TextField monthField; + + @FXML + private TextField weekOfField; + + @FXML + private MenuButton dayTaskBar; + + @FXML + private TextField nameTextField; + + @FXML + private TextField descriptionTextField; + + @FXML + private VBox monday; + + @FXML + private VBox tuesday; + + @FXML + private VBox wednesday; + + @FXML + private VBox thursday; + + @FXML + private VBox friday; + + @FXML + private VBox saturday; + + @FXML + private VBox sunday; + + @FXML + private TextField eventNameTextField; + + @FXML + private TextField eventDescriptionTextField; + + @FXML + private TextField eventStartTimeField; + + @FXML + private TextField eventDurationField; + + @FXML + private TextField eventDayField; + + @FXML + private TextField taskDayField; + + @FXML + private TextField commitEventField; + + @FXML + private TextField commitTaskField; + + private Popup warningPopup; + + private String taskName; + + private String taskDescription; + + private String eventName; + + private String eventDescription; + + private String eventStartTime; + + private String eventDuration; + + private String taskDay; + + private String eventDay; + + private String openFilePath; + + private String saveFilePath; + + @FXML + private TextField savePath; + + @FXML + private TextField loadPath; + + + /** + * Initializes a controller for a Java Bullet Journal. + * + * @param week the week to be displayed + * @param stage the stage to be displayed on + */ + public BujoController(Week week, Stage stage) { + this.week = week; + this.stage = stage; + } + + /** + * Initializes a game of Java Bullet Journal. + */ + public void run() { + + this.warningPopup = new Popup(); + Scene warningScene = new BujoView(this).loadWarn(); + + warningPopup.getContent().add(warningScene.getRoot()); + Button b = new Button("Done!"); + b.setOnAction(e -> warningPopup.hide()); + + warningPopup.getContent().add(b); + + this.commitEventField.setOnKeyTyped(event -> this.week.setMaxEvents(Integer.parseInt( + this.commitEventField.getText()))); + this.commitTaskField.setOnKeyTyped(event -> this.week.setMaxTasks(Integer.parseInt( + this.commitTaskField.getText()))); + + Popup taskPopup = new Popup(); + Scene taskScene = new BujoView(this).loadTask(); + initPopupButton(this.taskButton, taskPopup, taskScene); + + this.nameTextField.setOnKeyTyped( + event -> this.taskName = this.nameTextField.getText()); + this.descriptionTextField.setOnKeyTyped( + event -> this.taskDescription = this.descriptionTextField.getText()); + this.taskDayField.setOnKeyTyped(event -> this.taskDay = this.taskDayField.getText()); + + Popup eventPopup = new Popup(); + Scene eventScene = new BujoView(this).loadEvent(); + initPopupButton(this.eventButton, eventPopup, eventScene); + this.eventNameTextField.setOnKeyTyped( + event -> this.eventName = this.eventNameTextField.getText()); + this.eventDescriptionTextField.setOnKeyTyped( + event -> this.eventDescription = this.eventDescriptionTextField.getText()); + this.eventStartTimeField.setOnKeyTyped( + event -> this.eventStartTime = this.eventStartTimeField.getText()); + this.eventDurationField.setOnKeyTyped(event -> this.eventDuration = this.eventDurationField + .getText()); + this.eventDayField.setOnKeyTyped(event -> this.eventDay = this.eventDayField.getText()); + + + Popup loadFilePopup = new Popup(); + Scene openFileScene = new BujoView(this).loadOpen(); + this.loadPath.setOnKeyTyped(event -> this.openFilePath = this.loadPath.getText()); + + initPopupButton(this.openButton, loadFilePopup, openFileScene); + + Popup saveFilePopup = new Popup(); + Scene saveFileScene = new BujoView(this).loadSave(); + this.savePath.setOnKeyTyped(event -> this.saveFilePath = this.savePath.getText()); + + initPopupButton(this.saveButton, saveFilePopup, saveFileScene); + + this.monthField.setText(this.week.getMonth()); + this.monthField.setOnAction(event -> this.week.setMonth(this.monthField.getText())); + + this.weekOfField.setText(this.week.getWeekOf()); + this.weekOfField.setOnAction(event -> this.week.setMonth(this.monthField.getText())); + + + } + + /** + * Loads a selected .bujo file into a Java Bullet Journal. + */ + private void loadFile(String filename) { + StringBuilder file = new StringBuilder(); + Scanner scanner = null; + try { + scanner = new Scanner(Path.of(filename)); + } catch (IOException e) { + throw new RuntimeException(e); + } + + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + file.append(line); + } + + scanner.close(); + + try { + JsonNode json = new ObjectMapper().readTree(file.toString()); + + WeekJson weekJson = new ObjectMapper().convertValue(json, WeekJson.class); + + this.week = weekJson.toWeek(); + + this.commitEventField.setText(Integer.toString(this.week.getMaxEvents())); + this.commitTaskField.setText(Integer.toString(this.week.getMaxTasks())); + + this.monthField.setText(this.week.getMonth()); + this.weekOfField.setText(this.week.getWeekOf()); + + for (Day day : this.week.getDays()) { + populateDay(day); + } + + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + private void populateDay(Day day) { + for (Event event : day.getEvents()) { + Label eventLabel = new Label(event.toString()); + getVbox(day.getName()).getChildren().add(eventLabel); + } + + for (Task task : day.getTasks()) { + Label taskLabel = new Label(task.toString()); + taskLabel.setOnMouseClicked(event -> handleLabelClick(taskLabel, task)); + getVbox(day.getName()).getChildren().add(taskLabel); + } + } + + /** + * Saves a Java Bullet Journal to a .bujo file. + */ + private void saveFile(String filename) { + BujoFileWriter.writeBujo(this.week, filename); + } + + /** + * Adds a task to a Java Bullet Journal. + */ + private void addTaskFromPopup() { + Day day = this.week.getDays()[Day.getDayIndex(this.taskDay)]; + + if (day.getTasks().size() >= this.week.getMaxTasks()) { + this.warningPopup.show(this.stage); + } + + Task task = new Task(this.taskName, this.taskDescription, day.getName()); + day.addTask(task); + + Label taskLabel = new Label(task.toString()); + taskLabel.setOnMouseClicked(event -> handleLabelClick(taskLabel, task)); + getVbox(this.taskDay).getChildren().add(taskLabel); + } + + /** + * Adds a task to a Java Bullet Journal. + */ + private void addEventFromPopup() { + + Day day = this.week.getDays()[Day.getDayIndex(this.eventDay)]; + + if (day.getEvents().size() >= this.week.getMaxEvents()) { + this.warningPopup.show(this.stage); + } + + int hour = Integer.parseInt(this.eventStartTime.split(":")[0]); + int minute = Integer.parseInt(this.eventStartTime.split(":")[1]); + + Event event = + new Event(this.eventName, this.eventDescription, day.getName(), new Time(hour, minute), + Integer.parseInt(this.eventDuration)); + day.addEvent(event); + + Label eventLabel = new Label(event.toString()); + getVbox(this.eventDay).getChildren().add(eventLabel); + } + + /** + * Handles clicking a task label in a Java Bullet Journal. + */ + private void handleLabelClick(Label taskLabel, Task task) { + task.setComplete(!task.isComplete()); + taskLabel.setText(task.toString()); + } + + /** + * Returns the correct VBox for a given string + * + * @param day the string representing the day + * @return the correct VBox + */ + private VBox getVbox(String day) { + switch (day.toLowerCase()) { + case "monday": + return this.monday; + case "tuesday": + return this.tuesday; + case "wednesday": + return this.wednesday; + case "thursday": + return this.thursday; + case "friday": + return this.friday; + case "saturday": + return this.saturday; + case "sunday": + return this.sunday; + default: + throw new IllegalArgumentException("No such day"); + } + } + + /** + * Initializes the task button in a Java Bullet Journal. + */ + private void initPopupButton(Button button, Popup popup, Scene s) { + button.setOnAction(event -> showPopup(popup)); + + popup.getContent().add(s.getRoot()); + + Button b = new Button("Done!"); + b.setOnAction(e -> popup.hide()); + + popup.getContent().add(b); + popup.setOnHidden(e -> handleHiddenPopup(button)); + } + + /** + * Handles a hidden popup in a Java Bullet Journal. + */ + private void handleHiddenPopup(Button button) { + if (button == this.taskButton) { + addTaskFromPopup(); + } + if (button == this.eventButton) { + addEventFromPopup(); + } + if (button == this.openButton) { + loadFile(this.openFilePath); + } + if (button == this.saveButton) { + saveFile(this.saveFilePath); + } + } + + /** + * Shows a dialog for a task in a Java Bullet Journal. + */ + private void showPopup(Popup popup) { + popup.show(this.stage); + } +} diff --git a/src/main/java/cs3500/pa05/model/BujoFileWriter.java b/src/main/java/cs3500/pa05/model/BujoFileWriter.java new file mode 100644 index 0000000..94dea3f --- /dev/null +++ b/src/main/java/cs3500/pa05/model/BujoFileWriter.java @@ -0,0 +1,68 @@ +package cs3500.pa05.model; + +import com.fasterxml.jackson.databind.JsonNode; +import java.io.FileWriter; +import java.io.IOException; + +/** + * A class that contains methods to write a Bullet Journal to a file. + */ +public class BujoFileWriter { + /** + * Writes a Bullet Journal to a file. + * + * @param week the week to write + * @param path the path to write to + */ + public static void writeBujo(Week week, String path) { + try { + FileWriter myWriter = new FileWriter(path); + myWriter.write(weekToJson(week).toString()); + myWriter.close(); + } catch (IOException e) { + // write failed + } + } + + /** + * Converts a week to a JsonNode. + * + * @param week the week to convert + * @return the JsonNode representing the week + */ + public static JsonNode weekToJson(Week week) { + DayJson[] dayJsons = new DayJson[7]; + Day[] days = week.getDays(); + for (int i = 0; i < 7; i++) { + dayJsons[i] = dayToJson(days[i]); + } + WeekJson weekJson = new WeekJson(dayJsons, week.getMaxTasks(), week.getMaxEvents(), + week.getTheme().toString(), week.getMonth(), week.getWeekOf()); + return JsonUtils.serializeRecord(weekJson); + } + + /** + * Converts a day to a JsonNode. + * + * @param day the day to convert + * @return the JsonNode representing the day + */ + public static DayJson dayToJson(Day day) { + TaskJson[] tasks = new TaskJson[day.getTasks().size()]; + EventJson[] events = new EventJson[day.getEvents().size()]; + + for (Task task : day.getTasks()) { + tasks[day.getTasks().indexOf(task)] = new TaskJson(task.getName(), task.getDescription(), + task.getDay(), task.isComplete()); + } + + for (Event event : day.getEvents()) { + events[day.getEvents().indexOf(event)] = new EventJson(event.getName(), + event.getDescription(), event.getDay(), + new TimeJson(event.getStartTime().getHour(), event.getStartTime().getMinute()), + event.getDuration()); + } + + return new DayJson(day.getName(), tasks, events); + } +} diff --git a/src/main/java/cs3500/pa05/model/Commitment.java b/src/main/java/cs3500/pa05/model/Commitment.java new file mode 100644 index 0000000..f2c279c --- /dev/null +++ b/src/main/java/cs3500/pa05/model/Commitment.java @@ -0,0 +1,62 @@ +package cs3500.pa05.model; + +/** + * Represents a commitment in a day. + */ +public abstract class Commitment { + + /** + * represents the name + */ + public String name; + + /** + * represents the description + */ + public String description; + + /** + * represents a day + */ + public String day; + + /** + * Constructs a commitment with the given name, description, and day. + * + * @param name the commitment's name + * @param description the commitment's description + * @param day the day of the commitment + */ + public Commitment(String name, String description, String day) { + this.name = name; + this.description = description; + this.day = day; + } + + /** + * Returns the name of this commitment. + * + * @return the name of this commitment + */ + public String getName() { + return this.name; + } + + /** + * Returns the description of this commitment. + * + * @return the description of this commitment + */ + public String getDescription() { + return this.description; + } + + /** + * Returns the day of this commitment. + * + * @return the day of this commitment + */ + public String getDay() { + return this.day; + } +} diff --git a/src/main/java/cs3500/pa05/model/Day.java b/src/main/java/cs3500/pa05/model/Day.java new file mode 100644 index 0000000..13d5b00 --- /dev/null +++ b/src/main/java/cs3500/pa05/model/Day.java @@ -0,0 +1,89 @@ +package cs3500.pa05.model; + +import java.util.ArrayList; + +/** + * Represents a day in a week. + */ +public class Day { + private final String name; + + private final ArrayList tasks; + + private final ArrayList events; + + /** + * Constructs a day with the given name. + * + * @param name the day's name + */ + public Day(String name) { + this.name = name; + this.tasks = new ArrayList<>(); + this.events = new ArrayList<>(); + } + + /** + * Returns the name of this day + * + * @return the name of this day + */ + public String getName() { + return this.name; + } + + /** + * Returns this day's tasks. + * + * @return this day's tasks + */ + public ArrayList getTasks() { + return this.tasks; + } + + /** + * Returns this day's events. + * + * @return this day's events + */ + public ArrayList getEvents() { + return this.events; + } + + /** + * Returns the index of this day given its name + * + * @param name of the day + * @return the index of this day given its name + */ + public static int getDayIndex(String name) { + return switch (name.toLowerCase()) { + case "monday" -> 0; + case "tuesday" -> 1; + case "wednesday" -> 2; + case "thursday" -> 3; + case "friday" -> 4; + case "saturday" -> 5; + case "sunday" -> 6; + default -> throw new IllegalArgumentException("No such day"); + }; + } + + /** + * Adds a task to this day + * + * @param task the task + */ + public void addTask(Task task) { + this.tasks.add(task); + } + + /** + * Adds an event to this day + * + * @param event the event + */ + public void addEvent(Event event) { + this.events.add(event); + } +} diff --git a/src/main/java/cs3500/pa05/model/DayJson.java b/src/main/java/cs3500/pa05/model/DayJson.java new file mode 100644 index 0000000..346bc9a --- /dev/null +++ b/src/main/java/cs3500/pa05/model/DayJson.java @@ -0,0 +1,26 @@ +package cs3500.pa05.model; + +import cs3500.pa05.model.Event; +import cs3500.pa05.model.Task; + +/** + * Represents a Json view of a day. + */ +public record DayJson(String name, TaskJson[] tasks, EventJson[] events) { + + /** + * Returns the day represented by this Json + * + * @return the day represented by this Json + */ + public Day toDay() { + Day day = new Day(this.name); + for (TaskJson task : this.tasks) { + day.addTask(task.toTask()); + } + for (EventJson event : this.events) { + day.addEvent(event.toEvent()); + } + return day; + } +} diff --git a/src/main/java/cs3500/pa05/model/Event.java b/src/main/java/cs3500/pa05/model/Event.java new file mode 100644 index 0000000..eb0f548 --- /dev/null +++ b/src/main/java/cs3500/pa05/model/Event.java @@ -0,0 +1,60 @@ +package cs3500.pa05.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents in an event in a day. + */ +public class Event extends Commitment { + + private final Time startTime; + + // Duration in minutes + private final int duration; + + /** + * Constructs an event with the given name, description, day, start time, and duration. + * + * @param name the event's name + * @param description the event's description + * @param day the day of the event + * @param startTime the start time of the event + * @param duration the duration of the event + */ + public Event(@JsonProperty("name") String name, @JsonProperty("description") String description, + @JsonProperty("day") String day, @JsonProperty("start-time") Time startTime, + @JsonProperty("duration") int duration) { + super(name, description, day); + this.startTime = startTime; + this.duration = duration; + } + + /** + * Returns a string representation of the data stored by this Event object. + * + * @return a string representation of the data stored by this Event object + */ + @Override + public String toString() { + return this.getName() + "\n" + this.getDescription() + "\n" + this.startTime.toString() + "\n" + + this.duration; + } + + /** + * getter method for this startTime + * + * @return a Time object representing the start time of this event + */ + public Time getStartTime() { + return startTime; + } + + /** + * Returns the duration of this Event + * + * @return the duration of this Event + */ + public int getDuration() { + return duration; + } +} diff --git a/src/main/java/cs3500/pa05/model/EventJson.java b/src/main/java/cs3500/pa05/model/EventJson.java new file mode 100644 index 0000000..5f65297 --- /dev/null +++ b/src/main/java/cs3500/pa05/model/EventJson.java @@ -0,0 +1,25 @@ +package cs3500.pa05.model; + + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents a Json view of an Event + * + * @param name the name of the event + * @param description the description of the event + * @param day the day of the event + * @param time the time of the event + * @param duration the duration of the event + */ +public record EventJson( + @JsonProperty("name") String name, + @JsonProperty("description") String description, + @JsonProperty("day") String day, + @JsonProperty("start-time") TimeJson time, + @JsonProperty("duration") int duration) { + + public Event toEvent() { + return new Event(name, description, day, time.toTime(), duration); + } +} diff --git a/src/main/java/cs3500/pa05/model/JsonUtils.java b/src/main/java/cs3500/pa05/model/JsonUtils.java new file mode 100644 index 0000000..2b6455c --- /dev/null +++ b/src/main/java/cs3500/pa05/model/JsonUtils.java @@ -0,0 +1,26 @@ +package cs3500.pa05.model; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Simple utils class used to hold static methods that help with serializing and deserializing JSON. + */ +public class JsonUtils { + /** + * Converts a given record object to a JsonNode. + * + * @param record the record to convert + * @return the JsonNode representation of the given record + * @throws IllegalArgumentException if the record could not be converted correctly + */ + public static JsonNode serializeRecord(Record record) throws IllegalArgumentException { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.convertValue(record, JsonNode.class); + } catch (IllegalArgumentException e) { + System.out.println(e); + throw new IllegalArgumentException("Given record cannot be serialized"); + } + } +} diff --git a/src/main/java/cs3500/pa05/model/Task.java b/src/main/java/cs3500/pa05/model/Task.java new file mode 100644 index 0000000..e453b7a --- /dev/null +++ b/src/main/java/cs3500/pa05/model/Task.java @@ -0,0 +1,51 @@ +package cs3500.pa05.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents a task in a day. + */ +public class Task extends Commitment { + + private boolean complete = false; + + /** + * Constructs a task with the given name, description, and day. + * + * @param name the task's name + * @param description the task's description + * @param day the day of the task + */ + public Task(@JsonProperty("name") String name, @JsonProperty("description") String description, + @JsonProperty("day") String day) { + super(name, description, day); + } + + /** + * Returns a string representation of the data stored by this Task object. + * + * @return a string representation of the data stored by this Task object + */ + @Override + public String toString() { + return this.getName() + "\n" + this.getDescription() + (this.complete ? "[COMPLETE]}" : ""); + } + + /** + * Returns the value of this task's completed status. + * + * @return the value of this task's completed status + */ + public boolean isComplete() { + return this.complete; + } + + /** + * Sets the value of this Task object's complete field to the given value. + * + * @param complete weather this task is complete + */ + public void setComplete(boolean complete) { + this.complete = complete; + } +} diff --git a/src/main/java/cs3500/pa05/model/TaskJson.java b/src/main/java/cs3500/pa05/model/TaskJson.java new file mode 100644 index 0000000..785cfda --- /dev/null +++ b/src/main/java/cs3500/pa05/model/TaskJson.java @@ -0,0 +1,22 @@ +package cs3500.pa05.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents a Json view of a Task + * + * @param name the name of the task + * @param description the description of the task + * @param day the day of the task + * @param complete whether the task is complete + */ +public record TaskJson( + @JsonProperty("name") String name, + @JsonProperty("description") String description, + @JsonProperty("day") String day, + @JsonProperty("complete") boolean complete) { + + public Task toTask() { + return new Task(name, description, day); + } +} diff --git a/src/main/java/cs3500/pa05/model/Theme.java b/src/main/java/cs3500/pa05/model/Theme.java new file mode 100644 index 0000000..c450e58 --- /dev/null +++ b/src/main/java/cs3500/pa05/model/Theme.java @@ -0,0 +1,39 @@ +package cs3500.pa05.model; + + +/** + * Represents a theme of a BuJo + */ +public enum Theme { + DEFAULT, + DARK, + COLORFUL; + + /** + * Returns the string representation of this theme. + * + * @return the string representation of this theme + */ + public String toString() { + return switch (this) { + case DEFAULT -> "DEFAULT"; + case DARK -> "DARK"; + case COLORFUL -> "COLORFUL"; + }; + } + + /** + * Returns the theme represented by the given string. + * + * @param s the string representation of the theme + * @return the theme represented by the given string + */ + public static Theme fromString(String s) { + return switch (s) { + case "DEFAULT" -> DEFAULT; + case "DARK" -> DARK; + case "COLORFUL" -> COLORFUL; + default -> throw new IllegalArgumentException("Invalid theme"); + }; + } +} diff --git a/src/main/java/cs3500/pa05/model/Time.java b/src/main/java/cs3500/pa05/model/Time.java new file mode 100644 index 0000000..838bdfa --- /dev/null +++ b/src/main/java/cs3500/pa05/model/Time.java @@ -0,0 +1,55 @@ +package cs3500.pa05.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents a time in a day. + */ +public class Time implements Comparable