001package org.cpsolver.studentsct.model;
002
003import java.util.HashSet;
004import java.util.List;
005import java.util.Set;
006
007import org.cpsolver.coursett.model.RoomLocation;
008import org.cpsolver.coursett.model.TimeLocation;
009import org.cpsolver.ifs.assignment.Assignment;
010
011/**
012 * Representation of an unavailability. This is typically used when the student is
013 * also an instructor and he/she is teaching during some time (and hence not available
014 * for attending classes as a student). An unavailability can be marked as can overlap
015 * in time, in which case the time overlap is allowed but the overlapping time is to
016 * be minimized.<br>
017 * <br>
018 * 
019 * @version StudentSct 1.3 (Student Sectioning)<br>
020 *          Copyright (C) 2007 - 2016 Tomáš Müller<br>
021 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
022 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
023 * <br>
024 *          This library is free software; you can redistribute it and/or modify
025 *          it under the terms of the GNU Lesser General Public License as
026 *          published by the Free Software Foundation; either version 3 of the
027 *          License, or (at your option) any later version. <br>
028 * <br>
029 *          This library is distributed in the hope that it will be useful, but
030 *          WITHOUT ANY WARRANTY; without even the implied warranty of
031 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
032 *          Lesser General Public License for more details. <br>
033 * <br>
034 *          You should have received a copy of the GNU Lesser General Public
035 *          License along with this library; if not see
036 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
037 */
038public class Unavailability implements SctAssignment {
039    private Section iSection;
040    private Student iStudent;
041    private boolean iAllowOverlap;
042    
043    /**
044     * Constructor
045     * @param student student
046     * @param section section that the student is teaching
047     * @param canOverlap true if student can have classes during the time, but the overlapping time should be minimized
048     */
049    public Unavailability(Student student, Section section, boolean canOverlap) {
050        iStudent = student;
051        iSection = section;
052        iAllowOverlap = canOverlap;
053        iStudent.getUnavailabilities().add(this);
054        iSection.getUnavailabilities().add(this);
055    }
056    
057    /**
058     * Student
059     */
060    public Student getStudent() { return iStudent; }
061    
062    /**
063     * Section
064     */
065    public Section getSection() { return iSection; }
066    
067    @Override
068    public long getId() {
069        return getSection().getId();
070    }
071    
072    @Override
073    public TimeLocation getTime() { return getSection().getTime(); }
074    
075    /**
076     * Can student have classes during this unavailability? The overlapping time should be minimized in this case
077     * (like with lower priority free time requests).
078     */
079    @Override
080    public boolean isAllowOverlap() { return iAllowOverlap; }
081
082    @Override
083    public List<RoomLocation> getRooms() {
084        return getSection().getRooms();
085    }
086
087    @Override
088    public int getNrRooms() {
089        return getSection().getNrRooms();
090    }
091
092    @Override
093    public boolean isOverlapping(SctAssignment assignment) {
094        if (isAllowOverlap() || assignment.isAllowOverlap()) return false;
095        if (getTime() == null || assignment.getTime() == null) return false;
096        if (assignment instanceof Section && getTime().hasIntersection(assignment.getTime())) return true;
097        return false;
098    }
099
100    @Override
101    public boolean isOverlapping(Set<? extends SctAssignment> assignments) {
102        if (isAllowOverlap()) return false;
103        if (getTime() == null) return false;
104        for (SctAssignment assignment : assignments) {
105            if (assignment.isAllowOverlap()) continue;
106            if (assignment.getTime() == null) continue;
107            if (assignment instanceof Section && getTime().hasIntersection(assignment.getTime())) return true;
108        }
109        return false;
110    }
111
112    @Override
113    public void assigned(Assignment<Request, Enrollment> assignment, Enrollment enrollment) {
114    }
115
116    @Override
117    public void unassigned(Assignment<Request, Enrollment> assignment, Enrollment enrollment) {
118    }
119
120    /**
121     * Not used, always null
122     */
123    @Override
124    public Set<Enrollment> getEnrollments(Assignment<Request, Enrollment> assignment) {
125        return null;
126    }
127
128    @Override
129    public int compareById(SctAssignment a) {
130        if (a instanceof Unavailability) {
131            return new Long(getId()).compareTo(((Unavailability)a).getId());
132        } else {
133            return 1;
134        }
135    }
136    
137    /**
138     * Create dummy enrollment of this unavailability 
139     * @return created enrollment (warning: the returned enrollment has no request)
140     **/
141    public Enrollment createEnrollment() {
142        HashSet<SctAssignment> assignments = new HashSet<SctAssignment>();
143        assignments.add(this);
144        return new Enrollment(null, 0, null, assignments, null);
145    }
146    
147    @Override
148    public boolean equals(Object o) {
149        if (o == null || !(o instanceof Unavailability)) return false;
150        return getId() == ((Unavailability)o).getId();
151    }
152    
153    @Override
154    public int hashCode() {
155        return (int) (getId() ^ (getId() >>> 32));
156    }
157}