package com.din.din.webapp.beans.interfaces.wrappers;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.primefaces.model.DefaultScheduleEvent;
import com.din.din.model.dao.PlannedMenuDAO;
import com.din.din.model.dao.RecipeDAO;
import com.din.din.model.entities.KeyEntity;
import com.din.din.model.entities.PlannedMenu;
import com.din.din.model.entities.PlannedMenuEvent;
import com.din.din.model.entities.PlannedMenuEvent.MealType;
import com.din.din.model.entities.Project;
import com.din.din.model.entities.Recipe;
import com.din.din.model.util.EntityCachingManager;
import com.din.din.model.util.EntityCachingManager.CacheLoader;
import com.din.din.webapp.beans.interfaces.RecipeManager;
import com.din.din.webapp.beans.util.BeanUtil;
import com.google.appengine.api.datastore.Key;
public class DinDinScheduleEvent extends DefaultScheduleEvent implements Serializable {
private static final long serialVersionUID = -7805781269248360753L;
private EntityCachingManager cache = null;
private Recipe recipe = null;
private Project project = null;
private PlannedMenuEvent revision = null;
public DinDinScheduleEvent(Date day, final Project project, EntityCachingManager cache) {
super("", day, day, true);
this.cache = cache;
this.project = project;
PlannedMenuEvent plannedMenuEvent = new PlannedMenuEvent();
plannedMenuEvent.setEventDay(day);
try {
List<KeyEntity> plannedMenus = cache.getChildren(PlannedMenu.class, "project", project, new CacheLoader<PlannedMenu>() {
public List<PlannedMenu> onCacheLoad() {
return PlannedMenuDAO.getPlannedMenuByProject(project);
}
});
PlannedMenu plannedMenu = plannedMenus != null && plannedMenus.size() > 0 ? (PlannedMenu)plannedMenus.get(0) : new PlannedMenu();
plannedMenuEvent.setPlannedMenu(plannedMenu);
} catch (Exception e) {
e.printStackTrace();
}
setData(plannedMenuEvent);
}
public DinDinScheduleEvent(PlannedMenuEvent event, Project project, EntityCachingManager cache) {
this(event.getEventDay(), project, cache);
setData(event);
refreshEvent();
}
public void beginEdit() {
if(revision == null) {
PlannedMenuEvent event = (PlannedMenuEvent)super.getData();
revision = (PlannedMenuEvent)BeanUtil.copy(event);
}
}
public void endEdit() {
revision = null;
}
public synchronized void save() throws Exception {
if(revision != null) {
PlannedMenuEvent event = (PlannedMenuEvent)super.getData();
if(event.getPlannedMenu() != null) {
PlannedMenu plannedMenu = event.getPlannedMenu();
PlannedMenuEvent oldEvent = (PlannedMenuEvent)BeanUtil.copy(event);
BeanUtil.copyProperties(revision, event);
// Perform save of parent. In case of error, restore original values
try {
if(plannedMenu.getKey() == null) {
plannedMenu.setProject(project);
List<PlannedMenu> plannedMenus = new ArrayList<PlannedMenu>();
plannedMenus.add(plannedMenu);
project.setPlannedMenus(plannedMenus);
}
plannedMenu.getPlannedMenuEvents().add(event);
PlannedMenuDAO.save(plannedMenu, cache);
} catch (Exception e) {
BeanUtil.copyProperties(oldEvent, event);
throw e;
}
} else {
throw new IllegalStateException("Planned menu event expected to have parent.");
}
}
}
@Override
public void setStartDate(Date startDate) {
super.setStartDate(startDate);
getData().setEventDay(startDate);
}
@Override
public PlannedMenuEvent getData() {
return revision != null ? revision : (PlannedMenuEvent)super.getData();
}
public void refreshEvent() {
PlannedMenuEvent event = getData();
setAllDay(true);
setEditable(true);
setStartDate(event.getEventDay());
setEndDate(event.getEventDay());
String key = event.getMealType() != null ? event.getMealType().toString() : "Unknown";
setTitle(BeanUtil.getMessage(key));
}
public MealType getMealType() {
return getData().getMealType();
}
public void setMealType(MealType type) {
getData().setMealType(type);
}
public Recipe getRecipe() {
if(recipe == null && getData().getRecipeKey() != null) {
recipe = (Recipe)cache.get(Recipe.class, getData().getRecipeKey(), true, new CacheLoader<Recipe>() {
public List<Recipe> onCacheLoad() {
return RecipeDAO.getRecipesByProject(project);
}
});
if(recipe != null && (recipe.getRecipeItems() == null || recipe.getRecipeItems().size() == 0)) {
try {
RecipeDAO.loadRecipeItems(recipe, cache);
} catch (Exception e) {
Logger.getLogger(RecipeManager.class.getName()).log(Level.WARNING, "Unable to load RecipeItem list", e);
e.printStackTrace();
}
}
}
return recipe;
}
public void setRecipe(Recipe recipe) {
this.recipe = recipe;
Key key = recipe != null ? recipe.getKey() : null;
getData().setRecipeKey(key);
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((cache == null) ? 0 : cache.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
DinDinScheduleEvent other = (DinDinScheduleEvent) obj;
if (cache == null) {
if (other.cache != null)
return false;
} else if (!cache.equals(other.cache))
return false;
return true;
}
}