/**
 * *******************************************************************************
 *  Copyright (c) 2017 Timing-Architects Embedded Systems GmbH and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 * 
 *     Generated using Eclipse EMF
 * 
 * *******************************************************************************
 */
package org.eclipse.app4mc.amalthea.generator.configuration.impl;

import org.eclipse.app4mc.amalthea.generator.configuration.DoubleDistribution;
import org.eclipse.app4mc.amalthea.generator.configuration.IntegerTimeDistribution;
import org.eclipse.app4mc.amalthea.generator.configuration.RTMGCPackage;
import org.eclipse.app4mc.amalthea.generator.configuration.TriangleClock;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

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;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Triangle Clock</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.TriangleClockImpl#getMin_start <em>Min start</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.TriangleClockImpl#getMax_end <em>Max end</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.TriangleClockImpl#getShift <em>Shift</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.TriangleClockImpl#getPeriod <em>Period</em>}</li>
 * </ul>
 *
 * @generated
 */
public class TriangleClockImpl extends MinimalEObjectImpl.Container implements TriangleClock {
	/**
	 * The cached value of the '{@link #getMin_start() <em>Min start</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMin_start()
	 * @generated
	 * @ordered
	 */
	protected DoubleDistribution min_start;

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

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

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public DoubleDistribution getMin_start() {
		return min_start;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetMin_start(DoubleDistribution newMin_start, NotificationChain msgs) {
		DoubleDistribution oldMin_start = min_start;
		min_start = newMin_start;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.TRIANGLE_CLOCK__MIN_START, oldMin_start, newMin_start);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMin_start(DoubleDistribution newMin_start) {
		if (newMin_start != min_start) {
			NotificationChain msgs = null;
			if (min_start != null)
				msgs = ((InternalEObject)min_start).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.TRIANGLE_CLOCK__MIN_START, null, msgs);
			if (newMin_start != null)
				msgs = ((InternalEObject)newMin_start).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.TRIANGLE_CLOCK__MIN_START, null, msgs);
			msgs = basicSetMin_start(newMin_start, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.TRIANGLE_CLOCK__MIN_START, newMin_start, newMin_start));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public DoubleDistribution getMax_end() {
		return max_end;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetMax_end(DoubleDistribution newMax_end, NotificationChain msgs) {
		DoubleDistribution oldMax_end = max_end;
		max_end = newMax_end;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.TRIANGLE_CLOCK__MAX_END, oldMax_end, newMax_end);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMax_end(DoubleDistribution newMax_end) {
		if (newMax_end != max_end) {
			NotificationChain msgs = null;
			if (max_end != null)
				msgs = ((InternalEObject)max_end).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.TRIANGLE_CLOCK__MAX_END, null, msgs);
			if (newMax_end != null)
				msgs = ((InternalEObject)newMax_end).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.TRIANGLE_CLOCK__MAX_END, null, msgs);
			msgs = basicSetMax_end(newMax_end, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.TRIANGLE_CLOCK__MAX_END, newMax_end, newMax_end));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntegerTimeDistribution getShift() {
		return shift;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetShift(IntegerTimeDistribution newShift, NotificationChain msgs) {
		IntegerTimeDistribution oldShift = shift;
		shift = newShift;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.TRIANGLE_CLOCK__SHIFT, oldShift, newShift);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setShift(IntegerTimeDistribution newShift) {
		if (newShift != shift) {
			NotificationChain msgs = null;
			if (shift != null)
				msgs = ((InternalEObject)shift).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.TRIANGLE_CLOCK__SHIFT, null, msgs);
			if (newShift != null)
				msgs = ((InternalEObject)newShift).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.TRIANGLE_CLOCK__SHIFT, null, msgs);
			msgs = basicSetShift(newShift, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.TRIANGLE_CLOCK__SHIFT, newShift, newShift));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntegerTimeDistribution getPeriod() {
		return period;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetPeriod(IntegerTimeDistribution newPeriod, NotificationChain msgs) {
		IntegerTimeDistribution oldPeriod = period;
		period = newPeriod;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.TRIANGLE_CLOCK__PERIOD, oldPeriod, newPeriod);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPeriod(IntegerTimeDistribution newPeriod) {
		if (newPeriod != period) {
			NotificationChain msgs = null;
			if (period != null)
				msgs = ((InternalEObject)period).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.TRIANGLE_CLOCK__PERIOD, null, msgs);
			if (newPeriod != null)
				msgs = ((InternalEObject)newPeriod).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.TRIANGLE_CLOCK__PERIOD, null, msgs);
			msgs = basicSetPeriod(newPeriod, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.TRIANGLE_CLOCK__PERIOD, newPeriod, newPeriod));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case RTMGCPackage.TRIANGLE_CLOCK__MIN_START:
				return basicSetMin_start(null, msgs);
			case RTMGCPackage.TRIANGLE_CLOCK__MAX_END:
				return basicSetMax_end(null, msgs);
			case RTMGCPackage.TRIANGLE_CLOCK__SHIFT:
				return basicSetShift(null, msgs);
			case RTMGCPackage.TRIANGLE_CLOCK__PERIOD:
				return basicSetPeriod(null, 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 RTMGCPackage.TRIANGLE_CLOCK__MIN_START:
				return getMin_start();
			case RTMGCPackage.TRIANGLE_CLOCK__MAX_END:
				return getMax_end();
			case RTMGCPackage.TRIANGLE_CLOCK__SHIFT:
				return getShift();
			case RTMGCPackage.TRIANGLE_CLOCK__PERIOD:
				return getPeriod();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case RTMGCPackage.TRIANGLE_CLOCK__MIN_START:
				setMin_start((DoubleDistribution)newValue);
				return;
			case RTMGCPackage.TRIANGLE_CLOCK__MAX_END:
				setMax_end((DoubleDistribution)newValue);
				return;
			case RTMGCPackage.TRIANGLE_CLOCK__SHIFT:
				setShift((IntegerTimeDistribution)newValue);
				return;
			case RTMGCPackage.TRIANGLE_CLOCK__PERIOD:
				setPeriod((IntegerTimeDistribution)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case RTMGCPackage.TRIANGLE_CLOCK__MIN_START:
				setMin_start((DoubleDistribution)null);
				return;
			case RTMGCPackage.TRIANGLE_CLOCK__MAX_END:
				setMax_end((DoubleDistribution)null);
				return;
			case RTMGCPackage.TRIANGLE_CLOCK__SHIFT:
				setShift((IntegerTimeDistribution)null);
				return;
			case RTMGCPackage.TRIANGLE_CLOCK__PERIOD:
				setPeriod((IntegerTimeDistribution)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case RTMGCPackage.TRIANGLE_CLOCK__MIN_START:
				return min_start != null;
			case RTMGCPackage.TRIANGLE_CLOCK__MAX_END:
				return max_end != null;
			case RTMGCPackage.TRIANGLE_CLOCK__SHIFT:
				return shift != null;
			case RTMGCPackage.TRIANGLE_CLOCK__PERIOD:
				return period != null;
		}
		return super.eIsSet(featureID);
	}

} //TriangleClockImpl
