/*******************************************************************************
 * Copyright (c) 2006, 2007 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.core.internal.context.java;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.core.internal.IMappingKeys;
import org.eclipse.jpt.core.internal.ITextRange;
import org.eclipse.jpt.core.internal.context.base.IPersistentAttribute;
import org.eclipse.jpt.core.internal.resource.java.Annotation;
import org.eclipse.jpt.core.internal.resource.java.JavaPersistentAttributeResource;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.Filter;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;

public class JavaPersistentAttribute extends JavaContextModel
	implements IJavaPersistentAttribute
{
	protected String name;

	protected IJavaAttributeMapping defaultMapping;

	protected IJavaAttributeMapping specifiedMapping;

	protected JavaPersistentAttributeResource persistentAttributeResource;

	public JavaPersistentAttribute(IJavaPersistentType parent) {
		super(parent);
	}
	
	public void initializeFromResource(JavaPersistentAttributeResource persistentAttributeResource) {
		this.persistentAttributeResource = persistentAttributeResource;
		this.name = this.name(persistentAttributeResource);
		initializeDefaultMapping(persistentAttributeResource);
		initializeSpecifiedMapping(persistentAttributeResource);
	}
	
	protected void initializeDefaultMapping(JavaPersistentAttributeResource persistentAttributeResource) {
		this.defaultMapping = createDefaultJavaAttributeMapping(persistentAttributeResource);
	}

	protected void initializeSpecifiedMapping(JavaPersistentAttributeResource persistentAttributeResource) {
		String javaMappingAnnotationName = this.javaMappingAnnotationName(persistentAttributeResource);
		this.specifiedMapping = createJavaAttributeMappingFromAnnotation(javaMappingAnnotationName, persistentAttributeResource);
	}
	
	public JavaPersistentAttributeResource getPersistentAttributeResource() {
		return this.persistentAttributeResource;
	}
	
	public IJavaPersistentType persistentType() {
		return (IJavaPersistentType) this.parent();
	}

	public IJavaTypeMapping typeMapping() {
		return this.persistentType().getMapping();
	}

	public String primaryKeyColumnName() {
		return this.getMapping().primaryKeyColumnName();
	}

	public boolean isOverridableAttribute() {
		return this.getMapping().isOverridableAttributeMapping();
	}

	public boolean isOverridableAssociation() {
		return this.getMapping().isOverridableAssociationMapping();
	}

	public boolean isIdAttribute() {
		return this.getMapping().isIdMapping();
	}
	
	public String getName() {
		return this.name;
	}
	
	protected void setName(String newName) {
		String oldName = this.name;
		this.name = newName;
		firePropertyChanged(NAME_PROPERTY, oldName, newName);
	}

	public IJavaAttributeMapping getDefaultMapping() {
		return this.defaultMapping;
	}

	/**
	 * clients do not set the "default" mapping
	 */
	protected void setDefaultMapping(IJavaAttributeMapping newDefaultMapping) {
		IJavaAttributeMapping oldMapping = this.defaultMapping;
		this.defaultMapping = newDefaultMapping;	
		firePropertyChanged(IPersistentAttribute.DEFAULT_MAPPING_PROPERTY, oldMapping, newDefaultMapping);
	}

	public IJavaAttributeMapping getSpecifiedMapping() {
		return this.specifiedMapping;
	}

	/**
	 * clients do not set the "specified" mapping;
	 * use #setMappingKey(String)
	 */
	protected void setSpecifiedMapping(IJavaAttributeMapping newSpecifiedMapping) {
		IJavaAttributeMapping oldMapping = this.specifiedMapping;
		this.specifiedMapping = newSpecifiedMapping;	
		firePropertyChanged(IPersistentAttribute.SPECIFIED_MAPPING_PROPERTY, oldMapping, newSpecifiedMapping);
	}

	
	public IJavaAttributeMapping getMapping() {
		return (this.specifiedMapping != null) ? this.specifiedMapping : this.defaultMapping;
	}

	public String mappingKey() {
		return this.getMapping().getKey();
	}

	/**
	 * return null if there is no "default" mapping for the attribute
	 */
	public String defaultMappingKey() {
		return this.defaultMapping.getKey();
	}

	/**
	 * return null if there is no "specified" mapping for the attribute
	 */
	public String specifiedMappingKey() {
		return (this.specifiedMapping == null) ? null : this.specifiedMapping.getKey();
	}

	// TODO support morphing mappings, i.e. copying common settings over
	// to the new mapping; this can't be done in the same was as XmlAttributeMapping
	// since we don't know all the possible mapping types
	public void setSpecifiedMappingKey(String newKey) {
		if (newKey == specifiedMappingKey()) {
			return;
		}
		IJavaAttributeMapping oldMapping = getMapping();
		IJavaAttributeMapping newMapping = createJavaAttributeMappingFromMappingKey(newKey);
		setSpecifiedMapping(newMapping);
		if (newMapping != null) {
			this.persistentAttributeResource.setMappingAnnotation(newMapping.annotationName());
		}
		else {
			this.persistentAttributeResource.setMappingAnnotation(null);			
		}
		
		if (oldMapping != null) {
			Collection<String> annotationsToRemove = CollectionTools.collection(oldMapping.correspondingAnnotationNames());
			if (getMapping() != null) {
				CollectionTools.removeAll(annotationsToRemove, getMapping().correspondingAnnotationNames());
			}
			
			for (String annotationName : annotationsToRemove) {
				this.persistentAttributeResource.removeAnnotation(annotationName);
			}
		}
	}

//	public boolean includes(int offset) {
//		ITextRange fullTextRange = this.fullTextRange();
//		if (fullTextRange == null) {
//			//This happens if the attribute no longer exists in the java.
//			//The text selection event is fired before the update from java so our
//			//model has not yet had a chance to update appropriately. The list of
//			//JavaPersistentAttriubtes is stale at this point.  For now, we are trying
//			//to avoid the NPE, not sure of the ultimate solution to these 2 threads accessing
//			//our model
//			return false;
//		}
//		return fullTextRange.includes(offset);
//	}
//
//	public ITextRange fullTextRange() {
//		return this.attribute.textRange();
//	}

	public ITextRange validationTextRange(CompilationUnit astRoot) {
		return this.selectionTextRange(astRoot);
	}

	public ITextRange selectionTextRange(CompilationUnit astRoot) {
		return this.persistentAttributeResource.textRange(astRoot);
	}

	public void update(JavaPersistentAttributeResource persistentAttributeResource) {
		this.persistentAttributeResource = persistentAttributeResource;
		this.setName(this.name(persistentAttributeResource));
		this.updateDefaultMapping(persistentAttributeResource);
		this.updateSpecifiedMapping(persistentAttributeResource);
	}
	
	protected String name(JavaPersistentAttributeResource persistentAttributeResource) {
		return persistentAttributeResource.getName();	
	}
	
	public String specifiedMappingAnnotationName() {
		return (this.specifiedMapping == null) ? null : this.specifiedMapping.annotationName();
	}
	
	protected void updateSpecifiedMapping(JavaPersistentAttributeResource persistentAttributeResource) {
		String javaMappingAnnotationName = this.javaMappingAnnotationName(persistentAttributeResource);
		if (specifiedMappingAnnotationName() != javaMappingAnnotationName) {
			setSpecifiedMapping(createJavaAttributeMappingFromAnnotation(javaMappingAnnotationName, persistentAttributeResource));
		}
		else {
			if (getSpecifiedMapping() != null) {
				getSpecifiedMapping().update(persistentAttributeResource);
			}
		}
	}
	
	protected void updateDefaultMapping(JavaPersistentAttributeResource persistentAttributeResource) {
		String defaultMappingKey = jpaPlatform().defaultJavaAttributeMappingKey(this);
		if (getDefaultMapping().getKey() != defaultMappingKey) {
			setDefaultMapping(createDefaultJavaAttributeMapping(persistentAttributeResource));
		}
		else {
			getDefaultMapping().update(persistentAttributeResource);
		}
	}
	
	protected String javaMappingAnnotationName(JavaPersistentAttributeResource persistentAttributeResource) {
		Annotation mappingAnnotation = (Annotation) persistentAttributeResource.mappingAnnotation();
		if (mappingAnnotation != null) {
			return mappingAnnotation.getAnnotationName();
		}
		return null;
	}
	
	protected IJavaAttributeMapping createJavaAttributeMappingFromMappingKey(String key) {
		if (key == IMappingKeys.NULL_ATTRIBUTE_MAPPING_KEY) {
			return null;
		}
		return jpaPlatform().createJavaAttributeMappingFromMappingKey(key, this);
	}

	protected IJavaAttributeMapping createJavaAttributeMappingFromAnnotation(String annotationName, JavaPersistentAttributeResource persistentAttributeResource) {
		if (annotationName == null) {
			return null;
		}
		IJavaAttributeMapping mapping = jpaPlatform().createJavaAttributeMappingFromAnnotation(annotationName, this);
		mapping.initializeFromResource(persistentAttributeResource);
		return mapping;
	}

	protected IJavaAttributeMapping createDefaultJavaAttributeMapping(JavaPersistentAttributeResource persistentAttributeResource) {		
		IJavaAttributeMapping defaultMapping = jpaPlatform().createDefaultJavaAttributeMapping(this);
		defaultMapping.initializeFromResource(persistentAttributeResource);
		return defaultMapping;
	}

	/**
	 * the mapping might be "default", but it still might be a "null" mapping...
	 */
	public boolean mappingIsDefault() {
		return this.specifiedMapping == null;
	}

	@Override
	public Iterator<String> candidateValuesFor(int pos, Filter<String> filter, CompilationUnit astRoot) {
		Iterator<String> result = super.candidateValuesFor(pos, filter, astRoot);
		if (result != null) {
			return result;
		}
		return this.getMapping().candidateValuesFor(pos, filter, astRoot);
	}
	
	//************* Validation ******************************
	
	@Override
	public void addToMessages(List<IMessage> messages, CompilationUnit astRoot) {
		super.addToMessages(messages, astRoot);
		
		if (this.specifiedMapping != null) {
			this.specifiedMapping.addToMessages(messages, astRoot);
		}
		else if (this.defaultMapping != null) {
			this.defaultMapping.addToMessages(messages, astRoot);
		}
		
	}
	
	

}
