/*******************************************************************************
 * 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.StructuredModelManager;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.ui.StructuredTextReconciler;
import org.eclipse.wst.sse.ui.StructuredTextViewer;
import org.eclipse.wst.sse.ui.internal.reconcile.IReconcileStepAdapter;
import org.eclipse.wst.sse.ui.internal.reconcile.ReconcileAnnotationKey;
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;
import org.eclipse.wst.xml.ui.internal.Logger;


/**
 * A reconcile step for ContentModel based documents.
 * @deprecated using reconcileValidator extension point
 */
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 ReconcileAnnotationKey.PARTIAL;
	}

	public void initialValidate() {

		// (pa) perf: add the adapter for every node here
		XMLModel xModel = (XMLModel) StructuredModelManager.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) StructuredModelManager.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()]);
	}
}
