/*******************************************************************************
 * Copyright (c) 2010, 2012 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.jaxb.core.internal.context.java;

import java.util.List;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.resource.java.JavaResourcePackage;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.Filter;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;
import org.eclipse.jpt.jaxb.core.SchemaEntry;
import org.eclipse.jpt.jaxb.core.context.JaxbPackage;
import org.eclipse.jpt.jaxb.core.context.JaxbPackageInfo;
import org.eclipse.jpt.jaxb.core.context.XmlNs;
import org.eclipse.jpt.jaxb.core.context.XmlNsForm;
import org.eclipse.jpt.jaxb.core.context.XmlSchema;
import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
import org.eclipse.jpt.jaxb.core.resource.java.XmlNsAnnotation;
import org.eclipse.jpt.jaxb.core.resource.java.XmlSchemaAnnotation;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.eclipse.xsd.XSDForm;

public class GenericJavaXmlSchema
		extends AbstractJavaContextNode
		implements XmlSchema {
	
	protected String specifiedNamespace;
	
	protected String location;
	
	protected XmlNsForm specifiedAttributeFormDefault;
	
	protected XmlNsForm specifiedElementFormDefault;
	
	protected final ContextListContainer<XmlNs, XmlNsAnnotation> xmlNsPrefixContainer;
	
	
	public GenericJavaXmlSchema(JaxbPackageInfo parent) {
		super(parent);
		this.specifiedNamespace = this.getResourceNamespace();
		this.location = this.getResourceLocation();
		this.specifiedAttributeFormDefault = getResourceAttributeFormDefault();
		this.specifiedElementFormDefault = getResourceElementFormDefault();
		this.xmlNsPrefixContainer = this.buildXmlNsPrefixContainer();
	}
	
	
	// ********** synchronize/update **********
	
	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();
		this.setSpecifiedNamespace_(this.getResourceNamespace());
		this.setLocation_(this.getResourceLocation());
		this.setSpecifiedAttributeFormDefault_(getResourceAttributeFormDefault());
		this.setSpecifiedElementFormDefault_(getResourceElementFormDefault());
		this.syncXmlNsPrefixes();
	}
	
	@Override
	public void update() {
		super.update();
		this.updateXmlNsPrefixes();
	}
	
	public JaxbPackageInfo getJaxbPackageInfo() {
		return (JaxbPackageInfo) getParent();
	}
	
	public JaxbPackage getJaxbPackage() {
		return getJaxbPackageInfo().getJaxbPackage();
	}
	
	protected JavaResourcePackage getResourcePackage() {
		return getJaxbPackageInfo().getResourcePackage();
	}
	
	
	// ********** xml schema annotation **********
	
	protected XmlSchemaAnnotation getXmlSchemaAnnotation() {
		return (XmlSchemaAnnotation) this.getResourcePackage().getNonNullAnnotation(JAXB.XML_SCHEMA);
	}
	
	// ********** namespace **********
	
	public String getNamespace() {
		return (this.specifiedNamespace == null) ? "" : this.specifiedNamespace; //$NON-NLS-1$
	}
	
	public String getSpecifiedNamespace() {
		return this.specifiedNamespace;
	}

	public void setSpecifiedNamespace(String namespace) {
		this.getXmlSchemaAnnotation().setNamespace(namespace);
		this.setSpecifiedNamespace_(namespace);	
	}
	
	protected void setSpecifiedNamespace_(String namespace) {
		String old = this.specifiedNamespace;
		this.specifiedNamespace = namespace;
		this.firePropertyChanged(SPECIFIED_NAMESPACE_PROPERTY, old, namespace);
	}
	
	protected String getResourceNamespace() {
		return getXmlSchemaAnnotation().getNamespace();
	}
	
	
	// ********** location **********
	
	public String getLocation() {
		return this.location;
	}
	
	public void setLocation(String location) {
		this.getXmlSchemaAnnotation().setLocation(location);
		this.setLocation_(location);	
	}
	
	protected void setLocation_(String location) {
		String old = this.location;
		this.location = location;
		this.firePropertyChanged(LOCATION_PROPERTY, old, location);
	}
	
	protected String getResourceLocation() {
		return getXmlSchemaAnnotation().getLocation();
	}
	
	
	// ********** attribute form default **********
	
	public XmlNsForm getAttributeFormDefault() {
		return (this.specifiedAttributeFormDefault == null) ? XmlNsForm.UNSET : this.specifiedAttributeFormDefault;
	}
	
	public XmlNsForm getSpecifiedAttributeFormDefault() {
		return this.specifiedAttributeFormDefault;
	}
	
	public void setSpecifiedAttributeFormDefault(XmlNsForm attributeFormDefault) {
		getXmlSchemaAnnotation().setAttributeFormDefault(XmlNsForm.toJavaResourceModel(attributeFormDefault));
		setSpecifiedAttributeFormDefault_(attributeFormDefault);
	}
	
	protected void setSpecifiedAttributeFormDefault_(XmlNsForm attributeFormDefault) {
		XmlNsForm old = this.specifiedAttributeFormDefault;
		this.specifiedAttributeFormDefault = attributeFormDefault;
		firePropertyChanged(SPECIFIED_ATTRIBUTE_FORM_DEFAULT_PROPERTY, old, attributeFormDefault);
	}
	
	protected XmlNsForm getResourceAttributeFormDefault() {
		return XmlNsForm.fromJavaResourceModel(getXmlSchemaAnnotation().getAttributeFormDefault());
	}
	
	
	// ********** element form default **********
	
	public XmlNsForm getElementFormDefault() {
		return (this.specifiedElementFormDefault == null) ? XmlNsForm.UNSET : this.specifiedElementFormDefault;
	}
	
	public XmlNsForm getSpecifiedElementFormDefault() {
		return this.specifiedElementFormDefault;
	}
	
	public void setSpecifiedElementFormDefault(XmlNsForm elementFormDefault) {
		getXmlSchemaAnnotation().setElementFormDefault(XmlNsForm.toJavaResourceModel(elementFormDefault));
		setSpecifiedElementFormDefault_(elementFormDefault);
	}
	
	protected void setSpecifiedElementFormDefault_(XmlNsForm elementFormDefault) {
		XmlNsForm old = this.specifiedElementFormDefault;
		this.specifiedElementFormDefault = elementFormDefault;
		firePropertyChanged(SPECIFIED_ELEMENT_FORM_DEFAULT_PROPERTY, old, elementFormDefault);
	}
	
	protected XmlNsForm getResourceElementFormDefault() {
		return XmlNsForm.fromJavaResourceModel(getXmlSchemaAnnotation().getElementFormDefault());
	}
	
	
	// ********** xml namespace prefixes **********
	
	public ListIterable<XmlNs> getXmlNsPrefixes() {
		return this.xmlNsPrefixContainer.getContextElements();
	}
	
	public int getXmlNsPrefixesSize() {
		return this.xmlNsPrefixContainer.getContextElementsSize();
	}
	
	public XmlNs addXmlNsPrefix(int index) {
		XmlNsAnnotation annotation = this.getXmlSchemaAnnotation().addXmlns(index);
		return this.xmlNsPrefixContainer.addContextElement(index, annotation);
	}
	
	public void removeXmlNsPrefix(XmlNs xmlNsPrefix) {
		this.removeXmlNsPrefix(this.xmlNsPrefixContainer.indexOfContextElement(xmlNsPrefix));
	}
	
	public void removeXmlNsPrefix(int index) {
		this.getXmlSchemaAnnotation().removeXmlns(index);
		this.xmlNsPrefixContainer.removeContextElement(index);
	}
	
	public void moveXmlNsPrefix(int targetIndex, int sourceIndex) {
		this.getXmlSchemaAnnotation().moveXmlns(targetIndex, sourceIndex);
		this.xmlNsPrefixContainer.moveContextElement(targetIndex, sourceIndex);
	}
	
	protected XmlNs buildXmlNs(XmlNsAnnotation xmlNsAnnotation) {
		return this.getFactory().buildJavaXmlNs(this, xmlNsAnnotation);
	}
	
	protected void syncXmlNsPrefixes() {
		this.xmlNsPrefixContainer.synchronizeWithResourceModel();
	}
	
	protected void updateXmlNsPrefixes() {
		this.xmlNsPrefixContainer.update();
	}

	protected ListIterable<XmlNsAnnotation> getXmlNsAnnotations() {
		return getXmlSchemaAnnotation().getXmlns();
	}

	protected ContextListContainer<XmlNs, XmlNsAnnotation> buildXmlNsPrefixContainer() {
		XmlNsPrefixContainer container = new XmlNsPrefixContainer();
		container.initialize();
		return container;
	}
	
	
	// **************** content assist ****************************************
	
	@Override
	public Iterable<String> getJavaCompletionProposals(
			int pos, Filter<String> filter, CompilationUnit astRoot) {
		Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
		if (! CollectionTools.isEmpty(result)) {
			return result;
		}
		
		if (namespaceTouches(pos, astRoot)) {
			return getNamespaceProposals(filter);
		}
		
		for (XmlNs xmlns : getXmlNsPrefixes()) {
			result = xmlns.getJavaCompletionProposals(pos, filter, astRoot);
			if (! CollectionTools.isEmpty(result)) {
				return result;
			}
		}
		
		return EmptyIterable.instance();
	}
	
	protected boolean namespaceTouches(int pos, CompilationUnit astRoot) {
		return getXmlSchemaAnnotation().namespaceTouches(pos, astRoot);
	}
	
	protected Iterable<String> getNamespaceProposals(Filter<String> filter) {
		return StringTools.convertToJavaStringLiterals(
				new FilteringIterable<String>(
						new TransformationIterable<SchemaEntry, String>(
								getJaxbProject().getSchemaLibrary().getSchemaEntries()) {
							@Override
							protected String transform(SchemaEntry o) {
								return o.getNamespace();
							}
						}, 
						filter));
	}
	
	
	// **************** validation ********************************************
	
	@Override
	public TextRange getValidationTextRange(CompilationUnit astRoot) {
		return getXmlSchemaAnnotation().getTextRange(astRoot);
	}
	
	
	
	@Override
	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		super.validate(messages, reporter, astRoot);
		
		// removing this validation message for now:  see jaxb bug 823 (http://java.net/jira/browse/JAXB-823)
//		XsdSchema schema = getJaxbPackage().getXsdSchema();
//		if (schema != null) {
//			if (formConflicts(getAttributeFormDefault(), schema.getXSDComponent().getAttributeFormDefault())) {
//				messages.add(
//				DefaultValidationMessages.buildMessage(
//					IMessage.HIGH_SEVERITY,
//					JaxbValidationMessages.XML_SCHEMA__MISMATCHED_ATTRIBUTE_FORM_DEFAULT,
//					this,
//					getXmlSchemaAnnotation().getAttributeFormDefaultTextRange(astRoot)));
//			}
//			
//			if (formConflicts(getElementFormDefault(), schema.getXSDComponent().getElementFormDefault())) {
//				messages.add(
//				DefaultValidationMessages.buildMessage(
//					IMessage.HIGH_SEVERITY,
//					JaxbValidationMessages.XML_SCHEMA__MISMATCHED_ELEMENT_FORM_DEFAULT,
//					this,
//					getXmlSchemaAnnotation().getElementFormDefaultTextRange(astRoot)));
//			}
//		}
	}
	
	protected boolean formConflicts(XmlNsForm form, XSDForm xsdForm) {
		return (form == XmlNsForm.QUALIFIED) ^ (xsdForm == XSDForm.QUALIFIED_LITERAL);
	}
	
	
	/**
	 * xml ns prefix container adapter
	 */
	protected class XmlNsPrefixContainer
			extends ContextListContainer<XmlNs, XmlNsAnnotation> {
		
		@Override
		protected String getContextElementsPropertyName() {
			return XML_NS_PREFIXES_LIST;
		}
		
		@Override
		protected XmlNs buildContextElement(XmlNsAnnotation resourceElement) {
			return GenericJavaXmlSchema.this.buildXmlNs(resourceElement);
		}
		
		@Override
		protected ListIterable<XmlNsAnnotation> getResourceElements() {
			return GenericJavaXmlSchema.this.getXmlNsAnnotations();
		}
		
		@Override
		protected XmlNsAnnotation getResourceElement(XmlNs contextElement) {
			return contextElement.getResourceXmlNs();
		}
	}
}
