package de.dhbw.humbuch.viewmodel;

import java.util.Collection;
import java.util.Date;

import org.hibernate.criterion.Restrictions;

import com.google.common.eventbus.EventBus;
import com.google.inject.Inject;

import de.davherrmann.mvvm.ActionHandler;
import de.davherrmann.mvvm.BasicState;
import de.davherrmann.mvvm.State;
import de.davherrmann.mvvm.annotations.AfterVMBinding;
import de.davherrmann.mvvm.annotations.HandlesAction;
import de.davherrmann.mvvm.annotations.ProvidesState;
import de.dhbw.humbuch.event.MessageEvent;
import de.dhbw.humbuch.event.MessageEvent.Type;
import de.dhbw.humbuch.model.DAO;
import de.dhbw.humbuch.model.entity.BorrowedMaterial;
import de.dhbw.humbuch.model.entity.Category;
import de.dhbw.humbuch.model.entity.TeachingMaterial;

public class BookManagementViewModel {

	public interface TeachingMaterials extends
			State<Collection<TeachingMaterial>> {
	}

	public interface Categories extends State<Collection<Category>> {
	}

	public interface DoUpdateTeachingMaterial extends ActionHandler {
	}

	public interface DoFetchTeachingMaterial extends ActionHandler {
	}

	public interface DoDeleteTeachingMaterial extends ActionHandler {
	}

	public interface DoUpdateCategory extends ActionHandler {
	}

	@ProvidesState(TeachingMaterials.class)
	public final State<Collection<TeachingMaterial>> teachingMaterials = new BasicState<>(
			Collection.class);

	@ProvidesState(Categories.class)
	public final State<Collection<Category>> categories = new BasicState<>(
			Collection.class);

	private DAO<TeachingMaterial> daoTeachingMaterial;
	private DAO<Category> daoCategory;
	private DAO<BorrowedMaterial> daoBorrowedMaterial;
	private EventBus eventBus;

	/**
	 * Constructor
	 * 
	 * @param daoTeachingMaterial
	 *            DAO implementation to access TeachingMaterial entities
	 */
	@Inject
	public BookManagementViewModel(DAO<TeachingMaterial> daoTeachingMaterial,
			DAO<Category> daoCategory,
			DAO<BorrowedMaterial> daoBorrowedMaterial, EventBus eventBus) {
		this.daoTeachingMaterial = daoTeachingMaterial;
		this.daoCategory = daoCategory;
		this.daoBorrowedMaterial = daoBorrowedMaterial;
		this.eventBus = eventBus;
	}

	@AfterVMBinding
	private void afterVMBinding() {
		updateTeachingMaterials();
		updateCategories();
	}

	private void updateTeachingMaterials() {
		teachingMaterials.set(daoTeachingMaterial.findAll());
	}

	private void updateCategories() {
		categories.set(daoCategory.findAll());
	}

	/**
	 * Either persist a newly created TeachingMaterial or update an existing one
	 * 
	 * @param teachingMaterial
	 *            a TeachingMaterial to be persisted or updated
	 */
	@HandlesAction(DoUpdateTeachingMaterial.class)
	public void doUpdateTeachingMaterial(TeachingMaterial teachingMaterial) {
		if (teachingMaterial == null) {
			return;
		}
		daoTeachingMaterial.update(teachingMaterial);
		updateTeachingMaterials();
	}


	/**
	 * Deletes the teaching material or sets the validUntil date to the current
	 * Date. This decision depends on whether the teaching material is borrowed
	 * by a student.
	 * 
	 * @param teachingMaterial
	 *            the teacing material to be updated or deleted
	 */
	@HandlesAction(DoDeleteTeachingMaterial.class)
	public void doDeleteTeachingMaterial(TeachingMaterial teachingMaterial) {
		Collection<BorrowedMaterial> borrowedMaterial = daoBorrowedMaterial
				.findAllWithCriteria(Restrictions.eq("teachingMaterial",
						teachingMaterial));
		if (borrowedMaterial.isEmpty()) {
			daoTeachingMaterial.delete(teachingMaterial);
			updateTeachingMaterials();
			eventBus.post(new MessageEvent("Löschen erfolgreich",
					"Das Lehrmittel wurde gelöscht.", Type.INFO));
		} else {
			teachingMaterial.setValidUntil(new Date());
			daoTeachingMaterial.update(teachingMaterial);
			updateTeachingMaterials();
			eventBus.post(new MessageEvent("Löschen nicht möglich",
					"Das Lehrmittel ist noch ausgeliehen.", Type.INFO));
		}
	}
}

@@ -2891,17 +2891,16 @@
 ();%0A%09%7D%0A%0A
-%0A
 %09/**%0A%09 *
@@ -3385,16 +3385,23 @@
 riteria(
+%0A%09%09%09%09%09%09
 Restrict
@@ -3427,23 +3427,17 @@
 terial%22,
-%0A%09%09%09%09%09%09
+ 
 teaching
@@ -3445,16 +3445,57 @@
 aterial)
+,%0A%09%09%09%09%09%09Restrictions.eq(%22received%22, true)
 );%0A%09%09if 
@@ -3876,32 +3876,38 @@
 ew MessageEvent(
+%0A%09%09%09%09%09
 %22L%C3%B6schen nicht m
@@ -3957,19 +3957,89 @@
 eliehen.
-%22, 
+ Das G%C3%BCltigkeitsdatum wurde jedoch auf das heutige Datum gesetzt.%22,%0A%09%09%09%09%09
 Type.INF

Fix deletion of not yet borrowed materials