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

import java.lang.reflect.InvocationTargetException;
import java.util.Date;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
import org.eclipse.skills.BrokerTools;
import org.eclipse.skills.model.ISkillsPackage;
import org.eclipse.skills.model.ITask;
import org.eclipse.skills.model.IUser;
import org.eclipse.skills.model.IUserTask;
import org.eclipse.skills.service.ISkillService;

/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>User Task</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.skills.model.impl.MUserTask#getTask <em>Task</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MUserTask#getStarted <em>Started</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MUserTask#getFinished <em>Finished</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MUserTask#getHintsDisplayed <em>Hints Displayed</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MUserTask#getAdded <em>Added</em>}</li>
 * </ul>
 *
 * @generated
 */
public class MUserTask extends MinimalEObjectImpl.Container implements IUserTask {
	/**
	 * 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 #getStarted() <em>Started</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getStarted()
	 * @generated
	 * @ordered
	 */
	protected static final Date STARTED_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getStarted() <em>Started</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getStarted()
	 * @generated
	 * @ordered
	 */
	protected Date started = STARTED_EDEFAULT;

	/**
	 * The default value of the '{@link #getFinished() <em>Finished</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getFinished()
	 * @generated
	 * @ordered
	 */
	protected static final Date FINISHED_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getFinished() <em>Finished</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getFinished()
	 * @generated
	 * @ordered
	 */
	protected Date finished = FINISHED_EDEFAULT;

	/**
	 * The default value of the '{@link #getHintsDisplayed() <em>Hints Displayed</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getHintsDisplayed()
	 * @generated
	 * @ordered
	 */
	protected static final int HINTS_DISPLAYED_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getHintsDisplayed() <em>Hints Displayed</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getHintsDisplayed()
	 * @generated
	 * @ordered
	 */
	protected int hintsDisplayed = HINTS_DISPLAYED_EDEFAULT;

	/**
	 * The default value of the '{@link #getAdded() <em>Added</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getAdded()
	 * @generated
	 * @ordered
	 */
	protected static final Date ADDED_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getAdded() <em>Added</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getAdded()
	 * @generated
	 * @ordered
	 */
	protected Date added = ADDED_EDEFAULT;

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

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

	/**
	 * <!-- 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.USER_TASK__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.USER_TASK__TASK, oldTask, task));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Date getStarted() {
		return started;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setStarted(Date newStarted) {
		Date oldStarted = started;
		started = newStarted;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.USER_TASK__STARTED, oldStarted, started));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Date getFinished() {
		return finished;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setFinished(Date newFinished) {
		Date oldFinished = finished;
		finished = newFinished;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.USER_TASK__FINISHED, oldFinished, finished));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int getHintsDisplayed() {
		return hintsDisplayed;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setHintsDisplayed(int newHintsDisplayed) {
		int oldHintsDisplayed = hintsDisplayed;
		hintsDisplayed = newHintsDisplayed;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.USER_TASK__HINTS_DISPLAYED, oldHintsDisplayed, hintsDisplayed));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Date getAdded() {
		return added;
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void activate() {
		if (isStarted()) {
			getTask().getGoal().eAdapters().add(new AdapterImpl() {
				@Override
				public void notifyChanged(Notification msg) {
					if (ISkillsPackage.eINSTANCE.getDependency_Fulfilled().equals(msg.getFeature())) {
						if (msg.getNewBooleanValue()) {
							getTask().getGoal().eAdapters().remove(this);

							getTask().getGoal().deactivate();
							setFinished(new Date());

							BrokerTools.post(ISkillService.EVENT_TASK_COMPLETED, MUserTask.this);
						}
					}
				};
			});

			getTask().getGoal().activate();
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public IUser getUser() {
		return (IUser) eContainer;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public boolean isStarted() {
		return getStarted() != null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void revealNextHint() {
		if (getTask().getHints().size() > getHintsDisplayed())
			setHintsDisplayed(getHintsDisplayed() + 1);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case ISkillsPackage.USER_TASK__TASK:
				if (resolve) return getTask();
				return basicGetTask();
			case ISkillsPackage.USER_TASK__STARTED:
				return getStarted();
			case ISkillsPackage.USER_TASK__FINISHED:
				return getFinished();
			case ISkillsPackage.USER_TASK__HINTS_DISPLAYED:
				return getHintsDisplayed();
			case ISkillsPackage.USER_TASK__ADDED:
				return getAdded();
		}
		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.USER_TASK__TASK:
				setTask((ITask)newValue);
				return;
			case ISkillsPackage.USER_TASK__STARTED:
				setStarted((Date)newValue);
				return;
			case ISkillsPackage.USER_TASK__FINISHED:
				setFinished((Date)newValue);
				return;
			case ISkillsPackage.USER_TASK__HINTS_DISPLAYED:
				setHintsDisplayed((Integer)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ISkillsPackage.USER_TASK__TASK:
				setTask((ITask)null);
				return;
			case ISkillsPackage.USER_TASK__STARTED:
				setStarted(STARTED_EDEFAULT);
				return;
			case ISkillsPackage.USER_TASK__FINISHED:
				setFinished(FINISHED_EDEFAULT);
				return;
			case ISkillsPackage.USER_TASK__HINTS_DISPLAYED:
				setHintsDisplayed(HINTS_DISPLAYED_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ISkillsPackage.USER_TASK__TASK:
				return task != null;
			case ISkillsPackage.USER_TASK__STARTED:
				return STARTED_EDEFAULT == null ? started != null : !STARTED_EDEFAULT.equals(started);
			case ISkillsPackage.USER_TASK__FINISHED:
				return FINISHED_EDEFAULT == null ? finished != null : !FINISHED_EDEFAULT.equals(finished);
			case ISkillsPackage.USER_TASK__HINTS_DISPLAYED:
				return hintsDisplayed != HINTS_DISPLAYED_EDEFAULT;
			case ISkillsPackage.USER_TASK__ADDED:
				return ADDED_EDEFAULT == null ? added != null : !ADDED_EDEFAULT.equals(added);
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
		switch (operationID) {
			case ISkillsPackage.USER_TASK___IS_COMPLETED:
				return isCompleted();
			case ISkillsPackage.USER_TASK___ACTIVATE:
				activate();
				return null;
			case ISkillsPackage.USER_TASK___GET_USER:
				return getUser();
			case ISkillsPackage.USER_TASK___IS_STARTED:
				return isStarted();
			case ISkillsPackage.USER_TASK___REVEAL_NEXT_HINT:
				revealNextHint();
				return null;
		}
		return super.eInvoke(operationID, arguments);
	}

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

		StringBuilder result = new StringBuilder(super.toString());
		result.append(" (started: ");
		result.append(started);
		result.append(", finished: ");
		result.append(finished);
		result.append(", hintsDisplayed: ");
		result.append(hintsDisplayed);
		result.append(", added: ");
		result.append(added);
		result.append(')');
		return result.toString();
	}

} // MUserTask
