/**
 *   Copyright (c) 2016 CEA LIST 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
 *  
 *   Contributors:
 *     CEA LIST - Initial API and implementation
 * 
 */
package org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.impl;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.Point;
import org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.Rectangle;
import org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.RpyGeometryPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Rectangle</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.impl.RectangleImpl#getTopLeft <em>Top Left</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.impl.RectangleImpl#getTopRight <em>Top Right</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.impl.RectangleImpl#getBottomLeft <em>Bottom Left</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.geometry.rpygeometry.impl.RectangleImpl#getBottomRight <em>Bottom Right</em>}</li>
 * </ul>
 *
 * @generated
 */
public class RectangleImpl extends PolygonImpl implements Rectangle {
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected RectangleImpl() {
		super();
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Point getTopLeft() {
		Point topLeft = basicGetTopLeft();
		return topLeft != null && topLeft.eIsProxy() ? (Point)eResolveProxy((InternalEObject)topLeft) : topLeft;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Point basicGetTopLeft() {
		// TODO: implement this method to return the 'Top Left' reference
		// -> do not perform proxy resolution
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTopLeft(Point newTopLeft) {
		// TODO: implement this method to set the 'Top Left' reference
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void unsetTopLeft() {
		// TODO: implement this method to unset the 'Top Left' reference
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isSetTopLeft() {
		// TODO: implement this method to return whether the 'Top Left' reference is set
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Point getTopRight() {
		Point topRight = basicGetTopRight();
		return topRight != null && topRight.eIsProxy() ? (Point)eResolveProxy((InternalEObject)topRight) : topRight;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Point basicGetTopRight() {
		// TODO: implement this method to return the 'Top Right' reference
		// -> do not perform proxy resolution
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTopRight(Point newTopRight) {
		// TODO: implement this method to set the 'Top Right' reference
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void unsetTopRight() {
		// TODO: implement this method to unset the 'Top Right' reference
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isSetTopRight() {
		// TODO: implement this method to return whether the 'Top Right' reference is set
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Point getBottomLeft() {
		Point bottomLeft = basicGetBottomLeft();
		return bottomLeft != null && bottomLeft.eIsProxy() ? (Point)eResolveProxy((InternalEObject)bottomLeft) : bottomLeft;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Point basicGetBottomLeft() {
		// TODO: implement this method to return the 'Bottom Left' reference
		// -> do not perform proxy resolution
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBottomLeft(Point newBottomLeft) {
		// TODO: implement this method to set the 'Bottom Left' reference
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void unsetBottomLeft() {
		// TODO: implement this method to unset the 'Bottom Left' reference
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isSetBottomLeft() {
		// TODO: implement this method to return whether the 'Bottom Left' reference is set
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Point getBottomRight() {
		Point bottomRight = basicGetBottomRight();
		return bottomRight != null && bottomRight.eIsProxy() ? (Point)eResolveProxy((InternalEObject)bottomRight) : bottomRight;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Point basicGetBottomRight() {
		// TODO: implement this method to return the 'Bottom Right' reference
		// -> do not perform proxy resolution
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBottomRight(Point newBottomRight) {
		// TODO: implement this method to set the 'Bottom Right' reference
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void unsetBottomRight() {
		// TODO: implement this method to unset the 'Bottom Right' reference
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isSetBottomRight() {
		// TODO: implement this method to return whether the 'Bottom Right' reference is set
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case RpyGeometryPackage.RECTANGLE__TOP_LEFT:
				if (resolve) return getTopLeft();
				return basicGetTopLeft();
			case RpyGeometryPackage.RECTANGLE__TOP_RIGHT:
				if (resolve) return getTopRight();
				return basicGetTopRight();
			case RpyGeometryPackage.RECTANGLE__BOTTOM_LEFT:
				if (resolve) return getBottomLeft();
				return basicGetBottomLeft();
			case RpyGeometryPackage.RECTANGLE__BOTTOM_RIGHT:
				if (resolve) return getBottomRight();
				return basicGetBottomRight();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case RpyGeometryPackage.RECTANGLE__TOP_LEFT:
				setTopLeft((Point)newValue);
				return;
			case RpyGeometryPackage.RECTANGLE__TOP_RIGHT:
				setTopRight((Point)newValue);
				return;
			case RpyGeometryPackage.RECTANGLE__BOTTOM_LEFT:
				setBottomLeft((Point)newValue);
				return;
			case RpyGeometryPackage.RECTANGLE__BOTTOM_RIGHT:
				setBottomRight((Point)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case RpyGeometryPackage.RECTANGLE__TOP_LEFT:
				unsetTopLeft();
				return;
			case RpyGeometryPackage.RECTANGLE__TOP_RIGHT:
				unsetTopRight();
				return;
			case RpyGeometryPackage.RECTANGLE__BOTTOM_LEFT:
				unsetBottomLeft();
				return;
			case RpyGeometryPackage.RECTANGLE__BOTTOM_RIGHT:
				unsetBottomRight();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case RpyGeometryPackage.RECTANGLE__TOP_LEFT:
				return isSetTopLeft();
			case RpyGeometryPackage.RECTANGLE__TOP_RIGHT:
				return isSetTopRight();
			case RpyGeometryPackage.RECTANGLE__BOTTOM_LEFT:
				return isSetBottomLeft();
			case RpyGeometryPackage.RECTANGLE__BOTTOM_RIGHT:
				return isSetBottomRight();
		}
		return super.eIsSet(featureID);
	}

} //RectangleImpl
