/**
 *  Copyright (c)2020 CEA LIST, Committer Name, and others.
 * 
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License 2.0
 *  which accompanies this distribution, and is available at
 *  https://www.eclipse.org/legal/epl-2.0/
 * 
 *  SPDX-License-Identifier: EPL-2.0
 * 
 *  Contributors:
 *  CEA LIST - Initial API and implementation
 *  Gabriel Pedroza (CEA LIST) gabriel.pedroza@cea.fr
 *  Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr 
 * 
 */
package org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.impl;

import org.eclipse.emf.common.notify.Notification;

import org.eclipse.emf.ecore.EClass;

import org.eclipse.emf.ecore.impl.ENotificationImpl;

import org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.SmartGridFrame;
import org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.pdp4engDesignPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Smart Grid Frame</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.impl.SmartGridFrameImpl#getConcentratorID <em>Concentrator ID</em>}</li>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.impl.SmartGridFrameImpl#getUserName <em>User Name</em>}</li>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.impl.SmartGridFrameImpl#getPostcode <em>Postcode</em>}</li>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.impl.SmartGridFrameImpl#getDate <em>Date</em>}</li>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.impl.SmartGridFrameImpl#getConsumption <em>Consumption</em>}</li>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.impl.SmartGridFrameImpl#getCrc <em>Crc</em>}</li>
 *   <li>{@link org.eclipse.papyrus.pdp4eng.designer.profile.pdp4engDesign.impl.SmartGridFrameImpl#getId <em>Id</em>}</li>
 * </ul>
 *
 * @generated
 */
public class SmartGridFrameImpl extends DataImpl implements SmartGridFrame {
	/**
	 * The default value of the '{@link #getConcentratorID() <em>Concentrator ID</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getConcentratorID()
	 * @generated
	 * @ordered
	 */
	protected static final String CONCENTRATOR_ID_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getConcentratorID() <em>Concentrator ID</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getConcentratorID()
	 * @generated
	 * @ordered
	 */
	protected String concentratorID = CONCENTRATOR_ID_EDEFAULT;

	/**
	 * The default value of the '{@link #getUserName() <em>User Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getUserName()
	 * @generated
	 * @ordered
	 */
	protected static final String USER_NAME_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getUserName() <em>User Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getUserName()
	 * @generated
	 * @ordered
	 */
	protected String userName = USER_NAME_EDEFAULT;

	/**
	 * The default value of the '{@link #getPostcode() <em>Postcode</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPostcode()
	 * @generated
	 * @ordered
	 */
	protected static final String POSTCODE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getPostcode() <em>Postcode</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPostcode()
	 * @generated
	 * @ordered
	 */
	protected String postcode = POSTCODE_EDEFAULT;

	/**
	 * The default value of the '{@link #getDate() <em>Date</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDate()
	 * @generated
	 * @ordered
	 */
	protected static final String DATE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getDate() <em>Date</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDate()
	 * @generated
	 * @ordered
	 */
	protected String date = DATE_EDEFAULT;

	/**
	 * The default value of the '{@link #getConsumption() <em>Consumption</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getConsumption()
	 * @generated
	 * @ordered
	 */
	protected static final String CONSUMPTION_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getConsumption() <em>Consumption</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getConsumption()
	 * @generated
	 * @ordered
	 */
	protected String consumption = CONSUMPTION_EDEFAULT;

	/**
	 * The default value of the '{@link #getCrc() <em>Crc</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCrc()
	 * @generated
	 * @ordered
	 */
	protected static final String CRC_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getCrc() <em>Crc</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCrc()
	 * @generated
	 * @ordered
	 */
	protected String crc = CRC_EDEFAULT;

	/**
	 * The default value of the '{@link #getId() <em>Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getId()
	 * @generated
	 * @ordered
	 */
	protected static final String ID_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getId() <em>Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getId()
	 * @generated
	 * @ordered
	 */
	protected String id = ID_EDEFAULT;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected SmartGridFrameImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return pdp4engDesignPackage.Literals.SMART_GRID_FRAME;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getConcentratorID() {
		return concentratorID;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setConcentratorID(String newConcentratorID) {
		String oldConcentratorID = concentratorID;
		concentratorID = newConcentratorID;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, pdp4engDesignPackage.SMART_GRID_FRAME__CONCENTRATOR_ID, oldConcentratorID, concentratorID));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getUserName() {
		return userName;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setUserName(String newUserName) {
		String oldUserName = userName;
		userName = newUserName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, pdp4engDesignPackage.SMART_GRID_FRAME__USER_NAME, oldUserName, userName));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getPostcode() {
		return postcode;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setPostcode(String newPostcode) {
		String oldPostcode = postcode;
		postcode = newPostcode;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, pdp4engDesignPackage.SMART_GRID_FRAME__POSTCODE, oldPostcode, postcode));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getDate() {
		return date;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setDate(String newDate) {
		String oldDate = date;
		date = newDate;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, pdp4engDesignPackage.SMART_GRID_FRAME__DATE, oldDate, date));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getConsumption() {
		return consumption;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setConsumption(String newConsumption) {
		String oldConsumption = consumption;
		consumption = newConsumption;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, pdp4engDesignPackage.SMART_GRID_FRAME__CONSUMPTION, oldConsumption, consumption));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getCrc() {
		return crc;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setCrc(String newCrc) {
		String oldCrc = crc;
		crc = newCrc;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, pdp4engDesignPackage.SMART_GRID_FRAME__CRC, oldCrc, crc));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getId() {
		return id;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setId(String newId) {
		String oldId = id;
		id = newId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, pdp4engDesignPackage.SMART_GRID_FRAME__ID, oldId, id));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case pdp4engDesignPackage.SMART_GRID_FRAME__CONCENTRATOR_ID:
				return getConcentratorID();
			case pdp4engDesignPackage.SMART_GRID_FRAME__USER_NAME:
				return getUserName();
			case pdp4engDesignPackage.SMART_GRID_FRAME__POSTCODE:
				return getPostcode();
			case pdp4engDesignPackage.SMART_GRID_FRAME__DATE:
				return getDate();
			case pdp4engDesignPackage.SMART_GRID_FRAME__CONSUMPTION:
				return getConsumption();
			case pdp4engDesignPackage.SMART_GRID_FRAME__CRC:
				return getCrc();
			case pdp4engDesignPackage.SMART_GRID_FRAME__ID:
				return getId();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case pdp4engDesignPackage.SMART_GRID_FRAME__CONCENTRATOR_ID:
				setConcentratorID((String)newValue);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__USER_NAME:
				setUserName((String)newValue);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__POSTCODE:
				setPostcode((String)newValue);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__DATE:
				setDate((String)newValue);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__CONSUMPTION:
				setConsumption((String)newValue);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__CRC:
				setCrc((String)newValue);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__ID:
				setId((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case pdp4engDesignPackage.SMART_GRID_FRAME__CONCENTRATOR_ID:
				setConcentratorID(CONCENTRATOR_ID_EDEFAULT);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__USER_NAME:
				setUserName(USER_NAME_EDEFAULT);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__POSTCODE:
				setPostcode(POSTCODE_EDEFAULT);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__DATE:
				setDate(DATE_EDEFAULT);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__CONSUMPTION:
				setConsumption(CONSUMPTION_EDEFAULT);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__CRC:
				setCrc(CRC_EDEFAULT);
				return;
			case pdp4engDesignPackage.SMART_GRID_FRAME__ID:
				setId(ID_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case pdp4engDesignPackage.SMART_GRID_FRAME__CONCENTRATOR_ID:
				return CONCENTRATOR_ID_EDEFAULT == null ? concentratorID != null : !CONCENTRATOR_ID_EDEFAULT.equals(concentratorID);
			case pdp4engDesignPackage.SMART_GRID_FRAME__USER_NAME:
				return USER_NAME_EDEFAULT == null ? userName != null : !USER_NAME_EDEFAULT.equals(userName);
			case pdp4engDesignPackage.SMART_GRID_FRAME__POSTCODE:
				return POSTCODE_EDEFAULT == null ? postcode != null : !POSTCODE_EDEFAULT.equals(postcode);
			case pdp4engDesignPackage.SMART_GRID_FRAME__DATE:
				return DATE_EDEFAULT == null ? date != null : !DATE_EDEFAULT.equals(date);
			case pdp4engDesignPackage.SMART_GRID_FRAME__CONSUMPTION:
				return CONSUMPTION_EDEFAULT == null ? consumption != null : !CONSUMPTION_EDEFAULT.equals(consumption);
			case pdp4engDesignPackage.SMART_GRID_FRAME__CRC:
				return CRC_EDEFAULT == null ? crc != null : !CRC_EDEFAULT.equals(crc);
			case pdp4engDesignPackage.SMART_GRID_FRAME__ID:
				return ID_EDEFAULT == null ? id != null : !ID_EDEFAULT.equals(id);
		}
		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(" (concentratorID: ");
		result.append(concentratorID);
		result.append(", userName: ");
		result.append(userName);
		result.append(", postcode: ");
		result.append(postcode);
		result.append(", date: ");
		result.append(date);
		result.append(", consumption: ");
		result.append(consumption);
		result.append(", crc: ");
		result.append(crc);
		result.append(", id: ");
		result.append(id);
		result.append(')');
		return result.toString();
	}

} //SmartGridFrameImpl
