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