/*
* Copyright (c) 2006-2009 by Dirk Riehle, http://dirkriehle.com
*
* This file is part of the Wahlzeit photo rating application.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/
package org.wahlzeit.model;
import com.google.api.client.util.ArrayMap;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.images.Image;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Parent;
import org.wahlzeit.services.DataObject;
import org.wahlzeit.services.EmailAddress;
import org.wahlzeit.services.Language;
import org.wahlzeit.services.ObjectManager;
import java.util.Map;
/**
* A photo represents a user-provided (uploaded) photo.
*/
@Entity
public class Photo extends DataObject {
/**
*
*/
public static final String IMAGE = "image";
public static final String THUMB = "thumb";
public static final String LINK = "link";
public static final String PRAISE = "praise";
public static final String NO_VOTES = "noVotes";
public static final String CAPTION = "caption";
public static final String DESCRIPTION = "description";
public static final String KEYWORDS = "keywords";
public static final String TAGS = "tags";
public static final String OWNER_ID = "ownerId";
public static final String STATUS = "status";
public static final String IS_INVISIBLE = "isInvisible";
public static final String UPLOADED_ON = "uploadedOn";
/**
*
*/
public static final int MAX_PHOTO_WIDTH = 420;
public static final int MAX_PHOTO_HEIGHT = 600;
public static final int MAX_THUMB_PHOTO_WIDTH = 105;
public static final int MAX_THUMB_PHOTO_HEIGHT = 150;
protected PhotoId id = null;
/**
*
*/
protected String ownerId;
/**
* Each photo can be viewed in different sizes (XS, S, M, L, XL)
* Images are pre-computed in these sizes to optimize bandwidth when requested.
*/
@Ignore
transient protected Map<PhotoSize, Image> images = new ArrayMap<PhotoSize, Image>();
/**
*
*/
protected boolean ownerNotifyAboutPraise = false;
protected EmailAddress ownerEmailAddress = EmailAddress.EMPTY;
protected Language ownerLanguage = Language.ENGLISH;
/**
*
*/
protected int width;
protected int height;
protected PhotoSize maxPhotoSize = PhotoSize.MEDIUM; // derived
/**
*
*/
protected Tags tags = Tags.EMPTY_TAGS;
/**
*
*/
protected PhotoStatus status = PhotoStatus.VISIBLE;
/**
*
*/
protected int praiseSum = 10;
protected int noVotes = 1;
protected int noVotesAtLastNotification = 1;
/**
*
*/
protected long creationTime = System.currentTimeMillis();
/**
* The default type is jpg
*/
protected String ending = "jpg";
/**
*
*/
//TODO: change it to a single long
@Id
Long idLong;
@Parent
Key parent = ObjectManager.applicationRootKey;
/**
*
*/
public Photo() {
id = PhotoId.getNextId();
incWriteCount();
}
/**
* @methodtype constructor
*/
public Photo(PhotoId myId) {
id = myId;
incWriteCount();
}
/**
* @methodtype get
*/
public Image getImage(PhotoSize photoSize) {
return images.get(photoSize);
}
/**
* @methodtype set
*/
public void setImage(PhotoSize photoSize, Image image) {
this.images.put(photoSize, image);
}
/**
* @methodtype get
*/
public String getIdAsString() {
return id.asString();
}
/**
* @methodtype get
*/
public PhotoId getId() {
return id;
}
/**
* @methodtype get
*/
public String getOwnerId() {
return ownerId;
}
/**
* @methodtype set
*/
public void setOwnerId(String newName) {
ownerId = newName;
incWriteCount();
}
/**
* @methodtype get
*/
public String getSummary(ModelConfig cfg) {
return cfg.asPhotoSummary(ownerId);
}
/**
* @methodtype get
*/
public String getCaption(ModelConfig cfg) {
String ownerName = UserManager.getInstance().getUserById(ownerId).getNickName();
return cfg.asPhotoCaption(ownerName);
}
/**
* @methodtype get
*/
public boolean getOwnerNotifyAboutPraise() {
return ownerNotifyAboutPraise;
}
/**
* @methodtype set
*/
public void setOwnerNotifyAboutPraise(boolean newNotifyAboutPraise) {
ownerNotifyAboutPraise = newNotifyAboutPraise;
incWriteCount();
}
/**
*
*/
public Language getOwnerLanguage() {
return ownerLanguage;
}
/**
*
*/
public void setOwnerLanguage(Language newLanguage) {
ownerLanguage = newLanguage;
incWriteCount();
}
/**
* @methodtype boolean-query
*/
public boolean hasSameOwner(Photo photo) {
return photo.getOwnerEmailAddress().equals(ownerEmailAddress);
}
/**
* @methodtype get
*/
public EmailAddress getOwnerEmailAddress() {
return ownerEmailAddress;
}
/**
* @methodtype set
*/
public void setOwnerEmailAddress(EmailAddress newEmailAddress) {
ownerEmailAddress = newEmailAddress;
incWriteCount();
}
/**
* @methodtype get
*/
public int getWidth() {
return width;
}
/**
* @methodtype get
*/
public int getHeight() {
return height;
}
/**
* @methodtype get
*/
public int getThumbWidth() {
return isWiderThanHigher() ? MAX_THUMB_PHOTO_WIDTH : (width * MAX_THUMB_PHOTO_HEIGHT / height);
}
/**
* @methodtype boolean-query
*/
public boolean isWiderThanHigher() {
return (height * MAX_PHOTO_WIDTH) < (width * MAX_PHOTO_HEIGHT);
}
/**
* @methodtype get
*/
public int getThumbHeight() {
return isWiderThanHigher() ? (height * MAX_THUMB_PHOTO_WIDTH / width) : MAX_THUMB_PHOTO_HEIGHT;
}
/**
* @methodtype set
*/
public void setWidthAndHeight(int newWidth, int newHeight) {
width = newWidth;
height = newHeight;
maxPhotoSize = PhotoSize.getFromWidthHeight(width, height);
incWriteCount();
}
/**
* Can this photo satisfy provided photo size?
*
* @methodtype boolean-query
*/
public boolean hasPhotoSize(PhotoSize size) {
return maxPhotoSize.asInt() >= size.asInt();
}
/**
* @methodtype get
*/
public PhotoSize getMaxPhotoSize() {
return maxPhotoSize;
}
/**
* @methodtype get
*/
public String getPraiseAsString(ModelConfig cfg) {
return cfg.asPraiseString(getPraise());
}
/**
* @methodtype get
*/
public double getPraise() {
return (double) praiseSum / noVotes;
}
/**
*
*/
public void addToPraise(int value) {
praiseSum += value;
noVotes += 1;
incWriteCount();
}
/**
* @methodtype boolean-query
*/
public boolean isVisible() {
return status.isDisplayable();
}
/**
* @methodtype get
*/
public PhotoStatus getStatus() {
return status;
}
/**
* @methodtype set
*/
public void setStatus(PhotoStatus newStatus) {
status = newStatus;
incWriteCount();
}
/**
* @methodtype boolean-query
*/
public boolean hasTag(String tag) {
return tags.hasTag(tag);
}
/**
* @methodtype get
*/
public Tags getTags() {
return tags;
}
/**
* @methodtype set
*/
public void setTags(Tags newTags) {
tags = newTags;
incWriteCount();
}
/**
* @methodtype get
*/
public long getCreationTime() {
return creationTime;
}
public String getEnding() {
return ending;
}
public void setEnding(String ending) {
this.ending = ending;
}
/**
* @methodtype boolean query
*/
public boolean hasNewPraise() {
return noVotes > noVotesAtLastNotification;
}
/**
* @methodtype set
*/
public void setNoNewPraise() {
noVotesAtLastNotification = noVotes;
incWriteCount();
}
}