Place.java 7.69 KB
/*
 * Copyright Codecrew Ry
 * 
 * All rights reserved.
 * 
 * This license applies to any software containing a notice placed by the 
 * copyright holder. Such software is herein referred to as the Software. 
 * This license covers modification, distribution and use of the Software. 
 * 
 * Any distribution and use in source and binary forms, with or without 
 * modification is not permitted without explicit written permission from the 
 * copyright owner. 
 * 
 * A non-exclusive royalty-free right is granted to the copyright owner of the 
 * Software to use, modify and distribute all modifications to the Software in 
 * future versions of the Software. 
 * 
 */
package fi.codecrew.moya.model;

import java.awt.Color;
import java.util.Calendar;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import fi.codecrew.moya.utilities.NumericStringComparator;

/**
 * 
 */
@Entity
@Table(name = "places")
public class Place extends GenericEntity implements Comparable<Place> {

	/**
     * 
     */
	private static final long serialVersionUID = -5314851260772328611L;

	@Lob
	@Column(name = "place_description")
	private String description;
	@Column(name = "place_name")
	private String name;
	@Column(name = "map_x")
	private int mapX = 0;
	@Column(name = "map_y")
	private int mapY = 0;
	@Column(name = "width")
	private int width = 0;
	@Column(name = "height")
	private int height = 0;
	@Column(name = "release_time")
	@Temporal(TemporalType.TIMESTAMP)
	private Calendar releaseTime;
	@Column(name = "place_details")
	@Lob
	private String details = "";
	@Column(name = "place_code")
	private String code = "";

	@OneToOne(mappedBy = "placeReservation")
	private GroupMembership placeReserver;

	@Column(name = "buyable", nullable = false)
	private boolean buyable = true;

	@Column(nullable = false)
	private boolean disabled = false;
	/**
	 * Which group has bought the place
	 */
	@ManyToOne
	@JoinColumn(name = "group_id", referencedColumnName = "id")
	private PlaceGroup group;

	@ManyToOne
	@JoinColumn(name = "provided_role_id", referencedColumnName = Role.ID_COLUMN)
	private Role providesRole;

	@JoinColumn(name = "map_id", referencedColumnName = EventMap.ID_COLUMN, nullable = true)
	@ManyToOne(optional = true, cascade = CascadeType.ALL)
	private EventMap map;
	/**
	 * Which ticket type is this place sold as
	 */
	@JoinColumn(name = "products_id", referencedColumnName = Product.ID_COLUMN)
	@ManyToOne()
	private Product product;
	/**
	 * Who is the current currentUser (mapped with code printed on the place) of
	 * the place. Used in Vectorama currentUser tracking.
	 */
	@JoinColumn(name = "current_eventuser_id", referencedColumnName = EventUser.ID_COLUMN)
	@ManyToOne
	private EventUser currentUser;

	public static enum PlaceState {
		FREE, DISABLED, LOCKED, TEMP_RESERVED_FORME,
		MY_PLACE, RESERVED
	}

	public PlaceState getState(EventUser user)
	{
		PlaceState ret = PlaceState.FREE;
		if (isDisabled()) {
			ret = PlaceState.DISABLED;
		} else {

			if (!isBuyable()) {
				ret = PlaceState.LOCKED;
			}
			if (isTaken()) {
				ret = PlaceState.RESERVED;
				//	logger.debug("Setting place Reserved {}", p);
			}
		}
		if (user != null) {
			if (isReservedFor(user)) {
				ret = PlaceState.TEMP_RESERVED_FORME;
			} else if (user.equals(getCurrentUser())
					|| (getGroup() != null && user.equals(getGroup().getCreator()))
					|| (getPlaceReserver() != null && user.equals(getPlaceReserver().getUser()))) {
				ret = PlaceState.MY_PLACE;

			}
		}

		return ret;
	}

	public Place() {
		super();
	}

	public Place(EventMap eventMap) {
		super();
		this.map = eventMap;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String placeDescription) {
		this.description = placeDescription;
	}

	public String getName() {
		return name;
	}

	public void setName(String placeName) {
		this.name = placeName;
	}

	public Integer getMapX() {
		return mapX;
	}

	public void setMapX(Integer mapX) {
		this.mapX = mapX;
	}

	public Integer getMapY() {
		return mapY;
	}

	public void setMapY(Integer mapY) {
		this.mapY = mapY;
	}

	public String getDetails() {
		return details;
	}

	public void setDetails(String placeDetails) {
		this.details = placeDetails;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String placeCode) {
		this.code = placeCode;
	}

	public PlaceGroup getGroup() {
		return group;
	}

	public void setGroup(PlaceGroup group) {
		if (group != null && map != null && !group.getEvent().equals(map.getEvent())) {
			throw new RuntimeException("Can not set Group from different Event to Place!");
		}
		this.group = group;
	}

	public EventMap getMap() {
		return map;
	}

	public void setMap(EventMap map) {
		this.map = map;
	}

	public Product getProduct() {
		return product;
	}

	public void setProduct(Product productsId) {
		this.product = productsId;
	}

	public EventUser getCurrentUser() {
		return currentUser;
	}

	public void setCurrentUser(EventUser usersId) {
		this.currentUser = usersId;
	}

	public void setPlaceReserver(GroupMembership placeReserver) {
		this.placeReserver = placeReserver;
	}

	public GroupMembership getPlaceReserver() {
		return placeReserver;
	}

	/**
	 * @return the height
	 */
	public Integer getHeight() {
		return height;
	}

	/**
	 * @param height
	 *            the height to set
	 */
	public void setHeight(Integer height) {
		this.height = height;
	}

	/**
	 * @return the width
	 */
	public Integer getWidth() {
		return width;
	}

	/**
	 * @param width
	 *            the width to set
	 */
	public void setWidth(Integer width) {
		this.width = width;
	}

	public boolean isTaken() {

		return (getReleaseTime() != null || getGroup() != null);
	}

	/**
	 * 
	 * @return Is the place reserved ( not bought for user)
	 */
	public boolean isReservedFor(EventUser u) {
		return (u.equals(getCurrentUser()) && getGroup() == null);
	}

	/**
	 * Check if the places releasetime has expired and it should be released for
	 * shopping
	 * 
	 * @return If the status of thie entity changed and it should be merged.
	 */
	public boolean checkReleased() {
		boolean ret = false;
		if (getGroup() == null && getReleaseTime() != null && Calendar.getInstance().after(getReleaseTime())) {
			setCurrentUser(null);
			setReleaseTime(null);
			ret = true;
		}
		return ret;
	}

	public void setBuyable(boolean buyable) {
		this.buyable = buyable;
	}

	public boolean isBuyable() {
		return buyable;
	}

	public void setReleaseTime(Calendar releaseTime) {
		this.releaseTime = releaseTime;
	}

	public Calendar getReleaseTime() {
		return releaseTime;
	}

	public void setProvidesRole(Role providesRole) {
		this.providesRole = providesRole;
	}

	public Role getProvidesRole() {
		return providesRole;
	}

	public boolean isDisabled() {
		return disabled;
	}

	public void setDisabled(boolean disabled) {
		this.disabled = disabled;
	}

	/**
	 * Note: this class has a natural ordering that is inconsistent with equals.
	 */
	@Override
	@Transient
	public int compareTo(Place o) {

		if (this.equals(o)) {
			return 0;
		}

		// Check null values;
		// Null is smaller than non null value.
		if (this.getName() == null || o.getName() == null) {
			if (this.getName() == null) {
				return 1;
			}
			if (o.getName() == null) {
				return -1;
			}
			// both names are null. Compare IDs
			return this.getNonNullId().compareTo(o.getNonNullId());
		}

		if (this.getName().equals(o.getName())) {
			return 0;
		}

		return NumericStringComparator.numericCompare(this.getName(), o.getName());
	}

}