/**
 */
package com.irtsaintexupery.pseim.mapping.util;

import java.util.Map;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.ResourceLocator;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.util.EObjectValidator;

import com.irtsaintexupery.pseim.mapping.CardinalityValue;
import com.irtsaintexupery.pseim.mapping.GraphElementMapping;
import com.irtsaintexupery.pseim.mapping.MappingPackage;
import com.irtsaintexupery.pseim.mapping.PatternApplication;
import com.irtsaintexupery.pseim.mapping.PortMapping;
import com.irtsaintexupery.pseim.pseim.Pattern;
import com.irtsaintexupery.pseim.seim.*;

/**
 * <!-- begin-user-doc -->
 * The <b>Validator</b> for the model.
 * <!-- end-user-doc -->
 * @see com.irtsaintexupery.pseim.mapping.MappingPackage
 * @generated
 */
public class MappingValidator extends EObjectValidator {
	/**
	 * The cached model package
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public static final MappingValidator INSTANCE = new MappingValidator();

	/**
	 * A constant for the {@link org.eclipse.emf.common.util.Diagnostic#getSource() source} of diagnostic {@link org.eclipse.emf.common.util.Diagnostic#getCode() codes} from this package.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see org.eclipse.emf.common.util.Diagnostic#getSource()
	 * @see org.eclipse.emf.common.util.Diagnostic#getCode()
	 * @generated
	 */
	public static final String DIAGNOSTIC_SOURCE = "com.irtsaintexupery.pseim.mapping";

	/**
	 * A constant with a fixed name that can be used as the base value for additional hand written constants.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	private static final int GENERATED_DIAGNOSTIC_CODE_COUNT = 0;

	/**
	 * A constant with a fixed name that can be used as the base value for additional hand written constants in a derived class.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected static final int DIAGNOSTIC_CODE_COUNT = GENERATED_DIAGNOSTIC_CODE_COUNT;

	/**
	 * Creates an instance of the switch.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public MappingValidator() {
		super();
	}

	/**
	 * Returns the package of this validator switch.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EPackage getEPackage() {
	  return MappingPackage.eINSTANCE;
	}

	/**
	 * Calls <code>validateXXX</code> for the corresponding classifier of the model.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected boolean validate(int classifierID, Object value, DiagnosticChain diagnostics, Map<Object, Object> context) {
		switch (classifierID) {
			case MappingPackage.PATTERN_APPLICATION:
				return validatePatternApplication((PatternApplication)value, diagnostics, context);
			case MappingPackage.CARDINALITY_VALUE:
				return validateCardinalityValue((CardinalityValue)value, diagnostics, context);
			case MappingPackage.PORT_MAPPING:
				return validatePortMapping((PortMapping)value, diagnostics, context);
			case MappingPackage.GRAPH_ELEMENT_MAPPING:
				return validateGraphElementMapping((GraphElementMapping)value, diagnostics, context);
			default:
				return true;
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean validatePatternApplication(PatternApplication patternApplication, DiagnosticChain diagnostics, Map<Object, Object> context) {
		if (!validate_NoCircularContainment(patternApplication, diagnostics, context)) return false;
		boolean result = validate_EveryMultiplicityConforms(patternApplication, diagnostics, context);
		if (result || diagnostics != null) result &= validate_EveryDataValueConforms(patternApplication, diagnostics, context);
		if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(patternApplication, diagnostics, context);
		if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(patternApplication, diagnostics, context);
		if (result || diagnostics != null) result &= validate_EveryProxyResolves(patternApplication, diagnostics, context);
		if (result || diagnostics != null) result &= validate_UniqueID(patternApplication, diagnostics, context);
		if (result || diagnostics != null) result &= validate_EveryKeyUnique(patternApplication, diagnostics, context);
		if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(patternApplication, diagnostics, context);
		if (result || diagnostics != null) result &= validatePatternApplication_InvariantName(patternApplication, diagnostics, context);
		return result;
	}

	/**
	 * The cached validation expression for the InvariantName constraint of '<em>Pattern Application</em>'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected static final String PATTERN_APPLICATION__INVARIANT_NAME__EEXPRESSION = "true";

	/**
	 * Validates the InvariantName constraint of '<em>Pattern Application</em>'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean validatePatternApplication_InvariantName(PatternApplication patternApplication, DiagnosticChain diagnostics, Map<Object, Object> context) {
		return
			validate
				(MappingPackage.Literals.PATTERN_APPLICATION,
				 patternApplication,
				 diagnostics,
				 context,
				 "http://www.eclipse.org/emf/2002/Ecore/OCL/Pivot",
				 "InvariantName",
				 PATTERN_APPLICATION__INVARIANT_NAME__EEXPRESSION,
				 Diagnostic.ERROR,
				 DIAGNOSTIC_SOURCE,
				 0);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean validateCardinalityValue(CardinalityValue cardinalityValue, DiagnosticChain diagnostics, Map<Object, Object> context) {
		return validate_EveryDefaultConstraint(cardinalityValue, diagnostics, context);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean validatePortMapping(PortMapping portMapping, DiagnosticChain diagnostics, Map<Object, Object> context) {
		Model matchedModel = ((PatternApplication)portMapping.eContainer()).getModel();
		TreeIterator<EObject> itM = matchedModel.eAllContents();
		EList<BorderElement> ports = portMapping.getModelPort();
		while (itM.hasNext()) {
			Element current = (Element) itM.next();
			if (ports.contains(current)) {
				ports.remove(current);
			}
		}
		Pattern matchedPattern = ((PatternApplication)portMapping.eContainer()).getPattern();
		TreeIterator<EObject> itP = matchedPattern.eAllContents();
		boolean patternFound = false;
		while (itP.hasNext()) {
			if (itP.next().equals(portMapping.getPatternPort())) {
				patternFound = true;
				break;
			}
		}
		if (patternFound && ports.isEmpty()) 
			return validate_EveryDefaultConstraint(portMapping, diagnostics, context);
		else
			return false;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean validateGraphElementMapping(GraphElementMapping graphElementMapping, DiagnosticChain diagnostics, Map<Object, Object> context) {
		Model matchedModel = ((PatternApplication)graphElementMapping.eContainer()).getModel();
		TreeIterator<EObject> itM = matchedModel.eAllContents();
		EList<GraphElement> elements = graphElementMapping.getModelGraphElement();
		while (itM.hasNext()) {
			Element current = (Element) itM.next();
			if (elements.contains(current)) {
				elements.remove(current);
			}
		}
		Pattern matchedPattern = ((PatternApplication)graphElementMapping.eContainer()).getPattern();
		TreeIterator<EObject> itP = matchedPattern.eAllContents();
		boolean patternFound = false;
		while (itP.hasNext()) {
			if (itP.next().equals(graphElementMapping.getPatternGraphElement())) {
				patternFound = true;
				break;
			}
		}
		if (patternFound && elements.isEmpty())
			return validate_EveryDefaultConstraint(graphElementMapping, diagnostics, context);
		else
			return false;
	}

	/**
	 * Returns the resource locator that will be used to fetch messages for this validator's diagnostics.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public ResourceLocator getResourceLocator() {
		// TODO
		// Specialize this to return a resource locator for messages specific to this validator.
		// Ensure that you remove @generated or mark it @generated NOT
		return super.getResourceLocator();
	}

} //MappingValidator
