/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Cameron Bateman/Oracle - initial API and implementation
 *    
 ********************************************************************************/
package org.eclipse.jst.jsf.context.symbol.internal.impl;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.context.symbol.IInstanceSymbol;
import org.eclipse.jst.jsf.context.symbol.IJavaTypeDescriptor2;
import org.eclipse.jst.jsf.context.symbol.IMapTypeDescriptor;
import org.eclipse.jst.jsf.context.symbol.IObjectSymbol;
import org.eclipse.jst.jsf.context.symbol.IPropertySymbol;
import org.eclipse.jst.jsf.context.symbol.ITypeDescriptor;
import org.eclipse.jst.jsf.context.symbol.SymbolFactory;
import org.eclipse.jst.jsf.context.symbol.SymbolPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>IMap Type Descriptor</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IMapTypeDescriptorImpl#getMapSource <em>Map Source</em>}</li>
 *   <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IMapTypeDescriptorImpl#isImmutable <em>Immutable</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class IMapTypeDescriptorImpl extends ITypeDescriptorImpl implements IMapTypeDescriptor {
    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    public static final String copyright = "Copyright 2006 Oracle"; //$NON-NLS-1$

    /**
     * The default value of the '{@link #getMapSource() <em>Map Source</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #getMapSource()
     * @generated
     * @ordered
     */
    protected static final Map MAP_SOURCE_EDEFAULT = null;

    /**
     * The cached value of the '{@link #getMapSource() <em>Map Source</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #getMapSource()
     * @generated
     * @ordered
     */
    protected Map mapSource = MAP_SOURCE_EDEFAULT;

    /**
     * The default value of the '{@link #isImmutable() <em>Immutable</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #isImmutable()
     * @generated
     * @ordered
     */
    protected static final boolean IMMUTABLE_EDEFAULT = true;

    /**
     * The cached value of the '{@link #isImmutable() <em>Immutable</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #isImmutable()
     * @generated
     * @ordered
     */
    protected boolean immutable = IMMUTABLE_EDEFAULT;

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

    /**
     * <!-- begin-user-doc -->
     * @return the static eClass 
     * <!-- end-user-doc -->
     * @generated
     */
    protected EClass eStaticClass() {
        return SymbolPackage.Literals.IMAP_TYPE_DESCRIPTOR;
    }

    /**
     * <!-- begin-user-doc -->
     * @return the map source 
     * <!-- end-user-doc -->
     * @generated
     */
    public Map getMapSource() {
        return mapSource;
    }

    /**
     * <!-- begin-user-doc -->
     * @param newMapSource 
     * <!-- end-user-doc -->
     * @generated
     */
    public void setMapSource(Map newMapSource) {
        Map oldMapSource = mapSource;
        mapSource = newMapSource;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE, oldMapSource, mapSource));
    }

    /**
     * <!-- begin-user-doc -->
     * @return true if this map is immutable as defined in the java.util.Map
     * interface. 
     * <!-- end-user-doc -->
     * @generated
     */
    public boolean isImmutable() {
        return immutable;
    }

    /**
     * <!-- begin-user-doc -->
     * @param newImmutable 
     * <!-- end-user-doc -->
     * @generated
     */
    public void setImmutable(boolean newImmutable) {
        boolean oldImmutable = immutable;
        immutable = newImmutable;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE, oldImmutable, immutable));
    }

    /* (non-Javadoc)
     * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getTypeSignature()
     * @generated NOT
     */
    public String getTypeSignature() 
    {
        // if the delegate has been set, use it
        if (eIsSet(SymbolPackage.IMAP_TYPE_DESCRIPTOR__TYPE_SIGNATURE_DELEGATE))
        {
            return getTypeSignatureDelegate();
        }
        
        // otherwise use Map
        return TypeConstants.TYPE_MAP;
    }

    public EList getInterfaceTypeSignatures() {
        return ECollections.EMPTY_ELIST;
    }

    public EList getSuperTypeSignatures() {
        return ECollections.EMPTY_ELIST;
    }

    /**
     * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getProperties()
     */
    public EList getProperties() 
    {
        final BasicEList  list = new BasicEList();
        final Map source = getMapSource();
        final Set keys = source.keySet();
        final Map segmentMap = processSegments(keys, source);
        list.addAll(segmentMap.values());
        return list;
    }
    
    public EList getMethods() 
    {
        // TODO: should this return the methods on  a Map?
        return ECollections.EMPTY_ELIST;
    }
    
    /**
     * @generated  NOT
     */
    public IObjectSymbol getArrayElement() {
		return null;
	}

    /**
     * @generated  NOT
     */
	public boolean isArray() {
		// a map is never an array
		return false;
	}

	private Map processSegments(final Set  keys, final Map source)
    {
        final Map segmentMap = new HashMap();
        
        for (final Iterator it = keys.iterator(); it.hasNext();)
        {
            final String key = (String) it.next();
            final String segments[] = key.split("\\."); //$NON-NLS-1$
            
            IPropertySymbol  property = 
                (IPropertySymbol) segmentMap.get(segments[0]);
            
            if (property == null)
            {
                final Object propValue = source.get(key);
                property = SymbolFactory.eINSTANCE.createIPropertySymbol();
                property.setName(segments[0]);
                ITypeDescriptor typeDesc = null;
                
                // TODO: need wrapper object to rationalize
                if (propValue != null)
                {
                    if (propValue instanceof IType)
                    {
                        typeDesc = SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();
                        ((IJavaTypeDescriptor2)typeDesc).setType((IType)propValue);
                    }
                    else if (propValue instanceof IInstanceSymbol)
                    {
                        typeDesc = ((IInstanceSymbol)propValue).getTypeDescriptor();
                    }
                    else if (propValue instanceof IPropertySymbol)
                    {
                        typeDesc = ((IPropertySymbol)propValue).getTypeDescriptor();
                    }
                    else
                    {
                        String className = propValue.getClass().getName();
                        String typeSignature = Signature.createTypeSignature(className, true);
                        typeDesc = SymbolFactory.eINSTANCE.createIMapTypeDescriptor();
                        ((IMapTypeDescriptor)typeDesc).setMapSource(new HashMap());
                        ((IMapTypeDescriptor)typeDesc).setTypeSignatureDelegate(typeSignature);
                        // inherit this descriptor's mutability
                        ((IMapTypeDescriptor)typeDesc).setImmutable(isImmutable());
                        property.setIntermediate(true);  // set the property as intermediate until we find out different
                    }
                    
                    property.setTypeDescriptor(typeDesc);
                    property.setReadable(true);
                    // is only writable if map is not immutable
                    property.setWritable(!isImmutable());
                }
                
                segmentMap.put(segments[0], property);
            }
            
            final ITypeDescriptor typeDesc = property.getTypeDescriptor();            
            
            if (typeDesc instanceof IMapTypeDescriptor)
            {
                if (segments.length == 1)
                {
                    // TODO: not always allowed ((IMapTypeDescriptor)typeDesc).getMapSource().put(null, source.get(key));
                    // property is more than simply intermediate
                    property.setIntermediate(false);
                }
                else
                {
                    ((IMapTypeDescriptor)typeDesc).getMapSource().
                        put(key.substring(key.indexOf('.')+1), source.get(key));
                }
            }
        }
        
        return segmentMap;
    }

    
    
    /**
     * <!-- begin-user-doc -->
     * @param featureID 
     * @param resolve 
     * @param coreType 
     * @return the object for the feature id 
     * <!-- end-user-doc -->
     * @generated
     */
    public Object eGet(int featureID, boolean resolve, boolean coreType) {
        switch (featureID) {
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE:
                return getMapSource();
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE:
                return isImmutable() ? Boolean.TRUE : Boolean.FALSE;
        }
        return super.eGet(featureID, resolve, coreType);
    }

    /**
     * <!-- begin-user-doc -->
     * @param featureID 
     * @param newValue 
     * <!-- end-user-doc -->
     * @generated
     */
    public void eSet(int featureID, Object newValue) {
        switch (featureID) {
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE:
                setMapSource((Map)newValue);
                return;
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE:
                setImmutable(((Boolean)newValue).booleanValue());
                return;
        }
        super.eSet(featureID, newValue);
    }

    /**
     * <!-- begin-user-doc -->
     * @param featureID 
     * <!-- end-user-doc -->
     * @generated
     */
    public void eUnset(int featureID) {
        switch (featureID) {
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE:
                setMapSource(MAP_SOURCE_EDEFAULT);
                return;
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE:
                setImmutable(IMMUTABLE_EDEFAULT);
                return;
        }
        super.eUnset(featureID);
    }

    /**
     * <!-- begin-user-doc -->
     * @param featureID 
     * @return true if is set
     * <!-- end-user-doc -->
     * @generated
     */
    public boolean eIsSet(int featureID) {
        switch (featureID) {
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE:
                return MAP_SOURCE_EDEFAULT == null ? mapSource != null : !MAP_SOURCE_EDEFAULT.equals(mapSource);
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE:
                return immutable != IMMUTABLE_EDEFAULT;
        }
        return super.eIsSet(featureID);
    }

    /**
     * <!-- begin-user-doc -->
     * @return the string representation 
     * <!-- end-user-doc -->
     * @generated
     */
    public String toString() {
        if (eIsProxy()) return super.toString();

        StringBuffer result = new StringBuffer(super.toString());
        result.append(" (mapSource: "); //$NON-NLS-1$
        result.append(mapSource);
        result.append(", immutable: ");  //$NON-NLS-1$
        result.append(immutable);
        result.append(')');
        return result.toString();
    }

} //IMapTypeDescriptorImpl
