/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.ui.reconcile;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcileResult;
import org.eclipse.jface.text.reconciler.IReconcileStep;
import org.eclipse.wst.sse.core.AdapterFactory;
import org.eclipse.wst.sse.core.INodeNotifier;
import org.eclipse.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.PropagatingAdapter;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.ui.Logger;
import org.eclipse.wst.sse.ui.StructuredTextReconciler;
import org.eclipse.wst.sse.ui.StructuredTextViewer;
import org.eclipse.wst.sse.ui.internal.reconcile.IReconcileAnnotationKey;
import org.eclipse.wst.sse.ui.internal.reconcile.IReconcileStepAdapter;
import org.eclipse.wst.sse.ui.internal.reconcile.StructuredReconcileStep;
import org.eclipse.wst.xml.core.document.XMLDocument;
import org.eclipse.wst.xml.core.document.XMLModel;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.eclipse.wst.xml.core.parser.XMLRegionContext;


/**
 * A reconcile step for ContentModel based documents.
 */
public class ReconcileStepForContentModel extends StructuredReconcileStep {
	private HashSet fLocalPartitionTypes = null;

	protected boolean fRanInitialValidate = false;

	public ReconcileStepForContentModel() {
		super();
		fLocalPartitionTypes = new HashSet();
	}

	public ReconcileStepForContentModel(StructuredTextViewer viewer, IReconcileStep step) {
		super(step);
		fLocalPartitionTypes = new HashSet();
	}

	private void addPartitionTypes(String[] types) {
		for (int i = 0; i < types.length; i++)
			fLocalPartitionTypes.add(types[i]);
	}

	/**
	 * Need to add partition types for ReconcileStepAdapterForXML here...
	 * 
	 */
	public String[] getPartitionTypes() {
		String[] superPartitionTypes = super.getPartitionTypes();
		String[] results = new String[superPartitionTypes.length + fLocalPartitionTypes.size()];
		System.arraycopy(superPartitionTypes, 0, results, 0, superPartitionTypes.length);
		System.arraycopy(fLocalPartitionTypes.toArray(), 0, results, superPartitionTypes.length, fLocalPartitionTypes.size());
		return results;
	}

	public int getScope() {
		return IReconcileAnnotationKey.PARTIAL;
	}

	public void initialValidate() {

		// (pa) perf: add the adapter for every node here
		XMLModel xModel = (XMLModel) getModelManager().getExistingModelForRead(getDocument());
		XMLDocument doc = xModel.getDocument();
		xModel.releaseFromRead();
		PropagatingAdapter propagatingAdapter = (PropagatingAdapter) doc.getAdapterFor(PropagatingAdapter.class);

		List factories = propagatingAdapter.getAdaptOnCreateFactories();
		ReconcilerAdapterFactoryForXML rAdapterFactoryForXML = null;
		AdapterFactory temp = null;
		// find the ReconcileStepAdapterFactory
		for (int i = 0; i < factories.size(); i++) {
			temp = (AdapterFactory) factories.get(i);
			if (temp.isFactoryForType(IReconcileStepAdapter.class)) {
				rAdapterFactoryForXML = (ReconcilerAdapterFactoryForXML) temp;
				break;
			}
		}

		if (rAdapterFactoryForXML != null) {
			rAdapterFactoryForXML.setShouldMarkForReconciling(false);
			initialValidateTree(doc, rAdapterFactoryForXML);
			rAdapterFactoryForXML.setShouldMarkForReconciling(true);
		}
	}

	/**
	 * Mark the INodeNotifier (Node) and all children of the INodeNotifier
	 * passed in.
	 * 
	 * @param notifier
	 */
	protected void initialValidateTree(INodeNotifier notifier, AdapterFactory rAdapterFactoryForXML) {
		if (isCanceled())
			return;

		if (notifier != null && notifier instanceof XMLNode) {
			XMLNode current = (XMLNode) notifier;
			IReconcileStepAdapter adapter = null;
			// loop siblings
			// pa_TODO for large XML files this loop goes for a LONG time
			// and the progress monitor never gets canceled
			while (current != null && !isCanceled()) {
				// adapt this notifier
				adapter = (IReconcileStepAdapter) rAdapterFactoryForXML.adapt(current);
				if (adapter != null) {
					((AbstractReconcileStepAdapter) adapter).setParentStep(this);
					adapter.markForReconciling(current);
					current.addAdapter(adapter);
					adapter.reconcile(getProgressMonitor(), current);
				}
				if (current.getFirstChild() != null) {
					initialValidateTree((XMLNode) current.getFirstChild(), rAdapterFactoryForXML);
				}
				current = (XMLNode) current.getNextSibling();
			}
		}
	}


	// Determines whether the IStructuredDocumentRegion is a XML "end tag"
	// since they're not allowed to have
	// attribute ITextRegions
	protected boolean isEndTag(IStructuredDocumentRegion structuredDocumentRegion) {
		return structuredDocumentRegion.getFirstRegion().getType() == XMLRegionContext.XML_END_TAG_OPEN;
	}

	// Determines whether the IStructuredDocumentRegion is a XML "start tag"
	// since they need to be
	// checked for proper XML attribute region sequences
	protected boolean isStartTag(IStructuredDocumentRegion structuredDocumentRegion) {
		return structuredDocumentRegion.getFirstRegion().getType() == XMLRegionContext.XML_TAG_OPEN;
	}

	// Because we check the "proper" closing separately from attribute
	// sequencing, we need to know what's
	// an appropriate close.
	protected boolean isTagCloseTextRegion(ITextRegion textRegion) {
		return textRegion.getType() == XMLRegionContext.XML_TAG_CLOSE || textRegion.getType() == XMLRegionContext.XML_EMPTY_TAG_CLOSE;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.ui.internal.ui.text.StructuredReconcileStep#reconcileModel(org.eclipse.jface.text.reconciler.DirtyRegion,
	 *      org.eclipse.jface.text.IRegion)
	 */
	protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion, IRegion subRegion) {
		if (dirtyRegion == null)
			return EMPTY_RECONCILE_RESULT_SET;

		// logging ------------------
		Logger.trace(StructuredTextReconciler.TRACE_FILTER, "[trace reconciler] > reconciling model in CONTENT MODEL step w/ dirty region: [" + dirtyRegion.getOffset() + ":" + dirtyRegion.getLength() + "]" + dirtyRegion.getText()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		// --------------------------

		int start = dirtyRegion.getOffset();
		int length = dirtyRegion.getLength();

		IReconcileResult[] results = validate(start, length);

		// logging ------------------
		Logger.trace(StructuredTextReconciler.TRACE_FILTER, "[trace reconciler] > CONTENT MODEL step done"); //$NON-NLS-1$
		// --------------------------
		return results;
	}

	/**
	 * Forces the IReconcilerAdapters for XMLNodes overlapping the given
	 * region to "validate" their Nodes.
	 * 
	 * @param startOffset
	 * @param length
	 */
	protected IReconcileResult[] validate(int startOffset, int length) {
		List results = new ArrayList();
		IReconcileResult[] temp = EMPTY_RECONCILE_RESULT_SET;

		if (!fRanInitialValidate) {
			initialValidate();
			fRanInitialValidate = true;
		} else {
			XMLModel model = (XMLModel) getModelManager().getExistingModelForRead(getDocument());
			int endOffset = startOffset + length;

			IndexedRegion indexedNode = model.getIndexedRegion(startOffset);
			IReconcileStepAdapter adapter = null;

			// sometimes for single key type length can be 0 (startOffset ==
			// endOffset)
			for (int i = startOffset; indexedNode != null && i <= endOffset && !isCanceled(); i++) {

				XMLNode xmlNode = (XMLNode) indexedNode;
				adapter = (IReconcileStepAdapter) xmlNode.getAdapterFor(IReconcileStepAdapter.class);
				if (adapter != null) {
					temp = adapter.reconcile(getProgressMonitor(), xmlNode);
					for (int j = 0; j < temp.length; j++)
						results.add(temp[j]);
					// this is for removal purposes later
					addPartitionTypes(adapter.getPartitionTypes());
				}
				//	visited.add(indexedNode);
				if (xmlNode.getFirstStructuredDocumentRegion() != null)
					i += xmlNode.getFirstStructuredDocumentRegion().getLength();
				else
					i++;

				indexedNode = model.getIndexedRegion(i);
			}
			model.releaseFromRead();
		}
		return (IReconcileResult[]) results.toArray(new IReconcileResult[results.size()]);
	}
}
