/**
 */
package org.eclipse.skills.model.impl;

import java.util.Objects;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.skills.model.ISkillsPackage;
import org.eclipse.skills.model.ITask;
import org.eclipse.skills.model.ITaskDependency;
import org.eclipse.skills.model.IUserTask;

/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>Task Dependency</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.skills.model.impl.MTaskDependency#getTask <em>Task</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MTaskDependency#isCompleted <em>Completed</em>}</li>
 * </ul>
 *
 * @generated
 */
public class MTaskDependency extends MUserDependency implements ITaskDependency {

	/**
	 * @generated NOT
	 */
	private NotificationAdapter fNotificationAdapter = null;

	/**
	 * The cached value of the '{@link #getTask() <em>Task</em>}' reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getTask()
	 * @generated
	 * @ordered
	 */
	protected ITask task;

	/**
	 * The default value of the '{@link #isCompleted() <em>Completed</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #isCompleted()
	 * @generated
	 * @ordered
	 */
	protected static final boolean COMPLETED_EDEFAULT = true;

	/**
	 * The cached value of the '{@link #isCompleted() <em>Completed</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #isCompleted()
	 * @generated
	 * @ordered
	 */
	protected boolean completed = COMPLETED_EDEFAULT;

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	protected MTaskDependency() {
		super();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return ISkillsPackage.Literals.TASK_DEPENDENCY;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public ITask getTask() {
		if (task != null && task.eIsProxy()) {
			InternalEObject oldTask = (InternalEObject)task;
			task = (ITask)eResolveProxy(oldTask);
			if (task != oldTask) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ISkillsPackage.TASK_DEPENDENCY__TASK, oldTask, task));
			}
		}
		return task;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public ITask basicGetTask() {
		return task;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setTask(ITask newTask) {
		ITask oldTask = task;
		task = newTask;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.TASK_DEPENDENCY__TASK, oldTask, task));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean isCompleted() {
		return completed;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setCompleted(boolean newCompleted) {
		boolean oldCompleted = completed;
		completed = newCompleted;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.TASK_DEPENDENCY__COMPLETED, oldCompleted, completed));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case ISkillsPackage.TASK_DEPENDENCY__TASK:
				if (resolve) return getTask();
				return basicGetTask();
			case ISkillsPackage.TASK_DEPENDENCY__COMPLETED:
				return isCompleted();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ISkillsPackage.TASK_DEPENDENCY__TASK:
				setTask((ITask)newValue);
				return;
			case ISkillsPackage.TASK_DEPENDENCY__COMPLETED:
				setCompleted((Boolean)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ISkillsPackage.TASK_DEPENDENCY__TASK:
				setTask((ITask)null);
				return;
			case ISkillsPackage.TASK_DEPENDENCY__COMPLETED:
				setCompleted(COMPLETED_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ISkillsPackage.TASK_DEPENDENCY__TASK:
				return task != null;
			case ISkillsPackage.TASK_DEPENDENCY__COMPLETED:
				return completed != COMPLETED_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuilder result = new StringBuilder(super.toString());
		result.append(" (completed: ");
		result.append(completed);
		result.append(')');
		return result.toString();
	}

	/**
	 * @generated NOT
	 */
	@Override
	public void activate() {
		final IUserTask usertask = getUsertask();
		if (usertask != null)
			setFulfilled((usertask.isCompleted() && isCompleted()) || (usertask.isStarted() && !isCompleted()));

		if (!isFulfilled()) {
			fNotificationAdapter = new NotificationAdapter();
			if (usertask != null)
				usertask.eAdapters().add(fNotificationAdapter);
			else
				getUser().eAdapters().add(fNotificationAdapter);
		}
	}

	/**
	 * @generated NOT
	 */
	@Override
	public void deactivate() {
		if (fNotificationAdapter != null) {
			getUser().eAdapters().remove(fNotificationAdapter);
			getUsertask().eAdapters().remove(fNotificationAdapter);

			fNotificationAdapter = null;
		}
	}

	/**
	 * @generated NOT
	 */
	private IUserTask getUsertask() {
		for (final IUserTask usertask : getUser().getUsertasks()) {
			if (Objects.equals(getTask(), usertask.getTask()))
				return usertask;
		}

		return null;
	}

	/**
	 * @generated NOT
	 */
	private class NotificationAdapter extends AdapterImpl {
		@Override
		public void notifyChanged(Notification msg) {
			if (isUserTasksChanged(msg)) {
				if (getUsertask() != null) {
					// re-evaluate
					deactivate();
					activate();
				}

			} else if ((isCurrentUserTask(msg)) && (isUserTaskStartedOrStopped(msg))) {
				// re-evaluate
				deactivate();
				activate();
			}
		}

		private boolean isUserTaskStartedOrStopped(Notification msg) {
			return (ISkillsPackage.eINSTANCE.getUserTask_Started().equals(msg.getFeature()))
					|| (ISkillsPackage.eINSTANCE.getUserTask_Finished().equals(msg.getFeature()));
		}

		private boolean isCurrentUserTask(Notification msg) {
			return Objects.equals(getUsertask(), msg.getNotifier());
		}

		private boolean isUserTasksChanged(Notification msg) {
			return ISkillsPackage.eINSTANCE.getUser_Usertasks().equals(msg.getFeature());
		}
	}
} // MTaskDependency
