/**
* Copyright © 2002 Instituto Superior Técnico
*
* This file is part of FenixEdu Academic.
*
* FenixEdu Academic is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FenixEdu Academic 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fenixedu.academic.domain;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import org.fenixedu.academic.domain.photograph.AspectRatio;
import org.fenixedu.academic.domain.photograph.Picture;
import org.fenixedu.academic.domain.photograph.PictureMode;
import org.fenixedu.academic.domain.photograph.PictureOriginal;
import org.fenixedu.academic.domain.util.email.Message;
import org.fenixedu.academic.domain.util.email.Recipient;
import org.fenixedu.academic.domain.util.email.SystemSender;
import org.fenixedu.academic.predicate.AccessControl;
import org.fenixedu.academic.util.Bundle;
import org.fenixedu.academic.util.ContentType;
import org.fenixedu.bennu.core.domain.Avatar;
import org.fenixedu.bennu.core.domain.Bennu;
import org.fenixedu.bennu.core.groups.Group;
import org.fenixedu.bennu.core.i18n.BundleUtil;
import org.imgscalr.Scalr;
import org.imgscalr.Scalr.Method;
import org.imgscalr.Scalr.Mode;
import org.joda.time.DateTime;
import pt.ist.fenixframework.Atomic;
public class Photograph extends Photograph_Base implements Comparable<Photograph> {
private static final String REJECTION_MAIL_SUBJECT_KEY = "photo.email.subject.rejection";
private static final String REJECTION_MAIL_BODY_KEY = "photo.email.body.rejection";
private Photograph() {
super();
setRootDomainObject(Bennu.getInstance());
setSubmission(new DateTime());
}
public Photograph(PhotoType photoType, ContentType contentType, byte[] original) {
this();
setPhotoType(photoType);
new PictureOriginal(this, original, contentType);
}
@Override
public Person getPerson() {
if (super.getPerson() != null) {
return super.getPerson();
}
if (getNext() != null) {
return getNext().getPerson();
}
return null;
}
@Override
public void setPhotoType(PhotoType photoType) {
super.setPhotoType(photoType);
if (photoType == PhotoType.INSTITUTIONAL) {
setState(PhotoState.APPROVED);
} else if (photoType == PhotoType.USER) {
setState(PhotoState.PENDING);
} else {
setState(PhotoState.PENDING);
}
}
@Override
public void setState(PhotoState state) {
if (getState() != state) {
super.setState(state);
setStateChange(new DateTime());
if (state == PhotoState.PENDING) {
setPendingHolder(Bennu.getInstance());
} else {
setPendingHolder(null);
}
if (state == PhotoState.REJECTED) {
logState("log.personInformation.photo.rejected");
Person person = AccessControl.getPerson();
if (person != null) {
setRejector(person);
}
SystemSender systemSender = getRootDomainObject().getSystemSender();
new Message(systemSender, systemSender.getConcreteReplyTos(),
new Recipient(getPerson().getUser().groupOf()).asCollection(), BundleUtil.getString(Bundle.PERSONAL,
REJECTION_MAIL_SUBJECT_KEY), BundleUtil.getString(Bundle.PERSONAL, REJECTION_MAIL_BODY_KEY), "");
}
if (state == PhotoState.APPROVED) {
Person person = AccessControl.getPerson();
if (person != null) {
setApprover(person);
}
if (getPhotoType() != PhotoType.INSTITUTIONAL) {
logState("log.personInformation.photo.approved");
}
}
}
}
@Override
public void setPrevious(Photograph previous) {
if (previous.getState() == PhotoState.PENDING) {
previous.setState(PhotoState.USER_REJECTED);
}
super.setPrevious(previous);
}
@Atomic
public void cancelSubmission() {
if (getState() == PhotoState.PENDING) {
setState(PhotoState.USER_REJECTED);
logState("log.personInformation.photo.canceled");
}
}
public void delete() {
setRootDomainObject(null);
if (getPendingHolder() != null) {
setPendingHolder(null);
}
setPerson(null);
Photograph prev = getPrevious();
if (prev != null) {
setPrevious(null);
prev.delete();
}
Photograph next = getNext();
if (next != null) {
setNext(null);
}
super.deleteDomainObject();
}
public byte[] getDefaultAvatar() {
return getCustomAvatar(1, 1, 100, 100, PictureMode.FIT);
}
private BufferedImage read(PictureOriginal original) {
BufferedImage image = Picture.readImage(original.getPictureData());
BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
result.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
return result;
}
public byte[] getCustomAvatar(int xRatio, int yRatio, int width, int height, PictureMode pictureMode) {
PictureOriginal original = getOriginal();
BufferedImage image =
original.getPictureFileFormat() == ContentType.JPG ? Picture.readImage(original.getPictureData()) : read(original);
return processImage(image, xRatio, yRatio, width, height, pictureMode);
}
public byte[] getCustomAvatar(AspectRatio aspectRatio, int width, int height, PictureMode pictureMode) {
return getCustomAvatar(aspectRatio.getXRatio(), aspectRatio.getYRatio(), width, height, pictureMode);
}
public byte[] getCustomAvatar(int width, int height, PictureMode pictureMode) {
return getCustomAvatar(width, height, width, height, pictureMode);
}
@Override
public int compareTo(Photograph photo) {
return getSubmission().compareTo(photo.getSubmission());
}
public void logCreate(Person person) {
if (getState() == PhotoState.PENDING) {
logState("log.personInformation.photo.created");
} else if (getState() == PhotoState.APPROVED) {
if (getPhotoType() == PhotoType.INSTITUTIONAL) {
logState("log.personInformation.photo.created.noValidation");
} else {
logState("log.personInformation.photo.approved");
}
}
}
private void logState(String keyLabel) {
final String personViewed = PersonInformationLog.getPersonNameForLogDescription(getPerson());
PersonInformationLog.createLog(getPerson(), Bundle.MESSAGING, keyLabel, personViewed);
}
public byte[] exportAsJPEG(byte[] photo, Color color) {
BufferedImage image = Picture.readImage(photo);
BufferedImage jpeg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
jpeg.createGraphics().drawImage(image, 0, 0, color, null);
return Picture.writeImage(jpeg, ContentType.JPG);
}
public byte[] exportAsJPEG(byte[] photo) {
return exportAsJPEG(photo, Color.WHITE);
}
public static byte[] mysteryManPhoto(int xRatio, int yRatio, int width, int height, PictureMode pictureMode) {
try (InputStream mm = Photograph.class.getClassLoader().getResourceAsStream("META-INF/resources/img/mysteryman.png")) {
return Avatar.process(mm, "image/png", width);
} catch (IOException e) {
return null;
}
}
private static byte[] processImage(BufferedImage image, int xRatio, int yRatio, int width, int height, PictureMode pictureMode) {
final BufferedImage transformed, scaled;
switch (pictureMode) {
case FIT:
transformed = Picture.transformFit(image, xRatio, yRatio);
break;
case ZOOM:
transformed = Picture.transformZoom(image, xRatio, yRatio);
break;
default:
transformed = Picture.transformFit(image, xRatio, yRatio);
break;
}
scaled = Scalr.resize(transformed, Method.QUALITY, Mode.FIT_EXACT, width, height);
return Picture.writeImage(scaled, ContentType.PNG);
}
}