001package org.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.3 (Examination Timetabling)<br>
020 *          Copyright (C) 2007 - 2014 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 */
038public 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     * @return period unique id
072     **/
073    public Long getId() {
074        return iId;
075    }
076
077    /** Period unique identifier 
078     * @param id period unique id
079     **/
080    public void setId(Long id) {
081        iId = id;
082    }
083
084    /**
085     * Day string, e.g., 07/12/10
086     * @return day of the period
087     */
088    public String getDayStr() {
089        return iDayStr;
090    }
091
092    /**
093     * Day index
094     * 
095     * @return index of the day within all days that are used for examination
096     */
097    public int getDay() {
098        return iDay;
099    }
100
101    /**
102     * Time string, e.g., 8:00am-10:00am
103     * @return time of the period
104     */
105    public String getTimeStr() {
106        return iTimeStr;
107    }
108
109    /**
110     * Time index
111     * 
112     * @return index of the time within all time that are used for examination
113     *         on the same day
114     */
115    public int getTime() {
116        return iTime;
117    }
118
119    /**
120     * Length of period in minutes
121     * 
122     * @return period length
123     */
124    public int getLength() {
125        return iLength;
126    }
127
128    /**
129     * Period index
130     * 
131     * @return index of the period within all examination periods
132     */
133    public int getIndex() {
134        return iIndex;
135    }
136
137    /**
138     * Period weight to be used to penalize unpopular periods
139     * 
140     * @return period weight
141     */
142    public int getPenalty() {
143        return iPenalty;
144    }
145
146    /**
147     * Previous period
148     * 
149     * @return period with index equal to index-1, null if this is the first
150     *         period
151     */
152    public ExamPeriod prev() {
153        return iPrev;
154    }
155
156    /**
157     * Next period
158     * 
159     * @return period with index equal to index+1, null if this is the last
160     *         period
161     */
162    public ExamPeriod next() {
163        return iNext;
164    }
165
166    /**
167     * Set priod indexes (only to be used by
168     * {@link ExamModel#addPeriod(Long, String, String, int, int)})
169     * 
170     * @param index
171     *            period index
172     * @param day
173     *            day index
174     * @param time
175     *            time index
176     */
177    public void setIndex(int index, int day, int time) {
178        iIndex = index;
179        iDay = day;
180        iTime = time;
181    }
182
183    /**
184     * Set previous period (only to be used by
185     * {@link ExamModel#addPeriod(Long, String, String, int, int)})
186     * 
187     * @param prev
188     *            previous period
189     */
190    public void setPrev(ExamPeriod prev) {
191        iPrev = prev;
192    }
193
194    /**
195     * Set next period (only to be used by
196     * {@link ExamModel#addPeriod(Long, String, String, int, int)})
197     * 
198     * @param next
199     *            next period
200     */
201    public void setNext(ExamPeriod next) {
202        iNext = next;
203    }
204
205    /**
206     * String representation
207     * 
208     * @return day string time string
209     */
210    @Override
211    public String toString() {
212        return getDayStr() + " " + getTimeStr();
213    }
214
215    /**
216     * String representation for debuging purposes
217     * 
218     * @return day string time string (idx: index, day: day index, time: time
219     *         index, weight: period penalty, prev: previous period, next: next
220     *         period)
221     */
222    public String toDebugString() {
223        return getDayStr() + " " + getTimeStr() + " (idx:" + getIndex() + ", day:" + getDay() + ", time:" + getTime()
224                + ", penalty:" + getPenalty()
225                + (prev() == null ? "" : ", prev:" + prev().getDayStr() + " " + prev().getTimeStr() + ")")
226                + (next() == null ? "" : ", next:" + next().getDayStr() + " " + next().getTimeStr() + ")");
227    }
228
229    @Override
230    public int hashCode() {
231        return iIndex;
232    }
233
234    @Override
235    public boolean equals(Object o) {
236        if (o == null || !(o instanceof ExamPeriod))
237            return false;
238        return getIndex() == ((ExamPeriod) o).getIndex();
239    }
240
241    @Override
242    public int compareTo(ExamPeriod p) {
243        return Double.compare(getIndex(), p.getIndex());
244    }
245}