001package edu.pdx.cs410J.grader.poa; 002 003import com.google.common.annotations.VisibleForTesting; 004import com.google.common.eventbus.EventBus; 005import com.google.common.eventbus.Subscribe; 006import com.google.inject.Inject; 007import com.google.inject.Singleton; 008import edu.pdx.cs410J.grader.gradebook.Assignment; 009import edu.pdx.cs410J.grader.gradebook.GradeBook; 010 011import java.time.LocalDateTime; 012import java.time.format.DateTimeFormatter; 013import java.util.ArrayList; 014import java.util.Collections; 015import java.util.List; 016import java.util.Optional; 017import java.util.regex.Matcher; 018import java.util.regex.Pattern; 019import java.util.stream.Collectors; 020 021@Singleton 022public class POAAssignmentsPresenter { 023 private final EventBus bus; 024 private final POAAssignmentsView view; 025 private List<Assignment> poaAssignments = Collections.emptyList(); 026 027 @Inject 028 public POAAssignmentsPresenter(EventBus bus, POAAssignmentsView view) { 029 this.bus = bus; 030 this.view = view; 031 this.view.addAssignmentSelectedHandler(this::fireAssignmentSelectedForAssignment); 032 033 this.bus.register(this); 034 } 035 036 private void fireAssignmentSelectedForAssignment(int index) { 037 Assignment assignment = this.poaAssignments.get(index); 038 this.view.setSelectedAssignmentDueDate(formatDueDate(assignment)); 039 fireAssignmentSelectedEvent(assignment); 040 } 041 042 private void fireAssignmentSelectedEvent(Assignment assignment) { 043 this.bus.post(new AssignmentSelectedEvent(assignment)); 044 } 045 046 @Subscribe 047 public void populateAssignmentNamesInView(GradeBookLoaded event) { 048 GradeBook book = event.getGradeBook(); 049 050 poaAssignments = book.assignmentsStream().filter(this::isAssignmentPOA).collect(Collectors.toList()); 051 052 if (!poaAssignments.isEmpty()) { 053 List<String> poaNames = poaAssignments.stream().map(Assignment::getName).collect(Collectors.toList()); 054 this.view.setAssignments(poaNames); 055 056 selectAssignmentWithMostRecentlyPastDueDate(); 057 } 058 } 059 060 private void selectAssignmentWithMostRecentlyPastDueDate() { 061 Optional<Assignment> mostRecentlyDueAssignment = this.poaAssignments.stream(). 062 filter(a -> a.getDueDate() != null). 063 filter(a -> a.getDueDate().isBefore(LocalDateTime.now())). 064 sorted((a1, a2) -> a1.getDueDate().compareTo(a2.getDueDate()) * -1). 065 findFirst(); 066 067 int index; 068 if (mostRecentlyDueAssignment.isPresent()) { 069 index = poaAssignments.indexOf(mostRecentlyDueAssignment.get()); 070 071 } else { 072 index = 0; 073 } 074 075 setSelectedAssignmentInView(index); 076 } 077 078 private void setSelectedAssignmentInView(int index) { 079 this.view.setSelectedAssignment(index); 080 this.view.setSelectedAssignmentDueDate(formatDueDate(this.poaAssignments.get(index))); 081 } 082 083 private boolean isAssignmentPOA(Assignment assignment) { 084 return assignment.getType() == Assignment.AssignmentType.POA; 085 } 086 087 @Subscribe 088 public void selectAssignmentThatMatchesSubmissionSubject(POASubmissionSelected submission) { 089 List<String> numbersInSubject = findNumbersInString(submission.getSubmission().getSubject()); 090 for (int i = 0; i < this.poaAssignments.size(); i++) { 091 Assignment assignment = this.poaAssignments.get(i); 092 for (String numberInSubject : numbersInSubject) { 093 if (assignment.getName().contains(numberInSubject)) { 094 setSelectedAssignmentInView(i); 095 fireAssignmentSelectedEvent(assignment); 096 } 097 } 098 } 099 } 100 101 @VisibleForTesting 102 static List<String> findNumbersInString(String string) { 103 Pattern pattern = Pattern.compile(".*?(\\d+).*?"); 104 Matcher matcher = pattern.matcher(string); 105 List<String> numbers = new ArrayList<>(); 106 while (matcher.find()) { 107 numbers.add(matcher.group(1)); 108 } 109 110 return numbers; 111 } 112 113 @VisibleForTesting 114 static String formatDueDate(Assignment assignment) { 115 LocalDateTime dueDate = assignment.getDueDate(); 116 if (dueDate == null) { 117 return ""; 118 } else { 119 return dueDate.format(DateTimeFormatter.ofPattern("M/d/yyyy h:mm a")); 120 } 121 } 122} 123