    001package net.sf.cpsolver.studentsct.model;
    002
    003import java.util.ArrayList;
    004import java.util.HashSet;
    005import java.util.List;
    006import java.util.Set;
    007
    008import net.sf.cpsolver.coursett.model.RoomLocation;
    009import net.sf.cpsolver.coursett.model.TimeLocation;
    010import net.sf.cpsolver.studentsct.StudentSectioningModel;
    011
    012
    013/**
    014 * Representation of a request of a student for free time. This class directly
    015 * implements {@link Assignment} API, with the appropriate free time. <br>
    016 * <br>
    017 *
    018 * @version StudentSct 1.2 (Student Sectioning)<br>
    019 *          Copyright (C) 2007 - 2010 Tomáš Müller<br>
    020 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
    021 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
    022 * <br>
    023 *          This library is free software; you can redistribute it and/or modify
    024 *          it under the terms of the GNU Lesser General Public License as
    025 *          published by the Free Software Foundation; either version 3 of the
    026 *          License, or (at your option) any later version. <br>
    027 * <br>
    028 *          This library is distributed in the hope that it will be useful, but
    029 *          WITHOUT ANY WARRANTY; without even the implied warranty of
    030 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    031 *          Lesser General Public License for more details. <br>
    032 * <br>
    033 *          You should have received a copy of the GNU Lesser General Public
    034 *          License along with this library; if not see
    035 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
    036 */
    037public class FreeTimeRequest extends Request implements Assignment {
    038    private TimeLocation iTime = null;
    039    private HashSet<Enrollment> iEnrollments = new HashSet<Enrollment>();
    040
    041    /**
    042     * Constructor
    043     *
    044     * @param id
    045     *            request unique id
    046     * @param priority
    047     *            request priority
    048     * @param alternative
    049     *            true if the request is alternative (alternative request can be
    050     *            assigned instead of a non-alternative course requests, if it
    051     *            is left unassigned)
    052     * @param student
    053     *            appropriate student
    054     * @param time
    055     *            appropriate time location that is requested to be free
    056     */
    057    public FreeTimeRequest(long id, int priority, boolean alternative, Student student, TimeLocation time) {
    058        super(id, priority, alternative, student);
    059        iTime = time;
    060    }
    061
    062    /** Return requested time to be free */
    063    @Override
    064    public TimeLocation getTime() {
    065        return iTime;
    066    }
    067
    068    /** Assignment API: free time request has no rooms */
    069    @Override
    070    public int getNrRooms() {
    071        return 0;
    072    }
    073
    074    /** Assignment API: free time request has no rooms */
    075    @Override
    076    public List<RoomLocation> getRooms() {
    077        return new ArrayList<RoomLocation>(0);
    078    }
    079
    080    /**
    081     * True, if this assignment is overlapping in time and space with the given
    082     * assignment.
    083     */
    084    @Override
    085    public boolean isOverlapping(Assignment assignment) {
    086        if (isAllowOverlap() || assignment.isAllowOverlap()) return false;
    087        if (getTime() == null || assignment.getTime() == null)
    088            return false;
    089        if (assignment instanceof FreeTimeRequest)
    090            return false;
    091        return getTime().hasIntersection(assignment.getTime());
    092    }
    093
    094    /**
    095     * True, if this assignment is overlapping in time and space with the given
    096     * set of assignments.
    097     */
    098    @Override
    099    public boolean isOverlapping(Set<? extends Assignment> assignments) {
    100        if (isAllowOverlap())
    101            return false;
    102        if (getTime() == null)
    103            return false;
    104        for (Assignment assignment : assignments) {
    105            if (assignment.isAllowOverlap())
    106                continue;
    107            if (assignment.getTime() == null)
    108                continue;
    109            if (assignment instanceof FreeTimeRequest)
    110                return false;
    111            if (getTime().hasIntersection(assignment.getTime()))
    112                return true;
    113        }
    114        return false;
    115    }
    116
    117    /** Create enrollment of this request */
    118    public Enrollment createEnrollment() {
    119        HashSet<Assignment> assignments = new HashSet<Assignment>();
    120        assignments.add(this);
    121        return new Enrollment(this, 0, null, assignments);
    122    }
    123
    124    /**
    125     * Create all possible enrollments of this request -- there is only one
    126     * possible enrollment: {@link FreeTimeRequest#createEnrollment()}
    127     */
    128    @Override
    129    public List<Enrollment> computeEnrollments() {
    130        List<Enrollment> enrollments = new ArrayList<Enrollment>(1);
    131        enrollments.add(createEnrollment());
    132        return enrollments;
    133    }
    134
    135    /** Enrollment with this assignment was assigned to a {@link Request}. */
    136    @Override
    137    public void assigned(Enrollment enrollment) {
    138        iEnrollments.add(enrollment);
    139    }
    140
    141    /** Enrollment with this assignment was unassigned from a {@link Request}. */
    142    @Override
    143    public void unassigned(Enrollment enrollment) {
    144        iEnrollments.remove(enrollment);
    145    }
    146
    147    /** Return the list of assigned enrollments that contains this assignment. */
    148    @Override
    149    public Set<Enrollment> getEnrollments() {
    150        return iEnrollments;
    151    }
    152
    153    /**
    154     * Request name: A for alternative, 1 + priority, Free Time, long name of
    155     * requested time
    156     */
    157    @Override
    158    public String getName() {
    159        return (isAlternative() ? "A" : "") + (1 + getPriority() + (isAlternative() ? -getStudent().nrRequests() : 0))
    160                + ". Free Time " + getTime().getDayHeader() + " " + getTime().getStartTimeHeader() + " - " + getTime().getEndTimeHeader();
    161    }
    162
    163    @Override
    164    public String toString() {
    165        return getName();
    166    }
    167
    168    /** Estimated bound for this request */
    169    @Override
    170    public double getBound() {
    171        return - getWeight() * ((StudentSectioningModel)getModel()).getStudentWeights().getBound(this);
    172    }
    173
    174    /** Free time request generally allow overlaps. */
    175    @Override
    176    public boolean isAllowOverlap() {
    177        return (getModel() == null ? true : ((StudentSectioningModel)getModel()).getStudentWeights().isFreeTimeAllowOverlaps());
    178    }
    179
    180    /** Sections first, then by {@link FreeTimeRequest#getId()} */
    181    @Override
    182    public int compareById(Assignment a) {
    183        if (a instanceof FreeTimeRequest) {
    184            return new Long(getId()).compareTo(((FreeTimeRequest)a).getId());
    185        } else {
    186            return 1;
    187        }
    188    }
    189
    190    @Override
    191    public int hashCode() {
    192        return super.hashCode() ^ getTime().hashCode();
    193    }
    194
    195
    196    @Override
    197    public boolean equals(Object o) {
    198        return super.equals(o) && (o instanceof CourseRequest) && getTime().equals(((FreeTimeRequest)o).getTime());
    199    }
    200
    201}