package com.din.din.webapp.beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.faces.model.SelectItemGroup;
import org.primefaces.event.CloseEvent;
import org.primefaces.event.ScheduleEntryMoveEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.ScheduleModel;
import com.din.din.model.dao.RecipeDAO;
import com.din.din.model.entities.KeyEntity;
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.EventManager;
import com.din.din.webapp.beans.interfaces.wrappers.DinDinScheduleEvent;
import com.din.din.webapp.beans.util.BeanUtil;
@ManagedBean
@SessionScoped
public class PlannerBean implements Serializable {
private static final long serialVersionUID = 7794739024335991344L;
private static MealType [] mealTypes = MealType.values();
private EventManager eventManager = null;
private DinDinScheduleEvent selected = null;
@ManagedProperty("#{cacheBean.cache}")
private EntityCachingManager cache = null;
@ManagedProperty("#{projectBean.project}")
private Project project = null;
public PlannerBean() {
}
public ScheduleModel getEventModel() {
assert(eventManager != null);
return eventManager.getEventModel();
}
public DinDinScheduleEvent getSelected() {
return selected;
}
public void setSelected(DinDinScheduleEvent selected) {
this.selected = selected;
}
public EntityCachingManager getCache() {
return cache;
}
public void setCache(EntityCachingManager cache) {
this.cache = cache;
initEventManager();
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
initEventManager();
}
public MealType[] getMealTypes() {
return mealTypes;
}
private void initEventManager() {
if(project != null && cache != null && eventManager == null) {
eventManager = new EventManager(project, cache);
}
}
public void onDateSelect(SelectEvent selectEvent) {
selected = new DinDinScheduleEvent((Date)selectEvent.getObject(), project, cache);
selected.beginEdit();
}
public void onEventSelect(SelectEvent selectEvent) {
selected = (DinDinScheduleEvent) selectEvent.getObject();
selected.beginEdit();
}
public void onEventClose(CloseEvent event) {
if(selected != null) {
selected.endEdit();
} else {
Logger.getLogger(PlannerBean.class.getName()).log(Level.WARNING, "Event window closed when no event selected!");
}
}
public synchronized void onEventMove(ScheduleEntryMoveEvent event) {
// Weird bug where moved events get moved twice the day delta. This compensates and makes it accurate.
// There may be unforeseen consequences. Be wary!
selected = (DinDinScheduleEvent)event.getScheduleEvent();
if(event.getDayDelta() != 0) {
Date eventDate = selected.getStartDate();
Calendar calendar = Calendar.getInstance();
calendar.setTime(eventDate);
calendar.add(Calendar.DAY_OF_MONTH, -event.getDayDelta());
selected.setStartDate(calendar.getTime());
selected.setEndDate(calendar.getTime());
save();
// if(FacesContext.getCurrentInstance().isValidationFailed()) {
// calendar.add(Calendar.DAY_OF_MONTH, -event.getDayDelta());
// selected.setStartDate(calendar.getTime());
// selected.setEndDate(calendar.getTime());
// eventManager.addEvent(selected);
// }
}
}
public synchronized String save() {
if(eventManager.isValid(selected)) {
try {
selected.save();
selected.refreshEvent();
eventManager.addEvent(selected);
} catch (Exception e) {
FacesContext.getCurrentInstance().validationFailed();
}
String plannedMenuEventLocalized = BeanUtil.getMessage("PlannedMenuEvent");
BeanUtil.addMessageFmt(FacesMessage.SEVERITY_INFO, "save.success", "save.success.message", plannedMenuEventLocalized);
} else {
String mealTypeLocalized = BeanUtil.getMessage(selected.getMealType().toString());
String dateString = BeanUtil.getDateString(selected.getStartDate());
BeanUtil.addMessageFmt(FacesMessage.SEVERITY_ERROR, "save.error", "edit.plannedMenuEvent.error.existingSlot", mealTypeLocalized, dateString);
FacesContext.getCurrentInstance().validationFailed();
}
return null;
}
public List<SelectItem> getRecipeList() {
List<SelectItem> recipeList = new ArrayList<SelectItem>();
Map<Object, List<KeyEntity>> recipeMapping = null;
try {
recipeMapping = cache.getMapped(Recipe.class, "category", "project", project, new CacheLoader<Recipe>() {
public List<Recipe> onCacheLoad() {
return RecipeDAO.getRecipesByProject(project);
}
});
} catch (Exception e) {
e.printStackTrace();
}
if(recipeMapping != null) {
for(Entry<Object, List<KeyEntity>> entry : recipeMapping.entrySet()) {
SelectItemGroup group = new SelectItemGroup(entry.getKey().toString());
List<KeyEntity> sublist = entry.getValue();
if(sublist.size() > 0) {
List<SelectItem> selectSublist = new ArrayList<SelectItem>();
for(KeyEntity entity : sublist) {
Recipe recipe = (Recipe)entity;
SelectItem item = new SelectItem(recipe, recipe.getTitle());
selectSublist.add(item);
}
group.setSelectItems(selectSublist.toArray(new SelectItem[0]));
recipeList.add(group);
}
}
}
return recipeList;
}
}