summaryrefslogtreecommitdiff
path: root/src/main/java/design
diff options
context:
space:
mode:
authorWillem Dalton <144246261+WillemDalton@users.noreply.github.com>2025-10-12 12:36:17 -0400
committerGitHub <noreply@github.com>2025-10-12 12:36:17 -0400
commitab1c8dbf8e3fbd7ae1affd17e7b5596b1e58e839 (patch)
tree91ed2c27e9735e05c8569f48e1130a95a7bdeb46 /src/main/java/design
parent1eca2f8681752ad359e8372780cdf719e2b1747d (diff)
parent050118d5d029382ffc3b11e9f8159fb297007ef5 (diff)
downloaddesignproject-design-6-ab1c8dbf8e3fbd7ae1affd17e7b5596b1e58e839.tar.gz
designproject-design-6-ab1c8dbf8e3fbd7ae1affd17e7b5596b1e58e839.tar.bz2
designproject-design-6-ab1c8dbf8e3fbd7ae1affd17e7b5596b1e58e839.zip
Merge pull request #12 from RIT-SWEN-262/menu-reorganize
Menu reorganize
Diffstat (limited to 'src/main/java/design')
-rw-r--r--src/main/java/design/ParPal.java7
-rw-r--r--src/main/java/design/controller/userinput/Menu.java10
-rw-r--r--src/main/java/design/controller/userinput/menus/AddClubMenu.java77
-rw-r--r--src/main/java/design/controller/userinput/menus/CourseSearch.java49
-rw-r--r--src/main/java/design/controller/userinput/menus/CourseSelectMenu.java100
-rw-r--r--src/main/java/design/controller/userinput/menus/FiltersMenu.java53
-rw-r--r--src/main/java/design/controller/userinput/menus/HolePlayMenu.java74
-rw-r--r--src/main/java/design/controller/userinput/menus/MainMenu.java8
-rw-r--r--src/main/java/design/controller/userinput/menus/ManageClubs.java95
-rw-r--r--src/main/java/design/controller/userinput/menus/ManageCourses.java50
-rw-r--r--src/main/java/design/controller/userinput/menus/SearchMenu.java46
-rw-r--r--src/main/java/design/controller/userinput/menus/SelectClub.java44
-rw-r--r--src/main/java/design/controller/userinput/menus/SelectCourse.java46
-rw-r--r--src/main/java/design/controller/userinput/menus/SelectUser.java30
-rw-r--r--src/main/java/design/controller/userinput/menus/StatisticsMenu.java121
-rw-r--r--src/main/java/design/controller/userinput/menus/UserSettings.java2
-rw-r--r--src/main/java/design/model/Club.java8
-rw-r--r--src/main/java/design/model/Course.java6
-rw-r--r--src/main/java/design/model/Golfer.java21
-rw-r--r--src/main/java/design/model/Swing.java4
-rw-r--r--src/main/java/design/persistence/JSONPersonalDatabase.java1
-rw-r--r--src/main/java/design/runtime/Session.java11
22 files changed, 470 insertions, 393 deletions
diff --git a/src/main/java/design/ParPal.java b/src/main/java/design/ParPal.java
index 6ea9872..8c15d59 100644
--- a/src/main/java/design/ParPal.java
+++ b/src/main/java/design/ParPal.java
@@ -3,9 +3,16 @@ package design;
import design.controller.userinput.Action;
import design.controller.userinput.menus.MainMenu;
import design.controller.userinput.menus.SelectUser;
+import design.runtime.Session;
+
+import java.time.LocalDateTime;
public class ParPal {
public static void main(String[] args) {
+ if (args.length >= 1) {
+ Session.setTimeOverride(LocalDateTime.parse(args[0]));
+ }
+
Action doAfter = () -> new MainMenu().present();
new SelectUser(doAfter).present();
}
diff --git a/src/main/java/design/controller/userinput/Menu.java b/src/main/java/design/controller/userinput/Menu.java
index 0b2fb26..ab633e1 100644
--- a/src/main/java/design/controller/userinput/Menu.java
+++ b/src/main/java/design/controller/userinput/Menu.java
@@ -11,19 +11,19 @@ public abstract class Menu {
var menuOptions = getMenuOptions();
System.out.println();
System.out.printf("-- %s --\n", getTitle().toUpperCase());
- for (int i = 0; i < menuOptions.size(); i++) {
- MenuOption menuOption = menuOptions.get(i);
+ for (int i = 1; i <= menuOptions.size(); i++) {
+ MenuOption menuOption = menuOptions.get(i-1);
System.out.printf("%s: %s\n", i, menuOption.getName());
}
- System.out.print("Selection: ");
+ System.out.printf("Selection (%s..%s): ", 1, menuOptions.size());
Scanner sc = new Scanner(System.in);
var line = sc.nextLine();
try {
- int i = Integer.parseInt(line);
+ int i = Integer.parseInt(line) - 1;
menuOptions.get(i).onAction();
- } catch (ArrayIndexOutOfBoundsException ex) {
+ } catch (IndexOutOfBoundsException ex) {
System.err.printf("Invalid option \"%s\"\n", line);
present();
}
diff --git a/src/main/java/design/controller/userinput/menus/AddClubMenu.java b/src/main/java/design/controller/userinput/menus/AddClubMenu.java
deleted file mode 100644
index ea18ed5..0000000
--- a/src/main/java/design/controller/userinput/menus/AddClubMenu.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package design.controller.userinput.menus;
-
-import design.controller.userinput.Menu;
-import design.controller.userinput.MenuOption;
-import design.model.Club;
-import design.model.Golfer;
-import design.persistence.PersonalDatabase;
-import design.runtime.Session;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Scanner;
-
-public class AddClubMenu extends Menu {
-
- @Override
- public String getTitle() {
- return "add a club";
- }
-
- @Override
- public List<MenuOption> getMenuOptions() {
- List<MenuOption> opts = new ArrayList<>();
-
- opts.add(new MenuOption("create new club", () -> {
- Golfer g = Session.getCurrentGolfer();
- if (g == null) {
- System.out.println("No user loaded.");
- new UserSettings().present();
- return;
- }
-
- Scanner sc = new Scanner(System.in);
-
- System.out.print("Manufacturer: ");
- String manufacture = sc.nextLine().trim();
-
- System.out.print("Nickname: ");
- String nickname = sc.nextLine().trim();
-
- // Pick type
- Club.ClubType[] types = Club.ClubType.values();
- System.out.println("Club type:");
- for (int i = 0; i < types.length; i++) {
- System.out.printf("%d: %s%n", i + 1, types[i]);
- }
-
- Club.ClubType type = null;
- while (type == null) {
- System.out.print("Select (1.." + types.length + "): ");
- String line = sc.nextLine().trim();
- int idx = Integer.parseInt(line);
- if (idx < 1 || idx > types.length) {
- System.out.println("Out of range. Try again.");
- continue;
- }
- type = types[idx - 1];
- }
-
- g.addClub(manufacture, nickname, type);
-
- // Add club to JSON
- try {
- PersonalDatabase.INSTANCE.updateGolfer(g);
- System.out.println("Club added and saved.");
- } catch (IOException e) {
- throw new RuntimeException("Failed to save club", e);
- }
- new UserSettings().present();
- }));
-
- opts.add(new MenuOption("cancel", () -> new UserSettings().present()));
- return opts;
- }
-}
diff --git a/src/main/java/design/controller/userinput/menus/CourseSearch.java b/src/main/java/design/controller/userinput/menus/CourseSearch.java
index 019965c..9d67b51 100644
--- a/src/main/java/design/controller/userinput/menus/CourseSearch.java
+++ b/src/main/java/design/controller/userinput/menus/CourseSearch.java
@@ -19,8 +19,9 @@ import java.util.Scanner;
* The actual SEARCH feature of course searching.
*/
public class CourseSearch extends Menu {
- CurrentSearchQuery query = CurrentSearchQuery.INSTANCE;
- PersonalDatabase GolferDB = PersonalDatabase.INSTANCE;
+ private final CurrentSearchQuery query = CurrentSearchQuery.INSTANCE;
+ private final PersonalDatabase personalDB = PersonalDatabase.INSTANCE;
+ private final Golfer golfer = Session.getCurrentGolfer();
@Override
public String getTitle() {
@@ -28,22 +29,6 @@ public class CourseSearch extends Menu {
}
/*
- * Prompt for input and search.
- */
- public void search() {
- System.out.print("Enter search term (blank for all): ");
- Scanner sc = new Scanner(System.in);
- String searchTerm = sc.nextLine();
-
- // search and present
- query.search(searchTerm);
- this.present();
-
- // reset the query after we're done.
- query.reset();
- }
-
- /*
* Display the results of our search.
*/
@Override
@@ -64,6 +49,22 @@ public class CourseSearch extends Menu {
return l;
}
+ /*
+ * Prompt for input and search.
+ */
+ @Override
+ public void present() {
+ System.out.print("Enter search term (blank for all): ");
+ Scanner sc = new Scanner(System.in);
+ String searchTerm = sc.nextLine();
+
+ // search and present
+ query.search(searchTerm);
+ super.present();
+
+ // reset the query after we're done.
+ query.reset();
+ }
// recursively go through tree structure of courselist to make menu options.
// this is all for displaying the menu options, not the actual sorting.
@@ -74,18 +75,10 @@ public class CourseSearch extends Menu {
var name = String.format("%s, %s, Difficulty: %s, %s holes, %s total par",
c.getName(), c.getLocation(), c.getDifficultyRating(), c.getHoleCount(), c.getTotalPar());
menuOptions.add(new MenuOption(name, () -> {
- Golfer currentGolfer = Session.getCurrentGolfer();
- if (currentGolfer == null) {
- // if we aren't logged in, notify the user.
- System.out.println("\n\n !!! log into a golfer account to add courses to your profile. !!! \n\n");
- new MainMenu().present();
- return;
- }
-
// add the course, try to save to DB.
- currentGolfer.addCourse(c);
+ golfer.addCourse(c);
try {
- GolferDB.updateGolfer(currentGolfer);
+ personalDB.updateGolfer(golfer);
} catch (IOException e) {
e.printStackTrace(); // not sure if we should format this prettier for the user if the DB fails.
}
diff --git a/src/main/java/design/controller/userinput/menus/CourseSelectMenu.java b/src/main/java/design/controller/userinput/menus/CourseSelectMenu.java
deleted file mode 100644
index af825e0..0000000
--- a/src/main/java/design/controller/userinput/menus/CourseSelectMenu.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package design.controller.userinput.menus;
-
-import design.controller.userinput.Menu;
-import design.controller.userinput.MenuOption;
-import design.model.Course;
-import design.model.Hole;
-import design.model.Round;
-
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Scanner;
-
-import design.persistence.MasterDatabase;
-import design.runtime.Session;
-
-public class CourseSelectMenu extends Menu {
-
- @Override
- public String getTitle() {
- return "course select";
- }
-
- @Override
- public List<MenuOption> getMenuOptions() {
- List<MenuOption> opts = new ArrayList<>();
-
- // 0) back
- opts.add(new MenuOption("back to main menu", () -> new MainMenu().present()));
-
- // 1) go to CourseSearchMenu to search for a course and add it profile
- opts.add(new MenuOption("Add Course to Profile", () -> new MainMenu().present()));
-
- // 2) pick course from MY PROFILE only
- opts.add(new MenuOption("pick course from my profile", () -> {
- var golfer = Session.getCurrentGolfer();
- Course[] mine = (golfer == null) ? new Course[0] : golfer.getCourses();
-
- // Checks user has courses of not informs them to add one to there profile
- if (mine == null || mine.length == 0) {
- System.out.println("You don't have any courses saved to your profile yet.");
- System.out.println("Use the 'Add Course to Profile' menu first.");
- this.present();
- return;
- }
- // Select a course
- Scanner sc = new Scanner(System.in);
-
- // Prints all courses
- System.out.println("-- MY COURSES --");
- for (int i = 0; i < mine.length; i++) {
- Course c = mine[i];
- System.out.printf("%d: %s (%s) | Holes: %d | Total Par: %d | Difficulty: %.1f%n",
- i + 1, c.getName(), c.getLocation(), c.getHoleCount(), c.getTotalPar(),
- c.getDifficultyRating());
- }
- // Select course by number
- Course selected = null;
- while (selected == null) {
- System.out.print("Select course # (1.." + mine.length + "): ");
- String line = sc.nextLine().trim();
- int idx = Integer.parseInt(line);
- if (idx < 1 || idx > mine.length) {
- System.out.println("Out of range. Try again.");
- continue;
- }
- selected = mine[idx - 1];
- }
- // Gets starting hole on course
- int startHoleNum = readStartingHole(sc, selected.getHoleCount());
- // Starts round and sends user to HolePlayMenu
- startRound(selected, startHoleNum);
- }));
-
- return opts;
- }
-
- private int readStartingHole(Scanner sc, int holeCount) {
- // Asks for a hole number until a valid number is selected
- while (true) {
- System.out.print("Starting hole (1.." + holeCount + ", blank=1): ");
- String s = sc.nextLine().trim();
- if (s.isEmpty())
- return 1;
- int start = Integer.parseInt(s);
- if (start < 1 || start > holeCount) {
- System.out.println("Starting hole must be between 1 and " + holeCount + ".");
- continue;
- }
- return start;
- }
- }
-
- private void startRound(Course c, int startHoleNum) {
- Hole startHole = c.getHoles().get(startHoleNum - 1);
- Round r = new Round(c, LocalDateTime.now(), startHole);
- Session.getCurrentGolfer().addRound(r);
- new HolePlayMenu(r).present();
- }
-}
diff --git a/src/main/java/design/controller/userinput/menus/FiltersMenu.java b/src/main/java/design/controller/userinput/menus/FiltersMenu.java
deleted file mode 100644
index 9f2d8df..0000000
--- a/src/main/java/design/controller/userinput/menus/FiltersMenu.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package design.controller.userinput.menus;
-
-import design.controller.userinput.Menu;
-import design.controller.userinput.MenuOption;
-import design.model.course_search.*;
-
-import java.util.List;
-
-import design.model.course_search.CurrentSearchQuery;
-
-/*
- * Tracks the user's current filters on their search.
- */
-public class FiltersMenu extends Menu {
- CurrentSearchQuery query = CurrentSearchQuery.INSTANCE;
-
- @Override
- public String getTitle() {
- return "filter menu";
- }
-
- /*
- * Add a new filter to our filter list
- */
- public void addFilter(CourseSorter filter) {
- CurrentSearchQuery.INSTANCE.addFilter(filter);
- System.out.println("\nAdded filter.\n");
- new SearchMenu().present();
- }
-
- /*
- * clear all of our filters.
- */
- public void clearFilters() {
- CurrentSearchQuery.INSTANCE.clearFilters();
- System.out.println("\nCleared all filters.\n");
- new SearchMenu().present();
- }
-
- /*
- * show our current filters.
- */
- @Override
- public List<MenuOption> getMenuOptions() {
-
- System.out.println("\nYou are filtering by ");
- System.out.println(query.printFilters());
-
- return List.of(
- new MenuOption("return to search", () -> new SearchMenu().present())
- );
- }
-}
diff --git a/src/main/java/design/controller/userinput/menus/HolePlayMenu.java b/src/main/java/design/controller/userinput/menus/HolePlayMenu.java
index 14e5345..c824341 100644
--- a/src/main/java/design/controller/userinput/menus/HolePlayMenu.java
+++ b/src/main/java/design/controller/userinput/menus/HolePlayMenu.java
@@ -2,6 +2,8 @@ package design.controller.userinput.menus;
import design.controller.userinput.Menu;
import design.controller.userinput.MenuOption;
+import design.model.Course;
+import design.model.Hole;
import design.runtime.Session;
import design.model.Club;
import design.model.Round;
@@ -17,8 +19,8 @@ public class HolePlayMenu extends Menu {
private final Round round;
private final HolePlayContext ctx;
- public HolePlayMenu(Round round) {
- this.round = round;
+ public HolePlayMenu() {
+ this.round = createRound();
this.ctx = new HolePlayContext(Session.getCurrentGolfer(), round, PersonalDatabase.INSTANCE);
}
@@ -44,38 +46,11 @@ public class HolePlayMenu extends Menu {
} else {
// 0) Take a shot
opts.add(new MenuOption("take a shot", () -> {
- // loads golfers clubs
- var golfer = Session.getCurrentGolfer();
- Club[] clubs = (golfer == null) ? new Club[0] : golfer.getClubs();
-
- if (clubs.length == 0) {
- System.out.println("You don't have any clubs yet. Add one first.");
- new AddClubMenu().present();
- this.present();
- return;
- }
-
- // list clubs
- System.out.println("-- YOUR CLUBS --");
- for (int i = 0; i < clubs.length; i++) {
- Club c = clubs[i];
- System.out.printf("%d: #%d %s - %s (%s)%n",
- i + 1, c.getId(), c.getNickname(), c.getManufacture(), c.getClubType());
- }
+ var selector = new SelectClub();
+ selector.present();
+ Club club = selector.getResult();
- // user selects one of their clubs
Scanner sc = new Scanner(System.in);
- Club club = null;
- while (club == null) {
- System.out.print("Select club # (1.." + clubs.length + "): ");
- String line = sc.nextLine().trim();
- int idx = Integer.parseInt(line);
- if (idx < 1 || idx > clubs.length) {
- System.out.println("Out of range. Try again.");
- continue;
- }
- club = clubs[idx - 1];
- }
// Get shot distance (defaults to 0 of not stated)
System.out.print("Distance (yds, blank=0): ");
@@ -111,4 +86,39 @@ public class HolePlayMenu extends Menu {
return opts;
}
+
+ private static Round createRound() {
+ var golfer = Session.getCurrentGolfer();
+
+ var selector = new SelectCourse();
+ selector.present();
+ Course course = selector.getResult();
+
+ Scanner sc = new Scanner(System.in);
+ // Gets starting hole on course
+ int startHoleNum = 1;
+ int holeCount = course.getHoleCount();
+ // Asks for a hole number until a valid number is selected
+ System.out.print("Starting hole (1.." + holeCount + ", blank=1): ");
+ String s = sc.nextLine().trim();
+ if (!s.isEmpty()) {
+ int start;
+ try {
+ start = Integer.parseInt(s);
+ } catch (NumberFormatException ex) {
+ System.out.println("Input must be a number");
+ return createRound();
+ }
+ if (start < 1 || start > holeCount) {
+ System.out.println("Starting hole must be between 1 and " + holeCount + ".");
+ return createRound();
+ }
+ startHoleNum = start;
+ }
+ // Starts round and sends user to HolePlayMenu
+ Hole startHole = course.getHoles().get(startHoleNum - 1);
+ Round r = new Round(course, Session.getDateTime(), startHole);
+ golfer.addRound(r);
+ return r;
+ }
}
diff --git a/src/main/java/design/controller/userinput/menus/MainMenu.java b/src/main/java/design/controller/userinput/menus/MainMenu.java
index 71a93b0..7522ceb 100644
--- a/src/main/java/design/controller/userinput/menus/MainMenu.java
+++ b/src/main/java/design/controller/userinput/menus/MainMenu.java
@@ -14,10 +14,12 @@ public class MainMenu extends Menu {
@Override
public List<MenuOption> getMenuOptions() {
return List.of(
+ new MenuOption("quit", () -> System.exit(0)),
new MenuOption("user settings...", () -> new UserSettings().present()),
- new MenuOption("add course to profile...", () -> new SearchMenu().present()),
+ new MenuOption("manage courses...", () -> new ManageCourses().present()),
+ new MenuOption("manage clubs...", () -> new ManageClubs().present()),
new MenuOption("statistics...", () -> new StatisticsMenu().present()),
- new MenuOption("log round...", () -> new CourseSelectMenu().present()),
- new MenuOption("quit", () -> {}));
+ new MenuOption("log round...", () -> new HolePlayMenu().present())
+ );
}
}
diff --git a/src/main/java/design/controller/userinput/menus/ManageClubs.java b/src/main/java/design/controller/userinput/menus/ManageClubs.java
new file mode 100644
index 0000000..6290444
--- /dev/null
+++ b/src/main/java/design/controller/userinput/menus/ManageClubs.java
@@ -0,0 +1,95 @@
+package design.controller.userinput.menus;
+
+import design.controller.userinput.Menu;
+import design.controller.userinput.MenuOption;
+import design.model.Club;
+import design.model.Golfer;
+import design.persistence.PersonalDatabase;
+import design.runtime.Session;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
+public class ManageClubs extends Menu {
+ private final Golfer golfer = Session.getCurrentGolfer();
+ private final PersonalDatabase personalDB = PersonalDatabase.INSTANCE;
+
+ @Override
+ public String getTitle() {
+ return "manage clubs";
+ }
+
+ @Override
+ public List<MenuOption> getMenuOptions() {
+ List<MenuOption> opts = new java.util.ArrayList<>();
+ opts.add(new MenuOption("return to main menu", () -> new MainMenu().present()));
+
+ opts.add(new MenuOption("list clubs", () -> {
+ for (Club club : golfer.getClubs()) {
+ System.out.printf("- %s\n", club);
+ }
+ this.present();
+ }));
+
+ opts.add(new MenuOption("remove club...", () -> {
+ var selector = new SelectClub();
+ selector.present();
+ golfer.removeClub(selector.getResult());
+ try {
+ personalDB.updateGolfer(golfer);
+ } catch (IOException ex) {
+ System.out.println("Failed to update golfer.");
+ }
+ this.present();
+ }));
+
+ opts.add(new MenuOption("add club...", () -> {
+ Scanner sc = new Scanner(System.in);
+
+ System.out.print("Manufacturer: ");
+ String manufacture = sc.nextLine().trim();
+
+ System.out.print("Nickname: ");
+ String nickname = sc.nextLine().trim();
+
+ var selector = new SelectClubType();
+ selector.present();
+ Club.ClubType type = selector.getResult();
+
+ golfer.addClub(manufacture, nickname, type);
+
+ // Add club to JSON
+ try {
+ personalDB.updateGolfer(golfer);
+ System.out.println("Club added and saved.");
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to save club", e);
+ }
+ this.present();
+ }));
+
+ return opts;
+ }
+
+ private static class SelectClubType extends Menu {
+ private Club.ClubType result;
+
+ @Override
+ public String getTitle() {
+ return "select club type";
+ }
+
+ public Club.ClubType getResult() {
+ return result;
+ }
+
+ @Override
+ public List<MenuOption> getMenuOptions() {
+ return Arrays.stream(Club.ClubType.values())
+ .map(t -> new MenuOption(t.name(), () -> result = t))
+ .toList();
+ }
+ }
+}
diff --git a/src/main/java/design/controller/userinput/menus/ManageCourses.java b/src/main/java/design/controller/userinput/menus/ManageCourses.java
new file mode 100644
index 0000000..4306560
--- /dev/null
+++ b/src/main/java/design/controller/userinput/menus/ManageCourses.java
@@ -0,0 +1,50 @@
+package design.controller.userinput.menus;
+
+import design.controller.userinput.Menu;
+import design.controller.userinput.MenuOption;
+import design.model.Course;
+import design.model.Golfer;
+import design.persistence.PersonalDatabase;
+import design.runtime.Session;
+
+import java.io.IOException;
+import java.util.List;
+
+public class ManageCourses extends Menu {
+ private final Golfer golfer = Session.getCurrentGolfer();
+ private final PersonalDatabase personalDB = PersonalDatabase.INSTANCE;
+
+ @Override
+ public String getTitle() {
+ return "manage courses";
+ }
+
+ @Override
+ public List<MenuOption> getMenuOptions() {
+ List<MenuOption> opts = new java.util.ArrayList<>();
+ opts.add(new MenuOption("return to main menu", () -> new MainMenu().present()));
+
+ opts.add(new MenuOption("list courses", () -> {
+ for (Course course : golfer.getCourses()) {
+ System.out.printf("- %s\n", course);
+ }
+ this.present();
+ }));
+
+ opts.add(new MenuOption("remove course...", () -> {
+ var selector = new SelectCourse();
+ selector.present();
+ golfer.removeCourse(selector.getResult());
+ try {
+ personalDB.updateGolfer(golfer);
+ } catch (IOException ex) {
+ System.out.println("Failed to update golfer.");
+ }
+ this.present();
+ }));
+
+ opts.add(new MenuOption("add course...", () -> new SearchMenu().present()));
+
+ return opts;
+ }
+}
diff --git a/src/main/java/design/controller/userinput/menus/SearchMenu.java b/src/main/java/design/controller/userinput/menus/SearchMenu.java
index 8b50265..48aebb0 100644
--- a/src/main/java/design/controller/userinput/menus/SearchMenu.java
+++ b/src/main/java/design/controller/userinput/menus/SearchMenu.java
@@ -2,10 +2,7 @@ package design.controller.userinput.menus;
import design.controller.userinput.Menu;
import design.controller.userinput.MenuOption;
-import design.model.course_search.SortByDifficulty;
-import design.model.course_search.SortByHoles;
-import design.model.course_search.SortByLocation;
-import design.model.course_search.SortByPar;
+import design.model.course_search.*;
import java.util.List;
@@ -13,6 +10,7 @@ import java.util.List;
* The main control panel for course searching.
*/
public class SearchMenu extends Menu {
+ private final CurrentSearchQuery query = CurrentSearchQuery.INSTANCE;
@Override
public String getTitle() {
@@ -21,15 +19,35 @@ public class SearchMenu extends Menu {
@Override
public List<MenuOption> getMenuOptions() {
- return List.of(
- new MenuOption("return to main menu", () -> new MainMenu().present()),
- new MenuOption("search...", () -> new CourseSearch().search()),
- new MenuOption("add difficulty filter...", () -> new FiltersMenu().addFilter(new SortByDifficulty())),
- new MenuOption("add hole count filter...", () -> new FiltersMenu().addFilter(new SortByHoles())),
- new MenuOption("add location filter...", () -> new FiltersMenu().addFilter(new SortByLocation())),
- new MenuOption("add par filter...", () -> new FiltersMenu().addFilter(new SortByPar())),
- new MenuOption("list filters", () -> new FiltersMenu().present()),
- new MenuOption("clear all filters", () -> new FiltersMenu().clearFilters())
- );
+ List<MenuOption> menuOptions = new java.util.ArrayList<>();
+
+ menuOptions.add(new MenuOption("return to main menu", () -> new MainMenu().present()));
+ menuOptions.add(new MenuOption("search...", () -> new CourseSearch().present()));
+
+ menuOptions.add(new MenuOption("sort by difficulty", () -> addFilter(new SortByDifficulty())));
+ menuOptions.add(new MenuOption("sort by hole count", () -> addFilter(new SortByHoles())));
+ menuOptions.add(new MenuOption("sort by location", () -> addFilter(new SortByLocation())));
+ menuOptions.add(new MenuOption("sort by par", () -> addFilter(new SortByPar())));
+
+ menuOptions.add(new MenuOption("list filters", () -> {
+ System.out.println("\nYou are filtering by ");
+ System.out.println(query.printFilters());
+ }));
+
+ menuOptions.add(new MenuOption("clear sorting filters", () -> {
+ query.clearFilters();
+ System.out.println("\nCleared all filters.\n");
+ this.present();
+ }));
+ return menuOptions;
+ }
+
+ /*
+ * Add a new filter to our filter list
+ */
+ public void addFilter(CourseSorter filter) {
+ query.addFilter(filter);
+ System.out.println("\nAdded sorting filter.\n");
+ this.present();
}
}
diff --git a/src/main/java/design/controller/userinput/menus/SelectClub.java b/src/main/java/design/controller/userinput/menus/SelectClub.java
new file mode 100644
index 0000000..f2f36ed
--- /dev/null
+++ b/src/main/java/design/controller/userinput/menus/SelectClub.java
@@ -0,0 +1,44 @@
+package design.controller.userinput.menus;
+
+import design.controller.userinput.Menu;
+import design.controller.userinput.MenuOption;
+import design.model.Club;
+import design.model.Golfer;
+import design.runtime.Session;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+public class SelectClub extends Menu {
+ private final Golfer golfer = Session.getCurrentGolfer();
+ private Club result;
+
+ @Override
+ public String getTitle() {
+ return "select club";
+ }
+
+ public Club getResult() {
+ Objects.requireNonNull(result);
+ return result;
+ }
+
+ @Override
+ public List<MenuOption> getMenuOptions() {
+ return Arrays.stream(golfer.getClubs())
+ .map(g -> new MenuOption(g.toString(), () -> result = g))
+ .toList();
+ }
+
+ @Override
+ public void present() {
+ if (!golfer.hasClubs()) {
+ System.out.println("You don't have any clubs yet. Add one first.");
+ new MainMenu().present();
+ return;
+ }
+
+ super.present();
+ }
+}
diff --git a/src/main/java/design/controller/userinput/menus/SelectCourse.java b/src/main/java/design/controller/userinput/menus/SelectCourse.java
new file mode 100644
index 0000000..efbdef5
--- /dev/null
+++ b/src/main/java/design/controller/userinput/menus/SelectCourse.java
@@ -0,0 +1,46 @@
+package design.controller.userinput.menus;
+
+import design.controller.userinput.Menu;
+import design.controller.userinput.MenuOption;
+import design.model.Course;
+import design.model.Golfer;
+import design.runtime.Session;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+public class SelectCourse extends Menu {
+ private final Golfer golfer = Session.getCurrentGolfer();
+ private Course result;
+
+ @Override
+ public String getTitle() {
+ return "select course";
+ }
+
+ public Course getResult() {
+ Objects.requireNonNull(result);
+ return result;
+ }
+
+ @Override
+ public List<MenuOption> getMenuOptions() {
+ return Arrays.stream(golfer.getCourses())
+ .map(c -> new MenuOption(c.toString(), () -> result = c))
+ .toList();
+ }
+
+ @Override
+ public void present() {
+ // Checks user has courses of not informs them to add one to their profile
+ if (!golfer.hasCourses()) {
+ System.out.println("You don't have any courses saved to your profile yet.");
+ System.out.println("Use the 'Add Course to Profile' menu first.");
+ new MainMenu().present();
+ return;
+ }
+
+ super.present();
+ }
+}
diff --git a/src/main/java/design/controller/userinput/menus/SelectUser.java b/src/main/java/design/controller/userinput/menus/SelectUser.java
index ffae559..e8b3874 100644
--- a/src/main/java/design/controller/userinput/menus/SelectUser.java
+++ b/src/main/java/design/controller/userinput/menus/SelectUser.java
@@ -31,24 +31,10 @@ public class SelectUser extends Menu {
var opts = new ArrayList<MenuOption>();
for (Golfer i : personalDB.getGolfers()) {
- MenuOption menuOption = new MenuOption(i.getUsername(), () -> {
- System.out.print("Enter password: ");
- var password = scanner.nextLine();
- if (i.checkPassword(password)) {
- // Sets user in Session too
- Session.setCurrentGolfer(i);
- System.out.printf("Loaded user: %s%n", i.getUsername());
- doAfter.onAction();
- } else {
- System.out.println("Incorrect password. ");
- this.present();
- }
- });
- opts.add(menuOption);
+ opts.add(new MenuOption(i.toString(), () -> login(i)));
}
opts.add(new MenuOption("<create>", () -> {
-
System.out.print("Enter username: ");
var username = scanner.nextLine();
@@ -68,4 +54,18 @@ public class SelectUser extends Menu {
return opts;
}
+
+ private void login(Golfer g) {
+ System.out.print("Enter password: ");
+ var password = scanner.nextLine();
+ if (g.checkPassword(password)) {
+ // Sets user in Session too
+ Session.setCurrentGolfer(g);
+ System.out.printf("Loaded user: %s%n", g);
+ doAfter.onAction();
+ } else {
+ System.out.println("Incorrect password. ");
+ this.present();
+ }
+ }
}
diff --git a/src/main/java/design/controller/userinput/menus/StatisticsMenu.java b/src/main/java/design/controller/userinput/menus/StatisticsMenu.java
index 3af790e..9ce0bd0 100644
--- a/src/main/java/design/controller/userinput/menus/StatisticsMenu.java
+++ b/src/main/java/design/controller/userinput/menus/StatisticsMenu.java
@@ -19,27 +19,82 @@ import java.util.List;
import java.util.Scanner;
public class StatisticsMenu extends Menu {
-
- Golfer golfer = Session.getCurrentGolfer();
+ private final Golfer golfer = Session.getCurrentGolfer();
@Override
public String getTitle() {
return "statistics menu";
}
+ @Override
+ public List<MenuOption> getMenuOptions() {
+ List<MenuOption> opts = new java.util.ArrayList<>();
+
+ opts.add(new MenuOption("return to main menu", () -> new MainMenu().present()));
+
+ opts.add(new MenuOption("view lifetime statistics", () -> {
+ Statistics stats = new LifetimeStats(golfer);
+
+ System.out.printf("Total swings: %d\n", stats.get_score());
+ System.out.printf("Total distance: %.1f\n", stats.get_distance());
+ this.present();
+ }));
+
+ opts.add(new MenuOption("view yearly statistics", () -> {
+ Statistics baseStats = new LifetimeStats(golfer);
+ Statistics yearStats = getUserYear(baseStats);
+
+ System.out.printf("Total swings: %d\n", yearStats.get_score());
+ System.out.printf("Total distance: %.1f\n", yearStats.get_distance());
+ this.present();
+ }));
+
+ opts.add(new MenuOption("view course statistics", () -> {
+ Statistics baseStats = new LifetimeStats(golfer);
+ Statistics yearStats = getUserYear(baseStats);
+ Statistics courseStats = getUserCourse(yearStats);
+
+ System.out.printf("Total swings: %d\n", courseStats.get_score());
+ System.out.printf("Total distance: %.1f\n", courseStats.get_distance());
+ this.present();
+ }));
+
+ opts.add(new MenuOption("view round statistics", () -> {
+ Statistics baseStats = new LifetimeStats(golfer);
+ Statistics yearStats = getUserYear(baseStats);
+ Statistics courseStats = getUserCourse(yearStats);
+ Statistics roundStats = getUserRound(courseStats);
+
+ System.out.printf("Total swings: %d\n", roundStats.get_score());
+ System.out.printf("Total distance: %.1f\n", roundStats.get_distance());
+ this.present();
+ }));
+
+ opts.add(new MenuOption("view hole statistics", () -> {
+ Statistics baseStats = new LifetimeStats(golfer);
+ Statistics yearStats = getUserYear(baseStats);
+ Statistics courseStats = getUserCourse(yearStats);
+ Statistics roundStats = getUserRound(courseStats);
+ Statistics holeStats = getUserHole(roundStats);
+
+ System.out.printf("Total swings: %d\n", holeStats.get_score());
+ System.out.printf("Total distance: %.1f\n", holeStats.get_distance());
+ this.present();
+ }));
+
+ return opts;
+ }
+
// Helper classes to get user input and handle finding the data they requested (Course, Hole, Year, etc.)
- @SuppressWarnings("resource")
private Statistics getUserYear(Statistics baseStats){
Scanner sc = new Scanner(System.in);
System.out.println("Enter year to search: ");
int year = Integer.parseInt(sc.nextLine());
- Statistics yearStats = new YearlyStats(baseStats, year);
- return yearStats;
+ return new YearlyStats(baseStats, year);
}
- @SuppressWarnings("resource")
private Statistics getUserCourse(Statistics baseStats){
Scanner sc = new Scanner(System.in);
Course[] courses = golfer.getCourses();
@@ -51,7 +106,6 @@ public class StatisticsMenu extends Menu {
return new CourseStats(baseStats, courses[selection - 1]);
}
- @SuppressWarnings("resource")
private Statistics getUserRound(Statistics baseStats){
Scanner sc = new Scanner(System.in);
Round[] rounds = baseStats.getRounds();
@@ -63,7 +117,6 @@ public class StatisticsMenu extends Menu {
return new RoundStats(baseStats, rounds[selection - 1]);
}
- @SuppressWarnings("resource")
private Statistics getUserHole(Statistics baseStats){
Scanner sc = new Scanner(System.in);
Round round = baseStats.getRounds()[0]; // Only 1 round
@@ -82,56 +135,4 @@ public class StatisticsMenu extends Menu {
}
return baseStats;
}
-
- @Override
- public List<MenuOption> getMenuOptions() {
- return List.of(
- new MenuOption("return to main menu", () -> new MainMenu().present()),
- new MenuOption("view lifetime statistics", () -> {
- Statistics stats = new LifetimeStats(golfer);
-
- System.out.printf("Total swings: %d\n", stats.get_score());
- System.out.printf("Total distance: %.1f\n", stats.get_distance());
- this.present();
- }),
- new MenuOption("view yearly statistics", () -> {
- Statistics baseStats = new LifetimeStats(golfer);
- Statistics yearStats = getUserYear(baseStats);
-
- System.out.printf("Total swings: %d\n", yearStats.get_score());
- System.out.printf("Total distance: %.1f\n", yearStats.get_distance());
- this.present();
- }),
- new MenuOption("view course statistics", () -> {
- Statistics baseStats = new LifetimeStats(golfer);
- Statistics yearStats = getUserYear(baseStats);
- Statistics courseStats = getUserCourse(yearStats);
-
- System.out.printf("Total swings: %d\n", courseStats.get_score());
- System.out.printf("Total distance: %.1f\n", courseStats.get_distance());
- this.present();
- }),
- new MenuOption("view round statistics", () -> {
- Statistics baseStats = new LifetimeStats(golfer);
- Statistics yearStats = getUserYear(baseStats);
- Statistics courseStats = getUserCourse(yearStats);
- Statistics roundStats = getUserRound(courseStats);
-
- System.out.printf("Total swings: %d\n", roundStats.get_score());
- System.out.printf("Total distance: %.1f\n", roundStats.get_distance());
- this.present();
- }),
- new MenuOption("view hole statistics", () -> {
- Statistics baseStats = new LifetimeStats(golfer);
- Statistics yearStats = getUserYear(baseStats);
- Statistics courseStats = getUserCourse(yearStats);
- Statistics roundStats = getUserRound(courseStats);
- Statistics holeStats = getUserHole(roundStats);
-
- System.out.printf("Total swings: %d\n", holeStats.get_score());
- System.out.printf("Total distance: %.1f\n", holeStats.get_distance());
- this.present();
- })
- );
- }
} \ No newline at end of file
diff --git a/src/main/java/design/controller/userinput/menus/UserSettings.java b/src/main/java/design/controller/userinput/menus/UserSettings.java
index 34b645d..04ec4d0 100644
--- a/src/main/java/design/controller/userinput/menus/UserSettings.java
+++ b/src/main/java/design/controller/userinput/menus/UserSettings.java
@@ -60,8 +60,6 @@ public class UserSettings extends Menu {
this.present();
}));
- opts.add(new MenuOption("add a club...", () -> new AddClubMenu().present()));
-
return opts;
}
}
diff --git a/src/main/java/design/model/Club.java b/src/main/java/design/model/Club.java
index 9fa3c87..b12fd99 100644
--- a/src/main/java/design/model/Club.java
+++ b/src/main/java/design/model/Club.java
@@ -1,5 +1,13 @@
package design.model;
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+@JsonIdentityInfo(
+ generator = ObjectIdGenerators.PropertyGenerator.class,
+ property = "id",
+ scope = Club.class
+)
public class Club {
public enum ClubType {
diff --git a/src/main/java/design/model/Course.java b/src/main/java/design/model/Course.java
index c199563..ce7c0e3 100644
--- a/src/main/java/design/model/Course.java
+++ b/src/main/java/design/model/Course.java
@@ -1,6 +1,5 @@
package design.model;
-import design.model.course_search.CourseList;
import design.model.course_search.ICourse;
import java.util.List;
@@ -9,7 +8,7 @@ public class Course implements ICourse {
private final int id;
private final String name;
- private final int difficultyRating;
+ private final float difficultyRating;
private final String location;
private final int holeCount;
private final int totalPar;
@@ -61,6 +60,7 @@ public class Course implements ICourse {
@Override
public String toString() {
- return name + ", " + location + ", " + difficultyRating + ", " + holeCount + ", " + totalPar;
+ return String.format("%s (%s) | Holes: %d | Total Par: %d | Difficulty: %.1f",
+ name, location, holeCount, totalPar, difficultyRating);
}
}
diff --git a/src/main/java/design/model/Golfer.java b/src/main/java/design/model/Golfer.java
index d34073f..48daae8 100644
--- a/src/main/java/design/model/Golfer.java
+++ b/src/main/java/design/model/Golfer.java
@@ -1,10 +1,12 @@
package design.model;
import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import java.util.ArrayList;
import java.util.List;
+@JsonPropertyOrder({ "clubs", "nextClubId" })
public class Golfer {
private String username;
private int passwordHash;
@@ -12,7 +14,7 @@ public class Golfer {
private final List<Course> courses;
private final List<Round> rounds;
private final List<Club> clubs; // Keep track of golfer's clubs
- private int nextClubId = 1;
+ private int nextClubId;
@JsonCreator
private Golfer(String username, int passwordHash, String fullName, List<Course> courses, List<Round> rounds,
@@ -72,6 +74,10 @@ public class Golfer {
courses.remove(course);
}
+ public boolean hasCourses() {
+ return !courses.isEmpty();
+ }
+
public Round[] getRounds() {
return rounds.toArray(Round[]::new);
}
@@ -86,6 +92,10 @@ public class Golfer {
return c;
}
+ public boolean hasClubs() {
+ return !clubs.isEmpty();
+ }
+
public boolean hasClub(Club c) {
return clubs.contains(c);
}
@@ -93,4 +103,13 @@ public class Golfer {
public Club[] getClubs() {
return clubs.toArray(Club[]::new);
}
+
+ @Override
+ public String toString() {
+ return String.format("%s (@%s)", fullName, username);
+ }
+
+ public void removeClub(Club c) {
+ clubs.remove(c);
+ }
}
diff --git a/src/main/java/design/model/Swing.java b/src/main/java/design/model/Swing.java
index a93b66f..43c20f0 100644
--- a/src/main/java/design/model/Swing.java
+++ b/src/main/java/design/model/Swing.java
@@ -1,7 +1,11 @@
package design.model;
+import com.fasterxml.jackson.annotation.JsonIdentityReference;
+
public class Swing {
private final int distance;
+
+ @JsonIdentityReference(alwaysAsId = true)
private final Club clubUsed;
public Swing(int distance, Club clubUsed) {
diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java
index 3975d14..db613d9 100644
--- a/src/main/java/design/persistence/JSONPersonalDatabase.java
+++ b/src/main/java/design/persistence/JSONPersonalDatabase.java
@@ -11,6 +11,7 @@ import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
+import design.model.Club;
import design.model.Course;
import design.model.Golfer;
diff --git a/src/main/java/design/runtime/Session.java b/src/main/java/design/runtime/Session.java
index fbf4b9c..59d31d8 100644
--- a/src/main/java/design/runtime/Session.java
+++ b/src/main/java/design/runtime/Session.java
@@ -2,8 +2,11 @@ package design.runtime;
import design.model.Golfer;
+import java.time.LocalDateTime;
+
public final class Session {
private static Golfer currentGolfer;
+ private static LocalDateTime timeOverride;
public static Golfer getCurrentGolfer() {
return currentGolfer;
@@ -12,4 +15,12 @@ public final class Session {
public static void setCurrentGolfer(Golfer currentGolfer) {
Session.currentGolfer = currentGolfer;
}
+
+ public static LocalDateTime getDateTime() {
+ return timeOverride != null ? timeOverride : LocalDateTime.now();
+ }
+
+ public static void setTimeOverride(LocalDateTime timeOverride) {
+ Session.timeOverride = timeOverride;
+ }
}