summaryrefslogtreecommitdiff
path: root/src/main/java/design
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/design')
-rw-r--r--src/main/java/design/controller/userinput/menus/FiltersMenu.java52
-rw-r--r--src/main/java/design/controller/userinput/menus/MainMenu.java1
-rw-r--r--src/main/java/design/controller/userinput/menus/SearchMenu.java32
-rw-r--r--src/main/java/design/controller/userinput/menus/SelectCourse.java60
-rw-r--r--src/main/java/design/model/Course.java33
-rw-r--r--src/main/java/design/model/course_search/CourseList.java46
-rw-r--r--src/main/java/design/model/course_search/CourseSorter.java2
-rw-r--r--src/main/java/design/model/course_search/CurrentSearchQuery.java86
-rw-r--r--src/main/java/design/model/course_search/ICourse.java1
-rw-r--r--src/main/java/design/model/course_search/SortByDifficulty.java14
-rw-r--r--src/main/java/design/model/course_search/SortByHoles.java17
-rw-r--r--src/main/java/design/model/course_search/SortByLocation.java14
-rw-r--r--src/main/java/design/model/course_search/SortByName.java14
-rw-r--r--src/main/java/design/model/course_search/SortByPar.java14
-rw-r--r--src/main/java/design/persistence/CSVMasterDatabase.java24
-rw-r--r--src/main/java/design/persistence/MasterDatabase.java2
16 files changed, 404 insertions, 8 deletions
diff --git a/src/main/java/design/controller/userinput/menus/FiltersMenu.java b/src/main/java/design/controller/userinput/menus/FiltersMenu.java
new file mode 100644
index 0000000..6923d3d
--- /dev/null
+++ b/src/main/java/design/controller/userinput/menus/FiltersMenu.java
@@ -0,0 +1,52 @@
+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;
+
+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", (c) -> new SearchMenu().present())
+ );
+ }
+}
diff --git a/src/main/java/design/controller/userinput/menus/MainMenu.java b/src/main/java/design/controller/userinput/menus/MainMenu.java
index c76e61a..8ee872e 100644
--- a/src/main/java/design/controller/userinput/menus/MainMenu.java
+++ b/src/main/java/design/controller/userinput/menus/MainMenu.java
@@ -15,6 +15,7 @@ public class MainMenu extends Menu {
public List<MenuOption> getMenuOptions() {
return List.of(
new MenuOption("user settings...", (a) -> new UserSettings().present()),
+ new MenuOption("add course to profile...", (a) -> new SearchMenu().present()),
new MenuOption("statistics...", (a) -> new StatisticsMenu().present()),
new MenuOption("log round...", (a) -> new CourseSelectMenu().present()),
new MenuOption("quit", (a) -> {}));
diff --git a/src/main/java/design/controller/userinput/menus/SearchMenu.java b/src/main/java/design/controller/userinput/menus/SearchMenu.java
new file mode 100644
index 0000000..9411b02
--- /dev/null
+++ b/src/main/java/design/controller/userinput/menus/SearchMenu.java
@@ -0,0 +1,32 @@
+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 java.util.List;
+
+public class SearchMenu extends Menu {
+
+ @Override
+ public String getTitle() {
+ return "search menu";
+ }
+
+ @Override
+ public List<MenuOption> getMenuOptions() {
+ return List.of(
+ new MenuOption("return to main menu", (a) -> new MainMenu().present()),
+ new MenuOption("search...", (a) -> new SelectCourse().search()),
+ new MenuOption("add difficulty filter...", (a) -> new FiltersMenu().addFilter(new SortByDifficulty())),
+ new MenuOption("add hole count filter...", (a) -> new FiltersMenu().addFilter(new SortByHoles())),
+ new MenuOption("add location filter...", (a) -> new FiltersMenu().addFilter(new SortByLocation())),
+ new MenuOption("add par filter...", (a) -> new FiltersMenu().addFilter(new SortByPar())),
+ new MenuOption("list filters", (a) -> new FiltersMenu().present()),
+ new MenuOption("clear all filters", (a) -> new FiltersMenu().clearFilters())
+ );
+ }
+}
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..0195bcf
--- /dev/null
+++ b/src/main/java/design/controller/userinput/menus/SelectCourse.java
@@ -0,0 +1,60 @@
+package design.controller.userinput.menus;
+
+import design.controller.userinput.Menu;
+import design.controller.userinput.MenuOption;
+import design.model.course_search.CurrentSearchQuery;
+import design.model.course_search.ICourse;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+public class SelectCourse extends Menu {
+ CurrentSearchQuery query = CurrentSearchQuery.INSTANCE;
+
+ @Override
+ public String getTitle() {
+ return "select course";
+ }
+
+ /*
+ * 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();
+
+ query.search(searchTerm);
+
+ present();
+ }
+
+ /*
+ * Display the results of our search.
+ */
+ @Override
+ public List<MenuOption> getMenuOptions()
+ {
+ var l = new ArrayList<MenuOption>();
+ List<ICourse> queryResult = query.getQueryResult().getCourses();
+
+ // we always want to return to menu as an option.
+ l.add(new MenuOption("return to main menu", (a) -> new MainMenu().present()));
+
+ // no results? let the user know.
+ if (queryResult.isEmpty())
+ {
+ System.out.println("\nNo matching courses found.\n");
+ }
+
+ // add all of our results.
+ l.addAll(query.getQueryResult().getCourses().stream()
+ .map(i -> new MenuOption(
+ i.getName() + ", " + i.getLocation() + ", Difficulty: " + i.getDifficultyRating() + ", " + i.getHoleCount() + " holes",
+ (a) -> {})).toList()); // TO DO: inputing the # for the course should add it to the user's profile
+ return l;
+ }
+
+}
diff --git a/src/main/java/design/model/Course.java b/src/main/java/design/model/Course.java
index f907622..4994381 100644
--- a/src/main/java/design/model/Course.java
+++ b/src/main/java/design/model/Course.java
@@ -1,5 +1,6 @@
package design.model;
+import design.model.course_search.CourseList;
import design.model.course_search.ICourse;
import java.util.List;
@@ -23,32 +24,50 @@ public class Course implements ICourse {
this.totalPar = totalPar;
this.holes = holes;
}
-
+
public int getId() {
return id;
}
-
+
+ @Override
public String getName() {
return name;
}
-
+
+ @Override
public float getDifficultyRating() {
return difficultyRating;
}
-
+
+ @Override
public String getLocation() {
return location;
}
-
+
+ @Override
public int getHoleCount() {
return holeCount;
}
-
+
+ @Override
public int getTotalPar() {
return totalPar;
}
-
+
+ @Override
public List<Hole> getHoles() {
return holes;
}
+
+ @Override
+ public String toString() {
+ return name + ", " + location + ", " + difficultyRating + ", " + holeCount + ", " + totalPar;
+ }
+
+ // dummy method due to composite pattern
+ @Override
+ public CourseList groupByCurrentSorter()
+ {
+ return null;
+ }
}
diff --git a/src/main/java/design/model/course_search/CourseList.java b/src/main/java/design/model/course_search/CourseList.java
index 82648c2..ac2f334 100644
--- a/src/main/java/design/model/course_search/CourseList.java
+++ b/src/main/java/design/model/course_search/CourseList.java
@@ -2,6 +2,7 @@ package design.model.course_search;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
import design.model.*;
@@ -66,6 +67,44 @@ public class CourseList implements ICourse {
sorter.sortCourses(courses);
}
+ public CourseList groupByCurrentSorter()
+ {
+ CourseList groupedList = new CourseList();
+
+ if (courses.isEmpty() || sorter == null)
+ {
+ return this;
+ }
+
+ // Sort by current sorter
+ sort();
+
+ // Group consecutive equal elements
+ List<ICourse> currentGroup = new ArrayList<>();
+ ICourse prev = null;
+
+ for (ICourse c : courses) {
+ if (prev == null || !sorter.isEqual(prev, c)) {
+ if (!currentGroup.isEmpty()) {
+ CourseList sublist = new CourseList();
+ sublist.setCourses(new ArrayList<>(currentGroup));
+ groupedList.add(sublist);
+ currentGroup.clear();
+ }
+ }
+ currentGroup.add(c);
+ prev = c;
+ }
+
+ if (!currentGroup.isEmpty()) {
+ CourseList sublist = new CourseList();
+ sublist.setCourses(currentGroup);
+ groupedList.add(sublist);
+ }
+
+ return groupedList;
+ }
+
/*
* All overrides of the ICourse class. This is a drawback of the composite pattern, but it's pretty negligible here. return some dummy values.
*/
@@ -86,4 +125,11 @@ public class CourseList implements ICourse {
@Override
public List<Hole> getHoles() { return null; }
+
+ @Override
+ public String toString()
+ {
+ // to do: implement returning courslist children
+ return "wip";
+ }
}
diff --git a/src/main/java/design/model/course_search/CourseSorter.java b/src/main/java/design/model/course_search/CourseSorter.java
index 7549645..8b4d42c 100644
--- a/src/main/java/design/model/course_search/CourseSorter.java
+++ b/src/main/java/design/model/course_search/CourseSorter.java
@@ -8,4 +8,6 @@ import java.util.List;
*/
public interface CourseSorter {
public void sortCourses(List<ICourse> courses);
+ public String toString();
+ public boolean isEqual(ICourse a, ICourse b);
} \ No newline at end of file
diff --git a/src/main/java/design/model/course_search/CurrentSearchQuery.java b/src/main/java/design/model/course_search/CurrentSearchQuery.java
new file mode 100644
index 0000000..3916f0a
--- /dev/null
+++ b/src/main/java/design/model/course_search/CurrentSearchQuery.java
@@ -0,0 +1,86 @@
+package design.model.course_search;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import design.persistence.MasterDatabase;
+
+/*
+ * Represents the state of our current search.
+ */
+public class CurrentSearchQuery {
+ public static final CurrentSearchQuery INSTANCE = new CurrentSearchQuery();
+
+
+ MasterDatabase db = MasterDatabase.INSTANCE;
+ private CourseList query = db.getCourseList();
+ private final List<CourseSorter> filters = new ArrayList<CourseSorter>();
+
+ // add a new filter
+ public void addFilter(CourseSorter filter)
+ {
+ filters.add(filter);
+ }
+
+ // clear the filters
+ public void clearFilters()
+ {
+ filters.clear();
+ }
+
+ // print out the filters ( this is for the model checking used filters )
+ public String printFilters()
+ {
+ String filterResult = "";
+
+ // no filters? let the user know.
+ if(filters.size() == 0)
+ {
+ return "nothing";
+ }
+
+ for( CourseSorter f : filters)
+ {
+ filterResult += f.toString() + " --> ";
+ }
+
+ // very silly way of removing the last arrow from our filter list. it's kind of dumb but it works fine.
+ filterResult = filterResult.substring(0, filterResult.length() - 5);
+ filterResult += "\n";
+
+ return filterResult;
+ }
+
+ // get all the filters
+ public List<CourseSorter> getFilters()
+ {
+ return filters;
+ }
+
+ // get our current query.
+ public CourseList getQueryResult()
+ {
+ return query;
+ }
+
+ public void search(String searchQuery)
+ {
+ List<ICourse> courses = db.getCourseList().getCourses().stream()
+ .filter(s -> s != null && s.toString().toLowerCase().contains(searchQuery.toLowerCase()))
+ .collect(Collectors.toList());
+
+ // Start with filtered base
+ CourseList current = new CourseList();
+ current.setCourses(courses);
+
+ // Sequentially apply filters
+ for (CourseSorter filter : filters)
+ {
+ current.setSorter(filter);
+ current = current.groupByCurrentSorter(); // regroup after each
+ }
+
+ query = current;
+ }
+}
diff --git a/src/main/java/design/model/course_search/ICourse.java b/src/main/java/design/model/course_search/ICourse.java
index e50eb1b..061bbfa 100644
--- a/src/main/java/design/model/course_search/ICourse.java
+++ b/src/main/java/design/model/course_search/ICourse.java
@@ -15,4 +15,5 @@ public interface ICourse {
List<Hole> getHoles();
int getHoleCount();
int getTotalPar();
+ CourseList groupByCurrentSorter();
}
diff --git a/src/main/java/design/model/course_search/SortByDifficulty.java b/src/main/java/design/model/course_search/SortByDifficulty.java
index 8c3251c..7660541 100644
--- a/src/main/java/design/model/course_search/SortByDifficulty.java
+++ b/src/main/java/design/model/course_search/SortByDifficulty.java
@@ -8,8 +8,22 @@ import java.util.Comparator;
* Willem Dalton
*/
public class SortByDifficulty implements CourseSorter {
+
+ @Override
public void sortCourses(List<ICourse> courses)
{
courses.sort(Comparator.comparing(ICourse::getDifficultyRating));
}
+
+ @Override
+ public boolean isEqual(ICourse a, ICourse b)
+ {
+ return a.getDifficultyRating() == b.getDifficultyRating();
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Difficulty";
+ }
} \ No newline at end of file
diff --git a/src/main/java/design/model/course_search/SortByHoles.java b/src/main/java/design/model/course_search/SortByHoles.java
index b1badab..80c0d16 100644
--- a/src/main/java/design/model/course_search/SortByHoles.java
+++ b/src/main/java/design/model/course_search/SortByHoles.java
@@ -8,8 +8,23 @@ import java.util.Comparator;
* Willem Dalton
*/
public class SortByHoles implements CourseSorter {
+
+ @Override
public void sortCourses(List<ICourse> courses)
{
courses.sort(Comparator.comparing(ICourse::getHoleCount));
}
-} \ No newline at end of file
+
+ @Override
+ public boolean isEqual(ICourse a, ICourse b)
+ {
+ return a.getHoleCount() == b.getHoleCount();
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Hole Count";
+ }
+
+}
diff --git a/src/main/java/design/model/course_search/SortByLocation.java b/src/main/java/design/model/course_search/SortByLocation.java
index 0d8a8d2..98ca0c6 100644
--- a/src/main/java/design/model/course_search/SortByLocation.java
+++ b/src/main/java/design/model/course_search/SortByLocation.java
@@ -8,8 +8,22 @@ import java.util.Comparator;
* Willem Dalton
*/
public class SortByLocation implements CourseSorter {
+
+ @Override
public void sortCourses(List<ICourse> courses)
{
courses.sort(Comparator.comparing(ICourse::getLocation));
}
+
+ @Override
+ public boolean isEqual(ICourse a, ICourse b)
+ {
+ return a.getLocation().equals(b.getLocation());
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Location";
+ }
} \ No newline at end of file
diff --git a/src/main/java/design/model/course_search/SortByName.java b/src/main/java/design/model/course_search/SortByName.java
index 2847d3e..17553a8 100644
--- a/src/main/java/design/model/course_search/SortByName.java
+++ b/src/main/java/design/model/course_search/SortByName.java
@@ -8,8 +8,22 @@ import java.util.Comparator;
* Willem Dalton
*/
public class SortByName implements CourseSorter {
+
+ @Override
public void sortCourses(List<ICourse> courses)
{
courses.sort(Comparator.comparing(ICourse::getName));
}
+
+ @Override
+ public boolean isEqual(ICourse a, ICourse b)
+ {
+ return a.getName().equals(b.getName());
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Name";
+ }
} \ No newline at end of file
diff --git a/src/main/java/design/model/course_search/SortByPar.java b/src/main/java/design/model/course_search/SortByPar.java
index 9a3eaf9..203aeaf 100644
--- a/src/main/java/design/model/course_search/SortByPar.java
+++ b/src/main/java/design/model/course_search/SortByPar.java
@@ -8,8 +8,22 @@ import java.util.Comparator;
* Willem Dalton
*/
public class SortByPar implements CourseSorter {
+
+ @Override
public void sortCourses(List<ICourse> courses)
{
courses.sort(Comparator.comparing(ICourse::getTotalPar));
}
+
+ @Override
+ public boolean isEqual(ICourse a, ICourse b)
+ {
+ return a.getTotalPar() == b.getTotalPar();
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Total Par";
+ }
} \ No newline at end of file
diff --git a/src/main/java/design/persistence/CSVMasterDatabase.java b/src/main/java/design/persistence/CSVMasterDatabase.java
index fe89191..adbf759 100644
--- a/src/main/java/design/persistence/CSVMasterDatabase.java
+++ b/src/main/java/design/persistence/CSVMasterDatabase.java
@@ -16,6 +16,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import design.model.course_search.*;
+
public class CSVMasterDatabase implements MasterDatabase {
private final List<Course> cache;
@@ -57,6 +59,28 @@ public class CSVMasterDatabase implements MasterDatabase {
return cache.get(id);
}
+ @Override
+ public CourseList getCourseList() {
+ CourseList courses = new CourseList();
+ for (Course c : cache)
+ {
+ courses.add(c);
+ }
+
+ return courses;
+ }
+
+ public CourseList getCourses(String s) {
+ CourseList courses = new CourseList();
+ for (Course c : cache)
+ {
+ if(c.getName().toLowerCase().contains(s.toLowerCase()))
+ courses.add(c);
+ }
+
+ return courses;
+ }
+
private static class CourseDeserializer extends JsonDeserializer<Course> {
int curID = 0;
diff --git a/src/main/java/design/persistence/MasterDatabase.java b/src/main/java/design/persistence/MasterDatabase.java
index ddc0434..3436ee0 100644
--- a/src/main/java/design/persistence/MasterDatabase.java
+++ b/src/main/java/design/persistence/MasterDatabase.java
@@ -1,10 +1,12 @@
package design.persistence;
import design.model.Course;
+import design.model.course_search.CourseList;
public interface MasterDatabase {
MasterDatabase INSTANCE = new CSVMasterDatabase("data/golf_courses_1000.csv");
Course[] getCourses();
+ CourseList getCourseList(); // unique from courses as this is a composite of ICourses.
Course getCourse(int id);
}