package gov.nysenate.openleg.model.entity;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.TreeMultiset;
import gov.nysenate.openleg.model.base.BaseLegislativeContent;
import java.io.Serializable;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class Committee extends BaseLegislativeContent implements Serializable
{
private static final long serialVersionUID = 867918085158335059L;
/** The name of the committee */
protected String name;
/** The legislative chamber containing the committee */
protected Chamber chamber;
/** The date that this version of the committee was reformed */
protected LocalDateTime reformed;
/** The normal meeting location. */
protected String location;
/** The day of the week when this committee normally meets. */
protected DayOfWeek meetDay;
/** The time of the day when the committee normally meets. */
protected LocalTime meetTime;
/** True if the committee normally meets on alternate weeks. */
protected boolean meetAltWeek;
/** A short memo that indicates that the committee will meet on alternate weeks. */
protected String meetAltWeekText;
/** List of all the committee members. */
protected TreeMultiset<CommitteeMember> members = TreeMultiset.create();
/** --- Constructors --- */
public Committee() {
super();
}
public Committee(Committee other) {
super(other);
this.name = other.name;
this.chamber = other.chamber;
this.reformed = other.reformed;
this.location = other.location;
this.meetDay = other.meetDay;
this.meetTime = other.meetTime;
this.meetAltWeek = other.meetAltWeek;
this.meetAltWeekText = other.meetAltWeekText;
this.members = TreeMultiset.create();
other.members.forEach((member) -> this.members.add(new CommitteeMember(member)));
}
public Committee(String name, Chamber chamber){
this.name = name;
this.chamber = chamber;
}
/** --- Operators --- */
public boolean membersEquals(Committee other) {
return
Objects.equals(this.name, other.name) &&
Objects.equals(this.session, other.session) &&
Objects.equals(this.members.size(), other.members.size()) &&
this.members.containsAll(other.members);
}
public boolean meetingEquals(Committee other) {
return
Objects.equals(this.name, other.name) &&
Objects.equals(this.session, other.session) &&
Objects.equals(this.location, other.location) &&
Objects.equals(this.meetDay, other.meetDay) &&
Objects.equals(this.meetTime, other.meetTime) &&
Objects.equals(this.meetAltWeek, other.meetAltWeek) &&
Objects.equals(this.meetAltWeekText, other.meetAltWeekText);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
final Committee other = (Committee) obj;
return
Objects.equals(this.name, other.name) &&
Objects.equals(this.chamber, other.chamber) &&
Objects.equals(this.reformed, other.reformed) &&
meetingEquals(other) &&
membersEquals(other);
}
@Override
public int hashCode() {
return Objects.hash(name, chamber, reformed, location, meetDay, meetTime, meetAltWeek, meetAltWeekText, members);
}
public static final Comparator<Committee> BY_DATE = (left, right) ->
ComparisonChain.start()
.compare(left.session, right.session)
.compare(left.publishedDateTime, right.publishedDateTime)
.result();
/** --- Helper functions --- */
public boolean isCurrent() {
// The current Committee should have a reformed date of 'infinity'
return reformed == null || reformed.isAfter(LocalDateTime.now());
}
public void updateMeetingInfo(Committee updatedCommittee) {
this.location = updatedCommittee.location;
this.meetDay = updatedCommittee.meetDay;
this.meetTime = updatedCommittee.meetTime;
this.meetAltWeek = updatedCommittee.meetAltWeek;
this.meetAltWeekText = updatedCommittee.meetAltWeekText;
}
/** --- Functional Getters/Setters --- */
public CommitteeId getId(){
return new CommitteeId(this.chamber, this.name);
}
public CommitteeSessionId getSessionId() {
return new CommitteeSessionId(this.chamber, this.name, this.session);
}
public CommitteeVersionId getVersionId() {
return new CommitteeVersionId(this.chamber, this.name, this.session, this.publishedDateTime);
}
/**
* --- Functional Getters/Setters ---
*/
public void addMember(CommitteeMember member) {
this.members.add(member);
}
public LocalDateTime getCreated() {
return this.publishedDateTime;
}
/** --- Basic Getters/Setters --- */
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Chamber getChamber() {
return chamber;
}
public void setChamber(Chamber chamber) {
this.chamber = chamber;
}
public LocalDateTime getReformed() {
return reformed;
}
public void setReformed(LocalDateTime reformed) {
this.reformed = reformed;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public DayOfWeek getMeetDay() {
return meetDay;
}
public void setMeetDay(DayOfWeek meetDay) {
this.meetDay = meetDay;
}
public LocalTime getMeetTime() {
return meetTime;
}
public void setMeetTime(LocalTime meetTime) {
this.meetTime = meetTime;
}
public boolean isMeetAltWeek() {
return meetAltWeek;
}
public void setMeetAltWeek(boolean meetAltWeek) {
this.meetAltWeek = meetAltWeek;
}
public String getMeetAltWeekText() {
return meetAltWeekText;
}
public void setMeetAltWeekText(String meetAltWeekText) {
this.meetAltWeekText = meetAltWeekText;
}
public List<CommitteeMember> getMembers() {
return members.stream().collect(Collectors.toList());
}
public void setMembers(Collection<CommitteeMember> members) {
this.members = TreeMultiset.create(members);
}
}