/*
 * Copyright (c) 2011, Patrik Dufresne. All rights reserved.
 * Patrik Dufresne PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.planimod.ui.views.planif;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.Collections;

import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.IObservableValue;

import com.patrikdufresne.managers.ManagerException;
import com.patrikdufresne.managers.databinding.ManagedObjectComputedSet;
import com.planimod.core.Employee;
import com.planimod.core.GeneratePlanifContext;
import com.planimod.core.Task;
import com.planimod.ui.PlanimodPolicy;

/**
 * This observable set provide collection of {@link Task}. This function is
 * wrapping the {@link GeneratePlanifContext#listTaskByEmployee(Employee)}.
 * 
 * @author Patrik Dufresne
 * 
 */
public class TaskByEmployeeComputedSet extends ManagedObjectComputedSet {
	/**
	 * The managers.
	 */
	private GeneratePlanifContext context;
	/**
	 * Observable employee.
	 */
	private IObservableValue employee;
	/**
	 * Property listener
	 */
	private PropertyChangeListener listener = new PropertyChangeListener() {
		@Override
		public void propertyChange(PropertyChangeEvent evt) {
			getRealm().exec(new Runnable() {
				@Override
				public void run() {
					makeDirty();
				}
			});
		}
	};

	/**
	 * Create a new observable set of employee.
	 * 
	 * @param context
	 *            the generate planif context
	 */
	public TaskByEmployeeComputedSet(GeneratePlanifContext context,
			IObservableValue employee) {
		this(Realm.getDefault(), context, employee);
	}

	/**
	 * Create a new observable set of employee.
	 * 
	 * @param realm
	 *            the realm
	 * @param site
	 *            The view site to get the generate planif context
	 * @param lockedElements
	 *            the observable locked elements
	 */
	public TaskByEmployeeComputedSet(Realm realm,
			GeneratePlanifContext context, IObservableValue employee) {
		super(context.getManagers(), Task.class, null,
				new IObservable[] { employee });
		this.context = context;
		this.employee = employee;
	}

	@Override
	public synchronized void dispose() {
		super.dispose();
		this.context = null;
	}

	/**
	 * This implementation query the database to get the employees qualify for
	 * all null planif event.
	 */
	@Override
	protected Collection doList() throws ManagerException {
		if (getEmployee() == null) {
			return Collections.EMPTY_SET;
		}
		try {
			return this.context.listTaskByEmployee(getEmployee());
		} catch (Exception e) {
			PlanimodPolicy.showException(e);
			return Collections.EMPTY_SET;
		}
	}

	/**
	 * Return the current employee value or null if the observable doesn't
	 * contain an employee object.
	 * 
	 * @return the current employee or null.
	 */
	protected Employee getEmployee() {
		if (this.employee.getValue() instanceof Employee) {
			return (Employee) this.employee.getValue();
		}
		return null;
	}

	@Override
	protected void startListening() {
		super.startListening();
		this.context.addPropertyChangeListener(
				GeneratePlanifContext.LIST_TASK_BY_EMPLOYEE, this.listener);
	}

	@Override
	protected void stopListening() {
		super.stopListening();
		this.context.removePropertyChangeListener(
				GeneratePlanifContext.LIST_TASK_BY_EMPLOYEE, this.listener);
	}

}