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

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
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.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.skills.Activator;
import org.eclipse.skills.Logger;
import org.eclipse.skills.model.IBadge;
import org.eclipse.skills.model.IReward;
import org.eclipse.skills.model.ISkill;
import org.eclipse.skills.model.ISkillsFactory;
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.AvatarCreator;
import org.eclipse.skills.service.ISkillService;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.ui.PlatformUI;

/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>User</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.skills.model.impl.MUser#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MUser#getSkills <em>Skills</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MUser#getUsertasks <em>Usertasks</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MUser#getImageLocation <em>Image Location</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MUser#getExperience <em>Experience</em>}</li>
 *   <li>{@link org.eclipse.skills.model.impl.MUser#getBadges <em>Badges</em>}</li>
 * </ul>
 *
 * @generated
 */
public class MUser extends MinimalEObjectImpl.Container implements IUser {
	/**
	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected static final String NAME_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected String name = NAME_EDEFAULT;

	/**
	 * The cached value of the '{@link #getSkills() <em>Skills</em>}' containment reference list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getSkills()
	 * @generated
	 * @ordered
	 */
	protected EList<ISkill> skills;

	/**
	 * The cached value of the '{@link #getUsertasks() <em>Usertasks</em>}' containment reference list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getUsertasks()
	 * @generated
	 * @ordered
	 */
	protected EList<IUserTask> usertasks;

	/**
	 * The default value of the '{@link #getImageLocation() <em>Image Location</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getImageLocation()
	 * @generated
	 * @ordered
	 */
	protected static final String IMAGE_LOCATION_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getImageLocation() <em>Image Location</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getImageLocation()
	 * @generated
	 * @ordered
	 */
	protected String imageLocation = IMAGE_LOCATION_EDEFAULT;

	/**
	 * The cached value of the '{@link #getExperience() <em>Experience</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getExperience()
	 * @generated
	 * @ordered
	 */
	protected ISkill experience;

	/**
	 * The cached value of the '{@link #getBadges() <em>Badges</em>}' containment reference list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getBadges()
	 * @generated
	 * @ordered
	 */
	protected EList<IBadge> badges;

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

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getName() {
		return name;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.USER__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<ISkill> getSkills() {
		if (skills == null) {
			skills = new EObjectContainmentEList<ISkill>(ISkill.class, this, ISkillsPackage.USER__SKILLS);
		}
		return skills;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<IUserTask> getUsertasks() {
		if (usertasks == null) {
			usertasks = new EObjectContainmentEList<IUserTask>(IUserTask.class, this, ISkillsPackage.USER__USERTASKS);
		}
		return usertasks;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getImageLocation() {
		return imageLocation;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setImageLocation(String newImageLocation) {
		String oldImageLocation = imageLocation;
		imageLocation = newImageLocation;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.USER__IMAGE_LOCATION, oldImageLocation, imageLocation));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public ISkill getExperience() {
		return experience;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetExperience(ISkill newExperience, NotificationChain msgs) {
		ISkill oldExperience = experience;
		experience = newExperience;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ISkillsPackage.USER__EXPERIENCE, oldExperience, newExperience);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setExperience(ISkill newExperience) {
		if (newExperience != experience) {
			NotificationChain msgs = null;
			if (experience != null)
				msgs = ((InternalEObject)experience).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ISkillsPackage.USER__EXPERIENCE, null, msgs);
			if (newExperience != null)
				msgs = ((InternalEObject)newExperience).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ISkillsPackage.USER__EXPERIENCE, null, msgs);
			msgs = basicSetExperience(newExperience, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ISkillsPackage.USER__EXPERIENCE, newExperience, newExperience));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<IBadge> getBadges() {
		if (badges == null) {
			badges = new EObjectContainmentEList<IBadge>(IBadge.class, this, ISkillsPackage.USER__BADGES);
		}
		return badges;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public IUserTask addTask(ITask task) {
		final IUserTask userTask = ISkillsFactory.eINSTANCE.createUserTask();
		userTask.setTask(task);

		getUsertasks().add(userTask);

		return userTask;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public ISkill getSkill(ISkill skill) {
		final Optional<ISkill> userSkill = getSkills().stream().filter(s -> s.getName().equals(skill.getName())).findFirst();
		if (userSkill.isPresent())
			return userSkill.get();

		// skill not present yet
		final ISkill newSkill = EcoreUtil.copy(skill);
		getSkills().add(newSkill);

		return newSkill;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void consume(IReward reward) {
		reward.payOut(this);
	}

	/**
	 * Get the image data for the chosen avatar.
	 *
	 * @generated NOT
	 */
	@Override
	public ImageDescriptor getAvatar() {
		final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class);
		if (skillService.hasResource(ISkillService.RESOURCE_AVATAR)) {
			try (InputStream input = skillService.openResource(ISkillService.RESOURCE_AVATAR)) {
				final ImageData imageData = new ImageData(input);
				return ImageDescriptor.createFromImageData(imageData);

			} catch (final IOException e) {
				Logger.warning(Activator.PLUGIN_ID, "Failed to load avatar image", e);
			}

		} else {
			try {
				final byte[] imageData = AvatarCreator.getRandomAvatarData();
				skillService.storeResource(ISkillService.RESOURCE_AVATAR, imageData);

				return getAvatar();
			} catch (final IOException e) {
				Logger.warning(Activator.PLUGIN_ID, "Failed to store a new avatar image", e);
			}
		}

		return ImageDescriptor.getMissingImageDescriptor();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public ISkill getSkill(String name) {
		for (final ISkill skill : getSkills()) {
			if (Objects.equals(skill.getName(), name))
				return skill;
		}

		return null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ISkillsPackage.USER__SKILLS:
				return ((InternalEList<?>)getSkills()).basicRemove(otherEnd, msgs);
			case ISkillsPackage.USER__USERTASKS:
				return ((InternalEList<?>)getUsertasks()).basicRemove(otherEnd, msgs);
			case ISkillsPackage.USER__EXPERIENCE:
				return basicSetExperience(null, msgs);
			case ISkillsPackage.USER__BADGES:
				return ((InternalEList<?>)getBadges()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case ISkillsPackage.USER__NAME:
				return getName();
			case ISkillsPackage.USER__SKILLS:
				return getSkills();
			case ISkillsPackage.USER__USERTASKS:
				return getUsertasks();
			case ISkillsPackage.USER__IMAGE_LOCATION:
				return getImageLocation();
			case ISkillsPackage.USER__EXPERIENCE:
				return getExperience();
			case ISkillsPackage.USER__BADGES:
				return getBadges();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ISkillsPackage.USER__NAME:
				setName((String)newValue);
				return;
			case ISkillsPackage.USER__SKILLS:
				getSkills().clear();
				getSkills().addAll((Collection<? extends ISkill>)newValue);
				return;
			case ISkillsPackage.USER__USERTASKS:
				getUsertasks().clear();
				getUsertasks().addAll((Collection<? extends IUserTask>)newValue);
				return;
			case ISkillsPackage.USER__IMAGE_LOCATION:
				setImageLocation((String)newValue);
				return;
			case ISkillsPackage.USER__EXPERIENCE:
				setExperience((ISkill)newValue);
				return;
			case ISkillsPackage.USER__BADGES:
				getBadges().clear();
				getBadges().addAll((Collection<? extends IBadge>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ISkillsPackage.USER__NAME:
				setName(NAME_EDEFAULT);
				return;
			case ISkillsPackage.USER__SKILLS:
				getSkills().clear();
				return;
			case ISkillsPackage.USER__USERTASKS:
				getUsertasks().clear();
				return;
			case ISkillsPackage.USER__IMAGE_LOCATION:
				setImageLocation(IMAGE_LOCATION_EDEFAULT);
				return;
			case ISkillsPackage.USER__EXPERIENCE:
				setExperience((ISkill)null);
				return;
			case ISkillsPackage.USER__BADGES:
				getBadges().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ISkillsPackage.USER__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case ISkillsPackage.USER__SKILLS:
				return skills != null && !skills.isEmpty();
			case ISkillsPackage.USER__USERTASKS:
				return usertasks != null && !usertasks.isEmpty();
			case ISkillsPackage.USER__IMAGE_LOCATION:
				return IMAGE_LOCATION_EDEFAULT == null ? imageLocation != null : !IMAGE_LOCATION_EDEFAULT.equals(imageLocation);
			case ISkillsPackage.USER__EXPERIENCE:
				return experience != null;
			case ISkillsPackage.USER__BADGES:
				return badges != null && !badges.isEmpty();
		}
		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___ADD_TASK__ITASK:
				return addTask((ITask)arguments.get(0));
			case ISkillsPackage.USER___GET_SKILL__ISKILL:
				return getSkill((ISkill)arguments.get(0));
			case ISkillsPackage.USER___CONSUME__IREWARD:
				consume((IReward)arguments.get(0));
				return null;
			case ISkillsPackage.USER___GET_AVATAR:
				return getAvatar();
			case ISkillsPackage.USER___GET_SKILL__STRING:
				return getSkill((String)arguments.get(0));
		}
		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(" (name: ");
		result.append(name);
		result.append(", imageLocation: ");
		result.append(imageLocation);
		result.append(')');
		return result.toString();
	}
} // MUser
