001package org.cpsolver.coursett.model;
002
003import java.util.HashMap;
004import java.util.Map;
005
006import org.cpsolver.coursett.constraint.RoomConstraint;
007import org.cpsolver.ifs.util.DistanceMetric;
008
009/**
010 * Room part of placement. <br>
011 * <br>
012 * 
013 * @version CourseTT 1.3 (University Course Timetabling)<br>
014 *          Copyright (C) 2006 - 2014 Tomáš Müller<br>
015 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
016 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
017 * <br>
018 *          This library is free software; you can redistribute it and/or modify
019 *          it under the terms of the GNU Lesser General Public License as
020 *          published by the Free Software Foundation; either version 3 of the
021 *          License, or (at your option) any later version. <br>
022 * <br>
023 *          This library is distributed in the hope that it will be useful, but
024 *          WITHOUT ANY WARRANTY; without even the implied warranty of
025 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
026 *          Lesser General Public License for more details. <br>
027 * <br>
028 *          You should have received a copy of the GNU Lesser General Public
029 *          License along with this library; if not see
030 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
031 */
032
033public class RoomLocation implements Comparable<RoomLocation> {
034    private int iPreference;
035    private String iName;
036    private Long iId;
037    private Long iBldgId;
038    private int iRoomSize;
039    private Double iPosX = null, iPosY = null;
040    private RoomConstraint iRoomConstraint = null;
041    private boolean iIgnoreTooFar = false;
042    private Map<Integer, Integer> iPreferenceByIndex = null;
043
044    /**
045     * Constructor
046     * 
047     * @param id
048     *            room id
049     * @param name
050     *            room name
051     * @param bldgId
052     *            building id
053     * @param preference
054     *            soft preference
055     * @param size
056     *            room size
057     * @param x
058     *            x-position of the building
059     * @param y
060     *            y-position of the building
061     * @param ignoreTooFar true if distance conflicts are to be ignored
062     * @param rc related room constraint
063     */
064    public RoomLocation(Long id, String name, Long bldgId, int preference, int size, Double x, Double y,
065            boolean ignoreTooFar, RoomConstraint rc) {
066        iId = id;
067        iName = name;
068        iPreference = preference;
069        iRoomSize = size;
070        iPosX = x;
071        iPosY = y;
072        iBldgId = bldgId;
073        iRoomConstraint = rc;
074        iIgnoreTooFar = ignoreTooFar;
075    }
076
077    /** Room id 
078     * @return room unique id
079     **/
080    public Long getId() {
081        return iId;
082    }
083
084    /** Building id 
085     * @return building unique id
086     **/
087    public Long getBuildingId() {
088        return iBldgId;
089    }
090
091    /** Room name 
092     * @return room name
093     **/
094    public String getName() {
095        return iName;
096    }
097
098    /** Room preference 
099     * @return room preference
100     **/
101    public int getPreference() {
102        return iPreference;
103    }
104
105    /** 
106     * Set room preference
107     * @param preference room preferences
108     */
109    public void setPreference(int preference) {
110        iPreference = preference;
111    }
112
113    /** Room size 
114     * @return room size
115     **/
116    public int getRoomSize() {
117        return iRoomSize;
118    }
119
120    /** Position of the building
121     * @param x X-coordinate (latitude) 
122     * @param y Y-coordinate (longitude)
123     **/
124    public void setCoordinates(Double x, Double y) {
125        iPosX = x;
126        iPosY = y;
127    }
128
129    /** X-position of the building 
130     * @return X-coordinate (latitude)
131     **/
132    public Double getPosX() {
133        return iPosX;
134    }
135
136    /** Y-position of the building
137     * @return Y-coordinate (longitude)
138     **/
139    public Double getPosY() {
140        return iPosY;
141    }
142
143    public boolean getIgnoreTooFar() {
144        return iIgnoreTooFar;
145    }
146
147    public RoomConstraint getRoomConstraint() {
148        return iRoomConstraint;
149    }
150
151    @Override
152    public String toString() {
153        return "Room{name=" + iName + ", pref=" + iPreference + "}";
154    }
155
156    @Override
157    public boolean equals(Object o) {
158        if (o == null || !(o instanceof RoomLocation))
159            return false;
160        return getId().equals(((RoomLocation) o).getId());
161    }
162
163    public double getDistanceInMeters(DistanceMetric m, RoomLocation roomLocation) {
164        if (getId().equals(roomLocation.getId()))
165            return 0.0;
166        if (getIgnoreTooFar() || roomLocation.getIgnoreTooFar())
167            return 0.0;
168        return m.getDistanceInMeters(getId(), getPosX(), getPosY(), roomLocation.getId(), roomLocation.getPosX(), roomLocation.getPosY());
169    }
170
171    public int getDistanceInMinutes(DistanceMetric m, RoomLocation roomLocation) {
172        if (getId().equals(roomLocation.getId()))
173            return 0;
174        if (getIgnoreTooFar() || roomLocation.getIgnoreTooFar())
175            return 0;
176        return  m.getDistanceInMinutes(getId(), getPosX(), getPosY(), roomLocation.getId(), roomLocation.getPosX(), roomLocation.getPosY());
177    }
178
179    @Override
180    public int compareTo(RoomLocation o) {
181        int cmp = -(Long.valueOf(getRoomSize())).compareTo(Long.valueOf(o.getRoomSize()));
182        if (cmp != 0)
183            return cmp;
184        return getName().compareTo((o).getName());
185    }
186
187    @Override
188    public int hashCode() {
189        return getId().hashCode();
190    }
191
192    /**
193     * Support for multiple rooms with different preferences: override default room preference for the given index
194     */
195    public int getPreference(int roomIndex) {
196        if (iPreferenceByIndex == null) return iPreference;
197        Integer pref = iPreferenceByIndex.get(roomIndex);
198        return (pref == null ? iPreference : pref);
199    }
200    /**
201     * Support for multiple rooms with different preferences: override default room preference for the given index
202     */
203    public void setPreference(int roomIndex, int preference) {
204        if (iPreferenceByIndex == null) iPreferenceByIndex = new HashMap<Integer, Integer>();
205        iPreferenceByIndex.put(roomIndex, preference);
206    }
207    /**
208     * Support for multiple rooms with different preferences: has preference overrides for particular rooms
209     */
210    public boolean hasPreferenceByIndex() { return iPreferenceByIndex != null && !iPreferenceByIndex.isEmpty(); }
211    /**
212     * Support for multiple rooms with different preferences: return preference overrides
213     */
214    public Map<Integer, Integer> getPreferenceByIndex() { return iPreferenceByIndex; }
215    
216    /**
217     * Support for multiple rooms with different preferences: return min preference
218     */
219    public int getMinPreference() {
220        int ret = getPreference();
221        if (iPreferenceByIndex != null)
222            for (Integer pref: iPreferenceByIndex.values())
223                if (pref < ret) ret = pref;
224        return ret;
225    }
226    /**
227     * Support for multiple rooms with different preferences: return max preference
228     */
229    public int getMaxPreference() {
230        int ret = getPreference();
231        if (iPreferenceByIndex != null)
232            for (Integer pref: iPreferenceByIndex.values())
233                if (pref > ret) ret = pref;
234        return ret;
235    }
236}