001    package net.sf.cpsolver.exam.model;
002    
003    /**
004     * Representation of an examination period. Examination timetabling model
005     * contains a list of non-overlapping examination periods. Each period has a
006     * day, starting time and a length (in minutes) defined. Each exam is to be
007     * assigned to one period that is available for the exam and that is of the same
008     * of greater length than the exam. <br>
009     * <br>
010     * A penalty weight ({@link ExamPeriod#getPenalty()}) can be assigned to each
011     * period. It is used to penalize unpopular examination times (e.g., evening or
012     * last-day). <br>
013     * <br>
014     * A list of periods is to be defined using
015     * {@link ExamModel#addPeriod(Long, String, String, int, int)}, inserting
016     * periods in the order of increasing days and times. <br>
017     * <br>
018     * 
019     * @version ExamTT 1.2 (Examination Timetabling)<br>
020     *          Copyright (C) 2007 - 2010 Tomas Muller<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     */
038    public class ExamPeriod implements Comparable<ExamPeriod> {
039        private int iIndex = -1;
040        private Long iId = null;
041        private String iTimeStr;
042        private String iDayStr;
043        private int iLength;
044        private int iDay, iTime;
045        private int iPenalty;
046        private ExamPeriod iPrev, iNext;
047    
048        /**
049         * Constructor
050         * 
051         * @param id
052         *            period unique identifier
053         * @param day
054         *            day (e.g., 07/12/10)
055         * @param time
056         *            (e.g., 8:00am-10:00am)
057         * @param length
058         *            length of period in minutes
059         * @param penalty
060         *            penalization of using this period
061         */
062        public ExamPeriod(Long id, String day, String time, int length, int penalty) {
063            iId = id;
064            iDayStr = day;
065            iTimeStr = time;
066            iLength = length;
067            iPenalty = penalty;
068        }
069    
070        /** Period unique identifier */
071        public Long getId() {
072            return iId;
073        }
074    
075        /** Period unique identifier */
076        public void setId(Long id) {
077            iId = id;
078        }
079    
080        /**
081         * Day string, e.g., 07/12/10
082         */
083        public String getDayStr() {
084            return iDayStr;
085        }
086    
087        /**
088         * Day index
089         * 
090         * @return index of the day within all days that are used for examination
091         */
092        public int getDay() {
093            return iDay;
094        }
095    
096        /**
097         * Time string, e.g., 8:00am-10:00am
098         */
099        public String getTimeStr() {
100            return iTimeStr;
101        }
102    
103        /**
104         * Time index
105         * 
106         * @return index of the time within all time that are used for examination
107         *         on the same day
108         */
109        public int getTime() {
110            return iTime;
111        }
112    
113        /**
114         * Length of period in minutes
115         * 
116         * @return period length
117         */
118        public int getLength() {
119            return iLength;
120        }
121    
122        /**
123         * Period index
124         * 
125         * @return index of the period within all examination periods
126         */
127        public int getIndex() {
128            return iIndex;
129        }
130    
131        /**
132         * Period weight to be used to penalize unpopular periods
133         * 
134         * @return period weight
135         */
136        public int getPenalty() {
137            return iPenalty;
138        }
139    
140        /**
141         * Previous period
142         * 
143         * @return period with index equal to index-1, null if this is the first
144         *         period
145         */
146        public ExamPeriod prev() {
147            return iPrev;
148        }
149    
150        /**
151         * Next period
152         * 
153         * @return period with index equal to index+1, null if this is the last
154         *         period
155         */
156        public ExamPeriod next() {
157            return iNext;
158        }
159    
160        /**
161         * Set priod indexes (only to be used by
162         * {@link ExamModel#addPeriod(Long, String, String, int, int)})
163         * 
164         * @param index
165         *            period index
166         * @param day
167         *            day index
168         * @param time
169         *            time index
170         */
171        public void setIndex(int index, int day, int time) {
172            iIndex = index;
173            iDay = day;
174            iTime = time;
175        }
176    
177        /**
178         * Set previous period (only to be used by
179         * {@link ExamModel#addPeriod(Long, String, String, int, int)})
180         * 
181         * @param prev
182         *            previous period
183         */
184        public void setPrev(ExamPeriod prev) {
185            iPrev = prev;
186        }
187    
188        /**
189         * Set next period (only to be used by
190         * {@link ExamModel#addPeriod(Long, String, String, int, int)})
191         * 
192         * @param next
193         *            next period
194         */
195        public void setNext(ExamPeriod next) {
196            iNext = next;
197        }
198    
199        /**
200         * String representation
201         * 
202         * @return day string time string
203         */
204        @Override
205        public String toString() {
206            return getDayStr() + " " + getTimeStr();
207        }
208    
209        /**
210         * String representation for debuging purposes
211         * 
212         * @return day string time string (idx: index, day: day index, time: time
213         *         index, weight: period penalty, prev: previous period, next: next
214         *         period)
215         */
216        public String toDebugString() {
217            return getDayStr() + " " + getTimeStr() + " (idx:" + getIndex() + ", day:" + getDay() + ", time:" + getTime()
218                    + ", penalty:" + getPenalty()
219                    + (prev() == null ? "" : ", prev:" + prev().getDayStr() + " " + prev().getTimeStr() + ")")
220                    + (next() == null ? "" : ", next:" + next().getDayStr() + " " + next().getTimeStr() + ")");
221        }
222    
223        @Override
224        public int hashCode() {
225            return iIndex;
226        }
227    
228        @Override
229        public boolean equals(Object o) {
230            if (o == null || !(o instanceof ExamPeriod))
231                return false;
232            return getIndex() == ((ExamPeriod) o).getIndex();
233        }
234    
235        @Override
236        public int compareTo(ExamPeriod p) {
237            return Double.compare(getIndex(), p.getIndex());
238        }
239    }