/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 * 
 * Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute for Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 * 
 * 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
 * $Id: OTModelManager.java 23416 2010-02-03 19:59:31Z stephan $
 * 
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 * 
 * Contributors:
 * Fraunhofer FIRST - Initial API and implementation
 * Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.core;

import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.ExternalJavaProject;
import org.eclipse.objectteams.otdt.internal.core.BinaryRoleType;
import org.eclipse.objectteams.otdt.internal.core.CallinMapping;
import org.eclipse.objectteams.otdt.internal.core.CalloutMapping;
import org.eclipse.objectteams.otdt.internal.core.CalloutToFieldMapping;
import org.eclipse.objectteams.otdt.internal.core.MappingElementInfo;
import org.eclipse.objectteams.otdt.internal.core.OTModel;
import org.eclipse.objectteams.otdt.internal.core.OTType;
import org.eclipse.objectteams.otdt.internal.core.RoleFileType;
import org.eclipse.objectteams.otdt.internal.core.RoleType;
import org.eclipse.objectteams.otdt.internal.core.util.MethodData;


/**
 * Manager provides connection between JavaModel and OTM.
 * 
 * @author jwloka
 * @version $Id: OTModelManager.java 23416 2010-02-03 19:59:31Z stephan $
 */
public class OTModelManager
{
	
	/** 
	 * Expose this constant from {@link ExternalJavaProject} for use by other OT plugins. 
	 * @since 3.7
	 */
	public static final String EXTERNAL_PROJECT_NAME = ExternalJavaProject.EXTERNAL_PROJECT_NAME;

	private final static OTModel MAPPING = OTModel.getSharedInstance();
	
	private static OTModelManager singleton;

    private OTModelReconcileListener reconcileListener;
	
	protected OTModelManager()
	{
		singleton = this;

		this.reconcileListener = new OTModelReconcileListener();
		JavaCore.addElementChangedListener(this.reconcileListener, ElementChangedEvent.POST_RECONCILE);
	}
	
	public static OTModelManager getSharedInstance()
	{
		if (singleton == null)
		{
			new OTModelManager();
		}
		
		return singleton;
	}
	
	public static void dispose()
	{
	    if (singleton != null)
	    {
	        JavaCore.removeElementChangedListener(singleton.reconcileListener);
	        OTModel.dispose();
	    }
	    
	    singleton = null;
	}

	/** Register a type of which we don't yet have the flags. */
	public void addUnopenedType(IType type) {
		MAPPING.addUnopenedType(type);
	}

	/**
	 * Add the propriate Object Teams Model element for a given IType 
	 */
	public IOTType addType(IType elem, int typeDeclFlags, String baseClassName, String baseClassAnchor, boolean isRoleFile)
	{
		IJavaElement parent = elem.getParent();
		IOTType result = null; 
				
		switch (parent.getElementType())
		{
		    case IJavaElement.COMPILATION_UNIT:
		    case IJavaElement.CLASS_FILE:
		    	if(isRoleFile)
				{   //  could also be a teeam, which is handled inside the constructor
		    		if (elem.isBinary())
		    		{
			        	MAPPING.addOTElement( result = new BinaryRoleType(elem, 
								parent, 
								typeDeclFlags, 
								baseClassName,
								baseClassAnchor));
		    		}
		    		else
		    		{
			        	MAPPING.addOTElement( result = new RoleFileType(elem, 
								parent, 
								typeDeclFlags, 
								baseClassName,
								baseClassAnchor));
		    		}
				} 
		    	else if (TypeHelper.isTeam(typeDeclFlags))
				{
					MAPPING.addOTElement( result = new OTType(IOTJavaElement.TEAM, elem, null, typeDeclFlags) );
				}
				break;
		    case IJavaElement.TYPE:
				IType   encType   = (IType)parent;
				IOTType otmParent = MAPPING.getOTElement(encType); 
					
				result = maybeAddRoleType(elem, otmParent, typeDeclFlags, baseClassName, baseClassAnchor);			
	    		break;
	    	//do nothing if anonymous type
	    	case IJavaElement.METHOD:	    		
	    		break;
	    	case IJavaElement.INITIALIZER:
	    		break;
	    	case IJavaElement.FIELD:
				break;
//TODO (jwl) Wether anonymous types are roles or not will be discoverable with 
//	    	 a future implementation (probably with the help of a newer version of the compiler)
	    		
//		    	case IJavaElement.METHOD:
//	    	    IMethod encMethod   = (IMethod)parent;
//	    	    otmParent = MAPPING.getOTElement(encMethod.getDeclaringType());
//	    	    
//	    	    addRoleType(elem, otmParent, typeDeclFlags, baseClassName);
//	    	    break;
//		    case IJavaElement.INITIALIZER:
//	    	    IInitializer encInitializer   = (IInitializer)parent;
//	    	    otmParent = MAPPING.getOTElement(encInitializer.getDeclaringType());
//	    	    
//	    	    addRoleType(elem, otmParent, typeDeclFlags, baseClassName);
//	    	    break;
//	    	case IJavaElement.FIELD:
//	    	    IField encField   = (IField)parent;
//	    	    otmParent = MAPPING.getOTElement(encField.getDeclaringType());
//	    	    
//	    	    addRoleType(elem, otmParent, typeDeclFlags, baseClassName);
//	    	    break;
		    default:
		    	new Throwable("Warning: unexpected parent for OT element: " + parent).printStackTrace(); //$NON-NLS-1$
		    	break;
		}
		return result;
	}

	private IOTType maybeAddRoleType(IType elem, IOTType otmParent, 
	        int typeDeclFlags, String baseClassName, String baseClassAnchor)
    {
		IOTType result = null;
        if ((otmParent != null) 
        	&& (TypeHelper.isTeam(otmParent.getFlags()) 
        		|| (TypeHelper.isRole(otmParent.getFlags())) ) )
        {				
        	MAPPING.addOTElement( result = new RoleType(elem, 
        	        							otmParent, 
        	        							typeDeclFlags, 
        	        							baseClassName,
        	        							baseClassAnchor));
        }
        return result;
    }

	
    /**
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended by clients.
	 */
    public ICallinMapping addCallinBinding(IType role, MappingElementInfo info)
	{
		IOTType otmRole = MAPPING.getOTElement(role);
		
		if ((otmRole != null) && (otmRole instanceof IRoleType))
		{
//{OTModelUpdate
		    IMethodSpec corrRoleMethData = info.getRoleMethod();
		    IMethod correspondingRoleMethod = 
		        role.getMethod(corrRoleMethData.getSelector(), 
		                       corrRoleMethData.getArgumentTypes()); 
//haebor}							   
			return new CallinMapping(info.getDeclarationSourceStart(),
						      info.getSourceStart(),
						      info.getSourceEnd(),
							  info.getDeclarationSourceEnd(),
							  (IRoleType)otmRole,
//{OTModelUpdate
//orig:	(IMethod) otmRole.getParent(),
						      correspondingRoleMethod,
//haebor}							           
							  info.getCallinName(),
							  info.getCallinKind(),
							  info.getRoleMethod(),
							  info.getBaseMethods(), info.hasSignature());   
		}
		
		return null;
	}

	/**
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended by clients.
	 */
	public ICalloutMapping addCalloutBinding(IType role, MappingElementInfo info)
	{
		IOTType otmRole = MAPPING.getOTElement(role);
		
		if ((otmRole != null) && (otmRole instanceof IRoleType))
		{
//{OTModelUpdate
		    IMethodSpec corrRoleMethData = info.getRoleMethod();
		    IMethod correspondingRoleMethod = 
		        role.getMethod(corrRoleMethData.getSelector(), 
		                       corrRoleMethData.getArgumentTypes()); 
//haebor}							   
			MethodData[] baseMethods = info.getBaseMethods();
			return new CalloutMapping(info.getDeclarationSourceStart(),
						       info.getSourceStart(),
						       info.getSourceEnd(),
							   info.getDeclarationSourceEnd(),
							   (IRoleType)otmRole,
//{OTModelUpdate
//orig:	(IMethod) otmRole.getParent(),
							   correspondingRoleMethod,
//haebor}							           
							   info.getRoleMethod(),
							   baseMethods == null ? null : baseMethods[0],
							   info.hasSignature(),
							   info.isOverride(),
							   info.getDeclaredModifiers(),
							   true/*addAsChild*/);
		}
		
		return null;
	}
	
	/**
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended by clients.
	 */
    public ICalloutToFieldMapping addCalloutToFieldBinding(IType role, MappingElementInfo info)
    {
        IOTType otmRole = MAPPING.getOTElement(role);
        
        if ((otmRole != null) && (otmRole instanceof IRoleType))
        {
            IMethodSpec corrRoleMethData = info.getRoleMethod();
            IMethod correspondingRoleMethod = 
                role.getMethod(corrRoleMethData.getSelector(), 
                               corrRoleMethData.getArgumentTypes()); 
            return new CalloutToFieldMapping(info.getDeclarationSourceStart(),
            		   info.getSourceStart(),
            		   info.getSourceEnd(),
                       info.getDeclarationSourceEnd(),
                       (IRoleType)otmRole,
                       correspondingRoleMethod,
					   info.getRoleMethod(),
					   info.getBaseField(),
					   info.hasSignature(),
					   info.isOverride(),
					   true/*addAsChild*/);
        }
        
        return null;
    }
    
    public void addOTElement(IOTType otType)
    {
        MAPPING.addOTElement(otType);
    }

	/**
	 * Returns associated OTM element for a given type if there is one.
	 * 
	 * @return corresponding OTM element or null if no such element exists
	 */
    public static IOTType getOTElement(@Nullable IType type)
    {
    	if (type != null) {
    		type.exists(); // ensure opened
    		return MAPPING.getOTElement(type);
    	}
    	return null;
    }

    public static boolean hasOTElementFor(@Nullable IType type)
    {
    	if (type != null) {
			type.exists(); // ensure opened
			return MAPPING.hasOTElementFor(type);
		}
    	return false;
    }
        
    public static void removeOTElement(IType type)
    {
    	removeOTElement(type, false);
    }

	/**
	 * @see OTModel#removeOTElement(IType, boolean)  
	 */
	public static void removeOTElement(IType type, boolean hasChanged)
	{
		MAPPING.removeOTElement(type, hasChanged);
	}
	
	/**
	 * Utility function.
	 * @param type
	 * @return true if an OT-Type is registered for type that is a role
	 */
	public static boolean isRole(IType type) {
		IOTType ottype = getOTElement(type);
		return ottype != null && ottype.isRole();
	}
	
	/**
	 * Utility function.
	 * @param type
	 * @return true if an OT-Type is registered for type that is a team
	 */
	public static boolean isTeam(IType type) {
		if (hasOTElementFor(type))
		{
			IOTType ottype = getOTElement(type);
			return ottype.isTeam();
		}
		return false;
	}
	
	/**
	 * returns true if this member belongs to a role. Takes binary role-interfaceparts into account.
	 * FIXME (carp): this is mostly a workaround for binary role-interfaceparts. When this problem is
	 * fixed conceptually, check and "port" all clients of this method.
	 */
	public static boolean belongsToRole(IMember member) 
	{
		IType enclosing = member.getDeclaringType();
		if (enclosing != null)
		{
			IOTType otType = getOTElement(enclosing);
			return otType != null && otType.isRole();
		}
		
		return false;
	}
}
