001    package net.sf.cpsolver.studentsct.model;
002    
003    import java.util.ArrayList;
004    import java.util.HashSet;
005    import java.util.List;
006    import java.util.Set;
007    
008    import net.sf.cpsolver.coursett.model.RoomLocation;
009    import net.sf.cpsolver.coursett.model.TimeLocation;
010    import 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 Tomas Muller<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     */
037    public 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    }