001package net.sf.cpsolver.studentsct.model;
002
003import java.util.Collections;
004import java.util.HashSet;
005import java.util.Set;
006
007/**
008 * Representation of a course offering. A course offering contains id, subject
009 * area, course number and an instructional offering. <br>
010 * <br>
011 * Each instructional offering (see {@link Offering}) is offered under one or
012 * more course offerings.
013 * 
014 * <br>
015 * <br>
016 * 
017 * @version StudentSct 1.2 (Student Sectioning)<br>
018 *          Copyright (C) 2007 - 2010 Tomáš Müller<br>
019 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
020 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
021 * <br>
022 *          This library is free software; you can redistribute it and/or modify
023 *          it under the terms of the GNU Lesser General Public License as
024 *          published by the Free Software Foundation; either version 3 of the
025 *          License, or (at your option) any later version. <br>
026 * <br>
027 *          This library is distributed in the hope that it will be useful, but
028 *          WITHOUT ANY WARRANTY; without even the implied warranty of
029 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
030 *          Lesser General Public License for more details. <br>
031 * <br>
032 *          You should have received a copy of the GNU Lesser General Public
033 *          License along with this library; if not see
034 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
035 */
036public class Course {
037    private long iId = -1;
038    private String iSubjectArea = null;
039    private String iCourseNumber = null;
040    private Offering iOffering = null;
041    private int iLimit = 0, iProjected = 0;
042    private double iEnrollmentWeight = 0.0;
043    private Set<Enrollment> iEnrollments = new HashSet<Enrollment>();
044    private Set<CourseRequest> iRequests = Collections.synchronizedSet(new HashSet<CourseRequest>());
045    private String iNote = null;
046
047    /**
048     * Constructor
049     * 
050     * @param id
051     *            course offering unique id
052     * @param subjectArea
053     *            subject area (e.g., MA, CS, ENGL)
054     * @param courseNumber
055     *            course number under the given subject area
056     * @param offering
057     *            instructional offering which is offered under this course
058     *            offering
059     */
060    public Course(long id, String subjectArea, String courseNumber, Offering offering) {
061        iId = id;
062        iSubjectArea = subjectArea;
063        iCourseNumber = courseNumber;
064        iOffering = offering;
065        iOffering.getCourses().add(this);
066    }
067
068    /**
069     * Constructor
070     * 
071     * @param id
072     *            course offering unique id
073     * @param subjectArea
074     *            subject area (e.g., MA, CS, ENGL)
075     * @param courseNumber
076     *            course number under the given subject area
077     * @param offering
078     *            instructional offering which is offered under this course
079     *            offering
080     * @param limit
081     *            course offering limit (-1 for unlimited)
082     * @param projected
083     *            projected demand
084     */
085    public Course(long id, String subjectArea, String courseNumber, Offering offering, int limit, int projected) {
086        iId = id;
087        iSubjectArea = subjectArea;
088        iCourseNumber = courseNumber;
089        iOffering = offering;
090        iOffering.getCourses().add(this);
091        iLimit = limit;
092        iProjected = projected;
093    }
094
095    /** Course offering unique id */
096    public long getId() {
097        return iId;
098    }
099
100    /** Subject area */
101    public String getSubjectArea() {
102        return iSubjectArea;
103    }
104
105    /** Course number */
106    public String getCourseNumber() {
107        return iCourseNumber;
108    }
109
110    /** Course offering name: subject area + course number */
111    public String getName() {
112        return iSubjectArea + " " + iCourseNumber;
113    }
114
115    @Override
116    public String toString() {
117        return getName();
118    }
119
120    /** Instructional offering which is offered under this course offering. */
121    public Offering getOffering() {
122        return iOffering;
123    }
124
125    /** Course offering limit */
126    public int getLimit() {
127        return iLimit;
128    }
129
130    /** Set course offering limit */
131    public void setLimit(int limit) {
132        iLimit = limit;
133    }
134
135    /** Course offering projected number of students */
136    public int getProjected() {
137        return iProjected;
138    }
139    
140    /** Called when an enrollment with this course is assigned to a request */
141    public void assigned(Enrollment enrollment) {
142        iEnrollments.add(enrollment);
143        iEnrollmentWeight += enrollment.getRequest().getWeight();
144    }
145
146    /** Called when an enrollment with this course is unassigned from a request */
147    public void unassigned(Enrollment enrollment) {
148        iEnrollments.remove(enrollment);
149        iEnrollmentWeight -= enrollment.getRequest().getWeight();
150    }
151    
152    /**
153     * Enrollment weight -- weight of all requests that are enrolled into this course,
154     * excluding the given one. See
155     * {@link Request#getWeight()}.
156     */
157    public double getEnrollmentWeight(Request excludeRequest) {
158        double weight = iEnrollmentWeight;
159        if (excludeRequest != null && excludeRequest.getAssignment() != null
160                && iEnrollments.contains(excludeRequest.getAssignment()))
161            weight -= excludeRequest.getWeight();
162        return weight;
163    }
164    
165    /** Set of assigned enrollments */
166    public Set<Enrollment> getEnrollments() {
167        return iEnrollments;
168    }
169    
170    /** Set of course requests requesting this course */
171    public Set<CourseRequest> getRequests() {
172        return iRequests;
173    }
174    
175    /**
176     * Course note
177     */
178    public String getNote() { return iNote; }
179    
180    /**
181     * Course note
182     */
183    public void setNote(String note) { iNote = note; }
184
185    @Override
186    public boolean equals(Object o) {
187        if (o == null || !(o instanceof Course)) return false;
188        return getId() == ((Course)o).getId();
189    }
190    
191    @Override
192    public int hashCode() {
193        return (int) (iId ^ (iId >>> 32));
194    }
195}